学习笔记3--给窗口添加一个小坐标
来源:互联网 发布:剑灵金燕捏脸数据 编辑:程序博客网 时间:2024/06/09 22:16
这次添加的内容同样是基于上一次的博文,本次打算添加两个内容:
(1) 在用光标与立方体进行交互时,改变光标的形状,让我们的界面更专业一点;
(2) 在OpenGL窗口的左下角添加一个三维直角坐标系,用来指示立方体当前的方向。
下面分别介绍两个内容的具体实现:
(1) 改变光标形状
首先,在openglwindow.h中添加私有数据成员用来管理光标:
private: QCursor cursor; //管理光标的显示形状
然后,在openglwindow.cpp中的构造函数中初试化在上一步中添加的数据成员:
//设置光标形状 cursor.setShape(Qt::ArrowCursor); setCursor(cursor);接下来,在openglwindow.h中添加光标释放事件:
void mouseReleaseEvent(QMouseEvent *event);接着在对鼠标事件进行更改:
void openglwindow::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 += glm::vec3(xoffset, -yoffset, 0.0f); }}//滚轮实现对物体的放大缩小,摄像机距离远近(放大缩小)void openglwindow::wheelEvent(QWheelEvent *event){ GLfloat sensitivity = 0.0005f; cameraPos *= (1.0f - event->delta() * sensitivity);}void openglwindow::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 openglwindow::mouseReleaseEvent(QMouseEvent *event){ //设置光标形状 cursor.setShape(Qt::ArrowCursor); setCursor(cursor);}(2) 添加三维坐标系
画坐标系无非就是画三条相互垂直的线。
首先,添加着色器,着色器程序,VAO,VBO等的数目(此处片段着色器与渲染立方体时相同):
const GLuint NumVertexShader = 2; //顶点着色器的数目const GLuint NumFragmentShader = 1; //片段着色器的数目const GLuint NumShaderProgram = 2; //着色器程序的数目const GLuint NumVAO = 2; //VAO的数目const GLuint NumVBO = 2; //VBO的数目然后,添加顶点着色器源码:
const GLchar *vertexShaderSource1 = //绘制三维坐标 "#version 330 core\n" "layout(location = 0) in vec3 vPosition;\n" "layout(location = 1) in vec3 vColor;\n" "out vec3 Color;\n" "uniform mat4 modelCoor;\n" "uniform mat4 viewCoor;\n" "uniform mat4 projectionCoor;\n" "void main()\n" "{\n" "Color = vColor;\n" "gl_Position = projectionCoor * viewCoor * modelCoor * vec4(vPosition, 1.0);\n" "}\n";接下来,在initializeGL函数中添加编译和链接着色器程序、添加坐标轴数据、添加VAO和VBO相关信息:
/* 第二个顶点着色器 */ IDVertexShader[1] = glCreateShader(GL_VERTEX_SHADER); glShaderSource(IDVertexShader[1], 1, &vertexShaderSource1, nullptr); glCompileShader(IDVertexShader[1]); //检查编译是否出错 glGetShaderiv(IDVertexShader[1], GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(IDVertexShader[1], 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; }
/* 第二个着色器程序 */ IDShaderProgram[1] = glCreateProgram(); glAttachShader(IDShaderProgram[1], IDVertexShader[1]); glAttachShader(IDShaderProgram[1], IDFragmentShader[0]); glLinkProgram(IDShaderProgram[1]); //检查链接错误 glGetProgramiv(IDShaderProgram[1], GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(IDShaderProgram[1], 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; }
//绘制坐标数据 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 };
/* 坐标 */ 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); //结束记录状态信息 /* 坐标 */最后,在paintGL函数中绘制坐标轴:
//画坐标 glUseProgram(IDShaderProgram[1]); glm::mat4 viewCoor; glm::mat4 projectionCoor; glm::mat4 modelCoor; GLint modelCoorLoc = glGetUniformLocation(IDShaderProgram[1], "modelCoor"); GLint viewCoorLoc = glGetUniformLocation(IDShaderProgram[1], "viewCoor"); GLint projCoorLoc = glGetUniformLocation(IDShaderProgram[1], "projectionCoor"); viewCoor = glm::lookAt(cameraPos, worldCentrol, cameraUp); projectionCoor = glm::perspective(glm::radians(45.0f), 5.0f / 3.0f, 0.1f, 100000.0f); //modelCoor = glm::translate(modelCoor, glm::vec3(-0.38f, -0.28f, glm::length(cameraPos) - 0.8f)); modelCoor = glm::translate(modelCoor, glm::vec3(-0.48f, -0.28f, glm::length(cameraPos) - 0.8f)); modelCoor = glm::rotate(modelCoor, glm::radians(pitch), glm::vec3(1.0f, 0.0f, 0.0f)); modelCoor = glm::rotate(modelCoor, glm::radians(yaw), glm::vec3(0.0f, 1.0f, 0.0f)); glUniformMatrix4fv(viewCoorLoc, 1, GL_FALSE, glm::value_ptr(viewCoor)); glUniformMatrix4fv(projCoorLoc, 1, GL_FALSE, glm::value_ptr(projectionCoor)); glUniformMatrix4fv(modelCoorLoc, 1, GL_FALSE, glm::value_ptr(modelCoor)); glBindVertexArray(IDVAO[1]); glDrawArrays(GL_LINES, 0, 2); glDrawArrays(GL_LINES, 2, 2); glDrawArrays(GL_LINES, 4, 2); glBindVertexArray(0);这样内容就添加完成了。
现在看一下效果:
这样,一个用来显示立方体的小程序就基本完成,当然这只是一个初级的原型,可以在这个原型的基础上添加一些功能,用来显示三维模型或者点云之类的。
编译环境及版本:Win10企业版+Qt 5.7.1(MSVC 2015, 32bit)+OpenGL3.3 Core Profile
1 0
- 学习笔记3--给窗口添加一个小坐标
- JavaScript学习笔记27-给对象添加一个方法
- 添加一个frame 坐标
- 给显示窗口添加一个Resizeable的角标
- 给hiAlert插件添加一个关闭窗口的方法
- HTML&CSS基础学习笔记1.28-给网页添加一个css样式
- 学习win32 API开发6-给窗口添加菜单
- appwidget 窗口小部件学习笔记
- VS2015使用小技巧 给一个项目添加类
- QT 给窗口添加图片
- 弹出一个小窗口
- maven3学习笔记3--maven的坐标
- unity3d基础学习笔记3:坐标
- 【Unity 3D】学习笔记十六:实例-添加与关闭窗口
- APS.NET_MVC5学习笔记 - 添加一个模型
- 给控件添加小图标
- VC++学习笔记2--------------如何给MFC对话框添加背景图片
- VC++学习笔记2--如何给MFC对话框添加背景图片
- 禁用Cookie后Session追踪
- 哈弗曼树
- 2-3-4树和B树
- Python 语法练习 -- 乘法表
- Jon Snow and his Favourite Number
- 学习笔记3--给窗口添加一个小坐标
- HDU 2033 JAVA
- leetcode274~H-Index
- 超大背包问题 折半枚举
- 我大C的博客开张啦!!!
- HDU 2034 JAVA
- mysql 触发器的详细用法
- mysql查询当天所有数据以及常用日期函数总结
- 李飞飞:如何教计算机理解图片