OpenGL-GLUT提供的9种实体对象绘制

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>

/* 需要旋转的变量*/
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

static int iShape = 1;


/*目录中的选择*/
void ProcessMenu(int value)
{
	iShape = value;

	/*
	glutPostRedisplay 标记当前窗口需要重新绘制。通过glutMainLoop下一次循环时,
	窗口显示将被回调以重新显示窗口的正常面板。
	多次调用glutPostRedisplay,在下一个显示回调只产生单一的重新显示回调。
	*/
	glutPostRedisplay();
}


/* 绘制函数(!!!)*/
void RenderScene(void)
{
	/*清屏*/
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	/*保存矩阵状态然后进行旋转操作*/

	/*
	终于明白为什么使用glPushMatrix()和glPopMatrix()的原因了。
	将本次需要执行的缩放、平移等操作放在glPushMatrix和glPopMatrix之间。
	glPushMatrix()和glPopMatrix()的配对使用可以消除上一次的变换对本次变换的影响。
	使本次变换是以世界坐标系的原点为参考点进行。
	*/
	glPushMatrix();
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	/*
	glRotatef(GLfloat angle,  GLfloat x,  GLfloat y,  GLfloat z);
	x,y,z中哪一个非0,则绕谁旋转
	*/
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

	/*glut提供的9种实体对象*/
	switch (iShape)
	{
		
	case 1:
		glutWireSphere(1.0f, 25, 25);
		/*
		void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
		radius:球体半径
		slices:球体经线条数
		stacks:球体纬线条数
		功能:用于渲染一个球体(由线条构成球体)
		*/
		break;

	case 2:
		/*
		绘制线框立方体
		*/
		glutWireCube(1.0f);
		break;

	case 3:
		/*
		绘制线框圆锥体
		*/
		glutWireCone(0.30f, 1.1f, 20, 20);
		break;

	case 4:
		/*
		线框圆环
		*/
		glutWireTorus(0.3f, 1.0f, 10, 25);
		break;

	case 5:
		/*
		线框12面体
		*/
		glutWireDodecahedron();
		break;

	case 6:
		/*
		线框8面体
		*/
		glutWireOctahedron();
		break;

	case 7:
		/*
		线框4面体
		*/
		glutWireTetrahedron();
		break;

	case 8:
		/*
		线框20面体
		*/
		glutWireIcosahedron();
		break;

	case 9:
		/*
		线框茶壶
		*/
		glutWireTeapot(1.0f);
		break;

	}


	
	glPopMatrix();

	glutSwapBuffers();
	/*
	但当我们进行复杂的绘图操作时,画面便可能有明显的闪烁。
	解决这个问题的关键在于使绘制的东西同时出现在屏幕上。
	所谓双缓冲技术, 是指使用两个缓冲区: 前台缓冲和后台缓冲。
	前台缓冲即我们看到的屏幕,后台缓冲则在内存当中,对我们来说是不可见的。
	每次的所有绘图操作都在后台缓冲中进行, 当绘制完成时, 把绘制的最终结果复制到屏幕上, 
	这样, 我们看到所有GDI元素同时出现在屏幕上,从而解决了频繁刷新导致的画面闪烁问题。
	*/
}

/*初始化操作*/
void SetupRC()
{
	/*设置初始背景是黑色*/
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	/*启用深度,要不就只是个平面*/
	glEnable(GL_DEPTH_TEST);

	/*设置绘制的线条是蓝色*/
	glColor3ub(50, 255, 255);
}

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;

	/*刷新窗口*/
	glutPostRedisplay();
}


