图形学实验(2)--OpenGL 入门

图形几何变换及裁剪

图形的几何变换

  • 把模型矩阵复位,
    即通过给模型视图矩阵加载上单位矩阵来复位原点。下面的代码把单位矩阵加载到模型视图矩阵中:
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    第一个函数用于指定当前操作的矩阵,其函数原型如下:
    glMatrixMode(GLenum mode);
    其中参数mode 用于确定将哪个矩阵堆栈用于矩阵操作,它的取值有:GL_MODELVIEW
    (模型视图矩阵堆栈),GL_PROJECTION(投影矩阵堆栈)和GL_TEXTURE(纹理矩阵堆
    栈)。一旦设置了当前操作矩阵,它就将保持为活动的矩阵,直到你修改它为止。
    第二个函数作用就是给当前操作矩阵加载上单位矩阵,。
#include<GL/glut.h>

//初始化窗口
void Initial();

void ChangeSize(int w, int h);

void Display();

//绘制三角形
void DrawTriangle();

int main(int argc, char* argv[])
{
	//初始化工具包
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	//窗口设置
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("1812030065-李诗雨");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(Display);

	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}
void Initial(void)
{
	//设置窗口背景色
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void DrawTriangle(void)
{
	glBegin(GL_TRIANGLES);
	glVertex2f(0.0f, 0.0f);
	glVertex2f(40.0f, 0.0f);
	glVertex2f(20.0f, 40.0f);
	glEnd();
}

void ChangeSize(int w, int h)
{
	if (h == 0) h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (w <= h)
		glOrtho(-120.0f, 120.0f, -120.0f * h / w, 120.0f * h / w, -120.0f, 120.0f);
	else
		glOrtho(-120.0f * w / h, 120.0f * w / h, -120.0f, 120.0f, -120.0f, 120.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void Display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	//绘制黑色坐标轴
	glColor3f(0.0f, 0.0f, 0.0f);
	//不裁剪窗口的话,屏幕的坐标位于窗口中心
	glBegin(GL_LINES);
	glVertex2f(-120.0f, 0.0f);
	glVertex2f(120.0f, 0.0f);
	glVertex2f(0.0f, -120.0f);
	glVertex2f(0.0f, 120.0f);
	glEnd();

	//绘制红色的三角形
	glColor3f(1.0f, 0.0, 0.0f);
	DrawTriangle();

	//画一个逆时针旋转200度的绿色三角形
	  //第一个参数表示逆时针旋转的度数,后三个参数指定旋转的矢量坐标
	glRotatef(200.0f, 0.0f, 0.0f, 1.0f);//以z轴为旋转轴(垂直屏幕方向),旋转的是坐标系
	glColor3f(0.0f, 1.0f, 0.0f);
	DrawTriangle();

	//画沿着x轴负向平移80的黄色三角形
	  //因为旋转的是坐标系,所以经过一次旋转之后要重置一下
	glLoadIdentity();
	glTranslatef(-80.0f, 0.0f, 0.0f);
	glColor3f(1.0, 1.0f, 0.0f);
	DrawTriangle();

	//画出沿x轴对称,沿x轴正向平移10,沿y轴负向平移10,缩放因子为 1.5,2.0,1.0的蓝色三角形
	glLoadIdentity();
	glTranslatef(10.0f, -10.0f, 0.0f);
	glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
	glScalef(1.5f, 2.0f, 1.0f);
	glColor3f(0.0f, 0.0f, 1.0f);
	DrawTriangle();

	glFlush();
}

在这里插入图片描述

掌握OpenGL中三维观察、透视投影、正交投影的参数设置。

  • 关于几何变换抵消坐标积累变换的方法
    glPushMatrix 变换 glPopMatrix 这个可以理解为把当前坐标状态(未作变换的)入栈,经过变换后坐标状态(未作变换的)出栈
    具体参考glPushMatrix ,glPopMatrix 的理解

  • 定义视景转换
    视点中心由eye[]控制,场景中心由center[]控制,y轴向上
    gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0);
    函数原型
    void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
    该函数定义一个视图矩阵,并与当前矩阵相乘。
    第一组eyex, eyey,eyez 相机在世界坐标的位置
    第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置
    第三组upx,upy,upz 相机向上的方向在世界坐标中的方向
    你把相机想象成为你自己的脑袋:
    第一组数据就是脑袋的位置
    第二组数据就是眼睛看的物体的位置
    第三组就是头顶朝向的方向(因为你可以歪着头看同一个物体)
    如果我们向前或向后移动,则相应的图像会变大或变小,这里其实就是运用了透视原理,近处的物体大,远处的物体小,实际物体的大小是不变的,
    同理改变center坐标(眼睛看去的那个点,可简单理解为视线的终点)也会影响球的大小,同样可以认为是改变了物体与观察点的距离所致。
    gluLookAt函数详解

  • gluPerspective 透视投影 gluperspective详解

  • glortho 创建一个正交平行的视景体(正投影),详解

关于里面的旋转不懂。。。

#include <GL/glut.h>

float fTranslate;
float fRotate; //场景自转角度
float fScale = 1.0f;

bool bPersp = false; //透视模式
bool bAnim = false; //场景自转
bool bWire = false;//边缘填充

int wHeight = 0;
int wWidth = 0;
//通过改变下面参数来控制茶壶
bool isTeapotRotate = false;
float teapotRotate = 0.0;//茶壶旋转
float teapotPos[] = { 0,0 }; //茶壶的位置

//窗口形状改变时调用
void reshape(int width, int height);
void updateView(int width, int height);
//绘图
void redraw();
void Draw_leg();
void Draw_Scene();
//按键调整参数
void key(unsigned char k, int x, int y);
//动画
void idle();


int main(int argc, char* argv[]) {
	//初始化工具包
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
	//窗口设置
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("1812030065-李诗雨");
	//全局回调函数,不断监听
	glutReshapeFunc(reshape);
	glutDisplayFunc(redraw);
	glutKeyboardFunc(key);
	glutIdleFunc(idle);//动画渲染的关键

	glutMainLoop();//进入循环
	return 0;
}

void reshape(int width, int height) {//参数是窗口的宽和高
	if (height == 0) {
		height = 1;
	}// 窗口太小时的处理
	wHeight = height;
	wWidth = width;
	updateView(wHeight, wWidth);
}
void updateView(int width,int height) {
	glViewport(0, 0, width, height);//重置当前视口
	//投影
	glMatrixMode(GL_PROJECTION);//选择投影矩阵
	glLoadIdentity();//重置投影矩阵
	//计算宽高比
	float whRatio = (GLfloat)width / (GLfloat)height;
	//是否开启透视模式
	if (bPersp) {
		gluPerspective(45.0f, whRatio, 0.1f, 100.0f);
	}
	else
		glOrtho(-3, 3, -3, 3, -100, 100);//建立修剪空间的范围

	glMatrixMode(GL_MODELVIEW);//选择模型视图矩阵
}

void idle() {
	glutPostRedisplay();//渲染动画
}

float eye[] = { 0,0,8 };
float center[] = { 0,0,0 };

void key(unsigned char k, int x, int y) {
	switch (k)
	{
	case 'q':exit(0); break;//退出
	case 'p':bPersp = !bPersp; updateView(wHeight, wWidth);break;//开启或关闭透视模式
	case ' ':bAnim = !bAnim;break;//开启或关闭场景自转
	case'o':bWire = !bWire;break;//开启或关闭边缘填充
	case 'a':eye[0] += 0.2; center[0] += 0.2; break;//更改eye和center在x轴上的坐标	
	case 'd':eye[0] -= 0.2; center[0] -= 0.2; break;//更改eye和center在x轴上的坐标	
	case 'w':eye[1] -= 0.2; center[1] -= 0.2; break;//更改eye和center在y轴上的坐标	
	case 's':eye[1] += 0.2; center[1] += 0.2; break;//更改eye和center在y轴上的坐标	
	case 'z':eye[2] -= 0.2; break;//更改eye在z轴上的坐标	
	case 'c':eye[2] += 0.2;  break;//更改eye在z轴上的坐标
		//茶壶相关操作
	case'l':if (teapotPos[0] < 2.0)teapotPos[0] += 0.1;break;
	case'j':if (teapotPos[0] > -2.0)teapotPos[0] -= 0.1; break;
	case'i':if (teapotPos[1] < 1.5)teapotPos[1] += 0.1; break;
	case'k':if (teapotPos[1] > -1.5)teapotPos[1] -= 0.1; break;
	case'e':isTeapotRotate = !isTeapotRotate; break;//开启或关闭茶壶自转
	default:
		break;
	}
}

void Draw_leg() {
	//画一个比例为1:1:3的桌子腿
	glScalef(1, 1, 3);
	glutSolidCube(1.0);
}
void Draw_Scene() {
	//画茶壶
	glPushMatrix();//当前坐标状态(未作变换的)入栈
	glTranslatef(teapotPos[0], 0, 4 + 1+teapotPos[1]);
	glRotatef(teapotRotate, 0, 0, 1);
	glRotatef(90, 1, 0, 0);
	glutSolidTeapot(1);
	glPopMatrix();//坐标状态(未作变换的)出栈

	//画桌子板
	glPushMatrix();//当前坐标状态(未作变换的)入栈
	glTranslatef(0, 0, 3.5);
	glScalef(5, 4, 1);
	glRotatef(90, 1, 0, 0);
	glutSolidCube(1.0);
	glPopMatrix();

	//画桌子腿
	glPushMatrix();
	glTranslatef(1.5, 1, 1.5);
	Draw_leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-1.5, 1, 1.5);
	Draw_leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(1.5, -1, 1.5);
	Draw_leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-1.5, -1, 1.5);
	Draw_leg();
	glPopMatrix(); 
}
void redraw() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();//重置当前modelview
	//定义视景转换,视点中心由eye[]控制,场景中心由center[]控制,y轴向上
	gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0);
	//是否开启边缘绘制模式
	if (bWire) {
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//设置两面均为边缘绘制方式
	}
	else {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//设置两面均为填充绘制方式
	}

	// 用来开启更新深度缓冲区的功能,也就是,如果通过比较后深度值发生变化了,
	//会进行更新深度缓冲区的操作。启动它,OpenGL就可以跟踪再Z轴上的像素,
	//这样,它只会再那个像素前方没有东西时,才会绘画这个像素。	
	//在做绘画3D时,这个功能最好启动,视觉效果比较真实。
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);//启动光照
	//设置光源LIGHT0的参数
	GLfloat white[] = { 1.0,1.0,1.0,1.0 };
	GLfloat light_pos[] = { 5,5,5,1 };
	glLightfv(GL_LIGHT0, GL_POSITION, light_pos); //设置光源位置
	glLightfv(GL_LIGHT0, GL_AMBIENT, white);//设置环境光颜色
	glEnable(GL_LIGHT0);//启动光源LIGHT0

	glRotatef(fRotate, 0, 1.0f, 0);//场景自转
	glRotatef(-90, 1, 0, 0);
	glScalef(0.2, 0.2, 0.2);
	Draw_Scene();

	if (bAnim) fRotate += 0.5f;
	if (isTeapotRotate) teapotRotate += 0.5f;//茶壶转角增加

	glutSwapBuffers();
}

