《Cg Tutorial》的第四章介绍了场景转换的一些基本概念,并就此给出了一个程序例子,演示了在Cg顶点程序中执行从模型空间到剪切空间的转换。由于顶点程序的模型视点投影距阵参数是uniform类型,因此是通过在应用程序中先手动计算各矩阵(包括平移、旋转、视点以及投影距阵),然后按照转换空间的顺序相乘,最后在传递给顶点程序的顺序来完成的。程序实现时,完全是通过传递参数,然后自己来构造相应的矩阵,这种办法虽然可行,但必须要对各种矩阵的构造原理十分的了解。考虑到OpenGL中,可以使用状态函数glGetFloatv来获取指定的矩阵,因此可以先执行相应的操作,让OpenGL来计算最终的合成矩阵,而我们则可以直接通过状态获取函数来得到最终的矩阵。下面就是基于这种方法的实现:
void getModelViewProjMatrix(float outModelViewProjMatix[16],
float fovy,float aspect,float zNear,float ZFar, /* The Projection Parameter*/
double eyex,double eyey,double eyez, /* The Eye Position */
double centerx,double centery,double centerz, /* The Center Position*/
double upx,double upy,double upz, /* The Up Vector*/
void (*transformOp)(void) /* The transform Operation*/)
{
float projMatrix[16];
// Get the projection matrix
getProjectMatrix(projMatrix,fovy,aspect,zNear,ZFar);
// ModelMatrix = Translate * Rotation * ...
// ModelViewMatrix = ViewMatrix * ModelMatrix
// ModelViewProjectionMatrix = ProjectionMatrix * ModelViewMatrix
// In OpenGL,the order of matrix multiplication is REVERSE to the order of function call
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// Multiple the modelview matrix by projection matrix
glMultMatrixf(projMatrix);
//do the transformation operation and camera setting
gluLookAt(eyex,eyey,eyez,centerx,centery,centerz,upx,upy,upz);
transformOp();
//get the modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX,outModelViewProjMatix);
glPopMatrix();
}
此函数用来获取模型视点矩阵与投影矩阵相乘的结果,这个结果就是传递给顶点程序的值。其中(fovy,aspect,zNear,ZFar)调用gluPerspectiv()函数,获取投影矩阵;(eyex, eyey,eyez
centerx,centery,centerz, upx,upy,upz)则用来调用gluLookAt()函数,设置视点矩阵。由于平移、旋转的操作顺序和次数不定,因此在这里是通过函数指针的形式指定。在这个函数中指定的具体的平移和旋转操作。
使用这种方法时,需要考虑到两个问题:
1、 从模型空间到剪切空间的转换顺序:

2、 在OpenGL中,矩阵相乘的顺序与函数调用的顺序相反:
例如:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(N);
glMultMatrixf(M);
glMultMatrixf(L);
glBegin(GL_POINTs);
glVertex3f(v);
glEnd();
在上述代码中,当前矩阵依次为I、N、NM、NML。变换后的顶点为NMLv。
3、 在OpenGL中,使用一维数组存储矩阵时,默认的方式是按列存储的,因此在使用Cg程序时,需要使用cgSetMatrixParameter{f,d}c来传递矩阵参数。
在所有参数设置相同时,试验的结果与书上的结果有一些出入,主要体现在物体在空间的位置不同。为了验证真实的情况,我在只使用OpenGL,不是用Cg程序的条件下绘制,绘制结果同我的一样。下面是在这三种方法下的最终结果:从左到右依次为使用上面方法渲染结果、使用纯OpenGL渲染结果以及书中自带结果

不知道这是我的方法有问题,还是书上程序有问题。
posted @
2007-09-14 14:58 soaroc 阅读(530) |
评论 (5) |
编辑
前一段时间开始接触OGRE开源引擎,下载了一个1.4.2版本的OGRE[开发代号为Eihort]。没想到安装特别的麻烦,从安装补丁到最后编译成功,竟然耗了一整天,怎一个"汗"字了得啊!
安装前也曾到网上搜过一些安装说明,可是没有一个成功的,后来是自己慢慢摸索着才成功的,个人感受不敢独享,下面详细的介绍我自己的安装步骤:
1、软件包下载准备:WindowsXP SP1补丁、OGRE安装程序包(我下载的是Source版本的,SDK版本没有源代码)及补丁(针对vc7和vc8有不同的补丁程序)、Cg Toolkit开发包(用于Cg语言编程的,可选)、DirectX SDK开发包(用于D3D编程,推荐)。
2、安装WindowsXP SP1补丁:WindowsXP SP1补丁号称是史上最BT的补丁了,安装前保证系统盘预留3G的空间,并且安装时要有足够的耐心,据说有人安装了3个多小时,我的内存是1G的,用了一个多小时。下面是一个注册表文件,需要先运行这个注册表文件再安装补丁。
reg export HKLM"Software"Policies"Microsoft"Windows"Installer installer.reg
reg add HKLM"Software"Policies"Microsoft"Windows"Installer /v MaxPatchCacheSize /t REG_DWORD /d 0 /f
net stop msiserver
start /wait VS80sp1-KB926604-X86-CHS.exe
reg delete HKLM"Software"Policies"Microsoft"Windows"Installer /v MaxPatchCacheSize /f
reg import installer.reg
net stop msiserver
del /q installer.reg 2>nul
其实前面的部分不过是照着微软官方网站的说明,翻译成注册表操作语言罢了。先导出注册表,存为install.reg。然后将安全策略中的对应键值由0改为1。然后安装SP1补丁(这里要求补丁程序位于.."wait下面),之后就是导入installer.reg文件。完成之后删除。(中间有一个net命令,用于隔断主机与域的网络连接)。
3、安装Cg Toolkit以及DirectX SDK开发包,最后解压缩OGRE的安装包。SDK版本的有安装导向,可以很方便的完成安装,但不提供源代码。Source版本的解压缩之后会生成一个ogrenew的文件夹,里面就是一大堆的工程文件和源代码。
4、解压缩之后需要先完整的编译一遍才可以使用,编译OGRE工程文件之前,先将OGRE的补丁解压缩,并将Dependencies文件夹拷贝到OGRE的工程文件夹目录下。
5、可以开始编译了,第一次编译大约需要二十多分钟,中间可能会出现N多的警告,都不用理会。
posted @
2007-09-07 11:15 soaroc 阅读(332) |
评论 (4) |
编辑