基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二)你好,三角形_QOpenGLExtraFunctions版
2018-04-06 12:53
651 查看
本篇文章,是一项带引号的“翻译”类型文章。Joey De Vries 的现代OpenGL教程是我看过最好的图形学教程,没有之一。奈何原作者是在Visual Studio平台进行开发,针对GUI和OpenGL的结合,没有多言。在自己实际开发应用中,没有好的GUI确是造成不少困扰,故我欲作为一名搬运工,将Vries大神的代码进行Qt平台的“移植”。预了解代码中关于OpenGL函数的详细解释,请看Vries的教程,连接如下。(这是此篇教程的原地址https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/)本篇目的是创立窗口,生成三角形,如下图所示。
Qt对OpenGL的支持,要求,必须public继承QOpenGLWidget类,然后重写[b]这三个函数。[/b]
这里介绍第一种方法,继承QOpenGLExtraFunction为了使用glShaderSource()这种OpenGL成员函数,要求必须proteced继承QOpenGLFunctions类,或QOpenGLExtraFunctions类,这里选择继承QOpenGLExtraFunctions类,因为这个类是QOpenGLFunctions类的子类,多了glGenVertexArrays(1, &VAO)这一函数。项目组织结构如下:
widget.h如下#ifndef WIDGET_H
#define WIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QDebug>
class Triangle : public QOpenGLWidget, protected QOpenGLExtraFunctions
{
public:
Triangle();
~Triangle();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
private:
GLuint shaderProgram;
};
#endif // WIDGET_H
widget.cpp如下#include "widget.h"
GLuint VBO, VAO;
const char *vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"void main(){\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\n\0";
const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main(){\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
Triangle::Triangle(){
}
Triangle::~Triangle(){
}
void Triangle::initializeGL(){
//着色器部分
this->initializeOpenGLFunctions();
//core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << endl;
}
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << endl;
}
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//VAO,VBO数据部分
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
glGenVertexArrays(1, &VAO);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Triangle::resizeGL(int w, int h){
glViewport(0, 0, w, h);
}
void Triangle::paintGL(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(0);
}main函数如下#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Triangle t;
t.show();
return a.exec();
}在继承QOpenGLExtraFunctions的情形下,整个Vries的代码可以在基本无改动的情况下,直接移植。
Qt对OpenGL的支持,要求,必须public继承QOpenGLWidget类,然后重写[b]这三个函数。[/b]
这里介绍第一种方法,继承QOpenGLExtraFunction为了使用glShaderSource()这种OpenGL成员函数,要求必须proteced继承QOpenGLFunctions类,或QOpenGLExtraFunctions类,这里选择继承QOpenGLExtraFunctions类,因为这个类是QOpenGLFunctions类的子类,多了glGenVertexArrays(1, &VAO)这一函数。项目组织结构如下:
widget.h如下#ifndef WIDGET_H
#define WIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QDebug>
class Triangle : public QOpenGLWidget, protected QOpenGLExtraFunctions
{
public:
Triangle();
~Triangle();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
private:
GLuint shaderProgram;
};
#endif // WIDGET_H
widget.cpp如下#include "widget.h"
GLuint VBO, VAO;
const char *vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"void main(){\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\n\0";
const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main(){\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
Triangle::Triangle(){
}
Triangle::~Triangle(){
}
void Triangle::initializeGL(){
//着色器部分
this->initializeOpenGLFunctions();
//core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << endl;
}
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << endl;
}
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//VAO,VBO数据部分
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
glGenVertexArrays(1, &VAO);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Triangle::resizeGL(int w, int h){
glViewport(0, 0, w, h);
}
void Triangle::paintGL(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(0);
}main函数如下#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Triangle t;
t.show();
return a.exec();
}在继承QOpenGLExtraFunctions的情形下,整个Vries的代码可以在基本无改动的情况下,直接移植。
相关文章推荐
- 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二)你好,三角形_QOpenGLShader版
- 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二)你好,三角形_QOpenGLFunctions_3_3_Core版
- 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(四)纹理
- 基于Qt的OpenGL可编程管线学习(1)- 绘制一个三角形
- 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(三)着色器
- Qt OpenGL:学习现代3D图形编程之一,画一个三角形
- Qt OpenGL:学习现代3D图形编程之三,移动三角形
- 基于Qt的OpenGL编程并能实现相应按钮点击事件
- 黑白棋算法简单实现与基于Qt的GUI编程的综合应用
- VC环境下基于MFC框架的OpenGL的编程环境的配置
- 基于VC++的OpenGL编程讲座之坐标变换
- OpenGL 按照三角形仿射变换并贴图渲染(基于shader)(二)
- 基于 qt 的 Opengl 渲染 YUV
- OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!
- 【Qt编程】基于Qt的词典开发系列<九>--JSON数据解析
- 现代3D图形编程学习-你好,三角形(译)
- VS2005下QT学习笔记-OpenGL编程
- Qt下的OpenGL 编程(3)绘制平面几何体
- Qt 插件综合编程-基于插件的OpenStreetMap瓦片查看器客户端(3) 插件管理机制