计算机图形学实验,用OpenGL实现三维空间,绘制三维房间、家具、房屋建筑等。
用到的OpenGL 函数
glColor3f(blue); //设置颜色
glutSolidCube(size);//绘制正方体
glVertex3f(x, y, z);//设置点坐标
glLightfv(a,b,c); //设置光源
glTranslatef(x, y, z`)`;//平移函数
glScalef(x, y, z); //放大/缩小函数
glRotatef(angle, x, y, z);//绕轴旋转函数
glutSolidSphere(radius, slices, stacks);//绘制球体
glBegin(图形类型) 与 glEnd(void)
在glBegin(arg)的参数部分选择要绘制的图形类型; 在glBegin()与glEnd()之间添加坐标点。比如绘制三角形,就选择glBegin()的参数为GL_TRIANGLES, glVertex3f(x, y, z)添加三角形三个顶点的坐标,末尾加上glEnd().这种代码绘制的图形一般是一个三维空间中的平面图形。
glBegin(GL_TRIANGLES);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
glPushMatrix() 与 glPopMatrix()
在glPushMatrix() 与 glPopMatrix() 之间添加绘制基本平面图形,通过组合、平移、放大缩小就能轻易的实现复杂三维视图。
比如: 用glutSolidCube(1);绘制一个边长为一个单位的立方体,这个立方体的中心坐标为(t0, 0, 0);
进行平移、放大:
glPushMatrix();
glTranslatef(1, 2, 3)
glScalef(1,1,3);
glPopMatrix();
这样立方体的中心位置的坐标变成了(1,2,3),而且长宽高分别变成了1,1,3个单位长度。
代码
//地板黑白纹理
//产生纹理
void makeCheckImages(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for(j = 0; j < checkImageWidth; j++) {
c = (((( i & 0x8) == 0) ^ ((j & 0x8)) == 0)) * 255;
if(c == 255)
{
checkImage[i][j][0] = (GLubyte) 180;
checkImage[i][j][1] = (GLubyte) 180;
checkImage[i][j][2] = (GLubyte) 180;
checkImage[i][j][3] = (GLubyte) 255;
}
else
{
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
}
//机器人
void people(void)
{
glColor3f(blue);
glutSolidCube(2); //身体
glColor3f(white);
glPushMatrix(); //头
glTranslatef(0, 1.5, 0);
glutSolidCube(1);
glPopMatrix();
glColor3f(black);
glLineWidth(3);
glBegin(GL_LINES);
glVertex3f(-0.2 ,1.75, 0.52);
glVertex3f(-0.3 ,1.75, 0.52);
glVertex3f( 0.2 ,1.75, 0.52);
glVertex3f( 0.3 ,1.75, 0.52);
glVertex3f( 0.1 ,1.25, 0.52);
glVertex3f(-0.1 ,1.25, 0.52);
glEnd();
glLineWidth(1);
glColor3f(brown);
glPushMatrix(); //腿
glTranslatef(-0.7, -2.25, 0);
glScalef(0.5, 2.5, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0.7, -2.25, 0);
glScalef(0.5, 2.5, 0.5);
glutSolidCube(1);
glPopMatrix();
//手
glPushMatrix();
glTranslatef(0, 0.25, 0);
glPushMatrix();
glTranslatef(-1.25, 0, 0);
glScalef(1, 0.5, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glRotated(pep_agl, 1, 0, 0);
glTranslatef(-1.75, -0.75, 0);
glScalef(0.5, 2, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(1.25, 0, 0);
glScalef(1, 0.5, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glRotated(-1 * pep_agl, 1, 0, 0);
glTranslatef( 1.75, -0.75, 0);
glScalef(0.5, 2, 0.5);
glutSolidCube(1);
glPopMatrix();
glPopMatrix();
}
void draw_people(void){
glPushMatrix();
glTranslatef(4, -6.5, -5);
people();
glPopMatrix();
}
//绘制树木
void draw_tree(void)
{
glPushMatrix();
glScalef(0.2, 0.2, 0.15);
glTranslatef(120, -60, -450);
//树干
glColor3f(brown);
constract(60,10,390,15,70,15);
build();
//树叶
glColor3f(hgreen);
glTranslatef(60,70,400);
glutSolidSphere(25.0, 20, 20); //球1
glTranslatef(20,0,0);
glutSolidSphere(25.0, 20, 20); //球2
glTranslatef(-10,0,-10);
glutSolidSphere(25.0, 20, 20); //球3
glTranslatef(0,0,20);
glutSolidSphere(25.0, 20, 20); //球4
glTranslatef(0,10,-10);
glutSolidSphere(25.0, 20, 20); //球4
glPopMatrix();
}
//草坪路
void draw_road(int x)
{
glColor3f(brown);
for (int i = 0; i < x; ++i) {
glPushMatrix();
glTranslatef(0, 0, i * 5);
constract(-5, -10, 0, 10, 0.1, 3.5);
build();
glPopMatrix();
}
}
//NUAA教学楼
void NUAA(void)
{
glMaterialfv(GL_FRONT, GL_AMBIENT, matWhite);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matWhite);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glTranslatef(0, 0, 150);
glRotated(180, 0, 1, 0);
glColor3f(brown);
constract(-15, 20, 0, 30, 70, -30);
build();
glColor3f(hgray);
constract(-35, -10, 0, 70, 30, -30);
build();
glColor4f(white, 0.35);
for (int i = 0; i < 9; ++i) {
glPushMatrix();
glTranslatef(0, 7 * i, 0);
constract(-12, 21, 0.2, 10, 6, -0.2);
build();
constract(2, 21, 0.2, 10, 6, -0.2);
build();
glPopMatrix();
}
glColor4f(white, 0.35);
constract(-30, -5, 0.2, 25, 20, -0.2);
build();
constract( 5, -5, 0.2, 25, 20, -0.2);
build();
glPushMatrix();
glTranslatef(-13, 84, 0.1);
glScalef(0.04, 0.05, 2);
glColor3f(red);
glLineWidth(5);
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'N');
glutStrokeCharacter(GLUT_STROKE_ROMAN, ' ');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'U');
glutStrokeCharacter(GLUT_STROKE_ROMAN, ' ');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'A');
glutStrokeCharacter(GLUT_STROKE_ROMAN, ' ');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'A');
glLineWidth(1);
glPopMatrix();
glPopMatrix();
}
//房子
void house(void)
{
glMaterialfv(GL_FRONT, GL_AMBIENT, matWhite);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matWhite);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glColor3f(brown);
constract(-15, -10, 0, 30, 70, -30);
build();
glColor4f(white, 0.35);
for (int i = 0; i < 9; ++i) {
glPushMatrix();
glTranslatef(0, 7 * i, 0);
constract(-12, -9, 0.2, 10, 6, -0.2);
build();
constract( 2, -9, 0.2, 10, 6, -0.2);
build();
glPopMatrix();
}
glPopMatrix();
}
//太阳
//太阳
glPushMatrix();
glColor3f(gold);
glTranslatef(0, 95, 0);
glutSolidSphere(5.0, 20, 20);
glPopMatrix();
//柜子
//柜子
void draw_closet(void)
{
glColor3f(1, 0.6, 0.3);
glMaterialfv(GL_FRONT, GL_AMBIENT, matBrown);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matBrown);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glTranslatef(16, -3, -16);
glScalef( 4, 14, 4);
glPushMatrix();
glutSolidCube(1);
glColor3f(black);
glLineWidth(2);
glBegin(GL_LINES);
glVertex3f(-0.5, 0.5, 0.51);
glVertex3f( 0.5, 0.5, 0.51);
glVertex3f( 0 , 0.5, 0.51);
glVertex3f( 0 ,-0.5, 0.51);
glVertex3f(-0.5,-0.5, 0.51);
glVertex3f( 0.5,-0.5, 0.51);
glVertex3f(-0.25, 0.05, 0.51);
glVertex3f(-0.25, 0.1, 0.51);
glVertex3f( 0.25, 0.1, 0.51);
glVertex3f( 0.25, 0.05, 0.51);
glEnd();
glPopMatrix();
glLineWidth(1);
glPopMatrix();
}
//花瓶
//花瓶
void draw_vase(void)
{
glPushMatrix();
glTranslatef(16, -5.5, -7);
glPushMatrix();
glScalef(0.1, 0.1, 0.1);
glTranslatef(-40, 0 ,0);
draw_tree();
glPopMatrix();
glPushMatrix();
glScalef(1, 1, 0.75);
glTranslatef(0.21, -0.75, -0.55);
glColor3f(blue);
constract(-1, -1, 0, 1, 1, -1);
build();
glPopMatrix();
glPopMatrix();
}
//房间内部墙壁
//墙
void draw_wall(void)
{
GLfloat x = 19;
GLfloat y = 10;
GLfloat z = 20;
//glColor3f(1.0, 1.0, 1.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, matWhite);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matWhite);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glBegin(GL_QUADS); //back wall
glColor3f(hgreen);
glVertex3f( x, y, -z);
glVertex3f(-x, y, -z);
//glColor3f(0.0, 1.0, 0.0);
glVertex3f(-x,-y, -z);
glVertex3f( x,-y, -z);
glEnd();
//top wall
glColor3f(gray);
glMaterialfv(GL_FRONT, GL_AMBIENT, matRed);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matRed);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glBegin(GL_QUADS);
glVertex3f( x, y, -z);
glVertex3f( x, y, 0);
glVertex3f(-x, y, 0);
glVertex3f(-x, y, -z);
glEnd();
//left wall
glMaterialfv(GL_FRONT, GL_AMBIENT, matGreen);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matGreen);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glBegin(GL_QUADS);
glColor3f(green);
glVertex3f(-x, y, -z);
glVertex3f(-x, y, 0);
glColor3f(1, 1, 0);
glVertex3f(-x,-y, 0);
glVertex3f(-x,-y, -z);
glEnd();
//base wall
glEnable(GL_TEXTURE_2D);//纹理
glColor3f(0, 0, 1);
glMaterialfv(GL_FRONT, GL_AMBIENT, matBlue);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matBlue);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-x,-y, -z);
glTexCoord2f(0.0, 1.0); glVertex3f(-x,-y, 0);
glTexCoord2f(1.0, 1.0); glVertex3f( x,-y, 0);
glTexCoord2f(1.0, 0.0); glVertex3f( x,-y, -z);
glEnd();
glDisable(GL_TEXTURE_2D);
//right wall
glMaterialfv(GL_FRONT, GL_AMBIENT, matYellow);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matYellow);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glBegin(GL_QUADS);
glColor3f(1, 1, 0);
glVertex3f( x,-y, -z);
glVertex3f( x,-y, 0);
glColor3f(0, 1, 0);
glVertex3f( x, y, 0);
glVertex3f( x, y, -z);
glEnd();
}
//床
//床
void draw_bed(void)
{
GLfloat x = 6;
GLfloat y1 = -7.5;
GLfloat y2 = -5;
GLfloat z1 = -19.9;
GLfloat z2 = -5;
//床头
glBegin(GL_QUADS);
glColor3f(0.f,0.54f,0.5f);
glVertex3f(x, y2, z1);
glVertex3f(-x, y2,z1);
glVertex3f(-x, y1,z1);
glVertex3f(x, y1, z1);
glEnd();
//床身
glBegin(GL_QUADS);
glColor3f(1.f,0.54f,0.5f);
glVertex3f(x, y1, z1);
glVertex3f(-x, y1,z1);
glVertex3f(-x, y1,z2);
glVertex3f(x, y1, z2);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.f,0.54f,0.5f);
glVertex3f(-x, y1, z1);
glVertex3f(-x, -8.99,z1);
glVertex3f(-x, -8.99,z2);
glVertex3f(-x, y1, z2);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.f,0.54f,0.5f);
glVertex3f(x, y1, z1);
glVertex3f(x, -8.99,z1);
glVertex3f(x, -8.99,z2);
glVertex3f(x, y1, z2);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.f,0.54f,0.5f);
glVertex3f(-x, y1,z2);
glVertex3f(x, y1, z2);
glVertex3f(x, -8.99, z2);
glVertex3f(-x, -8.99,z2);
glEnd();
//枕头
glBegin(GL_QUADS);
glColor3f(1.0f,0.84f,0.5f);
glVertex3f(x-0.5, -7, z1+0.5);
glVertex3f(0.5, -7,z1+0.5);
glVertex3f(0.5, -7,-17);
glVertex3f(x-0.5, -7,-17);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f,0.84f,0.5f);
glVertex3f(0.5, -7,-17);
glVertex3f(x-0.5, -7,-17);
glVertex3f(x-0.5, y1,-17);
glVertex3f(0.5, y1,-17);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f,0.84f,0.5f);
glVertex3f(-x+0.5, -7, z1+0.5);
glVertex3f(-0.5, -7,z1+0.5);
glVertex3f(-0.5, -7,-17);
glVertex3f(-x+0.5, -7,-17);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f,0.84f,0.5f);
glVertex3f(-0.5, -7,-17);
glVertex3f(-x+0.5, -7,-17);
glVertex3f(-x+0.5, y1,-17);
glVertex3f(-0.5, y1,-17);
glEnd();
//被子
glPushMatrix();
glTranslatef(0, -7.49, -10.5);
glScalef(2 * x, 0.1, 11);
glutSolidCube(1);
glPopMatrix();
}
//吊灯
//吊灯
void draw_light(void)
{
glPushMatrix(); //Celling Light
glColor3f(1, 1, 0);
glMaterialfv(GL_FRONT, GL_AMBIENT, matYellow);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matYellow);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
if(aCeilingLight) glMaterialfv(GL_FRONT, GL_EMISSION, matYellow);
glTranslatef(0,8.99,-10);
glRotatef(90, 1, 0, 0);
glutSolidCone(1,1,16,16);
glPopMatrix();
}
//椅子
//椅子
void draw_seat(void)
{
glColor3f(1, 0.6, 0.3);
glMaterialfv(GL_FRONT, GL_AMBIENT, matBrown);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matBrown);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glTranslatef(13.5 - seat_dis, -9, -5);
glScalef(0.8, 0.8, 0.8);
//凳子腿
glPushMatrix();
glTranslatef(-1, 0, -1);
glRotatef(-90, 1, 0, 0);
gluCylinder(obj, 0.2, 0.2, 2.5, 10, 10);
glPopMatrix();
glPushMatrix();
glTranslatef(1, 0, -1);
glRotatef(-90, 1, 0, 0);
gluCylinder(obj, 0.2, 0.2, 2.5, 10, 10);
glPopMatrix();
glPushMatrix();
glTranslatef(-1, 0, 1);
glRotatef(-90, 1, 0, 0);
gluCylinder(obj, 0.2, 0.2, 2.5, 10, 10);
glPopMatrix();
glPushMatrix();
glTranslatef(1, 0, 1);
glRotatef(-90, 1, 0, 0);
gluCylinder(obj, 0.2, 0.2, 2.5, 10, 10);
glPopMatrix();
//凳子面
glPushMatrix();
glTranslatef(0, 2.5, 0);
glScalef( 3, 0.5, 3);
glutSolidCube(1);
glPopMatrix();
glPopMatrix();
}
//时钟
//钟
void draw_clock(void)
{
glColor3f(1, 0.6, 0.3);
glMaterialfv(GL_FRONT, GL_AMBIENT, matYellow);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matYellow);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glTranslatef(0, 4, -19.0);
glScalef(0.75, 0.75, 1);
//圆盘
gluDisk(obj, 2.2, 2.5, 20, 4);
//时针
glLineWidth(2);
glBegin(GL_LINES);
glVertex3f(2.0 * cos(clock_agl1 * Pi / 180), 2.0 * sin(clock_agl1 * Pi / 180), 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(1 * cos(clock_agl2 * Pi / 180), 1.5 * sin(clock_agl2 * Pi / 180), 0);
glColor3f(black);
glVertex3f(0, 1.9, 0);
glVertex3f(0, 2.2, 0);
glVertex3f(1.9, 0, 0);
glVertex3f(2.2, 0, 0);
glVertex3f(0, -1.9, 0);
glVertex3f(0, -2.2, 0);
glVertex3f(-1.9, 0, 0);
glVertex3f(-2.2, 0, 0);
glEnd();
glLineWidth(1);
glColor3f(0.25, 0.25, 0.25);
gluDisk(obj, 0, 2.2, 20, 4);
glPopMatrix();
}
//日历
//日历
void draw_canlender(void)
{
glPushMatrix();
glTranslatef(-10, 3, -19.9);
glColor3f(0.98, 0.625, 0.12);
glBegin(GL_QUADS);
glVertex3f(-2, 2, -0.01);
glVertex3f(2, 2, -0.01);
glVertex3f(2, -2, -0.01);
glVertex3f(-2, -2, -0.01);
glEnd();
//画五角星
glColor3f(1.0, 0.0, 0.0);
GLfloat m=2.0f; //设边长为2
StarDisplay(m);
glColor3f(0.6, 0.4, 0.12);
glBegin(GL_QUADS);
glVertex3f(2, -2, -0.01);
glVertex3f(-2, -2, -0.01);
glVertex3f(-2, -4, -0.01);
glVertex3f(2, -4, -0.01);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex3f(-1.8, -2.1, 0);
glVertex3f(1.8, -2.1, 0);
glVertex3f(-1.8, -2.6, 0);
glVertex3f(1.8, -2.6, 0);
glVertex3f(-1.8, -3.1, 0);
glVertex3f(1.8, -3.1, 0);
glVertex3f(-1.8, -3.6, 0);
glVertex3f(1.8, -3.6, 0);
glEnd();
glPopMatrix();
}
//窗户
//窗户
void draw_window(void)
{
glPushMatrix();
glTranslatef(0, 0, 5);
glScalef(1, 1.2, 1.5);
glBegin(GL_QUADS);
glColor4f(1.0, 1.0, 1.0, 0.1);
glVertex3f(-18.99, 4, -12);
glVertex3f(-18.99, 4, -8);
glVertex3f(-18.99, 8, -8);
glColor4f(0.0, 0.0, 0.4, 0.1);
glVertex3f(-18.99, 8, -12);
glColor4f(1.0, 1.0, 1.0, 0.1);
glVertex3f(-20.1, 4, -12);
glVertex3f(-20.1, 4, -8);
glVertex3f(-20.1, 8, -8);
glColor4f(0.0, 0.0, 0.4, 0.1);
glVertex3f(-20.1, 8, -12);
glEnd();
glLineWidth(4);
glColor3f(0.6f, 0.4f, 0.12f);
glBegin(GL_LINES);
glVertex3f(-18.98f, 6, -12);
glVertex3f(-18.98f, 6, -8 );
glVertex3f(-18.98f, 8, -10);
glVertex3f(-18.98f, 4, -10);
glEnd();
glLineWidth(1);
glPopMatrix();
}
//桌子和茶壶
//桌子和茶壶
void draw_desk(void)
{
glColor3f(1, 0.6, 0.3);
glMaterialfv(GL_FRONT, GL_AMBIENT, matBrown);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matBrown);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
glPushMatrix();
glTranslatef(-14, -7.5, -5);
glScalef(2.0, 4.0, 1.5);
//桌腿
glPushMatrix();
glTranslatef(-1, 0, -1);
glScalef(0.2, 1.3, 0.2);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(1, 0, -1);
glScalef(0.2, 1.3, 0.2);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-1, 0, 1);
glScalef(0.2, 1.3, 0.2);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(1, 0, 1);
glScalef(0.2, 1.3, 0.2);
glutSolidCube(1);
glPopMatrix();
//面
glPushMatrix();
glTranslatef(0, 0.65, 0);
glScalef( 2.5, 0.1, 2.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix(); //Teapot
glColor3f(0,1,1);
glMaterialfv(GL_FRONT, GL_AMBIENT, matWhite);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matWhite);
glMaterialfv(GL_FRONT, GL_SPECULAR, matWhite);
glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
//glScalef(tea_scal, tea_scal, tea_scal);
glTranslatef(0.2, 0.93 + tea_high, 0);
glRotatef(-100, 0, 1, 0);
glutSolidTeapot(0.25 * tea_scal);
glPopMatrix();
//杯子
glColor3f(0,1,1);
glPushMatrix();
glTranslatef(0.28, 0.82, 1);
glRotated(90, 1, 0 ,0);
gluCylinder(obj,0.22, 0.12, 0.11, 20, 20);
glPopMatrix();
glPopMatrix();
}
//电视
//电视
void draw_tv(void)
{
glPushMatrix();
glTranslatef(18, 0, -5);
//电视机/电脑
glPushMatrix();
glTranslatef(0, 0, -2);
glScalef( 0.3, 4, 6);
glColor3f(0.0, 0.0, 0.0);
glutSolidCube(1);
glLineWidth(4);
glColor3f(0.0, 0.0, 1.0);
glutWireCube(1);
glLineWidth(1);
glPopMatrix();
glPopMatrix();
//电视桌
glPushMatrix();
glTranslatef(17.0, -8.8, -3);
glScalef(0.9, 0.6, 0.7);
glColor3f(1, 0.6, 0.3);
glPushMatrix();
glTranslatef(0, 0, -10);
glScalef( 4, 4, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 0, 0);
glScalef( 4, 4, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 2.25, -5);
glScalef( 4, 0.5, 10.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 8.25, -5);
glScalef( 4, 0.5, 10.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 5.25, -10);
glScalef( 4, 6, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 5.25, -5);
glScalef( 4, 6, 0.5);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 5.25, 0);
glScalef( 4, 6, 0.5);
glutSolidCube(1);
glPopMatrix();
if(tv_open){
glPushMatrix();
glTranslatef(0.8, 12, -9.5);
glScalef(0.001, 0.05, 0.02);
glRotated(-90, 0, 1, 0);
glColor3f(red);
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'H');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'E');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'L');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'L');
glutStrokeCharacter(GLUT_STROKE_ROMAN, 'O');
glPopMatrix();
}
glPopMatrix();
}
//台灯
//台灯
void draw_taideng(void)
{
glPushMatrix();
glTranslatef(10, -5, -17);
glPushMatrix();
glColor3f(1, 0, 1);
glMaterialfv(GL_FRONT, GL_AMBIENT, matBrown);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matBrown);
glMaterialfv(GL_FRONT, GL_SPECULAR, matBlack);
glMaterialfv(GL_FRONT, GL_SHININESS, matBlack);
glMaterialfv(GL_FRONT, GL_EMISSION, matBlack);
if(Light2)
glMaterialfv(GL_FRONT, GL_EMISSION, matBrown);
//glTranslatef(0,8.99,-10);
glRotatef(-90, 1, 0, 0);
glutSolidCone(1.5,2,16,16);
glPopMatrix();
glPushMatrix();
glTranslatef(0, -3.6, 0);
glScalef(3.0, 3, 3.0);
glColor3f(1, 0.6, 0.3);
glutSolidCube(1);
glPopMatrix();
glColor3f(0.0, 0.0, 0.0);
glPushMatrix();
glTranslatef(0, -2, 0.0);
glRotatef(-90, 1, 0, 0);
gluCylinder(obj, 0.4, 0.2, 2.99, 40, 40);
glPopMatrix();
glLineWidth(2);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(-1.48, -2.2, 1.51);
glVertex3f(-0.1, -2.2, 1.51);
glVertex3f(-0.1, -5, 1.51);
glVertex3f(-1.48,-5, 1.51);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(1.48, -2.2, 1.51);
glVertex3f(0.1, -2.2, 1.51);
glVertex3f(0.1, -5, 1.51);
glVertex3f(1.48,-5, 1.51);
glEnd();
glLineWidth(10);
glBegin(GL_POINTS);
glVertex3f(0.75, -3.5, 1.51);
glVertex3f(-0.75, -3.5, 1.51);
glEnd();
glLineWidth(1);
glPopMatrix();
}
//视角左转、右转函数
void turn_left(void)
{
int x = 0;
x = dir();
if(x == 1)
{
eobj[2] = eye[2]; //left
eobj[0] = eye[0] - 1;
}
else if(x == 2)
{ //right
eobj[2] = eye[2];
eobj[0] = eye[0] + 1;
}
else if(x == 3)
{
eobj[0] = eye[0]; //back
eobj[2] = eye[2] + 1;
}
else if(x == 4)
{
eobj[0] = eye[0]; //forward
eobj[2] = eye[2] - 1;
}
}
void turn_right(void)
{
int x = 0;
x = dir();
if(x == 1)
{
eobj[2] = eye[2];
eobj[0] = eye[0] + 1;
}
else if(x == 2)
{
eobj[2] = eye[2]; //left
eobj[0] = eye[0] - 1;
}
else if(x == 3)
{
eobj[0] = eye[0]; //forward
eobj[2] = eye[2] - 1;
}
else if(x == 4)
{
eobj[0] = eye[0]; //back
eobj[2] = eye[2] + 1;
}
}
void reshape(int w, int h) // Resize the GL Window. w=width, h=height
{
if (h == 0) h = 1;
WinWidth = w;
WinHeight = h;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
gluLookAt( eye[0], eye[1], eye[2], eobj[0], eobj[1], eobj[2], 0.0, 1.0, 0.0);
}
void keyboard(unsigned char key, int x, int y) // Handle the keyboard events here
{
switch (key)
{
case'\033'://press 'esc' to quit
exit(0);
break;
case'1':
Light0 = !Light0;
printf("Press key '1'.\n");
break;
case'2':
Light1 = !Light1;
printf("Press key '2'.\n");
break;
case'3':
Light2 = !Light2;
printf("Press key '3'.\n");
break;
case '4':
if(bookdis == 0)
bookdis = 4;
else bookdis = 0;
break;
case '5':
printf("Press key '5'.\n");
if(tea_high == 0)
tea_high = 1;
else tea_high = 0;
break;
case '6':
printf("Press key '6'.\n");
if(tea_scal == 1)
tea_scal += 0.5;
else if(tea_scal == 1.5)
tea_scal = 2;
else
tea_scal =1;
break;
case'7':
aMice = !aMice;
printf("Press key '7'.\n");
break;
case '8':
tv_open = !tv_open;
printf("Press key '8'.\n");
break;
case '9':
pep_retot = !pep_retot;
printf("Press key '8'.\n");
break;
case '0':
if(seat_dis == 0){
seat_dis = 2;
}
else{
seat_dis = 0;
}
printf("Press key '8'.\n");
break;
case 'o':
printf("Press key '0'.\n");
door_open = !door_open;
break;
case 'a':
printf("Press key 'a'.\n");
turn_left();
break;
case 'd':
printf("Press key 'd'.\n");
turn_right();
break;
case 'w':
printf("Press key 'w'.\n");
eye[1] += 1;
eobj[1] += 1;
break;
case 's':
printf("Press key 'w'.\n");
eye[1] -= 1;
eobj[1] -= 1;
break;
case 'b':
printf("Press key 'b'.\n");
eye[0] = eobj[0] = 0;
eye[1] = eobj[1] = 0;
eye[2] = 17.3;
eobj[2] = 16.3;
break;
}
}
//视角前后左右移动函数
void move_left(void)
{
int x = 0;
x = dir();
if(x == 1)
{
eye[0] -= 1;
eobj[0] -= 1;
}
else if(x == 2)
{
eye[0] += 1;
eobj[0] += 1;
}
else if(x == 3)
{
eye[2] += 1;
eobj[2] += 1;
}
else if(x == 4)
{
eye[2] -= 1;
eobj[2] -= 1;
}
}
void move_right(void)
{
int x = 0;
x = dir();
if(x == 1)
{
eye[0] += 1;
eobj[0] += 1;
}
else if(x == 2)
{
eye[0] -= 1;
eobj[0] -= 1;
}
else if(x == 3)
{
eye[2] -= 1;
eobj[2] -= 1;
}
else if(x == 4)
{
eye[2] += 1;
eobj[2] += 1;
}
}
void move_forward(void)
{
int x = 0;
x = dir();
if(x == 1)
{
eye[2] -= 1;
eobj[2] -= 1;
}
else if(x == 2)
{
eye[2] += 1;
eobj[2] += 1;
}
else if(x == 3)
{
eye[0] -= 1;
eobj[0] -= 1;
}
else if(x == 4)
{
eye[0] += 1;
eobj[0] += 1;
}
}
void move_back(void)
{
int x = 0;
x = dir();
if(x == 1)
{
printf("1");
eye[2] += 1;
eobj[2] += 1;
}
else if(x == 2)
{
eye[2] -= 1;
eobj[2] -= 1;
}
else if(x == 3)
{
eye[0] += 1;
eobj[0] += 1;
}
else if(x == 4)
{
eye[0] -= 1;
eobj[0] -= 1;
}
}
void specialkey(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
move_left();
printf("left\n");
break;
case GLUT_KEY_RIGHT:
move_right();
printf("right\n");
break;
case GLUT_KEY_UP:
printf("forward\n");
move_forward();
break;
case GLUT_KEY_DOWN:
printf("back\n");
move_back();
break;
default:
break;
}
reshape(WinWidth, WinHeight);
glutPostRedisplay();
}
//主函数
void init(void) // All Setup For OpenGL Goes Here
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
//glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
//鍒涘缓绾圭悊
makeCheckImages();
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
//瀹氫箟绾圭悊
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
//鎺у埗婊ゆ尝
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
void display(void) // Here's Where We Do All The Drawing
{
// TODO:
// Place light source here
setLight0(Light0);
setLight1(Light1);
setLight2(Light2);
setLight3(Light3);
obj = gluNewQuadric();
// TODO:
// Draw walls and objects here
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//绾圭悊鏄犲皠鏂瑰紡
draw_wall();
draw_bed();
draw_closet();
draw_light();
draw_seat();
draw_clock();
draw_canlender();
draw_window();
draw_tv();
draw_bookdesk();
draw_mouse();
draw_desk();
draw_taideng();
draw_vase();
out_house();
draw_people();
// TODO:
// Add animation here
glFlush();
glutSwapBuffers();
}
void idle(void)
{
if(!aMice){
if(aMiceEyeBigger){
aMiceEyeScale += 0.2;
if(aMiceEyeScale >= 3) aMiceEyeBigger = false;
}else{
aMiceEyeScale -= 0.2;
if(aMiceEyeScale <= 0) aMiceEyeBigger = true;
}
aMiceTrans[0] = aMiceTrans[1] = aMiceTrans[2] = 0;
}else{
aMiceEyeScale = 1;
aMiceTrans[2] += 0.05;
if(aMiceTrans[2] < 10)
aMiceTrans[0] += 0.2;
else
aMiceTrans[0] -= 0.2;
if(aMiceTrans[2] > 25)
aMiceTrans[0] = aMiceTrans[1] = aMiceTrans[2] = 0;
}
if(!door_open) {
if(door_dis > 0)
door_dis -= 0.05;
}
else{
if(door_dis <20)
door_dis += 0.05;
}
clock_agl1 -= 0.008;
if(clock_agl1 == 90) {
clock_agl2 -= 6;
}
if(pep_retot) {
pep_agl = pep_agl + pep_r;
if(pep_agl > 60) {
pep_r = -1;
}
if(pep_agl < -60) {
pep_r = 1;
}
}
else {
pep_agl = -45;
pep_r = 1;
}
reshape(WinWidth, WinHeight);
//Sleep(0.01);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
/*Initialization of GLUT Library */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
/*Create a window with title specified */
glutInitWindowSize(950, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Assignment 1");
init(); /*not GLUT call, initialize several parameters */
/*Register different CALLBACK function for GLUT to response
with different events, e.g. window sizing, mouse click or
keyboard stroke */
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialkey);
glutIdleFunc(idle);
/*Enter the GLUT event processing loop which never returns.
it will call different registered CALLBACK according
to different events. */
glutMainLoop();
return 0;
}
运行效果
//房子外部
//房间内部
//灯光
//房子左边建筑
//房子右边建筑
//正前方往前走