1、什么是OpenGL?
Open Graphics Library,它是一个由Khronos组织制定并维护的规范
OpenGL核心是一个C库,同时也支持多种语言的派生
核心模式
也叫可编程管线,提供了更多的灵活性,更高的效率,更重要的是可以更深入的理解图像编程,蓝色部分是编程的,通过这一条流水线,最后形成一个OpenGL程序
我们通过改变一些上下文变量来改变OpenGL状态,从而告诉OpenGL如何绘图
2、OpenGL对象
一个对象是指一些选项的集合,代表OpenGL状态的子集,例如:我们可以用一个对象来代表绘图窗口的设置:设置它的大小,至此的颜色位数等等,通常把OpenGL上下文比作一个大的结构体,这个大的结构体中包含很多子集
3、绘制三角形
paintGL:渲染OpenGL场景,widget需更新的调用
resizeGL:设置OpenGL视口、投影等,widget调整大小
initializeGL:设置OpenGL资源和状态,第一次调用上面之前调用
QOpenGLFunctions_4_5_Core 提供OpenGL版本核心模式的所有功能,是对OpenGL函数的封装,initializeOpenGLFunctions:初始化OpenGL函数,将Qt里的函数指针指向显卡的函数
顶点着色器:
它会在GPU上创建内存,用于储存我们顶点数据,通过顶点缓冲对象(vertex Buffer Objects VBO)管理,顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER。
配置OpenGL如何解释这些内存,通过顶点数组对象(VAO)管理(类型唯一),数组里的每一项都对应一个属性的解析,VAO并不保存实际数据,而是放顶点结果定义
绘制一个三角形
#include "AXBopenglWidget.h"
#include <string>
unsigned int VAO, VBO,EBO;
float vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,0.0f,
};
const char* f = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n void main()\n"
"{\n"
"gl_Position=vec4(aPos.x,aPos.y,aPos.z,1.0);\n"
"}\0";
const char* f1 = "#version 330 core\n"
"out vec4 FragColor;void main()\n"
"{\n"
"FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\0";
unsigned shaderProgram;
AXBopenglWidget::AXBopenglWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
AXBopenglWidget::~AXBopenglWidget()
{
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(shaderProgram);
doneCurrent();
}
void AXBopenglWidget::initializeGL()
{
initializeOpenGLFunctions();
// 创建VAO、VBO
// unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// 绑定VBO和VAO对象
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 为当前绑定到target的缓冲区对象创建一个新的数据存储
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 告诉显卡如何解析,第0个值,每个值是float,不需要标准化,每个步长
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// 开启VAO管理的第一个属性值
glEnableVertexAttribArray(0);
// 释放
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// 创建着色器
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1 ,&f, NULL);
glCompileShader(vertexShader);
// 片段着色器
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &f1, NULL);
glCompileShader(fragmentShader);
// 链接
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// 删掉
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void AXBopenglWidget::resizeGL(int w, int h)
{
}
void AXBopenglWidget::paintGL()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
绘制矩形(通过修改数据,使用EBO,其他代码不需要修改)
float vertices[] = {
0.5f,0.5f,0.0f, // top right
0.5f,-0.5f,0.0f, // bottom right
-0.5f,-0.5f,0.0f,
-0.5f,0.5f,0.0f,
};
unsigned int indices[] = {
0,1,3,
1,2,3,
};
// 创建EBO(在绑定VAO下进行创建EBO)
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),
indices, GL_STATIC_DRAW);
// 从EBO中拿数据(之前从VBO中拿数据改成从EBO中拿)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
版权声明:本文为weixin_45715405原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。