是时候开始进行opengl的学习了,我们一方面要依靠商业三维引擎,如unity3d/ue4/ce5等,培养使用引擎开发渲染的能力(当然不限于渲染,物理、粒子、gui、音效、动画等样样都能学到很深的程度,当然了我更偏向渲染方面),一方面又需要培养自己脱离引擎开发的能力,比如使用opengl/dx/vulkan直接去编写渲染组件或者纯渲染程序等。
这里顺便说一下,其实我个人来说内心是更喜欢dx和vulkan的,因为这两套图形API相比opengl更加先进,大家都知道渲染中一个很重要的性能瓶颈就是CPU的drawcall,也就是CPU整理几何数据提交给GPU渲染,在这点上dx和vulkan做到了更加极致的优化,也就是所谓的“多线程渲染”,正规来说就是“多线程提交”,使用到了CPU尽可能多的核心和线程整理提交几何数据,最大效率利用硬件资源,优化渲染速度,当然除此之外更不提dx和vulkan的画面渲染算法特性等,这些几乎超越opengl一个档次。
那么我为什么优先去学习opengl呢?在学习资料获取复杂度上,dx和opengl属于一个层级,比较简单就可以获取到学习dx和opengl的资料,不论是书籍还是博客还是其他等等,但是dx只能应用到pc和xbox主机上,无法应用到linux unix等嵌入式设备中,所以这点可能对我的职业生涯有点限制,因为按照目前发展趋势,小而精的嵌入式设备是未来发展的主流,在目前dx还没有统一嵌入式设备图形渲染库的前提下,所以我选择使用opengl,当然了我也看过一些dx的书籍,比如dx龙书。
然后呢opengl和vulkan相比,vulkan支持多平台,同时属于最先进的图形API框架一列,按照目前的趋势绝对是未来图形API霸主。只不过资料相对比较少,相应的answerhub和书籍或者博客都太少了,目前对于我们开发者来说,特别是国内996福报开发者,根本没太多时间去“趟雷”,所以在学习的时候很容易陷入泥潭。
所以这里总结一下:
1.如果你是纯粹的pc和主机爱好者和开发者,那毫不犹豫学习dx(dx包括一整套图形/音频/IO等API框架)。
2.如果你是在校学生,准备未来进入图形开发/游戏开发领域,请注意是未来,那么学习英语和vulkan(大部分资料还是英文)。
3.如果像我一样是福报码农(当然我基本上还是965的,没那么福报),不仅想要学习图形开发,而且还想顺便帮助一下自己的职业生涯,那么学习opengl,然后关注vulkan。
好了废话说了这么多,下面开始。
首先我们必须会一点点c++,完全不会c++的要稍微学一下,不需要学得太深,简单的语法、附加、链接、编译等会就可以了。下面我假定同学们会这么一点点c++。
首先,准备opengl的开发环境:
1.freeglut
2.glew
3.第三方opengl辅助库,后面学习高级效果的时候再说。
这里我是用cmake编译整理好了freeglut和glew,包含include/lib/bin,opengl依赖库下载,要注意我编译了freeglut的32位debug和release,但是glew只有32位release,所以后面都是使用32位release开发学习,添加依赖的时候别搞错了,如果出现编译链接问题,确保32位release,同时添加依赖名称。
下面就是一个最基本的opengl sample代码,创建窗口,绘制三角形,代码如下:
#include "stdafx.h"
#include
#include
//构建vector3向量结构体
struct Vector3
{
public:
float x;
float y;
float z;
Vector3(){}
Vector3(float x, float y, float z)
{
this->x = x;
this->y = y;
this->z = z;
}
};
GLuint vbo;
int main(int argc, char** argv)
{
//初始化->显示模式->窗口(xy坐标/width/height)->创建窗口
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("ogl sample");
//显示绘制循环
glutDisplayFunc([]() -> void{
//填充三角形数据,使用双缓冲技术,先填充GPU显存绘制缓冲,然后渲染
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
});
//glew初始化
GLenum ret = glewInit();
if (ret != GLEW_OK)
{
printf("error = %d", ret);
return -1;
}
//设置缓冲区颜色,背景色
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
//添加一个三角形的顶点数据
Vector3 vertices[3] =
{
Vector3(-0.5f, -0.5f, 0.0f),
Vector3(0.5f, -0.5f, 0.0f),
Vector3(0.0f, 0.5f, 0.0f)
};
//创建绑定buffer数据
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//渲染循环
glutMainLoop();
return 0;
}
效果图:
这里要说明的是,opengl的函数调用顺序就如sample代码中一样,大致就是初始化->显示循环处理->绑定几何数据->循环渲染。
后面我有时间就会继续学写opengl sample。