基于Qt的OPenGL可编程管线学习之Hello Triangle

编程入门 行业动态 更新时间:2024-10-09 14:26:35

基于Qt的OPenGL<a href=https://www.elefans.com/category/jswz/34/1763868.html style=可编程管线学习之Hello Triangle"/>

基于Qt的OPenGL可编程管线学习之Hello Triangle

 

之前学习过OpenGL的固定管线,后来了解到现在大部分公司都用可编程管线(programmable pipeline)。所以决定开始研究学习可编程管线。Qt5.*之后对OPenGL的支持更好了。经过一番学习,写了一个基于Qt 的OpenGL例子—— Hello Triangle Demo,在此记录一下加深一下印象,同时让像我一样的新手快速入门。本文假定您对OPenGL 的固定管线有所了解。

一、GLSL(OPenGL Shading Language)初探

现在只需要理解该语言用于编写运行在GPU上程序——“着色器”。下文会介绍如何编写着色器程序。现在先看看一些基本的语法特点。

$1.1类型修饰符

1> uniform:被uniform修饰的变量是在CPU程序中设置好的变量,对于着色器(vertex shader/fragment shader)只可以读。我们的CPU程序通过调用glUniform*()函数来对该变量赋值。例如下文中我们会使用代码来设置与平接头体(frustum)相关的矩阵供着色器使用。

// CPU Application 代码片段
_program->setUniformValue(_matrixUniform, matrix);// shader代码片段
uniform highp mat4 matrix;

2> attribute:被attribute修饰的变量是只能在vertex shader中使用的变量。不能在fragment shader中声明attribute变量,也不能被fragment shader使用。attribute表示一些顶点的数据比如:顶点坐标,法线,纹理坐标,顶点颜色等。

// CPU 顶点与颜色属性设置;
glVertexAttribPointer(_posAttr, 2, GL_FLOAT, GL_FALSE,0, vertexs);
glVertexAttribPointer(_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);// vertex shader代码片段,位置(posAttr)、颜色(colAttr)属性;
layout (location = 0) in vec4 posAttr;
attribute lowp vec4 colAttr;

3> varying :被varying修饰的变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改该变量的值,然后fragment shader使用该变量的值。因此变量在vertex和fragment shader二者之间的声明必须是一致的。CPU 程序不能使用此变量。

// vertex sharder
varying lowp vec4 col;
col = colAttr; // 赋值;// fragment sharder
varying lowp vec4 col;
gl_FragColor = col; // 读取到gl_FragColor[shader build-in]

二、CPU程序编码流程

这里简单列出Qt5OPenGL的使用方法,具体的OPenGL函数使用方式,将在下一篇与VAO一起陈述,基本流程如下图所示:

1.子类化QOpenGLWidget,重写下边函数。

2.初始化:初始化opengl函数(Qt 要求)——》编写着色器——》编译着色器——》链接着色器——》获取属性等的位置

3. 视口映射。

4.绘制

class QOpenGLShaderProgram;class OpenGLWidget : public QOpenGLWidget,protected QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:explicit OpenGLWidget(QWidget *parent = nullptr);protected:void initializeGL() override;void resizeGL(int widget, int height) override;void paintGL() override;private:QOpenGLShaderProgram *_program;GLuint _posAttr;GLuint _colAttr;GLuint _matrixUniform;
};
void OpenGLWidget::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.f, 0.f, 0.f,1.f);const static char *vertexShaderStr ="#version 330 core\n""layout (location = 0) in vec4 posAttr;\n""attribute lowp vec4 colAttr;\n""varying lowp vec4 col;\n""uniform highp mat4 matrix;\n""void main()\n""{\n""  col = colAttr;\n""   gl_Position = matrix * posAttr;\n""}\n";const static char *fragmentShaderStr ="#version 330 core\n""varying lowp vec4 col;\n""void main()\n""{\n""gl_FragColor = col;\n""}\n";QOpenGLShader *vertexShader =new QOpenGLShader(QOpenGLShader::Vertex, this);vertexShader->compileSourceCode(vertexShaderStr);QOpenGLShader *fragmentShader =new QOpenGLShader(QOpenGLShader::Fragment, this);fragmentShader->compileSourceCode(fragmentShaderStr);_program = new QOpenGLShaderProgram(this);_program->addShader(vertexShader);_program->addShader(fragmentShader);_program->link();_posAttr = _program->attributeLocation("posAttr");_colAttr = _program->attributeLocation("colAttr");_matrixUniform = _program->uniformLocation("matrix");
}

 

void OpenGLWidget::resizeGL(int w, int h)
{glViewport(0, 0, w, h);
}
void OpenGLWidget::paintGL()
{glClear(GL_COLOR_BUFFER_BIT);static GLfloat vertexs[] = {0.0f, 0.707f,-0.5f, -0.5f,0.5f, -0.5f};static GLfloat colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f};_program->bind();QMatrix4x4 matrix;matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);matrix.translate(0, 0, -2);_program->setUniformValue(_matrixUniform, matrix);glVertexAttribPointer(_posAttr, 2, GL_FLOAT, GL_FALSE,0, vertexs);glVertexAttribPointer(_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);glEnableVertexAttribArray(0);glEnableVertexAttribArray(1);glDrawArrays(GL_TRIANGLES, 0, 3);glDisableVertexAttribArray(1);glDisableVertexAttribArray(0);_program->release();}

三、运行结果

 

四、参考文献

Qt document

《OPenGL编程指南 9th edition》

下一篇将记录如何使用VAO以及介绍OPenGL绘制三角形的细节。 

 

 

 

更多推荐

基于Qt的OPenGL可编程管线学习之Hello Triangle

本文发布于:2024-03-08 16:49:35,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1721503.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:可编程   管线   Qt   OPenGL   Triangle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!