线段裁剪的Cohen-Sutherland算法

#include<stdio.h>
#include<stdlib.h>
#include<GL/glut.h>

#define LEFT_EDGE 1
#define RIGHT_EDGE 2
#define BOTTOM_EDGE 4
#define TOP_EDGE 8

void LineGL(int x0, int y0, int x1, int y1)
{
	glBegin(GL_LINES);
	glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(x0, y0);
	glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(x1, y1);
	glEnd();
}
//屏幕rect
struct Rectangle_
{
	float xmin, xmax, ymax, ymin;
};
Rectangle_ rect;

void Init();
void Reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);
//绘制屏幕和未裁剪的直线段
void myDisplay();

int x0, y0, x1, y1;//直线段两端顶点坐标
//给点编码,D3D2D1D0,如果x小于rect.xmin,则D0=1否则为0,编码从右往左,比较顺序:左右下上
int CompCode(int x, int y, Rectangle_ rect);
//Cohen Sutherland 裁剪算法,画出裁剪后的线段
int cohensutherlandlineclip(Rectangle_ rect, int& x0, int& y0, int& x1, int& y1);



int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(640, 480);
	glutCreateWindow("1812030065李诗雨");
	Init();
	glutDisplayFunc(myDisplay);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(keyboard);
	glutMainLoop();
	return 0;
}

