您的位置:首页 > 编程语言 > Qt开发

QT5.7中使用OpenGL开发记录(二)---- 绘制三角形

2018-01-03 13:44 483 查看

QT5.7中使用OpenGL开发记录(二)

    前言:最近在做一个项目,需要使用QT结合OpenGL进行开发。由于原来没有怎么用过OpenGL,只知道是个开源图形库,所以先在网上查询了一些资料,发现QT5.5以上版本已经集成了OpenGL,不过和纯OpenGL的使用有些区别,而且相关资料较少。为了便于后续开发并且方便大家共同学习,这里将我的学习过程进行记录(本博客内容只记录了本人的学习过程,不保证完整性和准确性,如想系统学习请绕行。)。由于本人图形开发经验较少,如有错漏敬请指出。

OpenGL渲染管线

    为了能更好的理解下文介绍的内容,需要先先对OpenGL的渲染管线有一定理解。这部分内容网上介绍的比较多,我就贴一个CSDN上看到相关博客,希望不了解的读者先自己了解下。

    http://blog.csdn.net/heyuchang666/article/details/50016865

绘制三角形

    在OpenGL中无论是2D图形还是3D图形,通常都使用三角形作为基本图元,在OpenGL上绘制三角形主要分为如下几步:

1. 准备数据:顶点、三角形顶点索引、颜色

//三角形顶点坐标
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,
};


2. 编写顶点着色器和片段着色器

     OpenGL中提供了这两种这色器的文件格式,在“新建文件->GLSL”中可以找到,我们选择Desktop版本的文件。我的工程中,文件名分别是vertexshader.vert和fragmentshader.frag,代码如下:

//vertexshader.vert
uniform mat4 matrix;
in vec4 vPosition;
in vec4 vColor;
out vec4 fColor;

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


//fragmentshader.frag
in vec4 fColor;

void main(void)
{
gl_FragColor = fColor;
}


     程序中,vPosition和vColor是用来承接三角形的位置和颜色数据的;matrix是模型矩阵,可以用来进行移动、旋转等变化;fColor是顶点着色器和片段着色器间的交互数据;gl_Position和gl_FrgColor是OpenGL内部识别变量。

3. 初始化OpenGL并载入模型参数

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::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);
}


4. 修改重置尺寸

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);
}


5. 修改绘制函数

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);
}


    运行结果如下图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt opengl qt5 图形
相关文章推荐