前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图形学上机实验

图形学上机实验

作者头像
客怎眠qvq
发布2022-11-01 16:17:33
1.5K0
发布2022-11-01 16:17:33
举报
文章被收录于专栏:某菜鸟の小屋

实验环境:win10、VS 2017、OPenGL库

实验一 基于OpenGL的二维图形绘制

要求

编程实现绘制一个五角星(基于OpenGL),效果如下图所示

问题分析

可以将一个五角星划分为10个三角形,假设五角星的各边长,分别计算出10个定点的坐标,然后逐个绘制三角形,将其拼接为五角星;

也可以利用参数方程,如下图所示,设大圆和小圆的半径分别为R、r,已知夹角为37度,在循环中计算绘制三角形。

代码

ProjectOne.cpp

代码语言:javascript
复制
#include <GL/glew.h>//OpenGL库
#include <GL/glut.h>//OpenGL辅助库
#include <math.h>
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //这句是不让控制台窗体出现,如果想要出现,去掉即可。

// 明确 计算三角函数 需要 theta * pi / 180
// 由于 两个三角形的theta角有36度的差值
// 点的坐标为 x = x0 + r(R) * sin(cos) theta
// 对于大圆 theta 为( 0 + 72 * i )* pi/180 == 0.4i * pi 
// 小圆theta 为 (36 + 72 * i) * pi / 180 == 0.2*pi + 0.4i * pi
// 两者相差只有 0.2 * pi


void init(void)
{
	glClearColor(1.0, 1.0, 1.0, 1.0);//设置背景色白色
}


void DrawStar1(float cx, float cy, float R, float r, float o)//五角星中心坐标x,y,大圆半径,小圆半径,初始角度
{
	float x0, y0, x1, y1;//
	float    Theta = o;//大圆对应角度
	float    theta = o + 0.2 * 3.14;//小圆对应角度
	for (int i = 0; i < 10; i++)
	{
		x0 = cx + R * cos(Theta);//大圆对应的x坐标
		y0 = cy + R * sin(Theta);//大圆对应y坐标

		x1 = cx + r * cos(theta);//小圆对应x坐标
		y1 = cy + r * sin(theta);//小圆对应y坐标
		glBegin(GL_LINES);//绘制
		glColor3f(1, 0, 0);
		glVertex2f(x0, y0);
		glVertex2f(x1, y1);
		glEnd();
		if (i % 2 == 0)
		{
			Theta = Theta + 0.4 * 3.14;//大圆对应角度变换
		}
		else
		{
			theta = theta + 0.4 * 3.14;//小圆对应角度变换
		}
	}
}

void DrawStar2(float cx, float cy, float R, float r, float o)//五角星中心坐标x,y,大圆半径,小圆半径,初始角度
{
	float x0, y0, x1, y1;//
	float    Theta = o;//大圆对应角度
	float    theta = o + 0.2 * 3.14;//小圆对应角度
	for (int i = 0; i < 10; i++)
	{
		x0 = cx + R * cos(Theta);//大圆对应的x坐标
		y0 = cy + R * sin(Theta);//大圆对应y坐标
		x1 = cx + r * cos(theta);//小圆对应x坐标
		y1 = cy + r * sin(theta);//小圆对应y坐标
		glColor3f(1, 0, 0);
		glBegin(GL_POLYGON);//绘制
		glVertex2f(x0, y0);
		glVertex2f(x1, y1);
		glVertex2f(cx, cy);
		glEnd();
		if (i % 2 == 0)
		{
			Theta = Theta + 0.4 * 3.14;//大圆对应角度变换
		}
		else
		{
			theta = theta + 0.4 * 3.14;//小圆对应角度变换
		}
	}
}

