原型的杂货铺首页

 
OpenGL编程(2)

 
发表新主题   回复主题    原型的杂货铺首页 -> 软件技术
阅读上一个主题 :: 阅读下一个主题  
作者 正文
klaaa
新手上路


加入时间: 2003/03/15
文章: 8

原币: 25

离线
文章时间: 2003-3-16 周日, 下午7:07    标题: OpenGL编程(2) 引用回复

OpenGL编程(2)

我们来做第二个例子,这次我们要真的画点什么了。

首先,讲述一下OpenGL的绘图机制。OpenGL的绘图过程是一个状态机过程,在任何地方将设置改变了,那么修改将会影响到今后的所有操作,所以改变任何设置的时候都要注意。

然后,说一下OpenGL的坐标。OpenGL假定所有场景都是放在三维坐标中的,其中xyz轴按右手正交方向排列。我们的绘图操作就是把绘制的东西放进这个三维坐标环境中。但是在显示器上显示的时候,始终显示的是一个二维画面,所以这里有一个坐标映射。这里慢慢讲述所用到的坐标系及其映射。第一,世界坐标系,它是OpenGL最基本最重要的坐标系,也就是我们进行绘图操作的地方。第二,视见区坐标系,它其实就是显示窗口的坐标系,它是一个二维坐标系,以窗口左下角为原点,从左到右是x轴正方向,从下到上是y轴正方向。这两个坐标系要联系起来,首先我们要明确我们显示的只是三维世界坐标系的一部分。这里就有一个裁剪的问题,即我们要定义一个区域,它是三维世界坐标系的一部分,只有在这个区域内的绘图结果才会被显示出来,并且显示的地方就是显示窗口内的视见区。

下面,我们结合例子来看看。第二个例子代码如下:

// OpenGL02.cpp
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>
void RenderScene(void)
{
glClearColor(0,0,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
glRectf(50.0f,50.0f,80.0f,80.0f);
glColor3f(0.0f,1.0f,0.0f);
glRectf(-50.0f,-50.0f,-80.0f,-80.0f);
glColor3f(1.0f,1.0f,0.0f);
glRectf(-50.0f,50.0f,-80.0f,80.0f);
glColor3f(0.0f,0.0f,0.0f);
glRectf(50.0f,-50.0f,80.0f,-80.0f);
glRectf(-10.0f,-10.0f,10.0f,10.0f);
glFinish();
glutSwapBuffers();
}
void ResetViewport(GLsizei width,GLsizei height)
{
if(height==0)height=1;
if(width==0)width=1;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f,100.0f,-100.0f,100.0f,-1.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(void)
{
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutCreateWindow("OpenGL02");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ResetViewport);
glutMainLoop();
return 0;
}

相对于第一个例子,有了一些变化。
在函数main中,多了一句:
glutReshapeFunc(ResetViewport);
这是告诉glut库,当glut库创建的窗口改变大小时,调用ResetViewport函数。

在函数ResetViewport中:
函数定义为void ResetViewport(GLsizei width,GLsizei height);
GLsizei是OpenGL定义的数据类型,对应于VC中的long。使用OpenGL的数据类型是为了在OpenGL升级之后保持兼容性,而不必修改源代码。
作为glut库的Reshape函数,glut库传递给它两个参数,分别是glut库创建的窗口的宽度和高度。

if(height==0)height=1;
if(width==0)width=1;
这是为了保证视见区大小不为零。

glViewport(0,0,width,height);
这里设置视见区,注意,坐标是以窗口左下角为原点的。
一般都设置视见区为整个窗口区域。当然也可以改变设置,大家可以自己试试。

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f,100.0f,-100.0f,100.0f,-1.0f,1.0f);
这里设置裁剪区域,首先使用glMatrixMode(GL_PROJECTION)告诉opengl下面操作对象是关系到裁剪的投影矩阵,然后glLoadIdentity()使得投影矩阵置为单位矩阵(至于这里为什么要这样做,以后再讲),接着使用glOrtho(-100.0f,100.0f,-100.0f,100.0f,-1.0f,1.0f)表明使用平行投影方式,投影区域为一个方块区域,其中x坐标从-100到100,y坐标从-100到100,z坐标从-1到1。这里z坐标的设置范围很小,这样我们的裁剪区域近似于一个平面。
一般做二维显示的时候可以这样做。

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
这里是将模型变换矩阵置为单位矩阵(至于这里为什么要这样做,以后再讲)。

在函数RenderScene中:
glClearColor(0,0,1,1);
glClear(GL_COLOR_BUFFER_BIT);
清空颜色缓冲区。

glColor3f(1.0f,0.0f,0.0f);
设置绘图颜色,函数glColor3f的三个参数分别表示RGB颜色,这里使用红色。

glRectf(50.0f,50.0f,80.0f,80.0f);
绘制矩形,使用矩形的一条对角线两个顶点的坐标来定义矩形,这里两个定点的坐标分别是(50,50,0)和(80,80,0),注意,glRectf函数绘制的矩形是在z=0这个平面上的。

glColor3f(0.0f,1.0f,0.0f);
glRectf(-50.0f,-50.0f,-80.0f,-80.0f);
glColor3f(1.0f,1.0f,0.0f);
glRectf(-50.0f,50.0f,-80.0f,80.0f);
glColor3f(0.0f,0.0f,0.0f);
glRectf(50.0f,-50.0f,80.0f,-80.0f);
glRectf(-10.0f,-10.0f,10.0f,10.0f);
这一段,使用不同的颜色和不同的坐标来绘制矩形,注意,由于OpenGL的状态机机制,所以一旦设置颜色后会影响到以后所有操作,这里绘制的最后一个矩形就是这样的。

glFinish();
glutSwapBuffers();
最后,结束操作,交换缓冲区。

这个例子也就没有什么可说的了,结束。

klaaa, 2003.03.16.
返回顶端
阅读会员资料 发送站内短信
显示文章:   
发表新主题   回复主题    原型的杂货铺首页 -> 软件技术 所有的时间均为 北京时间
1页,共1

 
论坛转跳:  
不能在本论坛发表新主题
不能在本论坛回复主题
不能在本论坛编辑自己的文章
不能在本论坛删除自己的文章
不能在本论坛发表投票
不能在这个论坛添加附件
可以在这个论坛下载文件


Powered by phpBB 2.0.3 © 2001, 2002 phpBB Group
中文phpBB开发小组提供技术支持