计算机图形学作业-三维线框图、实体图、场景图绘制,结合OpenGl。

一、初始化

        先写函数ChangeSize对窗口初始化,然后根据展示效果写不同的绘图函数。此处用OpenGL库与MFC工程结合,调用glut库中已有的glutWireTeapot、glutWireSphere等方法直接绘图。

void ChangeSize(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
	glMatrixMode(GL_MODELVIEW);
}

二、线框图

(1)茶壶线框图

    主函数void CMFCApplication2View::On32797(),绘制茶壶的线框图函数void RenderScene(void)。

1、代码如下:

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 1.0f);
	glLoadIdentity();
	gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glScalef(1.0f, 2.0f, 1.0f);
	glutWireTeapot(1.0);
	glutSwapBuffers();
}
//茶壶线框图
void CMFCApplication2View::On32797()
{
	// TODO: 在此添加命令处理程序代码
	glutInit(&__argc, __argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(w, h);    //窗口大小
	glutInitWindowPosition(100, 100);
	glutCreateWindow("瘦茶壶线框图");
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);
	
	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
	glutMainLoop();
}

2、效果如下:

(2)球体线框图

   主函数void CMFCApplication2View::On32798(),绘制球体的线框图函数void RenderScene1(void),在此通过调整glut库里的glutWireSphere参数,将线框球体压扁,展示出一个蜘蛛网的效果。

1、代码如下:

void RenderScene1(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 1.0f);
	glLoadIdentity();
	gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glScalef(1.0f, 2.0f, 1.0f);
	glutWireSphere(1,10,10);
	glutSwapBuffers();
}
//球体线框图
void CMFCApplication2View::On32798()
{
	// TODO: 在此添加命令处理程序代码
	glutInit(&__argc, __argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(w, h);    //窗口大小
	glutInitWindowPosition(100, 100);
	glutCreateWindow("蜘蛛网线框图");
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene1);
	
	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
	glutMainLoop();
}

2、效果如下:

二、实体图

        茶壶实体图:主函数void CMFCApplication2View::On32799(),绘制茶壶的实体图函数void RenderScene21(void)。

1、代码如下:

void RenderScene21(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 1.0f);
	glLoadIdentity();
	gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glScalef(1.0f, 2.0f, 1.0f);
	glutSolidTeapot(1.0);
	glutSwapBuffers();
}
//茶壶实体图
void CMFCApplication2View::On32799()
{
	// TODO: 在此添加命令处理程序代码
	glutInit(&__argc, __argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(w, h);    //窗口大小
	glutInitWindowPosition(100, 100);
	glutCreateWindow("茶壶实体图");
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene21);

	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
	glutMainLoop();
}

2、效果如下:

三、场景图

1、代码如下:

//OpenGL场景图 上下左右移动
//根据八个点绘制长方体
void constract(double x, double y, double z, double x1, double y1, double z1)
{
	eigh[0][0] = x;
	eigh[0][1] = y;
	eigh[0][2] = z;        //  第0个点

	eigh[1][0] = x;
	eigh[1][1] = y;
	eigh[1][2] = z + z1;     //  第一个点

	eigh[2][0] = x + x1;
	eigh[2][1] = y;
	eigh[2][2] = z + z1;     //  第二个点

	eigh[3][0] = x + x1;
	eigh[3][1] = y;
	eigh[3][2] = z;        //  第三个点
	for (int i = 0; i < 4; i++)  // for()循环来完成其余的四个点
	{
		for (int j = 0; j < 3; j++)
		{
			if (j == 1)
				eigh[i + 4][j] = eigh[i][j] + y1;
			else
				eigh[i + 4][j] = eigh[i][j];
		}
	}
}
//根据六个顶点绘制三棱柱
void cons(double x, double y, double z, double x1, double y1, double z1, double length)
{
	thre[0][0] = x;
	thre[0][1] = y;
	thre[0][2] = z;     //第一个点,三角形底边的一个点

	thre[1][0] = x1;
	thre[1][1] = y1;
	thre[1][2] = z1;    //第二个点,三角形上面的那个点

	int hemiZ = z - z1;
	int Z = 2 * hemiZ;

	thre[2][0] = x;
	thre[2][1] = y;
	thre[2][2] = z - Z; //第三个点,三角形底边的另外一个点

	for (int i = 3; i < 6; i++)
	{
		thre[i][0] = thre[i - 3][0] + length;
		thre[i][1] = thre[i - 3][1];
		thre[i][2] = thre[i - 3][2];
	}
	//点的顺序:0左侧-底面-前  1左侧-顶点  2左侧-底面-后 3右侧-底面-前  4右侧-顶点  5右侧-底面-后
}
//建造矩形
void build()
{
	glBegin(GL_POLYGON);
	glNormal3f(0.0, -1.0, 0.0);
	glVertex3f(eigh[0][0], eigh[0][1], eigh[0][2]);
	glVertex3f(eigh[1][0], eigh[1][1], eigh[1][2]);
	glVertex3f(eigh[2][0], eigh[2][1], eigh[2][2]);
	glVertex3f(eigh[3][0], eigh[3][1], eigh[3][2]);
	glEnd();   //     下底

	glBegin(GL_POLYGON);
	glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(eigh[1][0], eigh[1][1], eigh[1][2]);
	glVertex3f(eigh[0][0], eigh[0][1], eigh[0][2]);
	glVertex3f(eigh[4][0], eigh[4][1], eigh[4][2]);
	glVertex3f(eigh[5][0], eigh[5][1], eigh[5][2]);
	glEnd();   //     左面

	glBegin(GL_POLYGON);
	glNormal3f(1.0, 0.0, 0.0);
	glVertex3f(eigh[7][0], eigh[7][1], eigh[7][2]);
	glVertex3f(eigh[6][0], eigh[6][1], eigh[6][2]);
	glVertex3f(eigh[2][0], eigh[2][1], eigh[2][2]);
	glVertex3f(eigh[3][0], eigh[3][1], eigh[3][2]);
	glEnd();   //     右面

	glBegin(GL_POLYGON);
	glNormal3f(0.0, 0.0, 1.0);
	glVertex3f(eigh[5][0], eigh[5][1], eigh[5][2]);
	glVertex3f(eigh[6][0], eigh[6][1], eigh[6][2]);
	glVertex3f(eigh[2][0], eigh[2][1], eigh[2][2]);
	glVertex3f(eigh[1][0], eigh[1][1], eigh[1][2]);
	glEnd();   //     前面

	glBegin(GL_POLYGON);
	glNormal3f(0.0, 0.0, -1.0);
	glVertex3f(eigh[0][0], eigh[0][1], eigh[0][2]);
	glVertex3f(eigh[3][0], eigh[3][1], eigh[3][2]);
	glVertex3f(eigh[7][0], eigh[7][1], eigh[7][2]);
	glVertex3f(eigh[4][0], eigh[4][1], eigh[4][2]);
	glEnd();   //     后面

	glBegin(GL_POLYGON);
	glNormal3f(0.0, 1.0, 0.0);
	glVertex3f(eigh[4][0], eigh[4][1], eigh[4][2]);
	glVertex3f(eigh[7][0], eigh[7][1], eigh[7][2]);
	glVertex3f(eigh[6][0], eigh[6][1], eigh[6][2]);
	glVertex3f(eigh[5][0], eigh[5][1], eigh[5][2]);
	glEnd();   //     上面
}
//建造一个三棱柱,用于画房顶
void build2()
{
	//画左侧的三角形
	glBegin(GL_TRIANGLES);
	glVertex3f(thre[0][0], thre[0][1], thre[0][2]);
	glVertex3f(thre[1][0], thre[1][1], thre[1][2]);
	glVertex3f(thre[2][0], thre[2][1], thre[2][2]);
	glEnd();

	//画右侧的三角形
	glBegin(GL_TRIANGLES);
	glVertex3f(thre[3][0], thre[3][1], thre[3][2]);
	glVertex3f(thre[4][0], thre[4][1], thre[4][2]);
	glVertex3f(thre[5][0], thre[5][1], thre[5][2]);
	glEnd();

	//画前面的四边形
	glBegin(GL_POLYGON);
	//glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(thre[0][0], thre[0][1], thre[0][2]);
	glVertex3f(thre[3][0], thre[3][1], thre[3][2]);
	glVertex3f(thre[4][0], thre[4][1], thre[4][2]);
	glVertex3f(thre[1][0], thre[1][1], thre[1][2]);
	glEnd();

	//画后面的四边形
	glBegin(GL_POLYGON);
	//glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(thre[2][0], thre[2][1], thre[4][2]);
	glVertex3f(thre[1][0], thre[1][1], thre[1][2]);
	glVertex3f(thre[4][0], thre[4][1], thre[4][2]);
	glVertex3f(thre[5][0], thre[5][1], thre[4][2]);
	glEnd();

	//画底层的四边形
	glBegin(GL_POLYGON);
	//glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(thre[2][0], thre[2][1], thre[2][2]);
	glVertex3f(thre[0][0], thre[0][1], thre[0][2]);
	glVertex3f(thre[3][0], thre[3][1], thre[3][2]);
	glVertex3f(thre[5][0], thre[5][1], thre[5][2]);
	glEnd();
}