void DrawStar3(float cx, float cy, float R, float r, float o)//五角星中心坐标x,y,大圆半径,小圆半径,初始角度
{
	float x0, y0, x1, y1;
	float    Theta = o;				//大圆对应角度
	float    theta = o + 0.2 * 3.14;	//小圆对应角度
	for (int i = 0; i < 10; i++)
	{
		x0 = cx + R * cos(Theta);//大圆对应的x坐标
		y0 = cy + R * sin(Theta);//大圆对应y坐标
		x1 = cx + r * cos(theta);//小圆对应x坐标
		y1 = cy + r * sin(theta);//小圆对应y坐标
		if (i % 2 == 0)
		{
			glColor3f(1, 0, 0);
		}
		else
		{
			glColor3f(0, 1, 1);
		}
		glBegin(GL_POLYGON);//绘制
		glVertex2f(x0, y0);
		glVertex2f(x1, y1);
		glVertex2f(cx, cy);
		glEnd();
		if (i % 2 == 0)
		{
			Theta = Theta + 0.4 * 3.14;	//大圆对应角度变换
		}
		else
		{
			theta = theta + 0.4 * 3.14;	//小圆对应角度变换
		}
	}
}
void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);	//清除帧缓存
	DrawStar1(150, 300, 120, 50, 0);	//glFlush();//单缓冲时必须要,说明绘图命令(函数)结束
	DrawStar2(400, 300, 120, 50, 0);
	DrawStar3(650, 300, 120, 50, 0);
	glutSwapBuffers();//交换缓冲(双缓冲时使用)
}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);//设置视区(窗口内绘图区域)
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, width, 0, height);//设置图形数据范围
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
}
int main(int argc, char* argv[])
{
	glutInitWindowPosition(200, 200);//应用程序窗口位置
	glutInitWindowSize(800, 600);//窗口大小
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//双缓冲,单缓冲为GLUT_SINGLE
	glutCreateWindow("五角星绘制");//创建窗口,参数为窗口标题
	init();
	glutDisplayFunc(display);//图形绘制
	glutReshapeFunc(reshape);//窗口大小变化
	glutKeyboardFunc(keyboard);//键盘交互
	glutMainLoop();//必须,进入GLUT事件处理循环
	return 0;
}

效果展示

实验二 二维图形的几何变换

要求

  1. 实现一个五角星以任意角度在矩形四条边内部滚动,与边界碰撞时发生的反弹,参考台球在桌案上的滚动效果。
  2. 实现矩形框内一个五角星的连续放缩(大小变化)
  3. 注意:两个五角星在同一矩形内;放缩五角星的参照点为五角星的中心,五角星位置固定;滚动五角星的旋转角度和平移距离尽量一致。

问题分析

  1. 将滚动五角星看做半径为R的圆,滚动五角星的碰撞条件判断为:它的圆心到矩形边界的距离是否大于半径R。图示如下

红色矩形所框选的范围即为滚动五角星圆心所运动的区域。

  1. 旋转五角星只需要不停地调用放缩函数即可。

代码

ProjectTwo.cpp

代码语言:javascript
复制
// OpenGLOld.cpp : 定义控制台应用程序的入口点。
//
#include <GL/glew.h>//OpenGL库
#include <GL/glut.h>//OpenGL辅助库
#include <math.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) //这句是不让控制台窗体出现,如果想要出现,去掉即可。

void init(void)
{
	glClearColor(0.2, 0.3, 0.3, 1.0);//设置背景色
}

float alpha=0.0f;
float x = 0.0f, y = 0.0f;
double Scale = 0;