void Init()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_FLAT);
	rect.xmin = 100;
	rect.xmax = 300;
	rect.ymin = 100;
	rect.ymax = 300;
	x0 = 450, y0 = 0, x1 = 0, y1 = 450;
	printf("Press key 'c' to Clip!\nPress key 'r' to Restore!\n");
}
void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
	//绘制未裁剪的直线段
	LineGL(x0, y0, x1, y1);
	glFlush();
}
void Reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
void keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 'c'://Cohen Sutherland 裁剪
		cohensutherlandlineclip(rect, x0, y0, x1, y1);
		glutPostRedisplay();
		break;
	case 'r'://恢复
		Init();
		glutPostRedisplay();
		break;
	case 'x':
		exit(0);
		break;
	default:
		break;
	}
}

int CompCode(int x, int y, Rectangle_ rect)
{
	//二进制或运算 把符合条件的的位编码置1
	int code = 0;
	if (y < rect.ymin)
		code = code | 4;
	if (y > rect.ymax)
		code = code | 8;
	if (x > rect.xmax)
		code = code | 2;
	if (x < rect.xmin)
		code = code | 1;
	return code;
}
int cohensutherlandlineclip(Rectangle_ rect, int& x0, int& y0, int& x1, int& y1)
{
	int accept, done;
	float x, y;
	accept = 0;//=1表示取得裁剪范围内的线段
	done = 0;//=1表示裁剪完毕
	//给直线的两个顶点编码
	int code0, code1, codeout;
	code0 = CompCode(x0, y0, rect);
	code1 = CompCode(x1, y1, rect);
	//只要没裁剪完就继续求交裁剪
	do
	{
		if (!(code0 | code1))
		{//简取
			accept = 1;
			done = 1;
		}
		else if (code0 & code1)
		{//简弃
			done = 1;
		}
		else
		{
			//选择一个不在裁剪范围内的顶点,把编码赋给codeout
			if (code0 != 0)
				codeout = code0;
			else
				codeout = code1;
			//根据codeout和边界按位&的结果来确定直线跟那条边界相交并求交点
			if (codeout & LEFT_EDGE)
			{
				y = y0 + (y1 - y0) * (rect.xmin - x0) / (x1 - x0);
				x = (float)rect.xmin;
			}
			else if (codeout & RIGHT_EDGE)
			{
				y = y0 + (y1 - y0) * (rect.xmax - x0) / (x1 - x0);
				x = (float)rect.xmax;
			}
			else if (codeout & BOTTOM_EDGE)
			{
				x = x0 + (x1 - x0) * (rect.ymin - y0) / (y1 - y0);
				y = (float)rect.ymin;
			}
			else if (codeout & TOP_EDGE)
			{
				x = x0 + (x1 - x0) * (rect.ymax - y0) / (y1 - y0);
				y = (float)rect.ymax;
			}

			//把跟边界的交点编码
			if (codeout == code0)
			{
				x0 = x; y0 = y;
				code0 = CompCode(x0, y0, rect);
			}
			else {
				x1 = x; y1 = y;
				code1 = CompCode(x1, y1, rect);
			}
		}
	} while (!done);
	//如果裁剪范围内有线段,就画出来
	if (accept)
		LineGL(x0, y0, x1, y1);
	return accept;
}

定义裁剪平面对网状球体裁剪

#include <GL\glut.h>

// 旋转参数 
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

void Initial(void);
void ChangeSize(GLsizei w, GLsizei h);

