OpenGL入门教程
最近拿着OpenGL玩了一下,在玩的过程中遇到了许多问题,一直很困惑,通过网上各种查找资料,终于解决了,但同时也感觉到作为一个从没接触过计算机图像学的人来说,网上的很多教程都没有站在一个初学者的位置上讲解,这里把我一直困惑的一些很简单的问题解释一遍。我的开发环境为Mac的OS X系统,编译器为gcc。
看了一些OpenGL写的代码,发现OpenGL的代码格式是比较固定的,以超级宝典中的第一个程序sample为例:#include <OpenGL/gl.h>#include <OpenGL/glu.h>#include <Glut/glut.h>
void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f, 0.0f, 0.0f); glRectf(-25.0f, 25.0f, 25.0f, -25.0f); glFlush(); } void SetupRC(void) { glClearColor(0.0f, 0.0f, 1.0f, 1.0f); } void ChangeSize(GLsizei w, GLsizei h) { GLfloat aspectRadio; if(h == 0){ h = 1; } glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); aspectRadio = (GLfloat)w/(GLfloat)h; if(w <= h){ glOrtho(-100.0, 100.0, -100/aspectRadio, 100.0/aspectRadio, 1.0, -1.0); } else { glOrtho(-100.0 * aspectRadio, 100.0 * aspectRadio, -100, 100.0, 1.0, -1.0); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char** argv) { glutInit(&argc, argv); //简单的传递命令行参数,并对GLUT函数库进行初始化 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA); //告诉OpenGL在显示窗口时使用单缓冲显示模式,并使用RGBA颜色模式
glutInitWindowSize(500, 500); //设置窗口尺寸(长和宽)
glutInitWindowPosition(100,100); //设置窗口在屏幕的位置 glutCreateWindow("Simple"); //设置窗口的名字 glutDisplayFunc(RenderScene); //显示回调函数,在需要刷新显示时被调用 glutReshapeFunc(ChangeSize); //改变尺寸回调函数,在改变窗口时进行调用,改变后窗口的长、宽做为参数传入到ChangeSize中 SetupRC(); //普通函数,设置OpenGL的状态,在某些程序中以init代替 glutMainLoop(); //主循环函数 return 0; }
程序运行结果:
针对这个函数,我想重点解释其中三个概念:glViewport 和 glOrtho 的使用和OpenGL中的单位问题。
这个程序的作用是在窗口中显示一个红色的小正方形,通过glRectlf实现,两个定点的坐标是(-25,25)及(25,-25),OK,问题来了,这里面的25的单位是什么,是像素么?后来上网查了一下,说OpenGL中的数值是逻辑数值,也就是说是没有单位的,那没有单位怎么确定大小呢,这里就要牵扯上glViewport 和 glOrtho这两个函数了。
glOrtho函数是确定一个取景的范围,就好像相机的镜头,glOrtho(left, right, bottom, top, near, far) 确定了取景的逻辑值范围,比如glOrtho(-100,100,-100,100,-1,1) 就是取了一个以(0,0)为中心,边长为200的正方形,这里的-100、100等也是逻辑数值,和之前的-25、25对应,这个结果通过逻辑数值的相对值确定了结果中蓝色部分和红色部分的比例,在该程序中,红色正方形边长是50,可以从图上大致看书红蓝边长之比1:4的关系。
glOrtho确定了图像的比例,以本程序为例,红色的方块在屏幕上显示时具体对应多少像素呢,这个就是glViewport来实现了。glViewport(x, y, width, length) 通过(x,y)确定显示区域的左下角坐标,width和 length表示面积大小,这些数值单位都是像素,比如本例中的glViewport(0,0,w,h),就是以(0,0)为左下角(也是实际中的左下角),w和h是实际中传过来的长和宽,是通过glutInitWindowSize(500,500)来确定最初值。
然后调用glutMainLoop就进入主循环了,这个主循环负责识别各种事件,比如glutDisplayFunc, 刷新时调用,glutReshapeFunc, 改变窗口形状时调用,glutKeyboardFunc,收到键盘输入时调用,而glutMainLoop就是在收到各种触发事件时进行相关的调用。
posted on 2013-06-26 20:18 Hou_OnTheRun 阅读(670) 评论(0) 编辑 收藏 举报