OpenGL(二)图形绘制之多边形面的绘制

本次通过绘制一个三角形来学习相关的知识。


#include
#include
#include
#include
#include

//窗口的大小
GLsizei windowWidth;
GLsizei windowHeight;


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

//确定多边形的绕法的方向
BOOL bwinding = TRUE;


//初始化窗口
void SetupRC(void)
{
	//设置窗口背景西颜色为黑色
	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();


	if (w <= h)
	{
		windowWidth = 250.0f;
		windowHeight = 250.0f*h / w;
	}
	else
	{
		windowWidth = 250.0f*h / w;
		windowHeight = 250.0f;
	}
	glOrtho(0.0f, windowWidth, 0.0f, windowHeight, 1.0f, -1.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void RenderScene(void)
{
	//用当前背景颜色填充窗口
	glClear(GL_COLOR_BUFFER_BIT);

    //旋转图形
	//glPushMatrix — push and pop the current matrix stack
	//将当前矩阵保存入堆栈顶(保存当前矩阵)。
	//我们可以形象地认为glPushMatrix()就是“记住自己在哪”,
	//glPopMatrix()就是“返回自己原来所在地”。
	glPushMatrix(); 


	//围绕x轴坐标旋转
	glRotatef(xRot,1.0f,0.0f,0.0f);  
	//围绕y轴坐标旋转
	glRotatef(yRot,0.0f,1.0f,0.0f);
	
	//设置点的大小以及线宽
	glPointSize(5);
	glLineWidth(5);

	//设置多边形绕法的方向是顺时针还是逆时针

	//flFrontFace控制多边形的正面是如何决定的
	if (bwinding)
		glFrontFace(GL_CW);   //顺绕法为正面 
	else
		glFrontFace(GL_CCW);  //逆时针为正面

	//绘制三角形
	glBegin(GL_TRIANGLES);
	glColor3f(0.0f,1.0f,0.0f);  //绿色
	glVertex3f(100,160,0);
	glColor3f(1.0f, 0.0f, 1.0f);//紫色
	glVertex3f(100,100,0);
	glColor3f(0.0f, 0.0f, 1.0f);//蓝色
	glVertex3f(160,100,0);
	glEnd();
    
	glPopMatrix();
	//刷新命令缓冲区
	glutSwapBuffers();
}

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


	//结合glPushMatrix()和glPopMatrix()绘图模式理解旋转
	// 首先,glPushMateix记住来的绘图坐标(起点)
	//glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	//glRotatef(yRot, 0.0f, 1.0f, 0.0f);
	//然后旋转相应的坐标后绘制图形
	//glPopMatrix 回到了坐标原来的位置(起点)

	printf("%lf\n",yRot);
	if (xRot >= 360.0f)   xRot = 0.0f;
	//if (xRot < -1.0f)    xRot=355.0f;
	if (yRot>=360.0f)    yRot = 0.0f;
	//if (yRot < -1.0f)    yRot = 355.0f;


	//刷新窗口  强制
	glutPostRedisplay();
}
void ProcessMenu(int value)
{
	switch (value)
	{
	case 1:
		//修改多边形正面为填充模式
		glPolygonMode(GL_FRONT,GL_FILL);
		break;
	case 2:
		//修改多边形正面为线模式
		glPolygonMode(GL_FRONT,GL_LINE);
		break;
	case 3:
		//修改多变行正面为点填充模式
		glPolygonMode(GL_FRONT,GL_POINT);
		break;
	case 4:
		//修改多变形背面为填充模式
		glPolygonMode(GL_BACK,GL_FILL);
		break;
	case 5:
		////修改多边形背面面为线模式
		glPolygonMode(GL_BACK,GL_LINE);
		break;
	case 6:
		//修改多变行背面为点填充模式
		glPolygonMode(GL_BACK,GL_POINT);
		break;
	case 7:
		//设置多边形的阴影模式为平面明暗模式
		glShadeModel(GL_FLAT);
		break;
	case 8:
	    //设置多变形的阴影模式为光滑明暗模式
		glShadeModel(GL_SMOOTH);
		break;
	case 9:
		bwinding = !bwinding;
		break;
	default: break;
	}
	//强制刷新
	glutPostRedisplay();
}

int main(int argc,char *argv[])
{
	int nModeMenu;
	int nMainMenu;
	int nColorMenu;

	//initialize the GLUT library  
	//初始化GLUT库
	glutInit(&argc,argv);

	
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
	glutCreateWindow("多边形演示");
    
	//回调函数
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
    
	//设置特殊键盘相应回调函数
	glutSpecialFunc(SpecialKeys);
	//void glutSpecialFunc(void(*func)(int key,int x,int y));
	//special函数第一个关键字是键盘的值,  x,y是获取鼠标点击的坐标
	
	//创建一个(弹出式)子菜单并定义菜单回调函数
	nModeMenu = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("正面多边形填充模式",1);
	glutAddMenuEntry("正面线宽模型",2);
	glutAddMenuEntry("正面点模式",3);
	glutAddMenuEntry("反面多边形填充模式",4);
	glutAddMenuEntry("反面多变形线宽模型",5);
	glutAddMenuEntry("反面多变形点模式",6);

	//再增加一个子菜单
	nColorMenu = glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("平面明暗模式",7);
	glutAddMenuEntry("光滑明暗模式",8);

	//创建主菜单
	nMainMenu = glutCreateMenu(ProcessMenu);
	glutAddSubMenu("多边形模式",nModeMenu);
	glutAddSubMenu("颜色模式",nColorMenu);
	glutAddMenuEntry("改变绕法",9);

	glutAttachMenu(GLUT_RIGHT_BUTTON);
	SetupRC();
	glutMainLoop();
	return 0;
}


运行结果

OpenGL(二)图形绘制之多边形面的绘制_第1张图片




1.三角形的绘制
在OpenGL中,面是由多边形构成的。三角形可能是最简单的多边形,它有三条边。可以使用GL_TRIANGLES模式通过把三个顶点连接到一起而绘出三角形。
使用GL_TRIANGLE_STRIP模式可以绘制几个相连的三角形,系统根据前三个顶点绘制第一个多边形,以后每指定一个顶点,就与构成上一个三角形的后两个顶点绘制形的一个三角形。
使用GL_TRIANGLE_FAN模式可以绘制一组相连的三角形,这些三角形绕着一个中心点成扇形排列。第一个顶点构成扇形的中心,用前三个顶点绘制会最初的三角形后,随后的所有顶点都和扇形中心以及紧跟在它前面的顶点构成下一个三角形,此时是以顺时针方向穿过顶点。
2.绕法
在绘制三角形的过程中,三个顶点将三角形封闭的过程是有序的,即三角形的构成路径具有方向性,我们把指定顶点时顺序和方向的组合称为"绕法"。绕法是任何多边形图元的一个重要特征。一般默认情况下,OpenGL认为逆时针绕法的多边形是正对着的,这一特性对于希望给多边形的正面和背面赋予不同的物理特性十分有用。如果要反转OpenGL的默认行为,

                             调用glFrontFace(GL_CW);GL_CW告诉OpenGL应该把顺时针缠绕的多边形正对着的。

                              为了改回把逆时针绕法视为正面,可以使用GL_CCW.
3.明暗处理
在绘制多边形时,我们常常指定绘制的颜色,而在OpenGL中,颜色实际上是对各个顶点而不是对各个多边形指定的。多边形的轮廓或者内部用单一的颜色或许多不同的颜色来填充的处理方式成为明暗处理。

                 在OpenGL中,用单一颜色处理的称为平面明暗处理(FlatShading),用许多不同颜色处理的称为光滑明暗处理(Smooth Shading),也称为Gourand明暗处理(Gourand Shading).

                     设置明暗处理模式的函数void glShadeModel(GLenum mode)参数mode取值为GL_FLAT或GL_SMOOTH。
                      应用平面明暗处理模式时,多边形内每个点的法向一致,其颜色也一致,OpenGL用指定多边形最后一个顶点时的颜色作为填充多边形的纯色。

4.多边形的模式
          多边形不是必须用当前颜色填充的。默认情况下绘制的多边形是实心的,但可以通过指定把多边形绘制为轮廓或只是点(只画出顶点)来修改这项默认行为。函数glPolygonMode(Glenum face,Glenum mode);允许把多边形渲染为填充的实心,轮廓线或只是点。另外,可以把这项渲染模式应用到多边形的两面或只应用到正面或背面。参数face指定多边形的哪一面受模式改变的影响——GL_FRONT,GL_BACK或GL_FRONT_AND_BACK。参数mode用于指定新的绘图模式。GL_FILL是默认值,生成填充的多边形;GL_LINE生成多边形的轮廓;而GL_POINT只画出顶点。GL_LINE和GL_POINT绘制的点和线受glEdgeFlag所设置边缘标记的影响。
5.多边形的绘制规则
         在使用大量多边形构造一个复杂表面时,有两条重要规则。
第一条规则是所有多边形都必须是平面的,也就是说,多边形的所有顶点必须唯有一个平面上,不能在空间中扭曲
第二条规则是多边形的边缘不能相交,而且多边形必须是凸的。

你可能感兴趣的:(OpenGL)