// 在窗口中绘制图形 
void Display(void);
void SpecialKeys(int key, int x, int y);

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("1812030065李诗雨");
	glutDisplayFunc(Display);  
	glutSpecialFunc(SpecialKeys);
	glutReshapeFunc(ChangeSize);
	Initial();
	glutMainLoop();
	return 0;
}

void Initial(void)
{
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
	glShadeModel(GL_FLAT);
}

void ChangeSize(GLsizei w, GLsizei h)
{
	if (h == 0)  h = 1;
	// 设置视区尺寸     
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	// 建立修剪空间的范围    
	gluPerspective(60.0f, (GLfloat)w / (GLfloat)h, 1.0f, 20.0f);

	glMatrixMode(GL_MODELVIEW);
}

void Display(void)
{
	//定义裁减平面方程系数
	GLdouble eqn[4] = { 1.0, 1.0, 0.0, 1.0 };
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glPushMatrix();

	//沿 z 轴负向平移一段距离,保证良好的观察效果    
	glTranslatef(0.0, 0.0, -5.0);
	//设置裁减平面    
	glClipPlane(GL_CLIP_PLANE0, eqn);
	glEnable(GL_CLIP_PLANE0);
	//使球体旋转  
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);
	glutWireSphere(2.0f, 20, 20);
	glPopMatrix();
	glFlush();
}

void SpecialKeys(int key, int x, int y)
{
	if (key == GLUT_KEY_UP)  xRot -= 5.0f;
	if (key == GLUT_KEY_DOWN) xRot += 5.0f;
	if (key == GLUT_KEY_LEFT) yRot -= 5.0f;
	if (key == GLUT_KEY_RIGHT) yRot += 5.0f;

	if (xRot > 356.0f) xRot = 0.0f;
	if (xRot < -1.0f) xRot = 355.0f;
	if (yRot > 356.0f) yRot = 0.0f;
	if (yRot < -1.0f) yRot = 355.0f;

	glutPostRedisplay();
}

在这里插入图片描述

真实感图形绘制

1.理解程序框架

体会遮挡关系

#include<GL/glut.h>

enum{FILL,WIRE};
enum{SPHERE=1,CONE,WALLS};
int rendermode = FILL;
GLUquadricObj* sphere, * cone, * base;

static GLfloat lightpos[] = { 50.f,50.f,-320.f,1.f };
static GLfloat wall_mat[] = { 0.8f,0.8f,0.8f,1.f };
static GLfloat sphere_mat[] = { 1.0f,0.2f,0.2f,1.f };
static GLfloat cone_mat[] = { 0.2f,1.0f,0.2f,1.f };

void Initial();
void Display();
void menu(int );
void drawscene();

int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);

	glutInitWindowPosition(100, 100);
	glutInitWindowSize(500, 500);
	glutCreateWindow("Wireframe and ZBuffer 1812030065-李诗雨");
	glutDisplayFunc(Display);

	glutCreateMenu(menu);
	glutAddMenuEntry("Solid Fill", FILL);//把FILL这个位置的参数传入到menu函数中
	glutAddMenuEntry("Wireframe", WIRE);
	glutAttachMenu(GLUT_RIGHT_BUTTON);//按右键显示菜单


	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}