void DrawStar3(float cx, float cy, float R, float r, float o)//五角星中心坐标x,y,大圆半径,小圆半径,初始角度
{
	float x0, y0, x1, y1;
	float    Theta = o;				//大圆对应角度
	float    theta = o + 0.2 * 3.14;	//小圆对应角度
	for (int i = 0; i < 10; i++)
	{
		x0 = cx + R * cos(Theta);//大圆对应的x坐标
		y0 = cy + R * sin(Theta);//大圆对应y坐标
		x1 = cx + r * cos(theta);//小圆对应x坐标
		y1 = cy + r * sin(theta);//小圆对应y坐标
		if (i % 2 == 0)
		{
			glColor3f(1, 0, 0);
		}
		else
		{
			glColor3f(0, 1, 1);
		}
		glBegin(GL_POLYGON);//绘制
		glVertex2f(x0, y0);
		glVertex2f(x1, y1);
		glVertex2f(cx, cy);
		glEnd();
		if (i % 2 == 0)
		{
			Theta = Theta + 0.4 * 3.14;	//大圆对应角度变换
		}
		else
		{
			theta = theta + 0.4 * 3.14;	//小圆对应角度变换
		}
	}
}

void MyDrawRect()
{
	glBegin(GL_LINE_LOOP);
	glVertex2f(0, 0);
	glVertex2f(0, 700);
	glVertex2f(1000, 700);
	glVertex2f(1000, 0);
	glEnd();

}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);//清除帧缓存
	
	//模型观察矩阵初始化
	glMatrixMode(GL_MODELVIEW);
	
	// 旋转与碰撞
	glPushMatrix();
	glTranslatef(150.0f+x,300.0f+y,0.0f);
	glRotatef(alpha, 0, 0, 1);
	glTranslatef(-150.0f-x, -300.0f-y, 0.0f);

	DrawStar3(150+x, 300+y, 100, 40, 0);
	//glLoadIdentity();
	glPopMatrix();

	//缩放
	glPushMatrix();
	glTranslatef(300.0, 200.0, 0.0);
	glScalef(Scale, Scale, 1);
	glTranslatef(-300.0, -200.0, 0.0);

	DrawStar3(300, 200, 100, 40, 0.1*3.14);
	//glLoadIdentity();
	glPopMatrix();

	MyDrawRect();

	//glFlush();//单缓冲时必须要,说明绘图命令(函数)结束
	glutSwapBuffers();//交换缓冲(双缓冲时使用)
}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);//设置视区(窗口内绘图区域)

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, width, 0, height);//设置图形数据范围
//	glMatrixMode(GL_MODELVIEW);
//	glLoadIdentity();
}

int flag = 0, flagX = 0, flagY = 0;


void change()
{
	alpha += 0.2f;
	if (alpha > 360) alpha -= 360;

	// 放缩判断
	if (flag == 0) {
		Scale += 0.002;
		if (Scale > 2.5) {
			flag = 1;
		}
	} else if (flag == 1) {
		Scale -= 0.002;
		if (Scale < 0.2) {
			flag = 0;
		}
	}

	// X取值范围判断	(x1, x2)   
	// x1 = x - R 
	// x2 = x + R
	if (flagX == 0) {
		x += 0.2f;
		if (x + 150 >= 900) {
			flagX = 1;
		}
	}
	else if (flagX == 1) {
		x -= 0.2f;
		if (x + 150 <= 100) {
			flagX = 0;
		}
	}

	// Y值取值范围判断 (y1, y2)
	// y1 = y - R
	// y2 = y + R

	if (flagY == 0) {
		y += 0.2f;
		if (y + 300 >= 600) {
			flagY = 1;
		}
	}else if (flagY == 1) {
		y -= 0.2f;
		if (y + 300 <= 100) {
			flagY = 0;
		}
	}

	glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{

}

int main(int argc, char* argv[])
{
	glutInitWindowPosition(200, 200);//应用程序窗口位置
	glutInitWindowSize(800, 600);//窗口大小
	
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//双缓冲,单缓冲为GLUT_SINGLE
	glutCreateWindow("Project Two");//创建窗口,参数为窗口标题
	init();

	glutDisplayFunc(display);//图形绘制
	glutReshapeFunc(reshape);//窗口大小变化
	glutKeyboardFunc(keyboard);//键盘交互
	glutIdleFunc(change);//键盘交互

	glutMainLoop();//必须,进入GLUT事件处理循环

	return 0;
}

效果展示

实验三 & 实验四

要求

  1. 构建一个丰富的三维场景,包括立方体、球体、圆柱体;
  2. 为它们添加合适的纹理;
  3. 在场景中添加光源;
  4. 可以使用按键控制你视角的移动及光源的移动。

代码

ProjectFour.cpp

代码语言:javascript
复制
// OpenGLOld.cpp : 定义控制台应用程序的入口点。
//
#include <Windows.h>
#include <GL/glew.h>//OpenGL库
#include <GL/glut.h>//OpenGL辅助库

#include <math.h>
#include "SOIL/SOIL.h"

#include "cgSphere.h"
#include "cgCylinder.h"
#include "cgCube.h"
#include "cgQuad.h"

#include "Bitmap.h"
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) //这句是不让控制台窗体出现,如果想要出现,去掉即可。

