发信人: wend.bbs@bbs.cst.sh.cn (问道), 信区: cnprogram
标 题: OPENGL基础篇(3)
发信站: 生命玄机站 (Sat Feb 28 23:35:59 1998)
转信站: Lilac!ustcnews!cstshnews!lifebbs
前面三篇文章已经把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]
--
※ 来源:·“生命玄机”站 bbs.cst.sh.cn·[FROM: Wend.bbs@bbs.net.tsi]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.060毫秒