OpenGL学习(2)-第一个三角形

来源:互联网 发布:java 代码 log4j 编辑:程序博客网 时间:2024/04/30 06:25

终于开始了


先配置VS2010开发环境。

在VS2010中,新建win32控制台项目Triangle,选择空项目,之后在属性管理器中,选中Triangle右键,在Triangle属性页面--配置属性--VC++目录,添加对应的包含文件路径、库文件路径等。

好像可以直接在VS2010的目录X:\Program Files\Microsoft Visual Studio 10.0\VC下的include、lib等目录里放文件或者文件夹来使用OpenGL,待验证。


在蓝色背景上绘制一个红色三角形

代码

//triangle.cpp#include <GLTools.h>//OpneGL 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(等价的)#endifGLBatch triangleBatch;//batch 批处理GLShaderManager shaderManager;
//Window has changed size, or has just been created. In earlier 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 backgroundglClearColor(0.0f, 0.0f, 1.0f, 1.0f);shaderManager.InitializeStockShaders();//load up a triangleGLfloat 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 scenevoid RenderScene(void){//Clear the windw with current clearing colorglClear(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 the back bufferglutSwapBuffers();}
//Main entry point for GLUT based programsint 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;}

运行效果



代码分析

#include <GLTools.h>包含大部分GLTools中类似C的独立函数
#include <ShaderManager.h> 移入GLTools着色管理器类(Shader Manager),没有着色器,不能在OpenGL核心框架中进行着色,ShaderManager允许创建并管理着色器,同时提供一组 存储着色器(Stock Shader),进行一些初步和基础的渲染。

#define FREEGLUT_STATIC
#include <GL/glut.h>windows和linux上,使用freeglut的静态库版本,需要添加FREEGLUT_STATIC处理器宏




void main(int argc, char* argv) argc-整数,用来统计运行程序时,送给main的命令行参数个数;*argv[]-字符串数组,存放指向你的字符串参数的指针数组,
每一个元素指向一个参数,argv[0]-指向程序运行的全路径名;argv[1]-指向DOS命令行中,执行程序名后的第一个字符串;argv[2]-指向执行程序名后的第二个字符串;类推;argv[argc]为NULL
{
 
gltSetWorkingDirectory(argv[0]);设置当前工作目录,windows中不必要,因工作目录默认是与程序的可执行程序相同目录;在Mac OS 中,将当前工作文件夹改为应用程序捆绑包(Application Bundle)中的/Resource文件夹。


//进行GLUT的标准设置
   glutInit(&argc, argv); 传输命令行参数并初始化GLUT库


   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
设置GLUT创建窗口时使用哪种类型的显示模式,此处双缓冲窗口(GLUT_DOUBLE)、RGBA颜色模式(GLUT_RGBA)、将一个深度缓
冲区分配为显示的一部分,能够执行深度测试(GLUT_DEPTH)、一个可用的模板缓冲区(GLUT_STENCIL).
双缓冲窗口:指绘图命令实际在离屏缓冲区执行,然后迅速转换成窗口视图,常用来生成动画效果
RGBA颜色模式:Red、Green、Blue、Alpha


   glutInitWindowSize(800, 600); 设置GLUT窗口大小
   glutCreateWindow("Triangle"); 创建以Triangle为标题窗口


//glut内部运行一个本地消息循环,拦截适当信息,调用为不同事件注册的回调函数
//为窗口改变大小设置一个回调函数,以便能够设置视点
   glutReshapeFunc(ChangeSize);


   glutDisplayFunc(RenderScene); 注册一个函数以包含OpenGL渲染代码


//运行主消息循环前,初始化GLEW库,重新调用GLEW库初始化OpenGL驱动程序中所有丢失的入口点,以确保OpenGL API完全可用,调用glewInit来完成
//做任何渲染之前,检查确定驱动程序的初始化过程中没有出现为
   GLenum err=glewInit();
   if(GLEW_OK !=err)
   {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
   }




   SetupRC(); 调用SetupRC设置渲染环境,对GLUT没有影响。RC(Rendering Context),是一个运行中的OpenGL状态机的句柄,在任何OpenGL函数起作用前必须创建一个渲染环境


   glutMainLoop(); 开始主消息循环,被调用后,在主窗口关闭前都不会返回,一个应用程序中只需调用一次,负责处理所有操作系统特定的消息、按键动作等,直到关闭程序为止


   return 0;
}



