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

    刚开始学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()  

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值