OpenGL入门系列- 模型视图矩阵变换

一:基础知识:

     1:  OpenGL 坐标系变换过程:

clip_image001

    

     2:    glMatrixMode (GL_MODELVIEW) 干了什么事?  就是载入模型视图矩阵, 如下: 

     

OpenGL eye coordinates

     3:  模型试图矩阵的样子,和各行各列对应的变换:

          (m0, m1, m2),(m4, m5, m6)和(m8, m9, m10) 是用作欧拉变换和仿射变换,例如glRotate(),缩放glScalef().

             最右边的三个矩阵元素 (m12, m13, m14) 是用作位移变换的

Columns of OpenGL ModelView matrix

       4: OpenGL 矩阵相关API

          glPushMatrix()——将当前的矩阵压入矩阵栈

          glPopMatrix()——从当前的矩阵栈中弹出当前的矩阵

          glLoadIdentity()——设置当前矩阵为等同矩阵

          glLoadMatrix{fd}(m)——将当前矩阵替换成矩阵m

          glLoadTransposeMatrix{fd}(m)——将当前矩阵换成其转置矩阵

          glMultMatrix{fd}(m)——将当前矩阵乘以矩阵m,并且更新当前矩阵

          glMultTransposeMatrix{fd}(m)——将当前矩阵乘以其转置矩阵,并且更新当前矩阵

          glGetFloatv(GL_MODELVIEW_MATRIX, m) ——将GL_MODELVIEW矩阵的16个值加载到m中

二: 上代码; 基础知识不明白找其他书吧,基础的东西,说起来比较多;

//在ubuntu  QT 上编译通过,本程序里面的光照纯粹是为了显示三维效果,与矩阵变换无关。

#include <GL/glut.h>
#include <stdlib.h>

/*  Initialize material property and light source.
 */
void init (void)
{

   //Set up the environment light intensity
   GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
   //Set up the diffuse light intensity
   GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
   //Set up the specular light intensity
   GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   //light_position is NOT default value
   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };


   glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
   glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
   glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
   glLightfv (GL_LIGHT0, GL_POSITION, light_position);

   glEnable (GL_LIGHTING);
   glEnable (GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);

}

void display (void)
{
   GLfloat M[4][4];
   GLfloat V[4][4];

   //--------Debug---
   glGetFloatv(GL_MODELVIEW_MATRIX, M);
   glGetFloatv(GL_PROJECTION_MATRIX, V);
   //---------Debug---

   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix ();
   //沿着x轴旋转20度,画面向眼睛方向倾斜
   glRotatef (20.0, 1.0, 0.0, 0.0);  //MC=M1

   //--------Debug---
   glGetFloatv(GL_MODELVIEW_MATRIX, M);
   glGetFloatv(GL_PROJECTION_MATRIX, V);
   //---------Debug---

   glPushMatrix ();
   //向x移动-0.75, 向y移动0.5
   glTranslatef (-0.75, 0.5, 0.0); //MC=M1*M2

   //--------Debug---
   glGetFloatv(GL_MODELVIEW_MATRIX, M);
   glGetFloatv(GL_PROJECTION_MATRIX, V);
   //---------Debug---

   //沿着x轴旋转90度
   glRotatef (90.0, 1.0, 0.0, 0.0); //MC=M1*M2*M3

   //--------Debug---
   glGetFloatv(GL_MODELVIEW_MATRIX, M);
   glGetFloatv(GL_PROJECTION_MATRIX, V);
   //---------Debug---
   glutSolidTorus (0.275, 0.85, 15, 15);
   glPopMatrix ();

   //--------Debug---
   glGetFloatv(GL_MODELVIEW_MATRIX, M);
   glGetFloatv(GL_PROJECTION_MATRIX, V);
   //---------Debug---

   glPushMatrix ();
   glTranslatef (-0.75, -0.5, 0.0); //MC=M1*M2
   glRotatef (270.0, 1.0, 0.0, 0.0); //MC=M1*M2*M3
   glutSolidCone (1.0, 2.0, 15, 15);
   glPopMatrix ();

   glPushMatrix ();
   glTranslatef (0.75, 0.0, -1.0);
   glutSolidSphere (1.0, 15, 15);
   glPopMatrix ();

   glPopMatrix ();
   glFlush ();
}

void reshape(int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   if (w <= h)
      glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w,
               2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
   else
      glOrtho (-2.5*(GLfloat)w/(GLfloat)h,
               2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
   glMatrixMode (GL_MODELVIEW);
   glLoadIdentity ();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

/*  Main Loop
 *  Open window with initial window size, title bar,
 *  RGBA display mode, and handle input events.
 */
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (500, 500);
   glutCreateWindow (argv[0]);
   init ();
   glutReshapeFunc (reshape);
   glutDisplayFunc(display);
   glutKeyboardFunc (keyboard);
   glutMainLoop();
   return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑不溜秋的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值