CSDN博客

img houdy

OpenGL之OpenGL Extensions

发表于2004/10/6 14:29:00  3672人阅读

OpenGL扩展机制(OpenGL Extensions)是OpenGL的亮点之一。显卡的更新,带来了更多,更炫的新特性,使我们能够利用硬件的出色发挥来绘制出令人惊叹的3D画面。利用OpenGL的扩展机制,任何硬件厂商提供的新特性可以用方便的被我们的OpenGL程序所使用。(在这里不得不提一下OpenGL最强有力的对手Direct3D,Direct3D的更新机制是通过升级DirectX SDK开发包来实现了,这给我们的学习带来了不少的麻烦,我们不得不面对版本升级带来的各种问题,在这一点上,OpenGL的优势很明显)。
在使用OpenGL Extensions之前,一定要检查你的显卡是否支持这个扩展,只有确保了你的显卡支持这个扩展特性,才可以放心的使用。可以通过一些工具,如glview来完成这样的工作。
OpenGL的扩展机制使用起来并不复杂,但是仍然有一些人做了许多有益的工作,简化了我们使用OpenGL扩展的步骤,使我们使用OpenGL扩展就像OpenGL API自带的那样方便。这其中比较有名的是glext和GLEW,这这里我主要介绍GLEW.GLEW的全称是"OpenGL Extension Wrangler Library".GLEW主要帮助C/C++完成两项烦琐的任务:1)初始化和使用扩展;2)编写可移植的程序。有关GLEW更详细的资料和获取GLEW,可以查阅网站:http://glew.sourceforge.net/
有了以上的预备知识,我们就可以在我们程序中使用一些新特性,下面以ARB_multiTexture为例,讲讲具体的操作:
预备工作:
  硬件条件:一个支持ARB_multiTexture的显卡(怎么,不支持?要么升级显卡驱动,要么换个新的显卡吧:)
  软件条件:GLUT3.7.6--http://www.xmission.com/~nate/glut.html
           GLEW1.2.4--http://glew.sourceforge.net/
具体步骤:
1.确保GLUT和GLEW已经正确的安装。
2.包含头文件和连接库文件:
     #include <GL/glew.h>
     #include <GL/glut.h>  //注意,glew.h必须放在最前面
  连接库文件:opengl32.lib glu32.lib glut32.lib glew32.lib
3.glut和glew的初始化,glew必须在正确设定了Render Context后才能初始化,即在调用了glutCreateWindow()后才能初始话glew,相关的代码如下:
int _tmain(int argc, _TCHAR* argv[])
{
 glutInit(&argc, argv);
 glutCreateWindow("Multitexture");
 glutInitWindowSize(500,500);
 glutInitWindowPosition(0,0);
 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA);

 glutDisplayFunc(display);
 glutReshapeFunc(myReshape);

 GLenum err=glewInit();
 if( err!=GLEW_OK )
 {
  std::cout<<"Error:"<<glewGetErrorString(err);
  return 1;
 }

 myinit();
 glutMainLoop();
 return 0;

}
4.在程序的初始化阶段,创建Texture Objects,使渲染阶段可以在不同的纹理之间切换:
void myinit()
{

 glShadeModel(GL_FLAT);

 glGenTextures(1,&floor);
 glBindTexture(GL_TEXTURE_2D,floor);
 LoadBMPff("floor.bmp");
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

 glGenTextures(1,&light);
 glBindTexture(GL_TEXTURE_2D,light);
 LoadBMPff("lightmap.bmp");
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

}
5.在实际的渲染阶段,调用扩展提供的函数glActiveTextureARB()来指定当前操作的是哪一个纹理单元,在下一次调用glActiveTextureARB之前所有的函数适用于当前选定的纹理单元。具体的代码:
void display()
{

 glClear(GL_COLOR_BUFFER_BIT);

 glActiveTextureARB(GL_TEXTURE0_ARB);
 glEnable(GL_TEXTURE_2D);
 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
 glBindTexture(GL_TEXTURE_2D,floor);

 glActiveTextureARB(GL_TEXTURE1_ARB);
 glEnable(GL_TEXTURE_2D);
 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
 glBindTexture(GL_TEXTURE_2D,light);

 glPushMatrix();
 glBegin(GL_QUADS);
  glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
  glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);glVertex2f(-1.0,-1.0);

  glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
  glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);glVertex2f(-1.0,1.0);

  glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
  glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);glVertex2f(1.0,1.0);

  glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
  glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);glVertex2f(1.0,-1.0);
 glEnd();

 glPopMatrix();

 glFlush();
}

在这段渲染代码中,指定了两个纹理单元.这两个纹理单元共同的作用结果(实际上是纹理图案象素值相乘的结果)渲染到一个矩形物体上。由于两个纹理图案,一个是普通的纹理,一个是lightmap,渲染的效果就像light mapping的效果,这个技术已经广泛的应用在游戏中,如著名的Quake.

参考文献:
1.http://glew.sourceforge.net
2.http://www.gamedev.net/reference/articles/article1929.asp
3.http://www.opengl.org/resources/tutorials/sig99/advanced99/notes/node61.html

-----------------------------致力于多媒体技术,成为有思想的软件工程师------------------------

此文章为我原创作品,若要转载,请和本人联系,或注明出处。
欢迎大家对文章内容提出宝贵意见,同时希望大家及时指出文中的错误之处,这样我可以及时更正。
我的联系方式:
QQ: 7578420
Email: jerrydong@tom.com

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

阅读全文
0 0

相关文章推荐

img
取 消
img