荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: OPENGL(4)
发信站: BBS 荔园晨风站 (Thu Jan 21 23:16:52 1999), 转信


前面三篇文章已经把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.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店