OpenGL+Qt界面(三) Qt中实现OPENGL的基本交互+代码

来源:互联网 发布:唐安琪最新知乎 编辑:程序博客网 时间:2024/06/05 18:31

  • 开发环境
  • 实现结果
  • 实现步骤
  • 具体实现与代码
    • 增加交互函数
    • 修改simplevert
    • 设置uniform变量
    • 新增shader
    • 新增shaderProgram
    • 设置坐标shader的uniform
  • 工程文件
  • 参考

开发环境

vs2015+Qt5

实现结果

依赖于Qt的的一个界面,能够进行一定的交互和显示坐标轴
这里写图片描述

实现步骤

实现物体的移动
- 重新定义鼠标交互函数
- 修改shader文件,增加uniform变量
- 设置uniform变量
* 增加坐标轴*
- 新增shader
- 新增shaderProgram
- 设置unifom

具体实现与代码

1 增加交互函数

scenewindow.hpp

//新增函数protected:    void mouseMoveEvent(QMouseEvent *event);    void wheelEvent(QWheelEvent *event);    void mousePressEvent(QMouseEvent *event);    void mouseReleaseEvent(QMouseEvent *event);//新增交互变量private:    QCursor cursor; // 管理光标形状    QVector3D cameraPos = QVector3D(0.0f, 0.0f, 3.0f);    //相机位置    QVector3D worldCentrol = QVector3D(0.0f, 0.0f, 0.0f); //世界坐标原点,相机朝向    QVector3D cameraUp = QVector3D(0.0f, 1.0f, 0.0f);     //相机的顶部朝向y轴    QVector3D transVec = QVector3D(0.0f, 0.0f, 0.0f);     //局部坐标在世界坐标中的平移量(构建ModelMatrix,进行“局部空间”到“世界空间”的转换)    GLfloat yaw = 0.0f;       //偏航角      GLfloat pitch = 0.0f;     //俯仰角      GLfloat lastX = 0;        //光标上次x值      GLfloat lastY = 0;        //光标上次y值  

scenewindow.cpp
在构造函数中新增

cursor.setShape(Qt::ArrowCursor);setCursor(cursor);

增加交互函数

