绘制三个或三个以上的物体,并实现交互。
如图,我绘制了一张床,一张桌,床上有个人,桌上有个壶。
对图中所有物体整体有鼠标交互,按住鼠标左键能够改变视点位置
对物体总体可以进行键盘交互,左键左旋转,右键右移,上键往前移,下键往后移。
三个物体鼠标键盘交互
菜单,可以改变人的姿态及颜色。(因为菜单截不了屏,所以是拍摄的照片)
我会发布一个视频展示鼠标键盘菜单交互的效果。下一个文章详解各个部分的代码。
代码直接附上,各位自取(给我点个赞,就当分享费啦)
#include <Windows.h>
#include <stdio.h>
#include <math.h>
#include<iostream>
#include <gl/glut.h>
//#pragma comment(lib, "glut32.lib")
GLfloat angleX = 0.0f;
GLfloat angleY = 0.0f;
GLfloat zoom = 1.0f;
int lastX = -1;
int lastY = -1;
bool isDragging = false;
int menu = 0, submenu1 = 0, submenu2;
float m1 = 1.0, n1 = 0.75, l1 = 0.79;
float m2 = 0.29, n2 = 0.19, l2 = 0.44;
float m3 = 1.0, n3 = 0.0, l3 = 0.0;//床,壶,人的颜色设为变量
float a1 = 1, b1 = -5, c1 = -12.5;
float a2 = 1, b2 = -5, c2 = -10, p2 = 1, q2 = 1, r2 = 3;
float a3 = -0.5, b3 = -5, c3 = -9, p3 = 1, q3 = 1, r3 = 3;
float a4 = 2.5, b4 = -5, c4 = -9, p4 = 1, q4 = 1, r4 = 3;
float a5 = 0.3, b5 = -5, c5 = -5, p5 = 1.1, q5 = 1.1, r5 = 5;
float a6 = 1.7, b6 = -5, c6 = -5, p6 = 1.1, q6 = 1.1, r6 = 5;
float a7 = -8, b7 = -5.8, c7 = -10;//人和壶的图形坐标的xyz轴上的比例设为变量
void drawBed()
{
glColor3f(1, 0.92, 0.8);
// 床头
glPushMatrix();
glTranslatef(0, -6, -14);
glScalef(8, 8, 1);
glutSolidCube(1);
glPopMatrix();
// 床尾
glPushMatrix();
glTranslatef(0, -8.5, 0);
glScalef(8, 4, 1);
glutSolidCube(1);
glPopMatrix();
//床板
glPushMatrix();
glTranslatef(0, -7, -7);
glScalef(8, 1, 14);
glutSolidCube(1);
glPopMatrix();
//床垫
glColor3f(m1, n1, l1);
glPushMatrix();
glTranslatef(0, -6, -6.5);
glScalef(8, 1, 14);
glutSolidCube(1);
glPopMatrix();
}
void drawCloset()
{
glColor3f(1, 0.8, 0.5);
//桌面
glPushMatrix();
glTranslatef(-8, -7, -10);
glScalef(4, 1, 4);
glutSolidCube(1);
glPopMatrix();
//桌脚
glPushMatrix();
glTranslatef(-8, -9, -10);
glScalef(1, 4, 1);
glutSolidCube(1);
glPopMatrix();
}
void drawTeapot()//茶壶
{
glColor3f(m2, n2, l2);
glPushMatrix();
glTranslatef(a7, b7, c7);
glRotatef(-150, 0, 1, 0);
glutSolidTeapot(0.8);
glPopMatrix();
}
void drawPeople() {
glColor3f(m3, n3, l3);
//头
glPushMatrix();
glTranslatef(a1, b1, c1);
glScalef(1.2, 1.2, 1.2);
glutSolidSphere(1, 20, 20);
glPopMatrix();
//身
glPushMatrix();
glTranslatef(a2, b2, c2);
glScalef(p2, q2, r2);
glutSolidCube(1);
glPopMatrix();
//左手
glPushMatrix();
glTranslatef(a3, b3, c3);
glScalef(p3, q3, r3);
glutSolidCube(1);
glPopMatrix();
//右手
glPushMatrix();
glTranslatef(a4, b4, c4);
glScalef(p4, q4, r4);
glutSolidCube(1);
glPopMatrix();
//左脚
glPushMatrix();
glTranslatef(a5, b5, c5);
glScalef(p5, q5, r5);
glutSolidCube(1);
glPopMatrix();
//右脚
glPushMatrix();
glTranslatef(a6, b6, c6);
glScalef(p6, q6, r6);
glutSolidCube(1);
glPopMatrix();
}
void display(void)
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(zoom, zoom, zoom);
glRotatef(angleX, 1, 0, 0);
glRotatef(angleY, 0, 1, 0);
drawBed();
drawTeapot();
drawCloset();
drawPeople();
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
gluLookAt(0.0, 0.0, 15.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
int count1 = 0;
void key_board(int key, int x, int y)//键盘
{
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
if (key == GLUT_KEY_UP)//按“上”,放大图形
glScalef(1.5, 1.5, 1.5);
if (key == GLUT_KEY_DOWN)//按“下”,缩小图形
glScalef(0.5, 0.5, 0.5);
if (key == GLUT_KEY_LEFT)//按“左”,旋转图形
glRotated(10, 0, 1, 0);
if (key == GLUT_KEY_RIGHT)//按“右”,右移图形
glTranslated(10, 0, 0);
glutPostRedisplay();
}
void getcurrentmenu() {//菜单
int nmenu;
nmenu = glutGetMenu();
if (nmenu == submenu1)
printf("current is sub menu 1.\n");
else if (nmenu == submenu2)
printf("current is sub menu 2.\n");
}
void menuOption1(GLint option)
{
getcurrentmenu();
switch (option)//床,壶,人的颜色改变变量设置
{
case 1:
m1 = 1, n1 = 0.75, l1 = 0.79;
break;
case 2:
m1 = 1.0, n1 = 1.0, l1 = 0.0;
break;
case 3:
m1 = 0.13, n1 = 0.54, l1 = 0.13;
break;
case 4:
m2 = 0.29, n2 = 0.19, l2 = 0.44;
break;
case 5:
m2 = 1.0, n2 = 0.39, l2 = 0.28;
break;
case 6:
m2 = 0.09, n2 = 0.09, l2 = 0.44;
break;
case 7:
m3 = 1.0, n3 = 0.0, l3 = 0.0;
break;
case 8:
m3 = 0.5, n3 = 0.16, l3 = 0.16;
break;
case 9:
m3 = 1.0, n3 = 0.6, l3 = 0.07;
break;
}
}
void menuOption2(GLint option)
{
getcurrentmenu();
switch (option)
{
case 1:
a1 = 1, b1 = -1, c1 = -8;
a2 = 1, b2 = -3, c2 = -8, p2 = 1.5, q2 = 3, r2 = 1.5;
a3 = -0.5, b3 = -3.5, c3 = -8, p3 = 1, q3 = 3, r3 = 1;
a4 = 2.5, b4 = -3.5, c4 = -8, p4 = 1, q4 = 3, r4 = 1;
a5 = 0.3, b5 = -5, c5 = -5, p5 = 1.1, q5 = 1.1, r5 = 5;
a6 = 1.7, b6 = -5, c6 = -5, p6 = 1.1, q6 = 1.1, r6 = 5;//人坐起形态
break;
case 2:
a1 = 1, b1 = -5, c1 = -12.5;
a2 = 1, b2 = -5, c2 = -10, p2 = 1, q2 = 1, r2 = 3;
a3 = -0.5, b3 = -5, c3 = -9, p3 = 1, q3 = 1, r3 = 3;
a4 = 2.5, b4 = -5, c4 = -9, p4 = 1, q4 = 1, r4 = 3;
a5 = 0.3, b5 = -5, c5 = -5, p5 = 1.1, q5 = 1.1, r5 = 5;
a6 = 1.7, b6 = -5, c6 = -5, p6 = 1.1, q6 = 1.1, r6 = 5;//人躺下形态
break;
case 3:
a1 = 1, b1 = 3.2, c1 = -8;
a2 = 1, b2 = 1.5, c2 = -8, p2 = 1.5, q2 = 3, r2 = 1.5;
a3 = -0.5, b3 = 1, c3 = -8, p3 = 1, q3 = 3, r3 = 1;
a4 = 2.5, b4 = 1, c4 = -8, p4 = 1, q4 = 3, r4 = 1;
a5 = 0.3, b5 = -2.5, c5 = -8, p5 = 1.1, q5 = 5, r5 = 1.1;
a6 = 1.7, b6 = -2.5, c6 = -8, p6 = 1.1, q6 = 5, r6 = 1.1;//人站立形态
break;
case 4:
a1 = -7, b1 = -3, c1 = -7;
a2 = -7, b2 = -5, c2 = -7, p2 = 1.5, q2 = 3, r2 = 1.5;
a3 = -8, b3 = -4.5, c3 = -8.5, p3 = 3.5, q3 = 1, r3 = 1;
a4 = -7, b4 = -5.5, c4 = -5.5, p4 = 1, q4 = 3, r4 = 1;
a5 = -7, b5 = -9, c5 = -7.7, p5 = 1.1, q5 = 5, r5 = 1.1;
a6 = -7, b6 = -9, c6 = -6.3, p6 = 1.1, q6 = 5, r6 = 1.1;//人喝水形态
a7 = -9.5, b7 = -3.5, c7 = -8.5;
break;
}
}
void mouse(int button, int state, int x, int y) {//鼠标交互
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
isDragging = true;
lastX = x;
lastY = y;
}
else {
isDragging = false;
}
}
void motion(int x, int y) {
if (isDragging) {
int deltaX = x - lastX;
int deltaY = y - lastY;
lastX = x;
lastY = y;
angleY += deltaX;
angleX += deltaY;
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("三个实体");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutSpecialFunc(key_board);
submenu1 = glutCreateMenu(menuOption1);
glutAddMenuEntry("PinkBed", 1);
glutAddMenuEntry("YellowBed", 2);
glutAddMenuEntry("GreenBed", 3);
glutAddMenuEntry("PurpleTeapot", 4);
glutAddMenuEntry("RedTeapot", 5);
glutAddMenuEntry("BlueTeapot", 6);
glutAddMenuEntry("RedPeople", 7);
glutAddMenuEntry("BrownPeolple", 8);
glutAddMenuEntry("OrangePeoplet", 9);
submenu2 = glutCreateMenu(menuOption2);
glutAddMenuEntry("PeopleSit", 1);
glutAddMenuEntry("PeopleDown", 2);
glutAddMenuEntry("PeolpleStand", 3);
glutAddMenuEntry("PeolpleDrink", 4);
glutAddSubMenu("Cloor", submenu1);
glutAttachMenu(GLUT_RIGHT_BUTTON);//鼠标右键,可以根据需要修改不同按键触发菜单
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}