??xml version="1.0" encoding="utf-8" standalone="yes"?>
我目前只是尝试用了MatrixTransform PositionAttitudeTransform Group Projection Switch {各U功能的l节? 在介lMatrixTransform ?PositionAttitudeTransform 节点?我想先介l下osg当中矩阵的一些相关知?
其实,无需兛_osg矩阵是如何实现的.但是要记住的是osg中采用的左乘操作,我们qx里讨论的操作如旋转^Uȝ.
OpenGL? newpos = R* T * oldpos //先执行^U?后执?旋{ (全局坐标p?
osg当中: newpos =oldpos * T *R //先执行^U?后执行旋?nbsp; (全局坐标p?
因ؓ在osg当中矩阵执行的操作则是行矩阵操作.因此Z跟OpenGL的列矩阵做同?而不在定义的时候就相当于做了一个{|操??br>
因此在osg/State ?在用applyModelViewMatrix() osg/State 是OpenGL状态机的封?是与OpenGL交互的类
Matrix
inline void applyModelViewMatrix(const osg::RefMatrix* matrix)
{
if (_modelView!=matrix)
{
if (matrix)
{
_modelView=matrix;
glLoadMatrix(matrix->ptr());
}
else
{
_modelView=_identity;
glLoadIdentity();
}
}
}
它是直接使用glLoadMatrix(matrix)q行载入矩阵?因此它的转置刚好适应了OpenGL列优先的模式.
你只需牢记 在OSG当中变换的步骤则是左乘操?全局坐标p?..卛_边的是先执行变换?
谈完如上的那些之?我们现在来看MatrixTransform 和PositionAttitudeTransform.
参考坐标系有三U?br> RELATIVE_RF, //全局 相对 ()
ABSOLUTE_RF, //局?nbsp; l对 ()
ABSOLUTE_RF_INHERIT_VIEWPOINT //Z视点一个局部坐标系.很少用到.
MatrixTransform 故名 矩阵变换节点.在位于它的节点之下的节点都将按照q它的矩阵变换来q行模型变换操作.因此 MatrixTransform的主要功能之一是提供模型变换操作..你只要根据你所需要的讄其模型矩阵就?
x?setMatrix() 因此.查看计算当前World矩阵的方法就可以很清晰的明白其最后结果就?
如果是相对的.那么 先执行自w的变换,在执行父节点的变换操?q类似OpenGL中后写的变换是先执行的一?全局坐标p考虑)
否则是绝对的,那么当前矩阵是自n矩阵
MatrixTransform
bool MatrixTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
{
if (_referenceFrame==RELATIVE_RF)
{
matrix.preMult(_matrix);
}
else // absolute
{
matrix = _matrix;
}
return true;
}
PositionAttibuteTransform 是位置姿态节?.x们只可以调整该节点的所有孩子的位置以及姿?,我们也先来看一下它的矩阵变?
Positon
bool PositionAttitudeTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
{
if (_referenceFrame==RELATIVE_RF)
{
matrix.preMultTranslate(_position);
matrix.preMultRotate(_attitude);
matrix.preMultScale(_scale);
matrix.preMultTranslate(-_pivotPoint);
}
else // absolute
{
matrix.makeRotate(_attitude);
matrix.postMultTranslate(_position);
matrix.preMultScale(_scale);
matrix.preMultTranslate(-_pivotPoint);
}
return true;
}
PositionAttibuteTransform 的矩阵变换顺序的固定?可以说是MatrixTransform的一个特?,操作序我就不在详谈?因ؓ它的功能是Z实现姿态和位置.q有~放{?
因此 setPivotPoint 得之后的变换会Z此^UL作执?
那么实现一个例子来观察他们的效? 下面的例子则?br><1> 使用PositionAttitudeTransform 讄左边的牛. 位置位于(-10,0,0) 姿态ؓlz轴旋?0?
<2> 使用MatrixTransform 讄双的牛, 先执行^UL?10,0,0) 在绕z轴旋?0?因此使得q只牛偏屏幕内部一?(你画个坐标u 按全局思\演示 则就知道牛在上面位置?!)
例子
osg::Node* createTrans()
{
/**//** declare a root node*/
osg::Group* root = new osg::Group;
/**//** declare a Position Node*/
osg::PositionAttitudeTransform* posCow = new osg::PositionAttitudeTransform;
root->addChild(posCow);
/**//** declare a Matrix Node*/
osg::MatrixTransform* matrixCow = new osg::MatrixTransform;
root->addChild(matrixCow);
osg::Node* cow = osgDB::readNodeFile("cow.osg");
/**//**
When use Position Node and the ReferenceFrame is RELATIVE_RF
the matrix is Compute Trans(-pivot) * scale * Rotate * Trans(Pos)
here the pivot and scale is default,so it means that make rotate firstly.
*/
posCow->addChild(cow);
osg::Quat quat;
quat.makeRotate(osg::PI_2,osg::Vec3(0.0,0.0,1.0));
posCow->setAttitude(quat);
posCow->setPosition(osg::Vec3(-10,0.0,0.0));
/**//**
when use Matrix Node you can set the matrix what you want.
here , it make trans firstly and then make rotate.
*/
matrixCow->addChild(cow);
quat.makeRotate(osg::DegreesToRadians(60.0),osg::Vec3(0.0,0.0,1.0));
matrixCow->setMatrix(osg::Matrixd::translate(osg::Vec3(10.0,0.0,0.0))*osg::Matrixd::rotate(quat));
return root;
}
例子下蝲地址 : 源代码下?/a>
]]>
在看了一些之?大概了解了一些关于OpenGL渲染线的知?看了q个之后对于OpenGL的学习我惛_当是很有帮助.关于q么一的原文则是GLSL-LIGHTSOURCE 教程一个开部?原文地址:
是英文的..我在osgchina教程论坛上也见到qFreeSouth大牛的中文翻?.
关于渲染线什么呢?无非是在OpenGL的管道当中各个部分的功能以及如何在管道当中Ş成了我们惌的最l的一q图.(像素).而管U当中的操作可分Z下几个部?
阶段1. 指定几何对象.
??nbsp;U?三角?{一些几何图?.OpenGLl制几何囑օ的方法有以下三种:
<1> 一ơ一个顶?即用glBegin() glVertex() glEnd() 指定几何对象.
<2> 使用点数组..如glDrawArrays.glDrawElements.{?一ơ性的l制大量囑օ.
上面q两U模式则是立x?x定完囑օ之后会被立即渲染.卛_所有数据发往渲染线后立卌渲染.
<3>昄列表模式.它存储于OpenGL服务?(接收OpenGL命o的一?) glNewList glEndList glCallList .
阶段2 点处理操作:
不管以上的几何对象是如何指定?所有的几何数据都将会经q这个阶D?q个阶段负责的则是逐个点的操?
在这个阶D能做的工作则是:
1. 点变换...Ҏ模型视图和投q阵变?br> 2. 光照计算 法线变换(法线矩阵 是模型矩늚左上?*3的逆矩?和法U规格化
3. U理坐标变换.(U理矩阵)
4.材质状?U理坐标生成?
而最重要的则是变换以及光? 每个点在这个阶D分别是单独处理?
q个阶段所接收到的数据则是每个点的属性特?.输出则是变换后的点数据.
阶段3 囑օl装
在顶点处理之?点的全部属性都已经被确?在这个阶D顶点将会根据应用程序送往的图元规?
GL_POINTS GL_TRIANGLES {?会被组装成囑օ
阶段4 囑օ处理(裁剪 消隐)
<1>q个步骤W一个所做的应当是裁剪操?.会将囑օ与用户定义的裁剪q面 即glClipPlane 和模型投q阉|建立的视景比? q将会裁剪且丢弃位于视景和裁剪^面外部的囑օ.不在予以处理.
<2> 其次.若是采用透视投媄 那么.会Ҏ个顶点的x,y z坐标分别除以w.
<3>紧接着 则是p口变换将点坐标变换至窗口坐?
<4> 执行消隐操作
阶段5 栅格化操?/span>
<1>由图元处理传递过来的囑օ数据.在此会被分解成更小的单元ƈ对应帧缓冲区的各个像?q些单元被称之ؓ 片元. 一个片元可能包含窗口左?深度 颜色 U理坐标{属?
<2> 片元的属性则是图元上点数据{?span style="COLOR: red">l过插?/span>而确定的..q里生成的片元将会包含主颜色和次颜色.
glShadeMode() 函数的作用将会这里体?即用插?qx着? 或者用最后一个顶炚w?q面着?
<3> 点宽 U宽.多边形模?正面背面{一些特征也是q阶D发生作?
<4> 反走样也是这个阶Dv作用.
阶段6 片元处理
<1>上纹?通过U理坐标取得U理内存中相对应的颜?br> <2> 雑 通过片元距离当前视点位置修改颜色.
<3> 颜色汇?.(q个与合完全不同概??U理,d义的颜色,雑的颜?ơ颜色光照阶D计的颜色)汇M?
阶段7 逐个片元的操?br> <1> 所有的一些测?像素所有权 剪切(glScissor) Alpha试(glAlphaFunc) 模版试(glStencilFunc)
深度试 (glDephtFunc) 混合(glBlendFunc)
q些操作会最后媄响其在~冲区的颜色?
阶段8 帧缓冲操?/span>
<1>q个阶段执行帧缓冲的写入{操作等..最后生了昄出来的像?
glColorMask glStrncilMask glDepthMask glClearDepht glClearStencil glClearColor {?在q个阶段影响写入的?
以上只是讨论OpenGL 囑օl制的基本过E?那么Z像素囑փl制.几乎形同之上..只是在光栅化处理前的操作不一?即经q像素解?像素传输.栅格?最后Ş成片?..片元之后的处理完全一?.
因此 在着色器~程领域..你将可实?br> Vertex Shader 替换 点处理阶段
Fragment Shader 替换 片元处理阶段
Geometry Shader 替换 囑օl装阶段..
因ؓq三个阶D|军_都是最重要效果的阶D?.对于q些的可~程带来非常大的好处以及可控制的渲?!
]]>
Drawable 故名 可绘制的.. 那么什么才是可l制?我们可以惌.怋用的?U?三角?四边?{?q些是可绘制的.OpenGL大可只能实现l制最l也只是q些..
l常使用的场景图是一般都是一颗树. 那么在OSG也不例外.它是一颗节Ҏ.其最末梢的节ҎGeode.卛_子节? 一个Geode可以包含多个Drawable.因此在OSG中我们想要绘制诸如三角Ş{?最l需要用的肯定也是Geode叶子节点.然后Drawable加入Geode?..
osg/Drawable 只是一个抽象类.那么实现它的cL多少? q是比较多的.
而这中间最常用的莫属Geometry.几何体绘?.而说到几何体.需要的无非是点..颜色.以及如何l成囑օ<Primitive>..
因此一个Geometry需要拥有的数据大可有点.法线坐标 U理坐标.索引?..以及PrimitiveSet.
?法线,颜色{?需要用到矢??osg::Vec2 osg::Vec3 osg::Vec4
PrimitiveSet.则包含了l成如何l成一个图元的规则..如GL_POINT GL_TRIANGLES.{?
用实例说明吧.如用下面这D代码将会创Z个多彩的三角?和一个白色的立方?
Geode
osg::Node* create()
{
/**//**
geode is a leaf node,It must contain some drawables..
*/
osg::Geode* geode = new osg::Geode;
/**//** define a Geometry for draw a triangle.*/
osg::Geometry* triangle = new osg::Geometry;
geode->addDrawable(triangle);
/**//** triangle Vertexs */
osg::Vec3Array* Tvertex = new osg::Vec3Array;
triangle->setVertexArray(Tvertex);
Tvertex->push_back(osg::Vec3(-2.0,0.0,-1.0));
Tvertex->push_back(osg::Vec3( 0.0,0.0,-1.0));
Tvertex->push_back(osg::Vec3(-1.0,0.0, 1.0));
/**//** set the color */
osg::Vec3Array* Tcolor = new osg::Vec3Array;
triangle->setColorArray(Tcolor);
triangle->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
Tcolor->push_back(osg::Vec3(1.0,0.0,0.0));
Tcolor->push_back(osg::Vec3(0.0,1.0,0.0));
Tcolor->push_back(osg::Vec3(0.0,0.0,1.0));
/**//** set the normal*/
osg::Vec3Array* Tnormal = new osg::Vec3Array;
Tnormal->push_back(osg::Vec3(0.0,-1.0,0.0));
triangle->setNormalArray(Tnormal);
triangle->setNormalBinding(osg::Geometry::BIND_OVERALL);
/**//** set the Primitive use GL_TRIANGLES*/
osg::PrimitiveSet* Tprimitive = new osg::DrawArrays(GL_TRIANGLES,0,3);
triangle->addPrimitiveSet(Tprimitive);
/**//** now define a box(center,width)*/
osg::Box* boxtest = new osg::Box(osg::Vec3(1.5,0.0,0.0),1.0);
/**//** use the ShapeDrawable*/
osg::ShapeDrawable* box = new osg::ShapeDrawable(boxtest);
geode->addDrawable(box);
return geode;
}
q里我将解释一些东?
1.Geometry默认是用显C列表来l制囑օ?你大可观看源码或文档M?你可以设|?br> setUseDisplayList(false) 用?或者若在绑定数据的时候用了BING_PER_PRIMITIVE也将会禁用显C列?br> 2.ShapeDrawable 则是内置一些Ş状的囑օ.诸如 圆柱.球体.圆锥{?自己实现试一?
3.BING_PER_VERTEX 则指的每个顶点对应于一U属?如例子中的颜?.
4.BING_OVERALL 则是全部点使用一L属?如例子中的法U?
实例源代码下? ..下蝲地址
忘了说明一?在OSG当中的坐标系?z朝上.y朝里.x朝右..与OpenGL中刚好绕x轴旋转了90?.
q有一点则?我们通常情况下默认用视景器其中的一个关于摄像机漫游器其实默认是使用TrackballManipulator 因此.它会视点中心指向整个场景的包围球中?..
最l结果图:如下:
]]>
]]>
Osg 即OpenSceneGraph的简U?是一Ƒּ源的场景囑Ş?同时它也是跨q_?.Osg它基于场景图的概?利用了Y件开发当中的设计模式的理?设计q提供了一个基于OpenGL底层的面向对象的囑Ş开发框?.
Osg是完全由标准C++和OpenGL而写?充分利用STL和设计模式的Ҏ?可以说是h高性能,可扩?可移植的Ҏ?q前来讲似乎是来流行v来的一N常棒的场景图形库.仍需要更详细的解释方可去官方|站{查?gt;_<..
?关于OSG的学?
1.׃OSG是开源的,现在已经发展C2.9版本?代码量也日趋递增的趋?而缺完善的文档.所以说通读代码已经是g非常痛苦的学习过E?但是q依然是个最主要的方式之一.M的解释你都可能在代码中得到解{?
2.其次 英文版的官方|站 和中文的官方论坛也是一个学习的地方.在osgchina论坛怼得到array和flysky两位版主的详l解{和..osg英文官方|站 osg中国官方|站
3.邮g列表..列表当中都是一些很l典的问?你可以通过邮箱订阅来获?说真?我也没怎么l看....英文水^不高>_<.所以呢q在恶补着p... 邮g列表地址
4.有个非常著名的教E?.国军关于OSG的教E?.NPS...教程地址 .
没想到居然换了个地址x找了半天>_<..ofcourse English. 中文版的译文你可以在osgchina的论坛里扄?但好像不全面.
5. osg源代码中的所有例?examples...
6. 其次?掌握一定的OpenGL基础也是非常好的学习前提.我就是这两个同时一起学?gt;_<,
?关于OSG的一些内?
1.W一个重点则是场景管理的能力.可以理解成是一颗场景树.
2.osg的场景图形单U程/多线E?渲染 (渲染q程分ؓ:状态树和渲染树)
3.osg中实现很多非常实用的工具呀,模型d{?q不需要我们自己写很多代码d现这斚w的内?
4.osg集成所有的OpenGL的状态和Shader的一些内?.q有矩阵q算{?
q有许多内容我ƈ没有说的?gt;_< 因ؓ我只是看了一个月的代码和资料..也没有完整的写过很多E序.所以我依然q在学习当中.>_<
Z以上我们可以认ؓ.OSG是一个非常实用的高层囑Ş应用.
关于1.2两部分内容你可参?Array版主的某大?<最长的一?gt; 详述了OSG当中一帧当中发生的所有事?.
关于W三.部分 主要的集?osgDB和osgUtil q两个库当中.
关于W四部分 OpenGL状态集合主要是 osg/StateSet ?osg/StateAttribute osg/Shader osg/Matrix{许多类当中集成?
q是我目前所能说明的一?gt;_< 毕竟我也只是初学?.
我会这些天以来的学习以及代码的阅读q程中一些ȝ甚至体会写下?..
]]>
附上最q学NEHE 写的1-24的代?gt;_< 内部注有详细注释,如有些函数功能可详看opengl文档?nbsp; :下蝲地址
]]>
]]>
]]>
]]>
]]>
]]>
]]>
]]>
lesson_4的内容在lesson_3的基上添加了部分内容而写成的.q课当中,会使用到模型变换的旋{变换.
前几?曾用了glTranslatef(d)来移动模?q次用glRotatef 来旋转模?而ؓ了看C个动ȝ效果,注册一个空闲回调函?使得角度不断自增.
#include "openglglut.h"
/**//*
** opengl 教程W四译ֆ?br>
** 在窗口的左边部分l制一个多彩的三角?它将使用qx着?br>
** 在窗口的双部分l制一个蓝色的正方?它将使用单调着?br>
** 使得左边的三角ŞlY轴不停旋?br>
** 使得双的正方Şlx轴不停旋?br>
*/
double yRot=0.0; //三角形绕y轴旋转的角度
double xRot=0.0; //三角形绕x轴旋转的角度
int main(int argc, char** argv)
{
/**//** 初始化窗?nbsp;q创建窗?/span>*/
createWindow("opengl lesson_4",&argc,argv);
/**//** 注册glut的一些函?nbsp;*/
glutReshapeFunc(glutResize); //H口调整函数 使得调整后图形显CZ发生改变
glutIdleFunc(glutIdle); //I闲回调函数 使得在空闲时间内q行一些操?/span>
glutDisplayFunc(glutDisplay); //重绘函数 使得可以在窗口中l制囑Ş
glutSpecialFunc(glutSpecial); //Ҏ按键函数 使得实现全屏/H口切换
/**//** 初始化opengl的一些操?/span>*/
InitOpenGL();
/**//** q入仿真循环*/
glutMainLoop();
}
/**//** 实现头文件当中定义的l制函数 l制三角形和正方?nbsp;**/
void glutDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); //先初始化单位矩?/span>
glPushMatrix(); //当前矩阵复制一个压入栈?q保持当前矩阵不?/span>
glTranslatef(-1.5,0.0,-6.0);
glRotatef(yRot,0.0,1.0,0.0); //使得三角形绕y轴旋转yRot角度
//军_三角形三个顶点的颜色?三角形内部各个点的颜色将会是U性插值的
glBegin(GL_TRIANGLES); // l制三角?/span>
glColor3f(1.0f,0.0f,0.0f); //使用U色l制上顶?/span>
glVertex3f( 0.0f, 1.0f, 0.0f); //上顶?/span>
glColor3f(0.0f,1.0f,0.0f); //使用l色l制左下点
glVertex3f(-1.0f,-1.0f, 0.0f); //左下
glColor3f(0.0f,0.0f,1.0f); //使用蓝色l制右下点
glVertex3f( 1.0f,-1.0f, 0.0f); //右下
glEnd();
glPopMatrix(); //恢复当前矩阵Z一ơpush时的矩阵
glTranslatef(1.5f,0.0f,-6.0f);
glRotatef(xRot,1.0,0.0,0.0); //使得正方形绕x轴旋转xRot角度
glColor3f(0.0f,0.0f,1.0f); //当前颜色D|ؓ蓝色 l制整个正方?/span>
glBegin(GL_QUADS); // l制正方?/span>
glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
glVertex3f( 1.0f, 1.0f, 0.0f); // 右上
glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
glEnd();
glutSwapBuffers(); //强制l图命o执行l制在缓冲区交换出来
}
/**//** 实现头文件当中声明的I闲回调函数*/
void glutIdle(void)
{
yRot+=0.2f; //增加三角形旋转角?/span>
xRot-=0.15f; //减少正方形减角?/span>
glutPostRedisplay(); //使得执行完该函数后调用重l函?/span>
}
最l的l果?
末尾ȝ:
glRotatef(angle,x,y,z) ؓ使得模型lQ意u旋{angle角度.它将会生一个旋转矩阵右乘当前矩?所以改变了当前矩阵.而ؓ了得绘制的时候左边的三角形不影响到右Ҏ方Ş的变换矩阉|在绘制三角Ş之前使用glPushMatrix()保存当前矩阵,l制完成之后使用glPopMatrix() 恢复之前的矩?当然也可以用glLoadIdentity()讄当前矩阵为单位矩늚Ҏ来实现它..
其次,q次多了以个glIdleFunc() 注册I闲回调函数.卛_pȝ没有其他事g处理的时候将处理q个函数,使得旋{的角度不断改?
glPostRedisplay() 使得当前H口会q行重绘..Ҏ角度的改?从而得我们看到的是一个旋转当中的动画效果
最后将说明一点的?我曾在红宝书看到一D内?有时候ؓ了实现连l的旋{,我们可能会想到重复应用一个值很的旋{矩阵,q个会存在一个问?是误差,使得变换累积l果.我们应该摒弃q种做法.即用一个新的角度来变换.将使用如下的方?
glLoadIdentity();
glRotatef(new_angle,x,y,z);
只要new_angle=old_angle+offset
]]>
lesson_2?知道了如何简单的l制基本囑Ş的后,q次要学习如何使用glColor3d(f)来设|opengl状态机中的颜色.使得l制时候将采用自定义的颜色?
其实今天在ȝq个的时候,q不是在用opengl而是在用osg设计一个项目h物汽车R{O游类《可能应用在手机Q汽车导航上》的时候,惌vȝq的。我其实是想M图来写这份ȝ可能会更Ҏ理解?然而实在懒...
在图形学的显C流E:
三维囑Ş->模型视图变换->投媄变换->三维裁剪->视口->屏幕囑Ş昄
三维->二维的变换,ȝ来理解只是三l的物体在一pd的变换之后决定了屏幕上某些像素位|的颜色倹{最后这些颜色组成了一q图甅R就是我们所看到得最l屏q二l图形了?/p>
在大概了解这U流E之后,模型视图变换 无疑成为决定我们所看到的囑փ的轮廓?/p>
模型视图变换 应该来讲是包含两个变换的:模型变换,视图变换。ؓ什么将他们合在一起呢Q?在照相机成像pȝ?若固定相Z动移动模型会 {h?/span> 固定模型不动Ud相机?/p>
考究如下内容Q?/p>
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //当前矩阵讄为单位矩?/p>
glRotatef(45.0f,0.0,0.0,1.0); //按[0.0,0.0,1.0]u旋{45?/p>
glTranslatef(2.0,2.0,2.0); // q移?[2.0,2.0,2.0] glBegin(...); // L些东?br> ... 有两U方式理解:一U是局部坐标系的理解,一U是全局坐标pȝ理解?/p>
如果按照上面那些内容从上C的理解的方式是局部坐标系的理?/span>。opengl变换上的实现其实是个矩阵的乘法。按照局部坐标系的理?上面代码的变换是按照q样的顺序执行的: 先将局部坐标系lz轴旋?5度,在将局部坐标系的原点^U至[2.0,2.0,2.0]Q然后在局部坐标系内画物体?/p>
假设 旋{步骤的矩阵ؓRQ^U部分的矩阵为T 当前矩阵为C?/p>
new_C=old_C*R*T q是一个矩阵右乘操?/p>
理论上来?q就是一个坐标系的变换过E,R*T q个矩阵其实是原先的坐标pd换到现在的坐标系Q这个时候原先坐标系的点p变换成p1,p1=(R*T)*p?/p>
而按照全局坐标pȝ理解Q它的变换过E则是相反的Q这也是相当的好理解?在当前世界坐标系中画好该物体之后Q我必须它Ud到正的位置。那必须得先q移物体到[2.0,2.0,2.0],然后物体绕z轴旋?5度。这是一个相反的变换q程Q然而这个与前面的是{h?Z么? 考虑世界坐标pM点pQ经q^UL作后 p11=T*p; 在经q旋转操作后 p1=R*P11=R*(T*p) q是矩阵的一个左乘操?先变换的在后? 所以说new_C=(old_c*(R*(T))) 左乘 所以说q是一个等Lq程. 一般来,我们考虑的时候L世界坐标p考虑旋{q移{操作的.所以在写变换的时候最好的方式是?变换步骤一直左乘,而代码中则按左乘后结果矩늚序写代码?/p>
其次在理解以上的变换q程中模型变换的原理Q我们可以很好的理解gluLookAt(eye,center,up)的视囑֏换的q程Q现在只考虑模型不动Q照相机Ud的过E,且是在全局坐标pM的移动过E? opengl默认照相机框?是视点在原点 y轴ؓ向上方向 z轴负方向U方?/span> gluLookAt的目的在于得视点移动到eye位置 q看向center?/span> 则gluLookAt的过E先q移至eye,而center->eye(center指向eye)则ؓz方向设ؓz(Zx,Zy,Zz),Up方向为y轴方向,y,z的叉U则为x轴方?则只需它们都旋{Cp?/span> 所以这个时候模型变换矩阵就为《相对于模型来讲 相机Ud到eye{h于模型移动到-eye. |Xx Xy Xz 0| |1 0 0 -eyex| |Yx Yy Yz 0| * |0 1 0 -eyey| |Zx Zy Zz 0| |0 0 1 -eyez| |0 0 0 1| |0 0 0 1 |
...
...
glEnd();
]]>