void SceneWindow::mouseMoveEvent(QMouseEvent *event){    //鼠标左键用来实现对物体的旋转功能      if (event->buttons() == Qt::LeftButton)    {        //设置光标形状          cursor.setShape(Qt::ClosedHandCursor);        setCursor(cursor);        //计算yaw,pitch值的改变量          GLfloat xoffset = event->x() - lastX;        GLfloat yoffset = event->y() - lastY;        lastX = event->x();        lastY = event->y();        GLfloat sensitivity = 0.4f;     //旋转时的灵敏度          xoffset *= sensitivity;        yoffset *= sensitivity;        yaw += xoffset;        pitch += yoffset;        //可以用来设置俯仰角的上下界          if (pitch > 89.0f)            pitch = 89.0f;        if (pitch < -89.0f)            pitch = -89.0f;    }    //鼠标右键用来实现对移动物体(即局部坐标在世界坐标中的移动)      else if (event->buttons() == Qt::RightButton)    {        //计算x,y方向的偏移量          GLfloat xoffset = event->x() - lastX;        GLfloat yoffset = event->y() - lastY;        lastX = event->x();        lastY = event->y();        GLfloat sensitivity = 0.01f;    //移动时的灵敏度          xoffset *= sensitivity;        yoffset *= sensitivity;        //仅需在x-y平面内移动即可          transVec += QVector3D(xoffset, -yoffset, 0.0f);    }}//滚轮实现对物体的放大缩小,摄像机距离远近(放大缩小)  void SceneWindow::wheelEvent(QWheelEvent *event){    GLfloat sensitivity = 0.0005f;    cameraPos *= (1.0f - event->delta() * sensitivity);}void SceneWindow::mousePressEvent(QMouseEvent *event){    if (event->button() == Qt::LeftButton)    {        //设置光标形状          cursor.setShape(Qt::PointingHandCursor);        setCursor(cursor);    }    else if (event->button() == Qt::RightButton)    {        //设置光标形状          cursor.setShape(Qt::SizeAllCursor);        setCursor(cursor);    }    //记录点击光标时的位置      lastX = event->x();    lastY = event->y();}void SceneWindow::mouseReleaseEvent(QMouseEvent *event){    //设置光标形状      cursor.setShape(Qt::ArrowCursor);    setCursor(cursor);}

2 修改simple.vert

simple.vert

#version 330 corelayout(location = 0) in vec3 vPosition;layout(location = 1) in vec3 vColor;uniform mat4 model;uniform mat4 view;uniform mat4 projection;out vec3 Color;void main(){    gl_Position = projection * view * model * vec4(vPosition, 1.0);    Color = vColor;}

3 设置uniform变量

在paintGL中增加

//渲染彩色正方体  shaderCube.bind();QMatrix4x4 view;QMatrix4x4 projection;QMatrix4x4 model;view.lookAt(cameraPos, worldCentrol, cameraUp);projection.perspective(45.0f, 4.0f / 3.0f, 0.1f, 100000.0f);model.translate(transVec);model.rotate(pitch, 1.0f, 0.0f, 0.0f);  //按住左键,上下拖动鼠标让立方体绕x轴旋转  model.rotate(yaw, 0.0f, 1.0f, 0.0f);    //按住左键,左右拖动鼠标让立方体绕y轴旋转 shaderCube.setUniformValue("view", view);shaderCube.setUniformValue("projection", projection);shaderCube.setUniformValue("model", model);glBindVertexArray(IDVAO[0]);glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);glBindVertexArray(0);

4 新增shader

在shader文件中新增一个coordinate.vert 的文件

#version 330 corelayout(location = 0) in vec3 vPosition;layout(location = 1) in vec3 vColor;out vec3 Color;uniform mat4 modelCoor;uniform mat4 viewCoor;uniform mat4 projectionCoor;void main(){    Color = vColor;    gl_Position = projectionCoor * viewCoor * modelCoor * vec4(vPosition,1.0);}

5 新增shaderProgram

在SceneWindow中新增私有变量:
QOpenGLShaderProgram shaderCoor;

在initializeGL中增加

//初始化坐标着色器程序 shaderCoor.addShaderFromSourceFile(QOpenGLShader::Vertex, "shader/coordinate.vert");shaderCoor.addShaderFromSourceFile(QOpenGLShader::Fragment, "shader/simple.frag");shaderCoor.link();//新增坐标//绘制坐标数据      GLfloat coorVertices[] =    {        0.0f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f,        0.05f, 0.0f,  0.0f,  1.0f, 0.0f, 0.0f,        0.0f,  0.0f,  0.0f,  0.0f, 1.0f, 0.0f,        0.0f,  0.05f, 0.0f,  0.0f, 1.0f, 0.0f,        0.0f,  0.0f,  0.0f,  0.0f, 0.0f, 1.0f,        0.0f,  0.0f,  0.05f, 0.0f, 0.0f, 1.0f    };// 绑定 VAO VBO/* 显示坐标信息 */    glBindVertexArray(IDVAO[1]);    //开始记录状态信息      glBindBuffer(GL_ARRAY_BUFFER, IDVBO[1]);    glBufferData(GL_ARRAY_BUFFER, sizeof(coorVertices), coorVertices, GL_STATIC_DRAW);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);    glEnableVertexAttribArray(0);    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));    glEnableVertexAttribArray(1);    glBindBuffer(GL_ARRAY_BUFFER, 0);    glBindVertexArray(0);           //结束记录状态信息  

6 设置坐标shader的uniform

在paintGL函数中新增

shaderCoor.bind();    QMatrix4x4 viewCoor1;    QMatrix4x4 projectionCoor1;    QMatrix4x4 modelCoor1;    viewCoor1.lookAt(cameraPos, worldCentrol, cameraUp);    projectionCoor1.perspective(45.0f, 5.0f / 3.0f, 0.1f, 100000.0f);    //modelCoor1.translate(QVector3D(-0.48f, -0.28f, cameraPos1.length()-0.8f));    modelCoor1.setToIdentity();    modelCoor1.translate(QVector3D(-0.48f, -0.28f, cameraPos.length() - 0.8f));    modelCoor1.rotate(pitch, 1.0f, 0.0f, 0.0f);    modelCoor1.rotate(yaw, 0.0f, 1.0f, 0.0f);    shaderCoor.setUniformValue("viewCoor", viewCoor1);    shaderCoor.setUniformValue("projectionCoor", projectionCoor1);    shaderCoor.setUniformValue("modelCoor", modelCoor1);    glBindVertexArray(IDVAO[1]);    glDrawArrays(GL_LINES, 0, 2);    glDrawArrays(GL_LINES, 2, 2);    glDrawArrays(GL_LINES, 4, 2);    glBindVertexArray(0);

工程文件

百度云链接: https://pan.baidu.com/s/1c2wC3By 密码: m271

下一篇 Qt+OpenGL(五) 纹理贴图

参考

如何在Qt5中嵌入一个OpenGL程序部件
QOpenGLShaderProgram文档
QMatrix4x4 文档