void ChangeSize(int w, int h)
{
	GLfloat nRange = 1.9f;

	/*防止分母出现0的异常出现*/
	if (h == 0)
		h = 1;


	glViewport(0, 0, w, h);
	/*
	glViewport(GLint x,GLint y,GLsizei width,GLsizei height)为其函数原型。
	X,Y————以像素为单位,指定了视口的左下角(在第一象限内,以(0,0)为原点的)位置。
	width,height————表示这个视口矩形的宽度和高度,根据窗口的实时变化重绘窗口。
	*/

	/*
	重置当前指定的矩阵为单位矩阵.
	*/
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	

	if (w <= h)
		glOrtho(-nRange, nRange, -nRange*h / w, nRange*h / w, -nRange, nRange);
	/*
	void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
	其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);
	远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。
	所有的near和far值同时为正或同时为负。
	如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。
	这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。

	函数描述了一个平行修剪空间。
	这种投影意味着离观察者较远的对象看上去不会变小(与透视投影相反)。
	*/
	else
		glOrtho(-nRange*w / h, nRange*w / h, -nRange, nRange, -nRange, nRange);

	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	int nSolidMenu;
	int nWireMenu;
	int nMainMenu;

	/*
	初始化系列操作
	*/
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow("GLUT Shapes");

	/*
	创建目录:右击鼠标进行选择图形绘制
	*/
	nWireMenu = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("Sphere", 1);
	glutAddMenuEntry("Cube", 2);
	glutAddMenuEntry("Cone", 3);
	glutAddMenuEntry("Torus", 4);
	glutAddMenuEntry("Dodecahedron", 5);
	glutAddMenuEntry("Octahedron", 6);
	glutAddMenuEntry("Tetrahedron", 7);
	glutAddMenuEntry("Icosahedron", 8);
	glutAddMenuEntry("Teapot", 9);

	//	nMainMenu = glutCreateMenu(ProcessMenu);
	//	glutAddSubMenu("Wire", nWireMenu);
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	glutReshapeFunc(ChangeSize);
	/*
	改变窗口大小时保持图形比例
	*/
	glutSpecialFunc(SpecialKeys);
	/*
	注册鼠标响应事件,使用glutKeyboardFunc函数注册键盘响应事件
	*/
	glutDisplayFunc(RenderScene);
	SetupRC();

	glutMainLoop();

	return 0;
}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用OpenGL绘制国旗可以通过以下步骤实现: 1. 创建OpenGL上下文和窗口。 2. 设置绘制区域和视口。 3. 设置绘制颜色和深度缓冲区。 4. 绘制国旗的红色背景。 5. 绘制五颗黄色的五角星。可以使用OpenGL绘制多边形功能来绘制五角星,也可以使用纹理映射来贴上五角星的图案。 6. 交换前后缓冲区,显示绘制结果。 以下是一个简单的OpenGL绘制国旗的示例代码: ``` #include <GL/glut.h> void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f(1.0, 0.0, 0.0); // 设置绘制颜色为红色 glBegin(GL_QUADS); glVertex2f(-1.0, 1.0); glVertex2f(-1.0, -1.0); glVertex2f(1.0, -1.0); glVertex2f(1.0, 1.0); // 绘制国旗的红色背景 glEnd(); glColor3f(1.0, 1.0, 0.0); // 设置绘制颜色为黄色 glBegin(GL_POLYGON); glVertex2f(-0.5, 0.5); glVertex2f(-0.25, 0.25); glVertex2f(0.0, 0.5); glVertex2f(0.25, 0.25); glVertex2f(0.5, 0.5); glVertex2f(0.375, 0.25); glVertex2f(0.5, 0.0); glVertex2f(0.375, -0.25); glVertex2f(0.5, -0.5); glVertex2f(0.25, -0.375); glVertex2f(0.0, -0.5); glVertex2f(-0.25, -0.375); glVertex2f(-0.5, -0.5); glVertex2f(-0.375, -0.25); glVertex2f(-0.5, 0.0); glVertex2f(-0.375, 0.25); // 绘制五角星 glEnd(); glutSwapBuffers(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(800, 600); glutInitWindowPosition(100, 100); glutCreateWindow("OpenGL Flag"); glutDisplayFunc(display); glutMainLoop(); return 0; } ``` 该示例代码使用了OpenGL的基本绘图功能,通过绘制红色背景和黄色五角星实现了绘制国旗的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值