//开始绘制三维场景
void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();          //增加M矩阵
	glRotatef(rotate_x, 1.0, 0.0, 0.0);
	glRotatef(rotate_y, 0.0, 1.0, 0.0);

	glTranslatef(-270, 0, -270);
	glScalef(1.5, 1.5, 1.5);
	//constract第三个参数小了往里跑,第四个参数越小越窄,
	// 第五个参数小了top高度低了,第六个参数向外边长
	//地面底板(浅粉色)
	glBegin(GL_POLYGON);
	constract(-200, 0, 0, 700, 10, 500);
	glColor3f(slightpink);
	build();
	//墙壁(颜色为淡黄色)
	glColor3f(yellow);
	constract(50, 10, 100, 12, 160, 212);  //左墙壁
	build();
	constract(388, 10, 100, 12, 160, 212);   //右墙壁
	build();
	constract(62, 10, 100, 336, 160, 12);   //后墙壁
	build();
	constract(62, 10, 300, 336, 160, 12);   //前墙壁
	build();
	//房顶(颜色红色)
	glColor3f(red);
	cons(35, 170 + 0.1, 327, 35, 250 + 0.1, 206, 380);
	build2();
	//画矩形条 烟囱
	glColor3f(coffee);
	constract(80, 190, 110, 30, 120, 12);
	build();
	//太阳
	glColor3f(gold);
	glTranslatef(-90, 380, 0);
	glutSolidSphere(35.0, 20, 20);
	glTranslatef(-250, -350, 0);
	//门(门为蓝色,门把手为咖色)
	glColor3f(lightblue);
	constract(545, -20, 310, 50, 70, 6);  //门
	build();
	glColor3f(coffee);
	constract(580, -5, 312, 10, 20, 8);   //门把手
	build();
	//左窗户蓝色,添加透明度
	glColor4f(lightblue, 0.35);
	constract(430, 120, 312, 80, -80, 4);
	build();
	//右窗户蓝色,添加透明度
	glColor4f(lightblue, 0.35);
	constract(625, 120, 312, 80, -80, 4);
	build();
	//小路(颜色brown)
	for (int i = 340; i < 500; i += 45)
	{
		glColor3f(brown);
		constract(545, -20, i, 50, 2, 20);
		build();
	}
	// 第一组
	//1树干
	glColor3f(coffee);
	constract(165, -20, 390, 20, 50, 20);
	build();
	//1树叶
	glColor3f(deepgreen);
	glTranslatef(165, 50, 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);  //球5上
	glTranslatef(100, -80, -400);

	//2树干
	glColor3f(coffee);
	constract(-50, 0, 390, 20, 50, 20);
	build();
	//2树叶
	glColor3f(deepgreen);
	glTranslatef(-50, 50, 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);  //球5上
	glTranslatef(100, -80, -400);

	//3树干
	glColor3f(coffee);
	constract(-40, 20, 390, 20, 60, 20);
	build();
	//3树叶
	glColor3f(deepgreen);
	glTranslatef(-40, 60, 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);  //球5上
	glTranslatef(100, -80, -400);
	// 第二组
	//1树干
	glColor3f(coffee);
	constract(-240, 30, 280, 20, 70, 20);
	build();
	glColor3f(deepgreen);
	glTranslatef(-240, 110, 290);
	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);  //球5上
	glTranslatef(100, -80, -400);
	//2树干
	glColor3f(coffee);
	constract(-45, -10, 375, 20, 50, 20);
	build();
	glColor3f(deepgreen);
	glTranslatef(-45, 40, 385);
	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);  //球5上
	glTranslatef(100, -80, -400);
	//3树干
	glColor3f(coffee);
	constract(-20, 20, 390, 20, 30, 20);
	build();
	//3树干
	glColor3f(deepgreen);
	glTranslatef(-20, 60, 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);  //球5上
	glTranslatef(100, -80, -400);
	// 第三组
	//1树
	glColor3f(coffee);
	constract(-260, 30, 310, 20, 70, 20);
	build();
	glColor3f(deepgreen);
	glTranslatef(-260, 110, 320);
	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);  //球5上
	glTranslatef(100, -80, -400);
	//2树
	glColor3f(coffee);
	constract(-55, -10, 375, 20, 50, 20);
	build();
	glColor3f(deepgreen);
	glTranslatef(-55, 40, 385);
	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);  //球5上
	glTranslatef(100, -80, -400);
	//3树干
	glColor3f(coffee);
	constract(-30, 20, 390, 20, 30, 20);
	build();
	//3树干
	glColor3f(deepgreen);
	glTranslatef(-30, 60, 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);  //球5上
	glTranslatef(100, -80, -400);
	glFlush();  // 刷新
	glutSwapBuffers();//还要加上swapbuffer函数
}
//窗口初始化
void init2(void)
{
	GLfloat sun_direction[] = { 100.0, 100.0, 100.0, 0.0 };
	GLfloat sun_intensity[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat ambient_intensity[] = { 0.5, 0.5, 0.5, 1.0 };

	glEnable(GL_LIGHTING);              // 设置氛围光
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_intensity);

	glEnable(GL_LIGHT0);                //设置阳光
	glLightfv(GL_LIGHT0, GL_POSITION, sun_direction);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_intensity);

	glEnable(GL_COLOR_MATERIAL);        //打开颜色渲染
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glClearColor(0.0, 0.0, 0.0, 0.0);      //定义背景颜色为黑色

	glEnable(GL_BLEND); // 打开混合
	glEnable(GL_DEPTH_TEST);// 关闭深度测试
	glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基于源象素alpha通道值的半透明混合函数

	glMatrixMode(GL_PROJECTION);     // 定义视角
	glOrtho(-w, w, -h, h, -w, w); //创建一个正交平行的视景体
}
//键盘控制函数
void specialkeys(int key, int x, int y)
{
	if (key == GLUT_KEY_RIGHT)
		rotate_y += 5;
	else if (key == GLUT_KEY_LEFT)
		rotate_y -= 5;
	else if (key == GLUT_KEY_UP)
		rotate_x += 5;
	else if (key == GLUT_KEY_DOWN)
		rotate_x -= 5;
	glutPostRedisplay();
}
//三维场景图图像平移、旋转变换,键盘操控
void CMFCApplication2View::On32801()
{
	// TODO: 在此添加命令处理程序代码
	glutInit(&__argc, __argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(w, h);    //窗口大小
	glutInitWindowPosition(100, 100);
	glutCreateWindow("场景图");
	init2();
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_DEPTH_TEST);
	glutDisplayFunc(display);
	glutSpecialFunc(specialkeys);

	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
	glutMainLoop();
}

2、效果如下:

 

运行后的场景图                                                    键盘操作后的主视图

    

              键盘操作后的左视图                                   键盘操作后的俯视图

        在场景图的绘制中,用到了gl库中的glEnable(GL_LIGHTING)方法来设置氛围光。用到glEnable(GL_COLOR_MATERIAL)方法打开颜色渲染,让我画的图出现色彩。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值