发信人: yxy (田丝丝#冬眠的小肥鹰), 信区: GAME_Designer 
标  题: OPENGL(4) 
发信站: BBS 水木清华站 (Wed Jan 14 10:03:54 1998) 
 
前面三篇文章已经把OPENGL的编程基本结构描述完毕。以后 
会在这个基础上逐渐深化,不断增添新内容。这一篇是讲述 
键盘操作和动画基础(实际还差的远哪)。只是个简单的能 
由用户控制的动画,让物体前后移动,左右旋转。是我们自 
己的第一个QUAKE!当然这个版本谁买谁上当,呵呵。 
这篇的另一个目的就是加深前面对于CALLBACK函数的认识以 
及对于变换的直观解释,任何变换你都可以从屏幕上通过自 
己的操作看出来: 
我只把和以前变化的部分标记中文解释 
 
//////////////////////////////////////////////////// 
//sample.cpp 
#include "glos.h" 
#include <GL/gl.h> 
#include <GL/glaux.h> 
#include "windows.h" 
 
void myinit(void); 
void CALLBACK  display(void); 
void CALLBACK  reshape(GLsizei w,GLsizei h); 
 
//注意到乐吗?这里新加乐4个CALLBACK函数 
//类似display() reshape(),也由主函数调用它们 
//实现对键盘输入的响应 
void CALLBACK  left(void);//按 LEFT 
void CALLBACK  right(void);//按 RIGHT 
void CALLBACK  up(void);//按 UP 
void CALLBACK  down(void);//按 DOWN 
 
//两个全局变量,z_motion用来控制物体远近 
//rotate用来控制物体旋转 
static int z_motion=0,rotate=0; 
 
void myinit(void) 

    auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 
        auxInitPosition(0,0,500,500); 
        auxInitWindow("sample1"); 
        glClearColor(0.0,0.0,0.0,0.0); 
        glClear(GL_COLOR_BUFFER_BIT); 

 
void CALLBACK reshape(GLsizei w,GLsizei h) 

if(w<=500&&h<=500) 
glViewport(0,0,w,h); 
if(w>500&&h<=500) 
glViewport(0,0,500,h); 
if(w<=500&&h>500) 
glViewport(0,0,w,500); 
if(w>500&&h>500) 
glViewport(0,0,500,500); 
 
 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
///*if(w<=h) 
// glOrtho(-20.0,20.0,-20.0*(GLfloat)h/(GLfloat)w, 
//         20.0*(GLfloat)h/(GLfloat)w,-50.0,50.0); 
//else 
//  glOrtho(-20.0*(GLfloat)h/(GLfloat)w, 
//         20.0*(GLfloat)h/(GLfloat)w,-20.0,20.0,-50.0,50.0); 
//*/ 
/************************************************************/ 
//这里我们换一种投影方法:透射投影,有立体感的说 
//取代上次的平行投影。前4个参数是控制第一个截取面的 
//left right top bottom,然后两个参数控制近截取面的 
//Z坐标,远截取面的Z作标,函数声名如下: 
//void glFrustum(GLdouble left,GLdouble right, 
//               GLdouble bottom,GLdouble top, 
//               GLdouble near,GLdouble far); 
/************************************************************/ 
glFrustum(-20.0,20.0,-20.0,20.0,10.0,50.0); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 

 
void draw(void) 

glBegin(GL_TRIANGLE_STRIP); 
glColor3f(1.0,0.0,0.0); 
glVertex3f(15.0,0.0,0.0); 
glColor3f(0.0,1.0,0.0); 
glVertex3f(-15.0,0.0,0.0); 
glColor3f(0.0,0.0,1.0); 
glVertex3f(0.0,15.0,15.0); 
// 
glColor3f(0.0,1.0,1.0); 
glVertex3f(10.0,15.0,-15.0); 
// 
glColor3f(1.0,1.0,0.0); 
glVertex3f(15.0,0.0,0.0); 
// 
glEnd(); 

 
void CALLBACK display(void) 

glClearColor(0.0,0.0,0.0,1.0); 
glClear(GL_COLOR_BUFFER_BIT); 
 
//glPushMatrix(); 
glLoadIdentity(); 
 
//根据z_motion rotate两个参数确定变换的具体数值: 
//z_motion改变时,物体从原Z坐标-25,平移z_motion个单位 
glTranslatef(0.0,0.0,-25.0+z_motion); 
//rotate改变时,物体延Y轴(上下方向)旋转5*rotate度 
glRotatef(rotate*5.0,0.0,1.0,0.0); 
 
draw(); 
//glPopMatrix(); 
 
glFlush(); 

void CALLBACK left(void) 

//每当按下LEFT,rotate数值 +1 
//以下函数都类似 
rotate++; 

void CALLBACK right(void) 

rotate--; 

void CALLBACK up(void) 

z_motion++; 

void CALLBACK down(void) 

z_motion--; 

void main(void) 

        myinit(); 
 
//用辅助库的函数调用把left() right() up() down() 
//设为标准键盘输入处理函数 
    auxKeyFunc(AUX_LEFT,left); 
    auxKeyFunc(AUX_RIGHT,right); 
    auxKeyFunc(AUX_UP,up); 
    auxKeyFunc(AUX_DOWN,down); 
 
    auxReshapeFunc(reshape); 
    auxMainLoop(display); 

//end of sample 
//////////////////////////////////////////////////// 
如果运行这个程序会发现有较明显的闪烁感,这是单缓存模式 
造成的以后会讲到动画应采用双缓存模式,这样可以避免闪烁 
 
-- 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.74.90]