注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Hao的博客

I'm on my way……

 
 
 

日志

 
 
 
 

从OpenGL示例开始  

2010-05-31 10:53:31|  分类: OpenGL |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

      在开始学习OpenGL之前,首先通过一个例子来摸清使用OpenGL进行图形编程的大致框架。代码如下:

#include<GL/glut.h>
void Init();
void Display();
void Reshape(int w,int h);
int main(int argc,char **argv){

     glutInit(&argc,argv);  //初始化GLUT库并与窗口系统建立交互

     glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH);  //初始化窗口的显示模式
     glutInitWindowSize(500,500);  //初始化窗口大小
     glutInitWindowPosition(100,100);  //初始化窗口位置
     glutCreateWindow("简单光照");   //根据上面两个初始化设置,创建名为“简单光照”的窗口

     Init();  //初始化图形场景

     glutDisplayFunc(Display);  //注册当图形需要重新显示时的回调函数(如窗口第一次出现)
     glutReshapeFunc(Reshape);  //注册当改变窗口大小时调用的回调函数

     glutMainLoop();  //进入GLUT事件处理循环中(如显示窗口等等)
     return 0;
}
void Init(){
     //设置后面用到参数的值
     GLfloat light_position[]={1.0,1.0,1.0,0.0};
     GLfloat light_diffuse[]={1.0,1.0,0.0,0.0};
     GLfloat light_ambient[]={1.0,1.0,0.0,0.0};
     GLfloat light_specular[]={1.0,1.0,0.0,0.0};
     GLfloat mat_specular[]={1.0,1.0,0.0,0.0};
     GLfloat mat_shininess=50;

     glClearColor(1.0,1.0,1.0,0.0);  //设置窗口的背景颜色
     glShadeModel(GL_SMOOTH);  //设置着色模型

     //设置场景中光源GL_LIGHT0的位置、漫反射光颜色、环境光颜色以及镜面反射光颜色
     glLightfv(GL_LIGHT0,GL_POSITION,light_position);
     glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
     glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
     glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);

     //设置场景中物体的材质(这里只设置了镜面反射光颜色及高光指数)
     glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
     glMaterialfv(GL_FRONT,GL_SHININESS,&mat_shininess);

     glEnable(GL_LIGHTING);   //启动光照
     glEnable(GL_LIGHT0);   //使光源GL_LIGHT0有效
     glEnable(GL_DEPTH_TEST);  //启动深度检测
}
void Display(){
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //清除缓存区
     glutSolidSphere(1.0,80,65);  //画一个球体
     glFlush();  //立即将缓冲区内容输出,显示图形
}
void Reshape(int w,int h){
     glViewport(0,0,w,h);   //设置视口的区域,图形将显示在其中
     glMatrixMode(GL_PROJECTION);  //设置矩阵模型为投影矩阵
     glLoadIdentity();   //将当前矩阵设置为单位矩阵

     //将图形正交投影到z=0的平面上(通过乘以一个正交投影矩阵实现)
     if(w<=h)
         glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
     else
         glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);
     //切换回默认的矩阵模式
     glMatrixMode(GL_MODELVIEW);  //设置矩阵模型为模型视图矩阵
     glLoadIdentity();
}


可以看到,上面的代码已经将结构分得比较清晰了,我们就从main函数开始探讨OpenGL图形编程的大致框架

1.初始化使用OpenGL所需的环境(先要讲清楚如何绘图以及用什么绘图
2.设置绘图窗口的基本信息并创建窗口(需要有个画布给我们画图
3.初始化场景(在画图之前要先构思好一个场景,夕阳西下……
   a.指定画布的背景色和着色方式,这是在构思场景前的准备工作
   b.确定光源的位置及反射特性
   c.确定物体的材质,包括反射特性及纹理
   d.启动光源等
4.确定在场景下需要显示的图形(在场景中放入若干个物体
5.开始绘图(准备工作都做好后就可以开始画画了


后记:
1.在其他人的博客中有这么一句话“glutInit必须在其它的GLUT使用之前调用一次”。这句话按理说应该是比较合理的,也确实应该是这样,但是我发现不论把glutInit放在main函数中的哪个位置,甚至是直接注释掉,程序都可以正常运行,实在不知为何?

2.glutSolidSphere指定了半径为1.0,而1.0在窗口中显示的实际大小其实是跟glOrtho和glViewport中设定的参数有关。首先glViewport设定了一个图形的显示区域(视口)。如果将半径1.0改成1.5,那么这个球体就刚好是视口(不是窗口)的内切圆,也可以将半径和glOrtho的前四个参数同时放大10倍,将得到一样的结果。所以球体显示的大小与视口实际大小之间的比例与两个函数中相应参数之间的比例是一致的。

3.由于对象、视图和工作站窗口特性3者之间的独立性,如果用glOrtho函数定义的矩形视图的纵横比(宽与高之比)与由glViewport函数定义的窗口的纵横比不一致的话(如果未显示定义视口则依据Reshape中的参数,如果该函数也未定义,则根据glutInitWindowSize定义的窗口的纵横比),就有可能产生意想不到的结果,如失真。Reshape函数中的glOrtho就保证了纵横比的一致性。

4.在比较复杂的程序中,往往不能确定当前矩阵的模式,为了避免这种情形的发生,我们要及时切换回给定的矩阵模式。这就是Reshape函数中最后两句的意义。

  评论这张
 
阅读(817)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017