您的位置:首页 > 其它

机械版CG 实验3 变换参考实例

2007-10-26 22:53 316 查看
#include <GL/glut.h>

#include <stdlib.h>

static int shoulder = 0, elbow = 0;//shoulder:肩部角度,elbow: 肘部角度

void init(void)

{

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glShadeModel(GL_FLAT);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();//把当前的变换矩阵压入OpenGL内部栈中,用以保存当前矩阵

//画机器人的上臂

glTranslatef(-1.0f, 0.0f, 0.0f);//用平移矩阵乘当前矩阵,格式为:glTranslatef(x,y,z)

glRotatef((GLfloat) shoulder, 0.0f, 0.0f, 1.0f);//用旋转矩阵乘当前矩阵,格式为glRotatef (角度,x轴,y轴,z轴),这里是绕Z轴旋转

glTranslatef(1.0f, 0.0f, 0.0f);//再用平移矩阵乘当前矩阵,注意顺序

glPushMatrix();//变换矩阵压栈

glScalef(2.0f, 0.4f, 1.0f);//用缩放矩阵乘以当前矩阵,格式为glScalef(x缩放比例,y缩放比例,z缩放比例)

glutWireCube(1.0f);//glut库函数,画一个三维的Cube,参数为边长

glPopMatrix();//弹栈,现在矩阵恢复到使用缩放前的样子

//画机器人的前臂,请注意平移矩阵和旋转矩阵的变化

glTranslatef(1.0f, 0.0f, 0.0f);

glRotatef((GLfloat) elbow, 0.0f, 0.0f, 1.0f);

glTranslatef(1.0f, 0.0f, 0.0f);

glPushMatrix();

glScalef(2.0f, 0.4f, 1.0f);

glutWireCube(1.0f);

glPopMatrix();

glPopMatrix();

glFlush();

}

void reshape (int width, int height)

{

glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);//建立一个透视投影视图体,格式为:gluPerspective(视域的角度,宽高比,视点到近裁剪面的距离(总为正),视点到远裁剪面的距离(总为正))

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glTranslatef(0.0f, 0.0f, -5.0f);//用平移矩阵乘当前矩阵,注意,这会将所有绘制过程中绘制的物体平移

}

void keyboard(unsigned char key, int x, int y)

{

switch (key)

{

case 'a'://处理四个按键,改变旋转角度,转动手臂

shoulder = (shoulder + 5) % 360;

glutPostRedisplay();//重画

break;

case 'd':

shoulder = (shoulder - 5) % 360;

glutPostRedisplay();

break;

case 'q':

elbow = (elbow + 5) % 360;

glutPostRedisplay();

break;

case 'e':

elbow = (elbow - 5) % 360;

glutPostRedisplay();

break;

case 'x':

exit(0);

break;

default:

break;

}

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowSize(500, 500);

glutInitWindowPosition(100, 100);

glutCreateWindow("Transform");

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

return 0;

}

这个例子涉及了三维的造型,出现了许多新函数。

display()中用到了glPushMatrix()和glPopMatrix(),事实上glPushMatrix()可以理解为建立一个局部坐标系,glPopMatrix()恢复全局坐标系,它们可以嵌套使用。这两个函数会很频繁的用到。glutWireCube()画的是一个线框的Cube,这样的函数还有

void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);

void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);

void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);

void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);

void glutWireCube(GLdouble size);

void glutSolidCube(GLdouble size);

void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);

void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);

……

上面的例子里用glTranslatef (0.0, 0.0, -5.0)模拟了视点的变换,其实这一句可以放到display()中,效果是一样的,由于display()是不断被调用的,所以你的视点被不断改变.还有一个方法可以改变视点,函数

gluLookAt(eye_x, eye_y, eye_z, centerx, centery, centerz, upx, upy, upz)

参数:

eyex, eyey, eyez

指定视点的位置

centerx, centery, centerz

指定参考点(“目光”的焦点)

upx, upy, upz

指定向上向量的方向

(声明:本例部分来自《OpenGL编程指南》一书的示例,由于该书的旧版(第一版,1994年)已经流传于网络,希望没有触及到版权问题。)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: