OpengGL绘制立方体的三种方法

以下为绘制立方体的三种方法:

第一种方法为最为传统的,也是各个图形学书上的方法。

第二种方法为1.1新加入的 顶点数组,该绘制程序也能运行在OpenGL ES1.1上

第三种方法是第二种方法的改进,用索引数组代替了法向量。

先介绍这几种方法吧,以后在添加新的方法:

第一种方法:立即模式

void draw1(GLdouble dSize)
{
	double size = dSize * 0.5;
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glBegin(GL_QUADS);
	//上
	glColor4f(1.0, 0.0, 0.0, 1.0);
	glNormal3d(0.0, 0.0, 1.0); //上
	glVertex3d(dSize, dSize, dSize);
	glVertex3d(-dSize, dSize, dSize);
	glVertex3d(-dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, dSize);
	//下
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glNormal3d(0.0, 0.0, -1.0);//下
	glVertex3d(dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(dSize, -dSize, -dSize);
	//前
	glColor4f(1.0, 1.0, 0.0, 1.0);
	glNormal3d(1.0, 0.0, 0.0);//前
	glVertex3d(dSize, dSize, dSize);
	glVertex3d(dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, -dSize);
	glVertex3d(dSize, dSize, -dSize);
	//后
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glNormal3d(-1.0, 0.0, 0.0);//后
	glVertex3d(-dSize, dSize, dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, dSize);
	//左
	glColor4f(0.0, 1.0, 0.5, 1.0);
	glNormal3d(0.0, -1.0, 0.0);//左
	glVertex3d(dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, dSize);
	//右
	glColor4f(0.5, 1.0, 0.5, 1.0);
	glNormal3d(0.0, 1.0, 0.0);//右
	glVertex3d(dSize, dSize,dSize);
	glVertex3d(dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, dSize);//右
	glEnd();
}


第二种方法:顶点数组+法向量

void draw2(GLdouble dSize)
{
	double size = dSize * 0.5;
	GLdouble dVertexes[][3] = {
		{ dSize, dSize, dSize },{ -dSize, dSize, dSize },{ -dSize, -dSize, dSize },	{ dSize, -dSize, dSize },
		{ dSize, dSize, -dSize },{ -dSize, dSize, -dSize},{ -dSize, -dSize, -dSize },{ dSize, -dSize, -dSize },
		{ dSize, dSize, dSize },{ dSize, -dSize, dSize },{ dSize, -dSize, -dSize },	{ dSize, dSize, -dSize },
		{ -dSize, dSize, dSize },{ -dSize, dSize, -dSize },	{ -dSize, -dSize, -dSize }, { -dSize, -dSize, dSize },
		{ dSize, -dSize, dSize },{ dSize, -dSize, -dSize },	{ -dSize, -dSize, -dSize }, { -dSize, -dSize, dSize },
		{ dSize, dSize, dSize },{ dSize, dSize, -dSize },	{ -dSize, dSize, -dSize },	{ -dSize, dSize, dSize }
	};
	GLdouble dVertexNormals[][3] = {
		{ 0.0, 0.0, 1.0 },//上
		{ 0.0, 0.0, -1.0 },//下
		{ 1.0, 0.0, 0.0 },//前
		{ -1.0, 0.0, 0.0 },//后
		{ 0.0, -1.0, 0.0 },//左
		{ 0.0, 1.0, 0.0 }//右
	};
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, 0, dVertexNormals);
	glVertexPointer(3, GL_DOUBLE, 0, dVertexes);

	glColor4f(1.0, 0.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 0, 4);
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 4, 4);
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glDrawArrays(GL_QUADS, 8, 4);
	glColor4f(1.0, 1.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 12, 4);
	glColor4f(0.0, 1.0, 0.5, 1.0);
	glDrawArrays(GL_QUADS, 16, 4);
	glColor4f(0.5, 1.0, 0.5, 1.0);
	glDrawArrays(GL_QUADS, 20, 4);
}

第三种方法:顶点数组+法向量

