计算机图形学(一)——opengl实现三维立方体添加纹理光照与材质、键盘鼠标控制平移旋转和放大缩小

1.实验要求:

用OpenGL和C语言编写一个带纹理和材质的一个立方体的交互式程序。

1)要求生成一个在立方体,并在立方体的六个面上并分别实现不同的纹理映射和材质。纹理的类型为BMP图片纹理,材质类型可以自己设计。例如,三个面上实现纹理映射的头像和生活照,另外三个面上实现材质(金属、塑料等)。

2)可以利用鼠标和键盘进行交互,实现该立方体的旋转、平移和缩放。

2.实验效果图如下:

正常情况下

在这里插入图片描述

加入材质后

在这里插入图片描述

取消纹理后

在这里插入图片描述

线框图

在这里插入图片描述

3.部分核心代码附录如下:(需配置opengl环境)另外,所加入的纹理照片必须为bmp格式,命名分别为1 2 3即可

GLfloat  xrot;									// X 旋转量
GLfloat  yrot;									// Y 旋转量
GLfloat  zrot;									// Z 旋转量
float tx=0;
float ty=0;
float sf=0;
float M_PI=3.14159265f;  
static float c = M_PI/180.0f; //弧度和角度转换参数  
static int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向  
static float r = 1.75f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标  
float cameraDistance;

void Mouse(int button, int state, int x, int y) //处理鼠标点击  
{  
    if (state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标  
        oldmx = x, oldmy = y;  
		
}  
void onMouseMove(int x, int y) //处理鼠标拖动  
{  
    //printf("%d\n",du);  
    du += x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了  
    h += (y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了  
  
    oldmx = x, oldmy = y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备  
	glutPostRedisplay();
}  

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glTranslatef(0.0f+tx,0.0f+ty,-4.0f);// 平移变换
	glScalef(1+sf,1+sf,1+sf); //缩放变换

   	glRotatef(xrot, 1.0f, 0.0f, 0.0f);
	glRotatef(yrot, 0.0f, 1.0f, 0.0f);
	glRotatef(zrot, 0.0f, 0.0f, 1.0f);
	//给出实体图
  
    glRotatef(30*c*du, 0.0f, 1.0f, 0.0f);  
    glRotatef(-h, -1.0f, 0.0f, 0.0f);  

	glBindTexture(GL_TEXTURE_2D, tex1);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);	
	glEnd();
	// Back Face
	glBindTexture(GL_TEXTURE_2D, tex2);
	glBegin(GL_QUADS);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
	glEnd();

	// Top Face
	glBindTexture(GL_TEXTURE_2D, tex3);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
	glEnd();

	// Bottom Face
//	glBindTexture(GL_TEXTURE_2D, texGround);
	glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
	glEnd();

	// Right face
//	glBindTexture(GL_TEXTURE_2D,texGround);
	glBegin(GL_QUADS);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
	glEnd();

	// Left Face
//	glBindTexture(GL_TEXTURE_2D, texGround);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
	glEnd();

	glutSwapBuffers();
}

void reshape(GLsizei w, GLsizei h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-5.0, 5.0, -5.0*(GLfloat)h / (GLfloat)w, 5.0*(GLfloat)h / (GLfloat)w, -5.0, 5.0);
    else
        glOrtho(-5.0*(GLfloat)w / (GLfloat)h, 5.0*(GLfloat)w / (GLfloat)h, -5.0, 5.0, -5.0, 5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
   	case 'd':    //当按下键盘上d时,以沿X轴旋转为主
		xrot += 3.0f;   //设置旋转增量
		glutPostRedisplay();   //重绘函数
		break;
	case 's':
		yrot += 3.0f;
		glutPostRedisplay();
		break;
	case 'a':
		zrot += 3.0f;
		glutPostRedisplay();
		break;
	case '1':
       sf+=0.1;
	   	glutPostRedisplay();
        break;
	case '2':
       sf-=0.1;
        break;
	case '3':
       glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//显示线框模型
        break;
	case '4':
       	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//显示实体模型
        break;
	case '5':
		glEnable(GL_LIGHTING);//开灯
		break;
	case '6':
		glDisable(GL_LIGHTING);//关灯
		break;
	case '8':
		glDisable(GL_TEXTURE_2D);//关闭纹理映射
		break;
	case '7':
		glEnable(GL_TEXTURE_2D);//打开纹理映射
		break;
    default:
        break;
    }
    glutPostRedisplay();
}
void specialKeyboard(int key,int x,int y)
{
if(key == GLUT_KEY_UP )
ty+=0.1;
if(key == GLUT_KEY_DOWN)
ty-=0.1;
if(key ==GLUT_KEY_LEFT)
tx-=0.1;
if(key==GLUT_KEY_RIGHT)
tx+=0.1;
glutPostRedisplay();
}

4.程序说明

上下左右键以及鼠标可以控制图形移动

按asd可以控制图形旋转

按1可以控制图形放大,2控制图形缩小

3显示线框模型 4显示实体模型

5添加光照 6取消光照

7添加纹理映射 8取消纹理映射

完整代码获取请添加QQ 1173953942

回复 立方体即可

  • 9
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值