您的位置:首页 > 运维架构

OpenGl 学习——三种变换的理解

2014-01-08 20:59 288 查看
    刚开始学OpenGL, 没有认真看书,结果似懂非懂,其实一点都没有搞懂,尤其是被里面的各种变换搞得晕来转去的。没办法,反复的读《OpenGL 编程指南》红宝书中关于变换的章节,终于有了点眉目了。瞬间感觉:啊,世界变得清明了许多!

 

   废话不多说,直接切入正题。

   首先,应该知道的是:1)、OpenGL中所有的变换对应的都是矩阵的乘法运算,每个变换对应一个变换矩阵。

                                           2)、OpenGL维护了不同的矩阵堆栈。

   具体的说,就是,OpenGL中的所有变换,包括平移、选择、缩放等变换都是基于矩阵的乘法运算的,每次变换都是把变换矩阵与相应矩阵堆栈的当前矩阵相乘,并再把它们的乘积作为该矩阵堆栈的当前矩阵。此外,不同的变换改变不同的矩阵堆栈。OpenGL维持了三个不同的矩阵,分别是GL_MODELVIEW、GL_PROJECTION、GL_TEXTURE,在施加不同的变换前需要切换到对应的堆栈模式上,该切换需要调用glMatrixMode()函数。

  操纵模型视图矩阵堆栈的变换包括模型变换和视图变换。模型变换包括移动、旋转、缩放物体,相应的需要调用glTranslate*()、glRotate*()、glScale*()函数,视图变换主要是用于修改观察点的位置和方向。需要注意的是,视图变换函数一定要出现在模型变换函数之前,以确保首先作用于物体的是模型变换。

  下面的的程序创建了两个定时旋转的三角形:# -*- coding: cp936 -*-
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

angle=0

def Draw():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glColor3f(1.0,0.0,0.0)
glLoadIdentity()
gluLookAt(0,0,5,0,0,0,0,1,0) #视图变换:把观察点移动到(0,0,5)位置,指向原点,y轴正方向作为朝上方向

glTranslatef(0,0,-10) #模型变换:平移物体到(0,0,-10)位置
glRotatef(angle,0,1,0) #模型变换:绕y轴旋转物体angle角度

glBegin(GL_TRIANGLES)
glVertex3f(-2.5, -2.5, 0.0)
glVertex3f(2.5, -2.5, 0.0)
glVertex3f(0, 0.0, 0.0)
glEnd()

glLoadIdentity() #将单位矩阵压到栈顶,恢复到原点位置开始绘制
glTranslatef(0,3,-20)
glRotatef(angle,1,0,0)

glColor3f(0.0,0.0,1.0)
glBegin(GL_TRIANGLES)
glVertex3f(-2.5, -2.5, 0.0)
glVertex3f(2.5, -2.5, 0.0)
glVertex3f(-2.5, 2.0, 0.0)
glEnd()

glFlush()

def init():
glClearColor(0.0,0.0,0.0,0.0)
glEnable(GL_COLOR_MATERIAL)

def reshape(w,h):
ratio=w/h
glViewport(0,0,w,h)
glMatrixMode(GL_PROJECTION) #切换矩阵模式为投影矩阵,以后的操作影响的是投影矩阵堆栈
glLoadIdentity()
gluPerspective(40,w/h,0.1,200) #创建一个视景体
glMatrixMode(GL_MODELVIEW) #切换矩阵模式为模型视图矩阵,以后的操作影响的是模型视图矩阵堆栈

def update(value):
global angle
angle+=0.4
if angle>360:
angle-=360
glutPostRedisplay()
glutTimerFunc(25,update,0)

glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(400, 400)
glutCreateWindow("test")
init()
glutDisplayFunc(Draw)
glutReshapeFunc(reshape)
glutTimerFunc(25,update,0)
glutMainLoop()  
   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息