void draw3(GLdouble dSize)
{
	double size = dSize * 0.5;
	GLdouble dVertexes[][3] = {
		{ dSize, dSize, dSize },//0		第一象限点
		{ -dSize, dSize, dSize },//1	第二象限点
		{ -dSize, -dSize, dSize },//2	第三象限点
		{ dSize, -dSize, dSize },//3	第四象限点
		{ dSize, dSize, -dSize },//4	第五象限点
		{ -dSize, dSize, -dSize },//5	第六象限点
		{ -dSize, -dSize, -dSize },//6	第七象限点
		{ dSize, -dSize, -dSize }//7	第八象限点
	};

	//使用索引表示面,4个索引值表示组成面的四个顶点
	GLubyte dIndices[][4] = {
		{ 0, 1, 2, 3 },//上
		{ 4, 5, 6, 7 },//下
		{ 0, 3, 7, 4 },//前
		{ 1, 5, 6, 2 },//后
		{ 3, 7, 6, 2 },//左
		{ 0, 4, 5, 1 }//右
	};
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_DOUBLE, 0, dVertexes);
	glColor4f(1.0, 0.0, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[0]);
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[1]);
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[2]);
	glColor4f(1.0, 0.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[3]);
	glColor4f(0.0, 1.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[4]);
	glColor4f(0.5, 0.5, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[5]);
	glDisable(GL_DEPTH_TEST);
	glDisableClientState(GL_VERTEX_ARRAY);
}


以下是完整的程序代码,环境采用freeglut+glew来运行

#if ( (defined(__MACH__)) && (defined(__APPLE__)) )   
#include <stdlib.h>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#include <OpenGL/glext.h>
#else
#include <stdlib.h>
#define GLEW_STATIC
#include <GL/glew.h>
#define FREEGLUT_STATIC
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#endif
#pragma comment(lib,"freeglut.lib")
#pragma comment(lib, "glew32s.lib")
#pragma comment(linker,"/NODEFAULTLIB:LiBCMT.lib")

GLfloat angle = 0.0; //set the angle of rotation
//第一种方法:立即模式
void draw1(GLdouble dSize)
{
	double size = dSize * 0.5;
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glBegin(GL_QUADS);
	//上
	glColor4f(1.0, 0.0, 0.0, 1.0);
	glNormal3d(0.0, 0.0, 1.0); //上
	glVertex3d(dSize, dSize, dSize);
	glVertex3d(-dSize, dSize, dSize);
	glVertex3d(-dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, dSize);
	//下
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glNormal3d(0.0, 0.0, -1.0);//下
	glVertex3d(dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(dSize, -dSize, -dSize);
	//前
	glColor4f(1.0, 1.0, 0.0, 1.0);
	glNormal3d(1.0, 0.0, 0.0);//前
	glVertex3d(dSize, dSize, dSize);
	glVertex3d(dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, -dSize);
	glVertex3d(dSize, dSize, -dSize);
	//后
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glNormal3d(-1.0, 0.0, 0.0);//后
	glVertex3d(-dSize, dSize, dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, dSize);
	//左
	glColor4f(0.0, 1.0, 0.5, 1.0);
	glNormal3d(0.0, -1.0, 0.0);//左
	glVertex3d(dSize, -dSize, dSize);
	glVertex3d(dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, -dSize);
	glVertex3d(-dSize, -dSize, dSize);
	//右
	glColor4f(0.5, 1.0, 0.5, 1.0);
	glNormal3d(0.0, 1.0, 0.0);//右
	glVertex3d(dSize, dSize,dSize);
	glVertex3d(dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, -dSize);
	glVertex3d(-dSize, dSize, dSize);//右
	glEnd();
}
//方法二:顶点数组+法向量(OpenGL ES1.1兼容)
void draw2(GLdouble dSize)
{
	double size = dSize * 0.5;
	GLdouble dVertexes[][3] = {
		{ dSize, dSize, dSize },{ -dSize, dSize, dSize },{ -dSize, -dSize, dSize },	{ dSize, -dSize, dSize },
		{ dSize, dSize, -dSize },{ -dSize, dSize, -dSize},{ -dSize, -dSize, -dSize },{ dSize, -dSize, -dSize },
		{ dSize, dSize, dSize },{ dSize, -dSize, dSize },{ dSize, -dSize, -dSize },	{ dSize, dSize, -dSize },
		{ -dSize, dSize, dSize },{ -dSize, dSize, -dSize },	{ -dSize, -dSize, -dSize }, { -dSize, -dSize, dSize },
		{ dSize, -dSize, dSize },{ dSize, -dSize, -dSize },	{ -dSize, -dSize, -dSize }, { -dSize, -dSize, dSize },
		{ dSize, dSize, dSize },{ dSize, dSize, -dSize },	{ -dSize, dSize, -dSize },	{ -dSize, dSize, dSize }
	};
	GLdouble dVertexNormals[][3] = {
		{ 0.0, 0.0, 1.0 },//上
		{ 0.0, 0.0, -1.0 },//下
		{ 1.0, 0.0, 0.0 },//前
		{ -1.0, 0.0, 0.0 },//后
		{ 0.0, -1.0, 0.0 },//左
		{ 0.0, 1.0, 0.0 }//右
	};
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, 0, dVertexNormals);
	glVertexPointer(3, GL_DOUBLE, 0, dVertexes);

	glColor4f(1.0, 0.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 0, 4);
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 4, 4);
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glDrawArrays(GL_QUADS, 8, 4);
	glColor4f(1.0, 1.0, 0.0, 1.0);
	glDrawArrays(GL_QUADS, 12, 4);
	glColor4f(0.0, 1.0, 0.5, 1.0);
	glDrawArrays(GL_QUADS, 16, 4);
	glColor4f(0.5, 1.0, 0.5, 1.0);
	glDrawArrays(GL_QUADS, 20, 4);
}

