OpenGL学习03-画点&按键处理

本篇中我们主要介绍画点的方法,在下面的例子中是通过一些列的点形成一个点环,点击键盘上的方向键,市点环沿着X、Y轴方向旋转。

 

程序如下所示:

#include <GL/glut.h>

#include <math.h>

void renderScene(void)  

{  

GLfloat x, y, z, angle;

glClear(GL_COLOR_BUFFER_BIT);   //使用当前清除颜色清除窗口,GL_COLOR_BUFFER_BIT说明清除的是颜色缓存区

glPushMatrix(); //正在使用矩阵入栈

glRotatef(xRot, 1.0f, 0.0f, 0.0f); //沿着X轴旋转

glRotatef(yRot, 0.0f, 1.0f, 0.0f); //沿着Y轴旋转

 

glBegin(GL_POINTS);

z = -50.0f;

for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.05f){

x = 50.0f * sin(angle); //通过角度计算X坐标

y = 50.0f * cos(angle); //通过角度计算X坐标

 

glVertex3f(x, y, z); //画点

 

z += 0.5f; //Z坐标渐变

}

glEnd();

glPopMatrix(); //矩阵出栈,即使用栈顶矩阵

glutSwapBuffers(); //交换渲染缓存

}  

void renderInit()

{

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置窗口清除颜色

glColor3f(0.0f, 1.0f, 0.0f);

}

void changeSize(GLsizei w, GLsizei h)//窗口大小被改变是调用

{

GLfloat aspectRatio;

 

if(h == 0)

h = 1;

glViewport(0, 0, w, h);//设置视口区域为整个窗口

//重置坐标系统

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

aspectRatio = (GLfloat)w/(GLfloat)h;
//设置正投影参数,保证无论窗口被拉伸还是压缩,都不会影响图形形状

if(w <= h)

glOrtho(-100.0, 100.0, -100.0/aspectRatio, 100.0/aspectRatio, -100.0, 100.0);

else

glOrtho(-100.0*aspectRatio, 100.0*aspectRatio, -100.0, 100.0, -100.0, 100.0);

//重置坐标系统

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void specialFunc(int key, int x, int y)

{

if(key == GLUT_KEY_UP){ //Up方向键

xRot += 5.0f;

}else if(key == GLUT_KEY_DOWN){ //Down方向键

xRot -= 5.0f;

}else if(key == GLUT_KEY_LEFT){ //Left方向键

yRot += 5.0f;

}else if(key == GLUT_KEY_RIGHT){ //Right方向键

yRot -= 5.0f;

}

 

if(key > 356.0f)

xRot = 0.0f;

if(key < -1.0f)

xRot = 355.0f;

if(key > 356.0f)

yRot = 0.0f;

if(key < -1.0f)

yRot = 355.0f;

glutPostRedisplay(); //重新绘制

}

int main(int argc, char **argv)  

{  

glutInit(&argc, argv);  

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  

glutInitWindowPosition(100,100);  

glutCreateWindow("Hello OpenGL");  

renderInit();

glutDisplayFunc(renderScene);  

glutReshapeFunc(changeSize);

glutSpecialFunc(specialFunc);//特殊按键处理函数

glutMainLoop(); 

return 0;  

运行程序:

 

 

(1)OpenGL状态机

对于一个特定的几何图形,有许多因素可能会影响他的绘制。是不是有一束光照到它上面?光线属性是怎么样的?材料属性又是什么?如果使用纹理,应该使用何种纹理?这样的问题很多。

我们把这种变量的集合称为管线的状态。状态机是一个抽象模型,表示一组状态变量集合。每个状态变量可以有不同的值,例如尅打开和关闭等。

打开关闭状态变量:

void glEnable (GLenum cap);

void glDisable (GLenum cap);

测试状态变量:

GLboolean glIsEnabled (GLenum cap);

OpenGL还提供一种方便的机制,可以保存一组范围内的所有状态,并在将来恢复他们。堆栈是一种方便的数据结构,允许把一些值压入堆栈,并以后将他们从堆栈中弹出。

void glPushAttrib (GLbitfield mask);

void glPopAttrib (void);

注意这两个函数的参数是个位段值,也就是一个掩码,这意味着可以使用OR来操作多个状态。

对矩阵的操作也有同样的方法:

void glPushMatrix (void);

void glPopMatrix (void);

在上面的例子中使用了该方法来保存矩阵。

 

(2)双缓冲

双缓冲有两个用处。(1)一些复杂的绘制可能需要很长的时间,我们并不希望在屏幕上显示图形合成的每个步骤,使用双缓冲可以先绘制一副图形,绘制完后在显示;(2)显示动画,每个帧在屏幕之外的缓存区中绘制,等绘制完成后在显示屏幕上,这样就形成了动画;

Glut函数库支持双缓冲窗口,使用

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA),GLUT_DOUBLE表示设置使用双缓冲窗口模式绘制;

接着,修改renderScene()函数尾部添加glutSwapBuffers();

需要刷新窗口时,使用glutPostRedisplay()请求重新刷新窗口;

 

(3)按键处理

Glut函数库提供了按键处理的方法,注册按键处理函数的方法为:

void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));

void glutSpecialFunc(void (*func)(int key, int x, int y));

其中,glutKeyboardFunc注册的函数为处理普通按键,glutSpecialFunc注册函数处理特殊按键(包括Home/End、PageUp/PageDown、方向键)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值