OpenGL环境配置(基于Qt窗口)
2017-11-24 18:25
369 查看
一,简述
OPenGL的环境配置由很多种,比如glut和glu,glfw和glad,glew和freeglut等,网上教程都有讲到,这些配置基本上都需要一个窗口库和OpenGL扩展库(用于管理函数指针的)。带领我入门的教程就LearnOpenGL,这是一个对初学者十分友好的教程,基于OpenGL3.3来讲解的,使用的环境就是glfw和glad组合。但在随后的实际项目中界面比较复杂,在不同窗口间数据传输,控件交互等操作,glfw库就显得有点小了,最后选择Qt来作为界面库使用。
为了和LearnOpenGL教程对应起来,需要搭建一个只使用Ot的界面,而不用它封装好的OpenGL类。写OpenGL程序是还是以LearnOpenGL中面向过程的风格。
二,环境版本
vs2013 + Qt5.5 + OpenGL3.3三,方法
和一般的环境配置一样,也需要一个三维绘图窗口和一个用于管理函数指针的库,在Qt中对应的就是两个类QOpenGLWidget和QOpenGLFunctions,只需要继承他们就可以了。class QOPenWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: QOPenWidget(QWidget *parent = 0); ~QOPenWidget(); private: void initializeGL(); /*写渲染前的配置信息*/ void resizeGL(int w, int h); /*窗口变化*/ void paintGL(); /*写渲染循环的内容*/ };
注意QOpenGLFunctions是基于OpenGL
ES 2.0的API,如果想用任意版本的原生OPenGL,需要用的一个类QAbstractOpenGLFunctions,它有很多子类,对应不同版本的OpenGL。如图这是Qt文档中的说明。
对于本示例来说使用的是3.3版,继承的类就是QOpenGLFunctions_3_3_Compatibility类。其他可按自己需要的版本来继承。下面来个完整的示例。
四,源码
QOPenWidget.h#ifndef QOPENWIDGET_H #define QOPENWIDGET_H #include <qopenglwidget.h> #include <qopenglfunctions_3_3_compatibility> #include <qopenglfunctions_4_3_compatibility> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> #include <qopenglvertexarrayobject.h> #include <qpushbutton.h> #include <qtimer.h> #include <string> #include <fstream> #include <sstream> #include <iostream> class QOPenWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Compatibility { Q_OBJECT public: QOPenWidget(QWidget *parent = 0); ~QOPenWidget(); private: void initializeGL(); void resizeGL(int w, int h); void paintGL(); //加载着色器程序 void CompileShader(unsigned int *id, const char* vertexPath, const char* fragmentPath, const char* geometryPath = NULL); private: //缓存对象 unsigned int VBO, VAO, EBO; //着色器程序ID unsigned int ID; //定时器 QTimer timer; }; #endif
QOPenWidget.cpp
#include "QOPenWidget.h" #include <iostream> #include <qtimer.h> #include<ctime> #include <string.h> QOPenWidget::QOPenWidget(QWidget *parent) :QOpenGLWidget(parent) { setUpdateBehavior(QOpenGLWidget::NoPartialUpdate); connect(&timer, SIGNAL(timeout()), this, SLOT(update())); timer.start(0); } QOPenWidget::~QOPenWidget() { } void QOPenWidget::initializeGL() { initializeOpenGLFunctions(); //初始化 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); //开启深度缓存 //添加着色器 CompileShader(&ID,"texture.vs", "texture.fs"); float vertices[] = { // 位置 // 颜色 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); //绑定VAO glBindVertexArray(VAO); //绑定VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); //把顶点数组复制到VBO glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 位置属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // 颜色属性 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); //解除绑定VBO glBindBuffer(GL_ARRAY_BUFFER, 0); //解除绑定EBO //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //解除绑定VAO glBindVertexArray(0); } void QOPenWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); } void QOPenWidget::paintGL() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); //激活着色器 glUseProgram(ID); //绑定顶点缓存对象 glBindVertexArray(VAO); //开始绘制 glDrawArrays(GL_TRIANGLES, 0, 3); //解除绑定 glBindVertexArray(0); } //加载着色器程序 void QOPenWidget::CompileShader(unsigned int *id, const char* vertexPath, const char* fragmentPath, const char* geometryPath) { std::string vertexCode; std::string fragmentCode; std::string geometryCode; std::ifstream vShaderFile; std::ifstream fShaderFile; std::ifstream gShaderFile; // 打开文件 vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; // 读取文件的缓冲内容到数据流中 vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); / 4000 / 关闭文件处理器 vShaderFile.close(); fShaderFile.close(); // 转换数据流到string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); if (geometryPath != NULL) { gShaderFile.open(geometryPath); std::stringstream gShaderStream; gShaderStream << gShaderFile.rdbuf(); gShaderFile.close(); geometryCode = gShaderStream.str(); } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); // 2. 编译着色器 unsigned int vertex, fragment; int success; char infoLog[512]; // 顶点着色器 vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); //编译着色器 glCompileShader(vertex); //检测编译时错误 glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); //如果编译错误进入语句 if (!success) { //获取错误信息 glGetShaderInfoLog(vertex, 512, NULL, infoLog); //打印错误 std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } //片元着色器 fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); //检测错误 glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { //获取错误原因 glGetShaderInfoLog(fragment, 512, NULL, infoLog); //打印 std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } //几何着色器 unsigned int geometry; if (geometryPath != nullptr) { const char * gShaderCode = geometryCode.c_str(); geometry = glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(geometry, 1, &gShaderCode, NULL); glCompileShader(geometry); } // 着色器程序 *id = glCreateProgram(); glAttachShader(*id, vertex); glAttachShader(*id, fragment); if (geometryPath != nullptr) glAttachShader(*id, geometry); glLinkProgram(*id); //检测错误 glGetProgramiv(*id, GL_LINK_STATUS, &success); if (!success) { //获取错误信息 glGetProgramInfoLog(ID, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } // 删除着色器,它们已经链接到我们的程序中了,已经不再需要了 glDeleteShader(vertex); glDeleteShader(fragment); if (geometryPath != nullptr) glDeleteShader(geometry); }
着色器
texture.vs
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; out vec3 ourColor; void main() { gl_Position = vec4(aPos, 1.0); ourColor = aColor; }
texture.fs
#version 330 core out vec4 FragColor; in vec3 ourColor; void main() { FragColor = vec4(ourColor, 1.0); }
五,显示效果
相关文章推荐
- halcon学习1---基于Qt的halcon环境配置
- QT5.4.0环境下配置OpenGL的glut库
- VC环境下基于MFC框架的OpenGL的编程环境的配置
- VC环境下基于MFC框架的OpenGL的编程环境的配置
- 基于MinGW的QT环境配置OpenCV
- (基于 TI8168) LINUX下QT环境配置,能用GDB+GDBSERVER进行调试
- windows8 下基于vs2013开发环境CGAL配置(cmake,cgal,qt.boost,qglviewer)教程
- 基于Ubuntu14.04环境下编译qt-everywhere-opensource-src-5.6.1配置qt creater 的arm编译器环境并移植到tiny210v2开发板上
- macOS下基于GLFW+GLAD的OpenGL环境配置
- 基于Kinect-OpenNI-OpenCV-OpenGL的环境变量配置
- 基于vs2008的opengl开发环境的配置
- 如何配置基于symbian的 QT环境?
- VC环境下基于MFC框架的OpenGL的编程环境的配置
- 基于Qt(Linux)的ROS开发环境配置
- win7下,QT 及 QGLViewer 环境配置总结 | 版本匹配问题 | 解决debug模式下无法打开窗口
- QT5.6.2基于VS2013开发环境配置(Win7 64位)
- VC++2010环境下基于MFC框架的OpenGL的编程环境的配置
- 基于LAMP的云服务器的 环境的配置
- OpenGL环境的配置及其一个测试Demo
- Qt5.3.1环境变量配置-----gyy