float alpha=0.0f;
float pos[]={0.0,1.5,0.0};
float headdir[]={0.0f,0.0f,-1.0f};
float rightdir[]={1.0f,0.0f,0.0f};

float step = 0.10f;
float beta = 180.0f;//与z轴正向夹角
float betastep = 1.0f;

cgSphere sphere, sun;
cgCylinder cylinder;
cgCube cube;

//光照变量
GLfloat light_position[] = { 0.0, 2.0, 1.0, 0.1 };
GLfloat light_color[] = { 1.0, 0.0, 0.0, 0.0 };
// 添加的光照
GLfloat sun_position[] = { -10.0, 5.0, 0.0, 0.0 };
GLfloat sun_color[] = { 1.0, 1.0, 1.0, 1.0 };

GLfloat aMaterial[] = { .20, 0.20, 0.20, 1.0 };		//环境光反射系数
GLfloat dMaterial[] = { .60, 0.60, 0.60, 1.0 };		//漫反射光反射系数
GLfloat sMaterial[] = { 0.4, 0.4,0.4, 1 };			//镜面反射光反射系数
GLfloat shiniess = 20;								//高光指数

int rendermode = 2;//0:填充; 1:线框;2:纹理

GLuint textureID;
int  frames=0;

GLuint LoadTexture(char* fname)
{
	GLuint tID;
	
	int width, height, nrComponents;
	unsigned char *data;
	
	data = SOIL_load_image(fname, &width, &height, &nrComponents,SOIL_LOAD_RGB);// 
	
	if (data)
	{
		GLenum internalFormat;
		GLenum dataFormat;
		bool gammaCorrection = false;
		if (nrComponents == 1)
		{
			internalFormat = dataFormat = GL_RED;
		}
		else if (nrComponents == 3)
		{
			internalFormat = gammaCorrection ? GL_SRGB : GL_RGB;
			dataFormat = GL_RGB;
		}
		else if (nrComponents == 4)
		{
			internalFormat = gammaCorrection ? GL_SRGB_ALPHA : GL_RGBA;
			dataFormat = GL_RGBA;
		}

		//生成纹理
		glGenTextures(1, &tID);
		glBindTexture(GL_TEXTURE_2D, tID);
	
		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);//这个函数居然不能用
		gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, dataFormat, GL_UNSIGNED_BYTE, data);
			
		//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
		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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	
		glBindTexture(GL_TEXTURE_2D, 0);

		SOIL_free_image_data(data);

		return tID;
	}

	return -1;	
}