void Initial() {
	glMatrixMode(GL_PROJECTION);
	glFrustum(-100.0, 100.0, -100.0, 100.0, 320.0, 640.0);//透视显示:左右下上近远
	glMatrixMode(GL_MODELVIEW);

	glEnable(GL_DEPTH_TEST);//打开深度缓冲设置
	glDepthFunc(GL_LEQUAL);//判断遮挡关系时,离视点近的遮挡离视点远的物体。GL-NEVER不判断,GL_ALWAYS,GL_LESS,GL_LEQUAL
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

	glNewList(SPHERE, GL_COMPILE);
	sphere = gluNewQuadric();//创建一个对象
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
	gluSphere(sphere, 50.f, 40, 40);//让该对象画球,参数:球体,半径,经度分割线,纬度分割线
	gluDeleteQuadric(sphere);//释放对象
	glEndList();

	glNewList(CONE, GL_COMPILE);
	cone = gluNewQuadric();
	base = gluNewQuadric();
	glPushMatrix();
	glRotatef(-90.f, 1.f, 0.f, 0.f);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
	gluQuadricOrientation(base, GLU_INSIDE);
	gluDisk(base, 0., 40., 20, 1);//碟盘(圆锥的底,如果画圆柱需要两个底)参数:对象,内环半径,外环半径,分割线,同心圆线
	gluCylinder(cone, 40., 0., 120., 20, 20);//圆锥,参数:对象,下半径,上半径,高,经度分割线,纬度分割线
	glPopMatrix();
	gluDeleteQuadric(cone);
	gluDeleteQuadric(base);
	glEndList();

	//WALLS
	glNewList(WALLS,GL_COMPILE);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);

	glBegin(GL_QUADS);
	glNormal3f(0.f, 1.f, 0.f);
	glVertex3f(-100.f, -100.f, -320.f);
	glVertex3f(100.f, -100.f, -320.f);
	glVertex3f(100.f, -100.f, -520.f);
	glVertex3f(-100.f, -100.f, -520.f);

	//left wall
	glNormal3f(1.f, 0.f, 0.f);
	glVertex3f(-100.f, -100.f, -320.f);
	glVertex3f(-100.f, -100.f, -520.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glVertex3f(-100.f, 100.f, -320.f);
	//right wall
	glNormal3f(-1.f, 0.f, 0.f);
	glVertex3f(100.f, -100.f, -320.f);
	glVertex3f(100.f, 100.f, -320.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(100.f, -100.f, -520.f);
	//ceiling
	glNormal3f(0.f, -1.f, 0.f);
	glVertex3f(-100.f, 100.f, -320.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(100.f, 100.f, -320.f);
	//back wall
	glNormal3f(0.f, 0.f, 1.f);
	glVertex3f(-100.f, -100.f, -520.f);
	glVertex3f(100.f, -100.f, -520.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glEnd();
	glEndList();
}

void menu(int selection) {
	rendermode = selection;
	glutPostRedisplay();
}

void drawscene() {
	glCallList(WALLS);
	glPushMatrix();
	glTranslatef(-20.f, -40.f, -400.f);
	glCallList(SPHERE);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(40.f, -100.f, -420.f);
	glCallList(CONE);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-40.f, -40.f, -400.f);
	glCallList(CONE);
	glPopMatrix();
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	switch (rendermode)
	{
	case FILL:
		drawscene(); break;
	case WIRE:
		glDisable(GL_LIGHTING);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//GL_POINTS,GL_FILL
		glColor4f(0.0, 0.0, 0.0, 1.0);
		drawscene();
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		glEnable(GL_LIGHTING);
		break;

	default:
		break;
	}
	glFlush();
}

在这里插入图片描述

2.产生一个三维物体,进行消隐处理

#include<GL/glut.h>
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
void RenderScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glEnable(GL_DEPTH_TEST);//深度测试
	glDepthFunc(GL_LEQUAL);
	glPushMatrix();
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

	glBegin(GL_QUADS);
	glColor3f(1.0, 0.0, 0.0);//red
	glVertex3f(10.0f, 10.0f, 10.0f);//上面
	glVertex3f(-10.0f, 10.0f, 10.0f);
	glVertex3f(-10.0f, -10.0f, 10.0f);
	glVertex3f(10.0f, -10.0f, 10.0f);

	glColor3f(0.0, 1.0, 0.0);//green
	glVertex3f(10.0f, 10.0f, -10.0f);//右面
	glVertex3f(10.0f, 10.0f, 10.0f);
	glVertex3f(10.0f, -10.0f, 10.0f);
	glVertex3f(10.0f, -10.0f, -10.0f);


	glColor3f(0.0, 0.0, 1.0);//blue
	glVertex3f(10.0f, -10.0f, -10.0f);//下面
	glVertex3f(-10.0f, -10.0f, -10.0f);
	glVertex3f(-10.0f, 10.0f, -10.0f);
	glVertex3f(10.0f, 10.0f, -10.0f);


	glColor3f(1.0, 1.0, 0.0);//yellow
	glVertex3f(-10.0f, 10.0f, 10.0f);//left
	glVertex3f(-10.0f, 10.0f, -10.0f);
	glVertex3f(-10.0f, -10.0f, -10.0f);
	glVertex3f(-10.0f, -10.0f, 10.0f);

	glColor3f(0.0, 1.0, 1.0);
	glVertex3f(10.0f, 10.0f, -10.0f);//back
	glVertex3f(-10.0f, 10.0f, -10.0f);
	glVertex3f(-10.0f, 10.0f, 10.0f);
	glVertex3f(10.0f, 10.0f, 10.0f);

	glColor3f(1.0, 0.0, 1.0);
	glVertex3f(10.0f, -10.0f, 10.0f);//front
	glVertex3f(-10.0f, -10.0f, 10.0f);
	glVertex3f(-10.0f, -10.0f, -10.0f);
	glVertex3f(10.0f, -10.0f, -10.0f);
	glEnd();
	glPopMatrix();
	glutSwapBuffers();
}

void Init() {
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glColor3f(0.0f, 1.0f, 0.0f);
	glShadeModel(GL_FLAT);
	glFrontFace(GL_CW);

}

void SpecialKeys(int key, int x, int y) {
	if (key == GLUT_KEY_UP)
		xRot -= 5.0f;
	if (key == GLUT_KEY_DOWN)
		xRot += 5.0f;
	if (key == GLUT_KEY_RIGHT)
		yRot -= 5.0f;
	if (key == GLUT_KEY_LEFT)
		yRot += 5.0f;
	if (key > 356.0f)
		xRot = 0.0f;
	if (key < -1.0f)
		xRot = 355.0f;
	if (key > 356.0f)
		yRot = 0.0f;
	if (key < -1.0f)
		yRot = 355.0f;
	glutPostRedisplay();
}

void ChangeSize(int w, int h)
{
	GLfloat nRange = 30.0f;
	if (h == 0) h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (w <= h)
		glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
	else
		glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	//初始化工具包
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);
	//窗口设置
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("cube 1812030065-李诗雨");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(SpecialKeys);
	glutDisplayFunc(RenderScene);

	Init();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}


在这里插入图片描述
在这里插入图片描述

3.移动光源

#include<GL/glut.h>
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
static GLfloat xRot1 = 0.0f;
static GLfloat yRot1 = 0.0f;

