网上代码《QT5.7中使用OpenGL开发记录(二)---- 绘制三角形》源代码改良

原文:https://blog.csdn.net/lonely_13/article/details/78960299
最近学习QT+OpenGL,OpenGL入门之后需要在QT上使用,貌似网上只有这个代码最全,但是编译起来各种问题,非常要命。
最终再根据QT官方文档等其他资料终于将这个代码补全,喜欢的点个赞就很感谢了。
vertexshader.vert

#version 330 core
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;

void main(void)
{
    fColor = vColor;
    gl_Position = matrix * vPosition;
}

fragmentshader.frag

#version 330 core
in vec4 fColor;

void main(void)
{
    gl_FragColor = fColor;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtWidgets/QMainWindow>
#include "ui_mainwindow.h"

class mainwindow : public QMainWindow
{
	Q_OBJECT

public:
	mainwindow(QWidget *parent = 0);
	~mainwindow();

private:
	Ui::mainwindowClass ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "OpenGLWidget.h"
#include <QVBoxLayout>
mainwindow::mainwindow(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	OpenGLWidget* openGLWidget = new OpenGLWidget();
	//为了便于让OpenGLWidget自动填充父窗口,这里为父窗口设置了一个布局
	QVBoxLayout* centralLayout = new QVBoxLayout();
	centralLayout->addWidget(openGLWidget);
	ui.centralWidget->setLayout(centralLayout);
}

mainwindow::~mainwindow()
{

}

OpenGLWidget.h

#pragma once
#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
	explicit OpenGLWidget(QWidget *parent = 0);

protected:
	void initializeGL();
	void paintGL();
	void resizeGL(int w, int h);
	void initVbo();
	QOpenGLShaderProgram* program;
	GLuint programId;
	GLint matrixLocation;
	GLint vertexLocation;
	GLint clorLocation;
	QMatrix4x4 projection;
	GLuint vVerticesLen;
	GLuint triIndexLen;
	GLuint colorsLen;
	GLuint verVbo;
	GLuint indexVbo;
	GLuint colorVbo;
};

OpenGLWidget.cpp

#include "OpenGLWidget.h"
#include <iostream>
#include <string>
//三角形顶点坐标
GLfloat vertex[] = {
	-0.5f, 0.0f,
	0.5f, 0.0f,
	0.0f, 0.5f,
};

//三角形顶点索引
GLuint triIndexs[] = { 0, 1, 2 };

//三角形顶点颜色
GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
OpenGLWidget::OpenGLWidget(QWidget *parent)
{
}


//OpenGLWidget::~OpenGLWidget()
//{
//}
void OpenGLWidget::initializeGL()
{
	//调用内容初始化函数
	initializeOpenGLFunctions();

	program = new QOpenGLShaderProgram(this);

	if (!program->addShaderFromSourceFile(QOpenGLShader::Vertex, "vertexshader.vert")){
		return;
	}
	if (!program->addShaderFromSourceFile(QOpenGLShader::Fragment, "fragmentshader.frag")){
		return;
	}
	if (!program->link()){
		return;
	}
	if (!program->bind()){
		return;
	}

	// 获取shaderprogram的id号,然后可以通过id号获取一些属性...
	programId = program->programId();

	// 从shaderprogram里面获取变量标识
	matrixLocation = glGetUniformLocation(programId, "matrix");
	vertexLocation = glGetAttribLocation(programId, "vPosition");
	clorLocation = glGetAttribLocation(programId, "vColor");

	initVbo();
}
void OpenGLWidget::resizeGL(int w, int h)
{
	glViewport(0, 0, w, h);

	// 模型矩阵重置
	projection.setToIdentity();
	// 透视投影
	qreal aspect = qreal(w) / qreal(h ? h : 1);
	projection.perspective(60.0f, aspect, 1.0f, 100.0f);
	// 增加了模型矩阵,需要做一定偏移量,保证物体刚开始渲染出来时可以被看到!
	projection.translate(0.0f, 0.0f, -2.0f);
}
void OpenGLWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

	// shader传入模型视图矩阵 projection可以理解为建立了一个坐标系空间,可以再这个空间内设置图形
	glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, projection.data());

	// shader绑定并启用颜色数组buffer
	glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
	glVertexAttribPointer(clorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(clorLocation);
	// 颜色值rgba,所以每四个float值作为一个颜色值,如果只是希望rgb,取三个值作为颜色值即可!


	// shader绑定并启用顶点数组buffer
	glBindBuffer(GL_ARRAY_BUFFER, verVbo);
	glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(vertexLocation);

	// shader绑定并顶点索引数组buffer - 索引无需启用
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
	glDrawElements(GL_TRIANGLES, triIndexLen, GL_UNSIGNED_INT, 0);

	// 解绑buffer、关闭启用顶点、颜色数组
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glDisableVertexAttribArray(vertexLocation);
	glDisableVertexAttribArray(clorLocation);
}
void OpenGLWidget::initVbo(){
	// 计算获得数组长度
	vVerticesLen = sizeof(vertex) / sizeof(GLfloat);
	triIndexLen = sizeof(triIndexs) / sizeof(GLuint);
	colorsLen = sizeof(colors) / sizeof(GLfloat);

	// 初始化顶点buffer并装载数据到显存
	glGenBuffers(1, &verVbo);
	glBindBuffer(GL_ARRAY_BUFFER, verVbo);
	glBufferData(GL_ARRAY_BUFFER, vVerticesLen * sizeof(GLfloat), vertex, GL_STATIC_DRAW);

	// 初始化索引buffer并装载数据到显存
	glGenBuffers(1, &indexVbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, triIndexLen * sizeof(GLuint), triIndexs, GL_STATIC_DRAW);

	// 初始化颜色buffer并装载数据到显存
	glGenBuffers(1, &colorVbo);
	glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
	glBufferData(GL_ARRAY_BUFFER, colorsLen * sizeof(GLfloat), colors, GL_STATIC_DRAW);
}

main.cpp

#include "mainwindow.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	mainwindow w;
	w.show();
	return a.exec();
}

测试能成功生成结果(不要自己调用继承的函数)
网上代码《QT5.7中使用OpenGL开发记录(二)---- 绘制三角形》源代码改良_第1张图片

你可能感兴趣的:(#,OpenGL)