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

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


    运行结果如下图所示:
这里写图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值