void Initial() {
	GLfloat light_diffuse[] = { 1.0,1.0,1.0,1.0 };
	GLfloat light_ambient[] = { 0.0,0.5,0.5,1.0 };
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);//设置环境光颜色

	GLfloat light1_diffuse[] = { 1.0,1.0,1.0,1.0 };
	GLfloat light1_ambient[] = { 0.0,0.5,0.5,1.0 };
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); 
	glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);//设置环境光颜色

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);//启动光源LIGHT0
	glEnable(GL_LIGHT1);//启动光源LIGHT1
	glEnable(GL_DEPTH_TEST);//深度测试
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void ChangeSize(int w, int h)
{
	if (h == 0) h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(40.0f, (GLfloat)w / (GLfloat)h, 1.0f, 20.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GLfloat light0_position[] = { 0.0f,0.0f,1.5f,1.0f };//最后一个参数1.0指前面设置的点位置,0.0为无限远处
	GLfloat light1_position[] = { 0.0f,0.0f,1.5f,1.0f };

	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);
	glRotated(yRot, 0.0f, 1.0f, 0.0f);
	glRotated(xRot, 1.0f, 0.0f, 0.0f);
	//设置光源的位置
	glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
	glTranslatef(0.0f, 0.0f, 1.5f);
	//绘制一个黄色的光球
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 1.0f, 0.0f);
	glutSolidSphere(0.1f, 50.0f, 50.0f);
	glEnable(GL_LIGHTING);

	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);
	glRotated(yRot1, 0.0f, 1.0f, 0.0f);
	glRotated(xRot1, 1.0f, 0.0f, 0.0f);
	//设置光源的位置
	glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
	glTranslatef(0.0f, 0.0f, 1.5f);
	//绘制一个红色的光球
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 0.0f, 0.0f);
	glutSolidSphere(0.1f, 50.0f, 50.0f);
	glEnable(GL_LIGHTING);

	glLoadIdentity();
	//设置材质属性
	GLfloat mat_diffuse[] = { 0.0f,0.5f,1.0f,1.0f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
	glTranslatef(0.0f, 0.0f, -5.0f);

	glutSolidTorus(0.275, 0.85, 50, 50);
	glLoadIdentity();

	glutSwapBuffers();
}

void Keys(unsigned char key, int x, int y) {
	switch (key)
	{
	case 'i':xRot -= 5.0f; break;
	case 'k':xRot += 5.0f; break;
	case 'j':yRot -= 5.0f; break;
	case 'l':yRot += 5.0f; break;

	case 'w':xRot1 -= 5.0f; break;
	case 's':xRot1 += 5.0f; break;
	case 'a':yRot1 -= 5.0f; break;
	case 'd':yRot1 += 5.0f; break;
	default:
		break;
	}

	if (key > 356.0f)
		xRot = 0.0f;
	if (key < -1.0f)
		xRot = 355.0f;
	if (key > 356.0f)
		yRot = 0.0f;
	if (key < -1.0f)
		yRot = 355.0f;

	if (key > 356.0f)
		xRot1 = 0.0f;
	if (key < -1.0f)
		xRot1 = 355.0f;
	if (key > 356.0f)
		yRot1 = 0.0f;
	if (key < -1.0f)
		yRot1 = 355.0f;

	glutPostRedisplay();
}

int main(int argc, char* argv[])
{
	//初始化工具包
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	//窗口设置
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("移动光源 1812030065-李诗雨");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(Display);
	glutKeyboardFunc(Keys);

	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}


在这里插入图片描述

4.一维纹理映射,画彩虹

#include<GL/glut.h>
#include <math.h>
#ifndef M_pI
#define M_PI 3.141592649
#endif

static GLubyte roygbiv_image[8][3] = {
	{0x3f,0x00,0x3f},//深蓝紫色
	{0x7f,0x00,0x7f},//蓝紫色
	{0xbf,0x00,0xbf},//靛蓝
	{0x00,0x00,0xff},//蓝色
	{0x00,0xff,0x00},//绿色
	{0xff,0xff,0x00},//黄色
	{0xff,0x7f,0x00},//橙色
	{0xff,0x00,0x00},//红色
};

void ChangeSize(int width, int height) {
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (float)width / (float)height, 0.1, 1000.0);
	glMatrixMode(GL_MODELVIEW);
}

void Initial() {
	glClearColor(0.3, 0.8, 1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//最基本的执行纹理映射的步骤
	//1.定义纹理,2.控制纹理,3.说明纹理映射的方式,4.绘制场景
	//1.定义纹理
	glTexImage1D(GL_TEXTURE_1D, 0, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, roygbiv_image);
	//2.控制纹理,设定纹理如何对应屏幕像素,实现纹理缩放纹理重复
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//3.说明纹理映射方式
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	//表示使用最靠近使用纹理像素的四个纹素的加权平均值
	//定义一维纹理,颜色分量为RGB
	//宽度为8,边界为0,使用无符号整数
	//定义纹理环境参数,使用纹理图像
}

void Display() {
	GLfloat x, y, z, th;
	//draw ground
	glDisable(GL_TEXTURE_1D);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	glPushMatrix();
	glRotatef(10.0f, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0, -40.0, -100.0);

	glColor3f(0.0, 0.8, 0.0);
	glBegin(GL_POLYGON);
	for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
		x = cos(th) * 200.0;
		z = sin(th) * 200.0;
		glVertex3f(x, 0.0, z);
	}
	glEnd();

	//draw rainbow
	glEnable(GL_TEXTURE_1D);
	glBegin(GL_QUAD_STRIP);//共享四边形
	for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
		x = cos(th) * 50.0;
		y = sin(th) * 50.0;
		z = -50.0;
		glTexCoord1f(0.0);
		glVertex3f(x, y, z);

		x = cos(th) * 55.0;
		y = sin(th) * 55.0;
		z = -50.0;
		glTexCoord1f(1.0);
		glVertex3f(x, y, z);
	}
	glEnd();
	glPopMatrix();
	glFlush();
}