void init(void)
{
	glClearColor(0.5, 1.0, 1.0, 1.0);//设置背景色白色
	glEnable(GL_DEPTH_TEST);

	/*GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。这三个属性与光源的三个对应属性类似,每一属性都由四个值组成。
	GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度(颜色)。
	GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。
	GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色)。
	通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果。
	使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。*/

	//光照
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_color);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_color);

	glLightfv(GL_LIGHT1, GL_POSITION, sun_position);

    glLightfv(GL_LIGHT1, GL_AMBIENT, sun_color);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_color);
    glLightfv(GL_LIGHT1, GL_SPECULAR, sun_color);

	// void glMaterial{if}(GLenum face, GLenum pname, TYPE param);
	// 参数pname的可能取值。
	// GL_AMBIENT_AND_DIFFUSE让您能够同时设置材质的环境颜色和散射颜色,并将它们设置为相同的RGBA值。
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aMaterial);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dMaterial);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, sMaterial);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shiniess);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	///////////////////////////

	//地球仪
	sphere.InitData(1.0f);
	sphere.SetPos(cgPoint3D(0.0f, 2.5f,-8.0f));
	sphere.SetTexture(LoadTexture("Textures/earth2.jpg"));

	// 太阳光照
	sun.InitData(3.0f);
	sun.SetPos(cgPoint3D(sun_position[0], sun_position[1], sun_position[2]));
	sun.SetTexture(LoadTexture("Textures/sun.jpeg"));

	// 正方体
	cube.InitData(1.0f);
	cube.SetPos(cgPoint3D(1.0f, 1.0f, -5.0f));
	cube.SetTexture(LoadTexture("Textures/timg.bmp"));

	// 圆柱体
	cylinder.InitData(1.0f, 5.0f);
	cylinder.SetPos(cgPoint3D(3.0f, 4.0f, -3.0f));
	cylinder.SetTextureID(LoadTexture("Textures/desert.bmp"));
	
	//地面纹理
	textureID = LoadTexture("Textures/timg.jpg");	
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT );//清除帧缓存和深度缓存
	
	//模型观察矩阵初始化
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	float at[3];
	for (int i=0; i<3; i++)
		at[i] = pos[i] + headdir[i];

	gluLookAt(pos[0], pos[1], pos[2], at[0], at[1], at[2], 0.0, 1.0, 0.0);

	if (rendermode==1)
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
	else
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

	//地面
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, textureID);
	glColor3f(1.0f,1.0f,1.0f);
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f,0.0f);//指定顶点纹理坐标
		glNormal3f(0,1,0);//指定顶点法向量
		glVertex3f(-50.0f,0.0f,50.0f);//指定顶点坐标

		glTexCoord2f(10.0f,0.0f);
		glNormal3f(0,1,0);
		glVertex3f(50.0f,0.0f,50.0f);

		glTexCoord2f(10.0f,10.0f);
		glNormal3f(0,1,0);
		glVertex3f(50.0f,0.0f,-50.0f);
		
		glTexCoord2f(0.0f,10.0f);
		glNormal3f(0,1,0);
		glVertex3f(-50.0f,0.0f,-50.0f);
	glEnd();
	glDisable(GL_TEXTURE_2D);

	glColor3f(0.25,0.5,0.5);
	sphere.Render();

	glColor3f(1.0,0.0,0.0);
	cube.Render();
	sun.Render();
	cylinder.Render();
	
	glutSwapBuffers();//交换缓冲(双缓冲时使用)
}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);//设置视区(窗口内绘图区域)

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	gluPerspective(60,(GLfloat) width/(GLfloat)height, 1.0, 200.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void change()
{
	glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
		case 'W':   //上移
		case 'w':
			for (int i=0; i<3; i++)
				pos[i] += step*headdir[i];
			break;
		case 'S':   //下移
		case 's':
			for (int i=0; i<3; i++)
				pos[i] -= step*headdir[i];
			break;
		case 'A':  //左移
		case 'a':
			for (int i=0; i<3; i++)
				pos[i] -= step*rightdir[i];	
			break;
		case 'D':   //右移
		case 'd':
			for (int i=0; i<3; i++)
				pos[i] += step*rightdir[i];
			break;

		case 'Z':   
		case 'z':
			//抬高相机
	         pos[1] += .30f;
			break;

		case 'X':   
		case 'x':
			//降低相机
	         pos[1] -= .30f;
			break;

		case 'T':   //修改绘制模式
		case 't':
			rendermode = (++rendermode)%2;
			break;	

		// 光源移动
		case '1':
			sun_position[0] += 1.0f;
			glLightfv(GL_LIGHT1, GL_POSITION, sun_position);
			sun.SetPos(cgPoint3D(sun_position[0], sun_position[1], sun_position[2]));
			break;
		case '2':
			sun_position[0] -= 1.0f;
			glLightfv(GL_LIGHT1, GL_POSITION, sun_position);
			sun.SetPos(cgPoint3D(sun_position[0], sun_position[1], sun_position[2]));
			break;
		case '3':
			sun_position[1] += 1.0f;
			glLightfv(GL_LIGHT1, GL_POSITION, sun_position);
			sun.SetPos(cgPoint3D(sun_position[0], sun_position[1], sun_position[2]));
			break;
		case '4':
			sun_position[1] -= 1.0f;
			glLightfv(GL_LIGHT1, GL_POSITION, sun_position);
			sun.SetPos(cgPoint3D(sun_position[0], sun_position[1], sun_position[2]));
			break;
		case '5':
			glEnable(GL_LIGHT1);
			break;
		case '6':
			glDisable(GL_LIGHT1);
			break;
		case '7':
			glEnable(GL_LIGHT0);
			break;
		case '8':
			glDisable(GL_LIGHT0);
			break;

		case 'n':
		case 'N':
			cube.UpdateTexCord();
			break;
	}

	glutPostRedisplay();
}