//定义视口
//不同环境下窗口大小变化的检测盒处理方法不同,GLUT库为此提供glutReshapeFunc()函数,注册了一个回调,供GLUT库在窗口维度改变时候调用
//传递到glutReshapeFunc() 的函数原型: void ChangeSize(GLsizei w, GLsizei h);


   void ChangeSize(int w, int h) 窗口大小改变时,接受新的w和h
  {
      glViewport(); 修改从目的坐标系统到屏幕坐标系上的映射
  }


//glViewport(GLint x, GLint y, GLsizei width, GLsizei height);其中x和y代表窗口中视口的左下角坐标,w和h是用像素表示的,通常x和y为0,但可以以实用视口在窗
//口中的不同区域渲染多个图形,此处为视口到窗口的映射,x、y与绘图坐标系统的x、y不一样
//视口以实际屏幕坐标定义了窗口中的区域,OpenGL可在这个区域中进行绘图的裁剪区域被映射到新的视口,如果指定了一个比窗口坐标更小的视口,渲染区域会缩小


//使用默认的笛卡尔坐标系统,在x、y和z上从-1到+1延伸,x、y为横、纵坐标轴,z轴正方向从屏幕向外,坐标(0, 0, 0)位于屏幕正中央




SetupRC()     设置渲染环境,在开始main()的主循环之前
{
   glClearColor(R,G,B,Alpha)   设置背景色/清除颜色




   shaderManager.InitializationStockShaders()  

初始化着色器管理器,着色管理器需要编译和链接它自己的着色器,必须在OpenGL初始化时调用

   GLfloat vVerts[]={}     指定图形顶点,此处三角形为基本图元,设置3个顶点的3组坐标对,在float数组中

   triangleBatch.Begin(GL_TRIANGLES, 3); 批次封装三角形的顶点,由GLTool封装类(Wrapper class) GLBatch的实例进行
   triangleBatch.CopyVertexData3f(vVerts);
   triangleBatch.End();
}




RenderScene()   渲染
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)真正进行颜色清除,清除一个 或一组缓冲区,颜色缓冲区、深度缓冲区、模板缓冲区,按位或(Bitwise OR)来同时清除所有3个缓冲区。
   
   vRed[]={} 设置一组浮点数表示红色(1.0, 0.0, 0.0, 1.0)
   
   shaderManager.UseStockShader(GLT_SHADER_IDENTITY, VRed)把红色传递给存储着色器,此处为 GLT_SHADER_IDENTITY--使用指定颜色以默认笛卡尔左边系在屏幕上渲染几何图形


   triangle.Draw() 将几何图形提交到着色器


   glutSwapBuffers() 设置OpenGL窗口时指定要一个双缓冲区渲染环境--将在后台缓冲区进行渲染,然后在结束时交换到前台,能够防止观察者看到可能伴随着动画帧与动画帧直接闪烁的渲染过程。缓冲区交换以平台特定方式进行,GLUT有一个单独函数调用来完成。
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

工作流程

main():设置工作目录---初始化glut库---设置glut显示模式---设置窗口大小---创建窗口---重画回到函数(可不需要?)---注册绘图函数glutDisplayFunc(RenderScene)--初始化GLEW库,并检测无错---设置渲染环境SetupRC()---glut主循环---返回

SetupRC():设置清除颜色glClearColor(R, G, B, A )--使用着色器管理器初始化 存储着色器 StockShader()--设置图形顶点 vVerts[]--批处理顶点数据

RenderScene():执行清除颜色glClear---设置渲染颜色--使用存储着色器--批处理进行绘制--交换缓冲区glutSwapBuffers

原创粉丝点击