int main(int argc, char *argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(792, 753);
	glutCreateWindow("rainbow 1812030065-李诗雨");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(Display);

	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}

在这里插入图片描述

交互技术与计算机动画

绘制折线

#include<gl/glut.h>
#include <iostream>
using namespace std;
int iPointNum = 0;
int a[100], b[100], w1, h1, w2, h2;
int winwidth = 400, winHeight = 300;
//变量的定义
void Initial() {
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void ChangeSize(int w, int h) {
	winwidth = w;
	winHeight = h;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, winwidth, 0.0, winHeight);
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	//绘制折线
	if (iPointNum > 1) {
		glBegin(GL_LINE_STRIP);
		for (int i = 0; i < iPointNum; i++)
			glVertex2i(a[i], b[i]);
		glEnd();

		glBegin(GL_LINES);
		glVertex2i(w1, h1);
		glVertex2i(w2, h2);
		glEnd();
	}
	glutSwapBuffers();
}

void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse) {
	//鼠标函数
	//按下鼠标左键绘制折线
	if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
		if (iPointNum == 0) {
			w1 = xMouse; h1 = winHeight - yMouse;
			a[iPointNum] = w1; b[iPointNum] = h1;
			iPointNum++;
		}
		else {
			w2 = xMouse; h2 = winHeight - yMouse;
			a[iPointNum] = w2; b[iPointNum] = h2;
			w1 = w2; h1 = h2;
			iPointNum++;
			glutPostRedisplay();
		}
	}
	/*按下鼠标右键结束绘制*/
	if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN) {
		iPointNum = 0;
	}
	
}

void PassiveMouseMove(GLint xMouse, GLint yMouse) {
	//鼠标移动函数
	//记录鼠标指针 的当前位置
	if (iPointNum) {
		w2 = xMouse;
		h2 = winHeight - yMouse;
		glutPostRedisplay();
	}
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("橡皮筋技术 181203065 李诗雨");
	glutDisplayFunc(Display);

	glutReshapeFunc(ChangeSize);
	glutMouseFunc(MousePlot);//指定鼠标响应函数
	glutPassiveMotionFunc(PassiveMouseMove);//指定鼠标移动响应函数

	Initial();
	glutMainLoop();
	return 0;
}

绘制矩形

#include<gl/glut.h>
#include <iostream>
using namespace std;
int iPointNum = 0;
int w1, h1, w2, h2;
int winwidth = 400, winHeight = 300;
//变量的定义
void Initial() {
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void ChangeSize(int w, int h) {
	winwidth = w;
	winHeight = h;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, winwidth, 0.0, winHeight);
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	//绘制
	glBegin(GL_LINES);
	glVertex2i(w1, h1);
	glVertex2i(w2, h1);
	glEnd();
	glBegin(GL_LINES);
	glVertex2i(w2, h1);
	glVertex2i(w2, h2);
	glEnd();
	glBegin(GL_LINES);
	glVertex2i(w1, h1);
	glVertex2i(w1, h2);
	glEnd();
	glBegin(GL_LINES);
	glVertex2i(w1, h2);
	glVertex2i(w2, h2);
	glEnd();
	glutSwapBuffers();
}

void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse) {
	//鼠标函数
	//按下鼠标左键绘制
	if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
		if (iPointNum == 0||iPointNum==2) {
			iPointNum = 1;
			w1 = xMouse; h1 = winHeight - yMouse;
		}
		else {
			w2 = xMouse; h2 = winHeight - yMouse;
			iPointNum = 2;
			glutPostRedisplay();
		}
	}
	
}

void PassiveMouseMove(GLint xMouse, GLint yMouse) {
	//鼠标移动函数
	//记录鼠标指针 的当前位置
	if (iPointNum==1) {
		w2 = xMouse;
		h2 = winHeight - yMouse;
		glutPostRedisplay();
	}
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("橡皮筋技术 181203065 李诗雨");
	glutDisplayFunc(Display);

	glutReshapeFunc(ChangeSize);
	glutMouseFunc(MousePlot);//指定鼠标响应函数
	glutPassiveMotionFunc(PassiveMouseMove);//指定鼠标移动响应函数

	Initial();
	glutMainLoop();
	return 0;
}

模型函数绘制示例(菜单)

#include <GL/glut.h>

static GLsizei iMode = 1;
//x,y 方向旋转参数
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

void Initial() {
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glColor3f(0.0f, 0.0f, 0.0f);
}

void ChangeSize(int w, int h) {
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-1.5f, 1.5f, -1.5f, 1.5f);
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//绕x轴旋转
	//绕y轴旋转
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

     /*指定要绘制的图元*/
	switch (iMode)
	{
	case 1:
		/*绘制线框正四面体*/
		glutWireTetrahedron(); break;
	case 2:
		/*绘制实体正四面体*/
		glutSolidTetrahedron(); break;
	case 3:
		/*绘制线框正八面体*/
		glutWireOctahedron(); break;
	case 4:
		/*绘制实体正八面体*/
		glutSolidOctahedron(); break;
	case 5:
		/*绘制线框球面*/
		glutWireSphere(1.0f,15,15); break;
	case 6:
		/*绘制实体球面*/
		glutSolidSphere(1.0f, 15, 15); break;
	case 7:
		/*绘制线框茶壶*/
		glutWireTeapot(1.0f); break;
	case 8:
		/*绘制实体茶壶*/
		glutSolidTeapot(1.0f); break;
	default:break;
	}
	glFlush();
}

