用openGL
实现一个模拟人行走的程序。
要求:
1、用多个立方图形构建人体模型(头,躯干,腿,胳膊等),不同部件采用不同颜色绘制。
2、定义各个局部坐标系,并实现各个部件的几何变换模拟人行走。
3、要求使用键盘控制改变行走方向,参考上机实验几何变换的内容
4、要求使用鼠标控制视角的变换,参考上机实验的视图变换内容
5、要求计算帧率
6、要求地面实现有近大远小的效果,参考上机实验的投影内容,主要是透视投影
#include <GL/glut.h>
// 定义人体模型的参数
float bodyWidth = 0.3f;
float bodyHeight = 0.6f;
float headRadius = 0.1f;
float legLength = 0.4f;
float armLength = 0.3f;
// 人体部件颜色
GLfloat headColor[] = {1.0f, 0.0f, 0.0f};
GLfloat bodyColor[] = {0.0f, 1.0f, 0.0f};
GLfloat legColor[] = {0.0f, 0.0f, 1.0f};
GLfloat armColor[] = {1.0f, 1.0f, 0.0f};
// 视角参数
float camX = 0.0f;
float camY = 2.0f;
float camZ = 4.0f;
float camAngle = 0.0f;
// 行走动画参数
float walkAngle = 0.0f;
float stepLength = 0.05f;
// 计算帧率参数
int frameCount = 0;
int currentTime = 0;
int previousTime = 0;
void drawHead() {
glColor3fv(headColor);
glutSolidSphere(headRadius, 20, 20);
}
void drawBody() {
glColor3fv(bodyColor);
glScalef(bodyWidth, bodyHeight, bodyWidth);
glutSolidCube(1.0f);
}
void drawLeg() {
glColor3fv(legColor);
glPushMatrix();
glTranslatef(-bodyWidth / 4, -bodyHeight / 2, 0.0f);
glScalef(0.5f, legLength, 0.5f);
glutSolidCube(1.0f);
glPopMatrix();
}
void drawArm() {
glColor3fv(armColor);
glPushMatrix();
glTranslatef(bodyWidth / 2, bodyHeight / 4, 0.0f);
glScalef(0.4f, armLength, 0.4f);
glutSolidCube(1.0f);
glPopMatrix();
}
void drawPerson() {
glPushMatrix();
drawHead();
drawBody();
glPushMatrix();
glTranslatef(bodyWidth / 4, -bodyHeight / 2, 0.0f);
drawLeg();
glPopMatrix();
glPushMatrix();
glTranslatef(-bodyWidth / 4, -bodyHeight / 2, 0.0f);
drawLeg();
glPopMatrix();
glPushMatrix();
glTranslatef(bodyWidth / 2, bodyHeight / 4, 0.0f);
drawArm();
glPopMatrix();
glPushMatrix();
glTranslatef(-bodyWidth / 2, bodyHeight / 4, 0.0f);
drawArm();
glPopMatrix();
glPopMatrix();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camX, camY, camZ, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// 绘制人体模型
glPushMatrix();
glRotatef(walkAngle, 0.0f, 1.0f, 0.0f);
drawPerson();
glPopMatrix();
glutSwapBuffers();
}
void update(int value) {
// 计算帧率
frameCount++;
int currentTime = glutGet(GLUT_ELAPSED_TIME);
if (currentTime - previousTime > 1000) {
float fps = frameCount / ((currentTime - previousTime) / 1000.0f);
printf("帧率:%.2f\n", fps);
previousTime = currentTime;
frameCount = 0;
}
// 行走动画
walkAngle += stepLength;
if (walkAngle > 360.0f) {
walkAngle -= 360.0f;
}
glutPostRedisplay();
glutTimerFunc(1000 / 60, update, 0);
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat) w / (GLfloat) h, 0.1f, 100.0f);
}
void keyboard(unsigned char key, int x, int y) {
// 使用键盘控制改变行走方向
switch (key) {
case 'w':
camZ -= 0.1f;
break;
case 's':
camZ += 0.1f;
break;
case 'a':
camAngle += 5.0f;
break;
case 'd':
camAngle -= 5.0f;
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL 人行走模拟");
glEnable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutTimerFunc(0, update, 0);
glutMainLoop();
return 0;
}
要实现使用OpenGL编写一个模拟人行走的程序,可以按照以下步骤进行:
导入GLUT(OpenGL Utility Toolkit)库,用于窗口管理和用户输入处理
创建窗口和视口:
使用glViewport函数设置视口大小
初始化OpenGL:
使用glMatrixMode函数将当前矩阵设置为投影矩阵模式
定义模型:
使用glColor函数设置不同部分的颜色
实现几何变换:
使用glRotatef函数进行旋转变换,模拟人体的转动
处理键盘输入:
在回调函数中根据按键的不同,实现相应的平移或旋转变换
处理鼠标输入:
在回调函数中根据鼠标的移动距离,实现视角的旋转变换
计算帧率:
根据时间间隔计算帧率
实现地面透视投影效果:
以下是一个基本的示例代码,实现了以上功能:
#include <GL/glut.h>
#include <iostream>
float angle = 0.0f; // 模拟人行走的旋转角度
float translateX = 0.0f; // 模拟人行走的平移距离
float translateY = 0.0f;
float rotationSpeed = 1.0f; // 旋转速度
float translationSpeed = 0.1f; // 平移速度
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// 设置视角和观察位置
gluLookAt(0.0, 0.0, 5.0, // 观察位置
0.0, 0.0, 0.0, // 观察目标
0.0, 1.0, 0.0); // 上向量
// 应用几何变换
glTranslatef(translateX, translateY, 0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
// 绘制立方体
glPushMatrix();
glTranslatef(-1.0f, 0.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidCube(1.0f);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glutSolidCube(1.0f);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)width/height, 0.1f, 100.0f);
}
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 'w':
translateY += translationSpeed;
break;
case 's':
translateY -= translationSpeed;
break;
case 'a':
translateX -= translationSpeed;
break;
case 'd':
translateX += translationSpeed;
break;
}
}
void mouse(int button, int state, int x, int y) {
if(state == GLUT_DOWN) {
if(button == GLUT_LEFT_BUTTON) {
angle += rotationSpeed;
} else if (button == GLUT_RIGHT_BUTTON) {
angle -= rotationSpeed;
}
}
}
void update(int value) {
glutPostRedisplay();
glutTimerFunc(16, update, 0); // 60帧每秒
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Walking Simulation");
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutTimerFunc(0, update, 0);
glutMainLoop();
return 0;
}
这只是一个基本的示例,可以根据具体需求和进一步学习OpenGL的知识进行更高级的功能实现。希望以上步骤和示例代码对你有所帮助。如果有任何问题,请随时提出。