OpenGL

广义上, 我们常聊的OpenGL是一套用于操作图形、图像的API. 狭义上, OpenGL的明确定义是一套接口规范Khronos组织维护.

我们电脑上的opengl库由显卡供应商提供, 由于不同供应商对Api的实现不一样, 当OpenGL库表现的行为与规范规定的不一致时, 就会出现相关bug.当产生一个bug时通常可以通过升级显卡驱动来解决, 这也是为什么总是建议你偶尔更新一下显卡驱动.

基本概念介紹

渲染模式(Immediate Mode)核心模式(Core-profile) 早期的OpenGl使用立即渲染模式(Immediate Mode)这个模式绘制简单但是灵活性和效率不高,随着时间的推移开发者对绘图细节的掌控有更多的需求, 从OpenGL3.2开始,规范文档开始废弃立即渲染模式,OpenGL的核心模式(Core-profile)开发开始流行.

扩展(Extension) 当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现。通过这种方式,开发者不必等待一个新的OpenGL规范面世,就可以使用这些新的渲染特性了,只需要简单地检查一下显卡是否支持此扩展。通常,当一个扩展非常流行或者非常有用的时候,它将最终成为未来的OpenGL规范的一部分。

if(GL_ARB_extension_name)
{
    // 使用硬件支持的全新的现代特性
}
else
{
    // 不支持此扩展: 用旧的方式去做
}

状态机(State Machine) OpenGL的状态通常被称为OpenGL上下文(Context), 我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲。最后,我们使用当前OpenGL上下文来渲染。当使用OpenGL的时候,我们会遇到一些状态设置函数(State-changing Function),这类函数将会改变上下文。以及状态使用函数(State-using Function),这类函数会根据当前OpenGL的状态执行一些操作。只要你记住OpenGL本质上是个大状态机,就能更容易理解它的大部分特性。

对象(Object) OpenGL库是用C语言写的,同时也支持多种语言的派生,但其内核仍是一个C库。由于C的一些语言结构不易被翻译到其它的高级语言,因此OpenGL开发的时候引入了一些抽象层。“对象(Object)”就是其中一个。简单理解就是一个C风格的结构体(Struct).

struct object_name {
    float  option1;
    int    option2;
    char[] name;
};

入门

创建窗口

Src code

//初始化GLFW
glfwInit();
//构造窗口
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
}
//建立渲染事件循环(Render Loop)
while(!glfwWindowShouldClose(window))
{
    glfwSwapBuffers(window);
    glfwPollEvents();    
}

OpenGL Es

OpenGL ES(OpenGL for Embedded Systems) 是一种免费的跨平台3D图形 API接口,其适用于低功耗设备,可用于嵌入式设备和移动设备(包括手机、车载大屏 和嵌入式电器终端设备)上渲染高效的 2D 、 3D 图形。 其由OpenGL(Open Graphics Library)针对嵌入式设备裁剪而来,去除了OpenGL中许多不是必须冗余特性,比如:GL_QUADS(四边形)、GL_POLYGONS(多边形)绘制模式、glBegin(开始)/glEnd(结束)等特性。

Qt中的OpenGL和OpenGL ES

Qt渲染 Qt渲染场景视图结构

QOpenGLContext ctx;
ctx.create();
QSurfaceFormat surface = ctx.format();
QString type;
if(surface.renderableType() == QSurfaceFormat::DefaultRenderableType)
    type = "DefaultRenderableType";
else if(surface.renderableType() == QSurfaceFormat::OpenGL)
    type = "OpenGL";
else if(surface.renderableType() == QSurfaceFormat::OpenGLES)
    type = "OpenGLES";
else if(surface.renderableType() == QSurfaceFormat::OpenVG)
    type = "OpenVG";
LOG_INFO(" Rendertype: "+type.toStdString());
LOG_INFO(" OpenGL version: "+QString::number(surface.majorVersion()).toStdString()+"."+QString::number(surface.minorVersion()).toStdString());

教程