void ProcessMenu(int value) {
	//选择绘制模式
	iMode = value;
	glutPostRedisplay();
}

//键盘绘制函数
void SpecialKeys(int key, int x, int y) {
	//绕x轴旋转的角度变化
	if (key == GLUT_KEY_UP) xRot -= 0.5f;
	if (key == GLUT_KEY_DOWN) xRot += 0.5f;

	//绕y轴旋转的角度的变化
	if (key == GLUT_KEY_LEFT) yRot -= 0.5f;
	if (key == GLUT_KEY_RIGHT) yRot += 0.5f;

	if (xRot > 356.0f) xRot = 0.0f;
	if (xRot < -1.0f) xRot = 355.0f;

	if (yRot > 356.0f) yRot = 0.0f;
	if (yRot < -1.0f) yRot = 355.0f;
	glutPostRedisplay();
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("openGl模型绘制函数示例 181203065 李诗雨");
	/*创建菜单并定义菜单的回调函数*/
	/*创造GLUT多面体绘制菜单*/
	int nGLutPolyMenu = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("线框正四面体", 1);
	glutAddMenuEntry("实体正四面体", 2);
	glutAddMenuEntry("线框正八面体", 3);
	glutAddMenuEntry("实体正八面体", 4);
	/*创建GLUT曲面绘制菜单*/
	int nGLutCurveMenu = glutCreateMenu(ProcessMenu);;
	glutAddMenuEntry("线框球面", 5);
	glutAddMenuEntry("实体球面", 6);
	glutAddMenuEntry("线框茶壶", 7);
	glutAddMenuEntry("实体茶壶", 8);

	/*创建主菜单*/
	int nMainMenu = glutCreateMenu(ProcessMenu);
	glutAddSubMenu("GLUT多面体绘制", nGLutPolyMenu);
	glutAddSubMenu("GLUT曲面绘制", nGLutCurveMenu);
	/*单击右键显示菜单*/
	glutAttachMenu(GLUT_RIGHT_BUTTON);



	glutDisplayFunc(Display);
	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(SpecialKeys);

	Initial();
	glutMainLoop();
	return 0;
}

动画:日地月模型

#include <GL/glut.h>

float fsunangle;
float fearthangle;

void Initial() {
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	GLfloat diffuse[] = { 1.0f,1.0f,0.0f,1.0f };
	GLfloat position[] = { 0.0f,0.0f,-250.0f,1.0f };
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT1, GL_POSITION, position);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT1);    //黄色光
	glEnable(GL_DEPTH_TEST);
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色和深度缓冲区
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -250.0f); //将图形沿z轴负方向移动

	//太阳
	GLfloat mat_diffuse[] = { 0.2f,0.8f,1.0f,1.0f };
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	GLfloat mat_emission1[] = { 0.98,0.25,0.12,1.0 };
	glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission1);//设置太阳颜色为红
	glutSolidSphere(30.0f, 40, 50);
	glEnable(GL_LIGHTING);

	//earth
	GLfloat mat_diffuse2[] = { 0.8,0.8,0.8,1.0 };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse2);
	GLfloat mat_emission2[] = { 0.0,0.0,1.0,1.0 };
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission2);//地球颜色设置为蓝色

	glRotatef(fsunangle, 0.0f, 1.0f, 0.0f);//绕y轴旋转--地球绕太阳转
	glTranslatef(100.f, 0.0f, 0.0f);//平移一段距离
	glutSolidSphere(8.0f, 40, 50);//draw earth

	//moon
	GLfloat mat_diffuse3[] = { 0.4, 0.4, 0.4, 1.0 };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse3);
	GLfloat mat_emission3[] = { 0.25,0.25,0.25,1.0 };
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission3);
	
	glRotatef(fearthangle, 0.0f, 1.0f, 1.0f);//绕斜轴旋转
	glTranslatef(20.f, 0.0f, 0.0f);//在地球的基础上再往外平移一段距离
	glutSolidSphere(4.0f, 40, 50);//draw moon

	fsunangle += 4.0f;//地球旋转步长
	fearthangle += 36.0f;//月球旋转步长
	if (fsunangle > 360.0f) {
		fsunangle = 4.0f;
	}
	if (fearthangle > 360.0f) {
		fearthangle = 36.0f;
	}

	glutSwapBuffers();
}

void ChangeSize(int w, int h) {
	GLfloat nRange = 80.f;
	if (h == 0) h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f, (GLfloat)w / (GLfloat)h, 1.0f, 1000.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void TimerFunc(int value) {
	glutPostRedisplay();
	glutTimerFunc(80, TimerFunc, 1);//80 ms restart
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("日地月模型 181203065 李诗雨");
	glutDisplayFunc(Display);
	glutReshapeFunc(ChangeSize);
	glutTimerFunc(500,TimerFunc,1);

	Initial();
	glutMainLoop();
	return 0;
}
  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值