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

终于开始了


先配置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(等价的)
#endif

GLBatch 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 background
	glClearColor(0.0f, 0.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 windw 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 the 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;
}

运行效果



代码分析

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值