行百里者半九十。为了激励自己能够不断的学习图形学,在此博客中记录自己学习OpenGL的过程与感悟。接下来的笔记全部基于OpenGL SuperBible5(蓝宝书),这篇文章将会从最基础的绘制Triangle开始。
一.需要的头文件以及静态库
1.GLUT
GLUT库相当于是OpenGL的实用工具箱,包括创建窗口,弹出式菜单,窗口管理...我的理解是GLUT库方便了我们进行窗口的创建...在VS中并不需要MFC的知识就可以利用GLUT库创建属于你自己的窗口。在Windows中,GLUT的开发已经中断,现有的一个叫做freeglut的函数库已经取代了它的位置,我们的蓝宝书教程用的也都是freeglut函数库。
2.GLEW与GLTools
在C/C++程序中使用OpenGL时,需要使用GLEW这样的第三方库来加载OpenGL函数。windows目前只支持OpenGL1.1的涵数,但 OpenGL现在都发展到2.0以上了,要使用这些OpenGL的高级特性,就必须下载最新的扩展,另外,不同的显卡公司,也会发布一些只有自家显卡才支 持的扩展函数,你要想用这数涵数,不得不去寻找最新的glext.h,有了GLEW扩展库,你就再也不用为找不到函数的接口而烦恼,因为GLEW能自动识 别你的平台所支持的全部OpenGL高级扩展涵数。也就是说,只要包含一个glew.h头文件,你就能使用gl,glu,glext,wgl,glx的全部函数。
GLTools是蓝宝书编写人员开发的库(因该是吧?不对请指正)。GLTools是基于GLEW库的,也就是说GLTools里面是封装了GLEW库的,这样我们就不用include<glew.h>而是include<GLTools.h>就可以了。GLTools里封装了用于操作矩阵和向量的3D数学库,并且有默认的shader可以渲染简单的3D对象。
上面提到的freeglut以及GLTools我已经上传到CSDN,并且有蓝宝书第五版中文版与英文原版(彩印的哦),有需要的同志们可以下载,下载链接:https://download.csdn.net/download/yuquan87/10429421
创建项目的时候需要将头文件包含进入项目。
freeglut的头文件目录如下:...\SB5\freeglut-2.6.0\include
GLTools头文件目录如下:...\SB5\Src\GLTools\include
包含头文件可不够,还需要链接静态库,我们在项目名称上点击右键,Add->Existing Item,添加:
..\SB5\freeglut-2.6.0\VisualStudio2008Static\Release下的freeglut_static.lib
添加...\SB5\VisualStudio2008\GLTools\Release下的gltools.lib
这样我们可以愉快的绘制第一个三角形啦!
// Triangle.cpp // Our first OpenGL program that will just draw a triangle on the screen. #include <GLTools.h> // OpenGL toolkit #include <GLShaderManager.h> // Shader Manager Class #ifdef __APPLE__ #include <glut/glut.h> // OS X version of GLUT #else #define FREEGLUT_STATIC #include <GL/glut.h> // Windows FreeGlut equivalent #endif GLBatch triangleBatch; GLShaderManager shaderManager;// /////////////////////////////////////////////////////////////////////////////// // Window has changed size, or has just been created. In either case, we need // to use the window dimensions to set the viewport and the projection matrix. void ChangeSize(int w, int h) { glViewport(0, 0, w, h); } /////////////////////////////////////////////////////////////////////////////// // This function does any needed initialization on the rendering context. // This is the first opportunity to do any OpenGL related tasks. void SetupRC() { // Blue background glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//设置背景颜色 shaderManager.InitializeStockShaders();//初始化着色器,使其可以编译链接自己的着色器 // Load up a triangle GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f }; triangleBatch.Begin(GL_TRIANGLES, 3); triangleBatch.CopyVertexData3f(vVerts); triangleBatch.End(); } /////////////////////////////////////////////////////////////////////////////// // Called to draw scene void RenderScene(void)//开始渲染 { // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);//清除屏幕上最后绘制的内容 GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f }; shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed); triangleBatch.Draw();//将几何图形 提交到着色器 // Perform the buffer swap to display back buffer glutSwapBuffers(); } /////////////////////////////////////////////////////////////////////////////// // Main entry point for GLUT based programs int main(int argc, char* argv[]) { gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(800, 600); glutCreateWindow("Triangle"); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC(); glutMainLoop(); return 0; }
复制上面的代码进入你的VS,看看是不是一样的效果^_^
源码解读(自我理解):
main函数中:
gltSetWorkingDirectory(argv[0]);
是为了用来设置当前工作目录。在windows平台下面是不需要这一句话的,去掉也可以正常运行。(因为工作目录与程序的可执行目录是一样的);
1. 我们需要初始化GLUT库,没有这个怎么创建窗口呢?
glutInit(&argc, argv);
2. 设置GLUT库,选择创建窗口时的显示模式(单缓冲还是双缓冲 颜色模式 是否深度测试 是否有模板缓存等等)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
3. 设置窗口大小,标题;
glutInitWindowSize(800, 600); glutCreateWindow("Triangle");
4. 运行系统本地消息循环,捕捉系统消息、按键动作等,设置视区函数(viewport)指定着色方式
glutReshapeFunc(ChangeSize);//viewpoert glutDisplayFunc(RenderScene);5. 初始化GLEW函数库
GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; }
6. 这时候可以把我们想绘制出的图形展示出来,可以加载纹理,建立几何图形、渲染器等工作
SetupRC();
最后就是开始主消息循环 并且结束main函数了
glutMainLoop(); return 0;GlutMainLoop函数在调用之后,在主窗口被关闭之前都不会返回,一个应用程序只需要调用一次,这个函数负责处理我们所有的消息,直到我们关闭程序为止。