学习笔记1--在Qt5中利用OpenGL渲染一个立方体
来源:互联网 发布:淘宝上的体检中心在哪 编辑:程序博客网 时间:2024/06/04 20:02
上文介绍了如何在Qt5中嵌入一个widget来作为OpenGL的渲染窗口,本文将在上文的基础上再嵌入的OpenGL部件中进行简单的渲染,本例打算绘制一个彩色的立方体;在接下来的介绍中,我不打算介绍OpenGL和Qt的知识,假设读者有所了解,如果想详细学习OpenGL的知识,我推荐如下链接:https://learnopengl-cn.github.io/
步骤:
(1) 创建用来存放着色器、VAO、VBO、EBO等的数组;
(2) 根据需求编写着色器源码;
(3) 编译着色器,将着色器链接成着色器程序;
(4) 初始化顶点数组(要渲染物体的顶点信息);
(5) 创建VAO、VBO、EBO对象;
(6) 将渲染的信息导入到缓冲区中(包括设置顶点属性指针);
(7) 渲染物体。
修改后的openglwidow.cpp文件:
#include "openglwindow.h"#include <iostream>/******************************************************************************* * 着色器、着色器程序、VAO(顶点数组对象)、VBO(顶点缓冲对象)、EBO(索引缓冲对象) ******************************************************************************/const GLuint NumVertexShader = 1; //顶点着色器的数目const GLuint NumFragmentShader = 1; //片段着色器的数目const GLuint NumShaderProgram = 1; //着色器程序的数目const GLuint NumVAO = 1; //VAO的数目const GLuint NumVBO = 1; //VBO的数目const GLuint NumEBO = 1; //EBO的数目GLuint IDVertexShader[NumVertexShader];GLuint IDFragmentShader[NumFragmentShader];GLuint IDShaderProgram[NumShaderProgram];GLuint IDVAO[NumVAO];GLuint IDVBO[NumVBO];GLuint IDEBO[NumEBO];/******************************************************************************* * 着色器源码 ******************************************************************************/const GLchar *vertexShaderSource = "#version 330 core\n" "layout(location = 0) in vec3 vPosition;\n" "layout(location = 1) in vec3 vColor;\n" "out vec3 Color;\n" "void main()\n" "{\n" "gl_Position = vec4(vPosition, 1.0);\n" "Color = vColor;\n" "}\n";const GLchar *fragmentShaderSource = "#version 330 core\n" "in vec3 Color;\n" "out vec4 fColor;\n" "void main()\n" "{\n" "fColor = vec4(Color, 1.0f);\n" "}\n";openglwindow::openglwindow(QWidget *parent) :QOpenGLWidget(parent){ //设置OpenGL的版本信息 QSurfaceFormat format; format.setRenderableType(QSurfaceFormat::OpenGL); format.setProfile(QSurfaceFormat::CoreProfile); format.setVersion(3,3); setFormat(format);}openglwindow::~openglwindow(){}void openglwindow::initializeGL(){ //初始化OpenGL函数 initializeOpenGLFunctions(); //设置全局变量 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); /******************************* 顶点着色器创建 *******************************/ /* 第一个顶点着色器 */ IDVertexShader[0] = glCreateShader(GL_VERTEX_SHADER); glShaderSource(IDVertexShader[0], 1, &vertexShaderSource, nullptr); glCompileShader(IDVertexShader[0]); //检查编译是否出错 GLint success; GLchar infoLog[512]; glGetShaderiv(IDVertexShader[0], GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(IDVertexShader[0], 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } /******************************* 片段着色器创建 *******************************/ /* 第一个片元着色器 */ IDFragmentShader[0] = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(IDFragmentShader[0], 1, &fragmentShaderSource, nullptr); glCompileShader(IDFragmentShader[0]); //检查编译是否出错 glGetShaderiv(IDFragmentShader[0], GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(IDFragmentShader[0], 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } /********************************* 链接着色器 *********************************/ /* 第一个着色器程序 */ IDShaderProgram[0] = glCreateProgram(); glAttachShader(IDShaderProgram[0], IDVertexShader[0]); glAttachShader(IDShaderProgram[0], IDFragmentShader[0]); glLinkProgram(IDShaderProgram[0]); //检查链接错误 glGetProgramiv(IDShaderProgram[0], GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(IDShaderProgram[0], 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } //删除着色器对象(生成着色器程序之后不再需要) glDeleteShader(IDVertexShader[0]); glDeleteShader(IDFragmentShader[0]); /******************************** 设置顶点数据 ********************************/ //彩色正方体 GLfloat vertices[] = { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.8f, 0.5f, 0.2f, -0.5f, 0.5f, -0.5f, 0.2f, 0.8f, 0.5f }; GLuint indices[] = { 0, 1, 2, 2, 3, 0, //前 4, 5, 6, 6, 7, 4, //后 0, 4, 7, 7, 3, 0, //左 1, 5, 6, 6, 2, 1, //右 0, 4, 5, 5, 1, 0, //上 3, 7, 6, 6, 2, 3 //下 }; /****************************************************************************/ /**************************** VAO\VBO\顶点属性指针 ****************************/ /****************************************************************************/ /* 创建相关对象 */ glGenVertexArrays(NumVAO, IDVAO); glGenBuffers(NumVBO, IDVBO); glGenBuffers(NumEBO, IDEBO); /* 显示立方体 */ glBindVertexArray(IDVAO[0]); //开始记录状态信息 glBindBuffer(GL_ARRAY_BUFFER, IDVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IDEBO[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, 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); //结束记录状态信息 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //在VAO后解绑,是为了不让VAO把解绑EBO的信息包含进入 /* 显示立方体 */ /* 固定属性区域 */ glEnable(GL_DEPTH_TEST); //开启深度测试}void openglwindow::paintGL(){ //清理屏幕 glClear(GL_COLOR_BUFFER_BIT); //渲染彩色正方体 glUseProgram(IDShaderProgram[0]); glBindVertexArray(IDVAO[0]); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); glBindVertexArray(0); //强制刷新缓冲区,保证命令被执行 glFlush();}void openglwindow::resizeGL(int width, int height){ //未使用 Q_UNUSED(width); Q_UNUSED(height);}运行结果:
从运行结果中我们看到的是一个矩形,并不是一个立方体,在下次博文中,我将添加一些简单的交互功能,让后就可以看到真正的立方体了。
编译环境及版本:Win10企业版+Qt 5.7.1(MSVC 2015, 32bit)+OpenGL3.3 Core Profile
0 0
- 学习笔记1--在Qt5中利用OpenGL渲染一个立方体
- Opengl学习笔记1 -- 做一个透视立方体
- 学习笔记0--如何在Qt5中嵌入一个OpenGL程序部件
- Android OpenGL ES学习笔记之绘制一个立方体
- Qt学习笔记(1)---QT5利用事件过滤器实现在控件上绘图
- sandy引擎学习笔记: 创建一个立方体
- 用 OpenGL 编一个立方体
- 使用opengl绘制一个立方体
- openGL编码实现一个立方体
- Qt5中关于OpenGL部分的学习
- OpenGL学习笔记--渲染yuv纹理
- 在OpenGL中渲染3DMAX模型
- 在Android中使用OpenGL效果渲染
- OpenGL入门学习之十五——从“绘制一个立方体”来看OpenGL的进化过程
- OpenGL入门学习——第十五课,从“绘制一个立方体”来看OpenGL的进化过程
- OpenGL入门学习——第十五课 从“绘制一个立方体”来看OpenGL的进化过程
- OpenGL入门学习之十五——从“绘制一个立方体”来看OpenGL的进化过程
- 用C# Managed DX渲染一个立方体
- 【Hibernate】——一对多映射
- SQL高级编程-子查询
- Lesson26 The best art critics
- C语言-根据输入的三角形的三条边判断三角形的类型,并输出它的面积和类型
- 知识库--Creating Transaction in Java Using Akka(124)
- 学习笔记1--在Qt5中利用OpenGL渲染一个立方体
- Hibernate-database returned no natively generated
- MySql基础
- GPS数据包解析
- Lesson27 A wet night
- PHP-无限分类-下拉列表实现
- 【zabbix教程三】——centos7 安装zabbix客户端并监控
- Lesson28 No parking
- OptiTrack 推主动 VR 追踪方案,成本大降 40%,VR 主题公园的春天要来了?