void SpecialKey(GLint key,GLint x,GLint y)
{
	switch (key)
	{
		case GLUT_KEY_UP:
			headdir[1] += 0.05f;
			break;

		case GLUT_KEY_DOWN:
			headdir[1] -= 0.05f;
			break;

		case GLUT_KEY_LEFT:
			//修改前进方向
			beta += betastep;
			headdir[0] = sin(beta / 180 * 3.14);
			headdir[2] = cos(beta / 180 * 3.14);
			headdir[1] = headdir[1];

			//修改右向方向
			rightdir[0] = -cos(beta / 180 * 3.14);
			rightdir[2] = sin(beta / 180 * 3.14);
			rightdir[1] = rightdir[1];
			break;

		case GLUT_KEY_RIGHT:
			//修改前进方向
			beta -= betastep;
			headdir[0] = sin(beta / 180 * 3.14);
			headdir[2] = cos(beta / 180 * 3.14);
			headdir[1] = headdir[1];

			//修改右向方向
			rightdir[0] = -cos(beta / 180 * 3.14);;
			rightdir[2] = sin(beta / 180 * 3.14);;
			rightdir[1] = rightdir[1];
			break;

	}

	glutPostRedisplay();
}

int main(int argc, char* argv[])
{
	glutInitWindowPosition(200, 200);//应用程序窗口位置
	glutInitWindowSize(800, 600);//窗口大小
	
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE| GLUT_DEPTH );//双缓冲,单缓冲为GLUT_SINGLE,深度缓存
	glutCreateWindow("Project Four");//创建窗口,参数为窗口标题
	init();

	glutDisplayFunc(display);//图形绘制
	glutReshapeFunc(reshape);//窗口大小变化
	glutKeyboardFunc(keyboard);//键盘交互
	glutSpecialFunc(&SpecialKey);//方向键
	glutIdleFunc(change);//空闲时间执行

	glutMainLoop();//必须,进入GLUT事件处理循环

	return 0;
}

效果展示

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实验一 基于OpenGL的二维图形绘制
    • 要求
      • 问题分析
        • 代码
          • 效果展示
          • 实验二 二维图形的几何变换
            • 要求
              • 问题分析
                • 代码
                  • 效果展示
                  • 实验三 & 实验四
                    • 要求
                      • 代码
                        • 效果展示
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档