/*
* 方法二:顶点数组+索引数组
空间象限----第一象限 ++
第二象限 -+
第三象限 --
第四象限 +-
五,六,七,八象限与前面一致。但Z轴为负
*/

void draw3(GLdouble dSize)
{
	double size = dSize * 0.5;
	GLdouble dVertexes[][3] = {
		{ dSize, dSize, dSize },//0		第一象限点
		{ -dSize, dSize, dSize },//1	第二象限点
		{ -dSize, -dSize, dSize },//2	第三象限点
		{ dSize, -dSize, dSize },//3	第四象限点
		{ dSize, dSize, -dSize },//4	第五象限点
		{ -dSize, dSize, -dSize },//5	第六象限点
		{ -dSize, -dSize, -dSize },//6	第七象限点
		{ dSize, -dSize, -dSize }//7	第八象限点
	};

	//使用索引表示面,4个索引值表示组成面的四个顶点
	GLubyte dIndices[][4] = {
		{ 0, 1, 2, 3 },//上
		{ 4, 5, 6, 7 },//下
		{ 0, 3, 7, 4 },//前
		{ 1, 5, 6, 2 },//后
		{ 3, 7, 6, 2 },//左
		{ 0, 4, 5, 1 }//右
	};
	glEnable(GL_DEPTH_TEST);//深度测试消除隐藏面
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_DOUBLE, 0, dVertexes);
	glColor4f(1.0, 0.0, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[0]);
	glColor4f(0.0, 1.0, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[1]);
	glColor4f(0.0, 0.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[2]);
	glColor4f(1.0, 0.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[3]);
	glColor4f(0.0, 1.0, 1.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[4]);
	glColor4f(0.5, 0.5, 0.0, 1.0);
	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, dIndices[5]);
	glDisable(GL_DEPTH_TEST);
	glDisableClientState(GL_VERTEX_ARRAY);
}
void display(void) {
	//几何变换和取景变换,都是取景矩阵
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//设置取景矩阵
	gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);//设置取景矩阵
	//设置几何矩阵
	glRotatef(angle, 1.0, 0.0, 0.0); //绕X轴旋转
	glRotatef(angle, 0.0, 1.0, 0.0); //绕Y轴旋转
	glRotatef(angle, 0.0, 0.0, 1.0); //绕Z轴旋转

	//绘制模型
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//drawSolidCube2(2);//绘制正方体
	draw3(1);
	glutSwapBuffers();
	angle += 0.01f;
}

void reshape(int w, int h) {
	//视区变换
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	//投影变换
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
}
int main(int argc, char **argv) {

	glutInit(&argc, argv);
	//创建窗口
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); //set up the double buffering
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("A basic OpenGL Window");
	//初始化GLEW
	glewInit();
	//窗口回调函数
	glutReshapeFunc(reshape);//改变窗口后调用,也可以理解为OpenGL的初始化,WM_SIZE,WM_CREATE
	glutDisplayFunc(display);//窗口显示后调用,WM_PAINT
	glutIdleFunc(display);//空闲时调用
	glutMainLoop();
	return 0;
}


阅读更多
想对作者说点什么? 我来说一句
相关热词

没有更多推荐了,返回首页

关闭
关闭
关闭