OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。
OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。【设计、仿真、模拟、游戏】
OpenGL的高效实现(利用了图形加速硬件)存在于Windows,部分UNIX平台和Mac OS。这些实现一般由显示设备厂商提供,而且非常依赖厂商提供的硬件。
学习OpenGL 可以参考以下教程:
Learn OpenGL 官方网站
LearnOpenGL CN (learnopengl-cn.github.io)
这是翻译成中文的官档,大部分的资料都是以这个教程来讲解的
被称为最好的OpenGL的视频教程
https://www.bilibili.com/video/BV1MJ411u7Bc
前面的讲得很不错,有一些精彩的代码技巧 visual studio
GAMES101-现代计算机图形学入门-闫令琪
https://www.bilibili.com/video/BV1X7411F74
原理讲解的最牛叉的中文教程,师出名门,看了就知道。
《QT+OpenGL学习之我见》合集 by zobol
https://www.bilibili.com/video/BV1wf4y1E7hY/
难得的讲解理解的视频,细节处见大家风采,以 Qt 为开发工具,适合Qter学习
计算机图形学OpenGL:天空盒子
https://www.bilibili.com/video/BV18F411s7xw
这个视频也不错,该up主有多个版本,供大家学习参考。
OpenGL Api docs
docs.gl
Opengl 常用api
openGL初学函数解释汇总 - ZefengYao - 博客园 (cnblogs.com)
介绍一些 Qt 中常使用的类:
QOpenGLWindow 相当于 glfw,用于渲染显示和处理键鼠事件
QOpenGLFunctions_3_3_Core 相当于 glad,实现了 opengl api 的封装
QVector3D 、QVector4D、 QMatrix4x4 相当于 glm库,各种向量和矩阵的运算都已经实现
QOpenGLTexture 和 QImage 相当于 sampler2D 和 stb_image.h
QOpenGLShader 、QOpenGLShaderProgram 渲染管线的封装,使用使用
Qt的项目文件内容
QT += core gui opengl widgets
CONFIG += c++17
SOURCES += \
main.cpp \
Widget.cpp
HEADERS += \
Widget.h
msvc{
QMAKE_CXXFLAGS += /utf-8
}
RESOURCES += \
res.qrc
程序的main方法
#include "Widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
头文件部分,自定义widget 并继承 QOpenGLWidget, QOpenGLFunctions_3_3_Core
QOpenGLWindow 相当于 glfw,用于渲染显示和处理键鼠事件
QOpenGLFunctions_3_3_Core 相当于 glad,实现了 opengl api 的封装
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
class Widget : public QOpenGLWidget,QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
// QOpenGLWidget interface
protected:
virtual void initializeGL() override;
virtual void paintGL() override;
// virtual void resizeGL(int w, int h) override; // 这个没有重写的必要
private:
unsigned int VAO,VBO;
QOpenGLShaderProgram shaderProgram; // 着色器程序
};
#endif // WIDGET_H
Widget 类的源代码文件,用来画一个opengl的入门三角形
#include "Widget.h"
#include
#define qout if( 1 ) qDebug() << __FILE__ << __LINE__ << ": "
float vertices[] = {
-0.5f, -0.5f, // left bottom
0.5f, -0.5f, // right bottom
0.0f, 0.5f, // center top
};
Widget::Widget(QWidget *parent)
: QOpenGLWidget(parent)
{
setWindowTitle ("Qt OpenGL");
}
Widget::~Widget()
{
makeCurrent ();
glDeleteBuffers (1,&VBO);
glDeleteVertexArrays (1,&VAO);
doneCurrent ();
}
void Widget::initializeGL()
{
initializeOpenGLFunctions ();
const char *version =(const char *) glGetString (GL_VERSION);
qout << QString(version);
glGenBuffers (1,&VBO);
glBindBuffer (GL_ARRAY_BUFFER,VBO);
glBufferData (GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glGenVertexArrays (1,&VAO);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
shaderProgram.addShaderFromSourceFile (QOpenGLShader::Vertex, ":/shader.vert");
shaderProgram.addShaderFromSourceFile (QOpenGLShader::Fragment,":/shader.frag");
shaderProgram.link ();
glBindBuffer (GL_ARRAY_BUFFER,0);
}
void Widget::paintGL()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 设置背景色
glClear(GL_COLOR_BUFFER_BIT); // 填充背景色
shaderProgram.bind ();
shaderProgram.setUniformValue ("u_color",1.0f, 0.5f, 0.2f, 1.0f);
// 绘制数组
glDrawArrays (GL_TRIANGLES,0,3);
}
加入 qt 的资源文件
gl_Position 是 GLSL 的关键字,不需要声明
#version 330 core
layout (location = 0) in vec2 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
};
加入 qt 的资源文件
#version 330 core
out vec4 FragColor;
uniform vec4 u_color;
void main()
{
FragColor = u_color;
}
Qt 用来学习 现代 OpenGL 还是比较方便的,成功运行程序后,可见到一个橙色的三角形。
QOpenGLBuffer 和 QOpenGLVertexArrayObject 这两个类,用起来并不太方便,依旧使用比较熟悉的opengl api。