openGL绘制正方体分别实现简单颜色绘制、纹理绘制、光照绘制

使用openGL绘制正方体;

面1:使用简单颜色绘制,颜色为绿色;

面2:使用简单颜色绘制,颜色为渐变色;

面3:绘制一维纹理;

面4:绘制二维纹理;

面5:光照绘制,黄色;

面6:光照绘制,橘色;

绘制效果如下:

                

需要注意的问题:

1、  在绘制纹理和光照的时候,要正确设置每个面的法线方向;使用函数glNormal3f( )进行设置;

2、  使用光照的时候,如果只是局部光照,要在局部光照结束之后,关闭光源,否则别的面也被光照;使用函数glDisable(GL_LIGHTING)实现;

3、  使用png图片作为二维纹理的时候需要将原始图片进行上下翻转,因为OpenGL以左下角为图像原点;自定义函数void upsidedown32(unsigned char *pImage, unsigned width, unsignedheight)实现图像上下翻转;

#include <GL/glut.h>
#include "lodepng.h"

void init(void);
void reshape(int w, int h);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void display(void);
void drawCoordinates(void);
void drawTetrahedron(void);

int mx,my; //position of mouse
int m_state=0; //mouse usage
float x_angle=20.0f, y_angle=20.0f; //angle of eye
float dist=10.0f; //distance from the eye

GLuint texDog, tex1D;

void upsidedown32(unsigned char *pImage, unsigned width, unsigned height)  //Upside down the image
{
	unsigned i;
	unsigned char *pLine;

	pLine = (unsigned char *)malloc(4*width);
	if(pLine == NULL)
	{
		printf("No memory left!");
		exit(0);
	}
	for(i=0; i<height/2; i++)
	{
		memcpy(pLine, &pImage[i*4*width], 4*width);
		memcpy(&pImage[i*4*width], &pImage[(height-1-i)*4*width], 4*width);
		memcpy(&pImage[(height-1-i)*4*width], pLine, 4*width);
	}
	free(pLine);
}


void init(void)
{
	int i;
	unsigned error;
	unsigned width, height;
	unsigned char *pDogImg;
	unsigned char img1D[16][3];

	error = lodepng_decode32_file(&pDogImg, &width, &height, "dog.png");
	if(error)
	{
		printf("error %u: %s\n", error, lodepng_error_text(error));
		exit(0);
	}
	upsidedown32(pDogImg, width, height); //Upside down the image
	glGenTextures(1, &texDog); //生成纹理号
	glBindTexture(GL_TEXTURE_2D, texDog);  //纹理绑定
	glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pDogImg); //定义纹理数据
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);  //设置纹理目标参数
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	free(pDogImg);

	for(i=0; i<16; i++)  //构造一维纹理
		if(i%4)
			img1D[i][0] = img1D[i][1] = img1D[i][2] = 255;
		else
			img1D[i][0] = img1D[i][1] = img1D[i][2] = 0;
	glGenTextures(1, &tex1D);
	glBindTexture(GL_TEXTURE_1D, tex1D);
	glTexImage1D(GL_TEXTURE_1D, 0, 3, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, img1D);
	glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);  //设置纹理环境参数
	glEnable(GL_DEPTH_TEST);
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
}


void mouse(int button, int state, int x, int y)
{
	if(button==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		mx = x;
		my = y;
		m_state = 0;
	}
	if(button==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
	{
		mx = x;
		my = y;
		m_state = 1;
	}
}

void motion(int x, int y)
{
	int dx,dy; //offset of mouse;

	dx = x-mx;
	dy = y-my;

	if(m_state == 0)
	{
		y_angle += dx*0.1f;
		x_angle += dy*0.1f;
	}
	else if(m_state == 1)
		dist += (dx+dy)*0.05f;
	
	mx = x;
	my = y;

	glutPostRedisplay();
}

void display(void)
{
	int rect[4];
	float w, h;
	//float lit_position[] = {0.0f, 0.0f, 1.0f, 0.0f};
	//float mat_yellow[] = {1.0f, 1.0f, 0.0f, 1.0f};

	glGetIntegerv(GL_VIEWPORT, rect);
	w = rect[2];
	h = rect[3];

	glClearColor(1.0f,1.0f,1.0f,0.0f);
	glClearDepth(1.0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity(); //对应单位阵I

	if(h < 1) h=1;
	gluPerspective(30.0, w/h, 0.1, 20.0); //对应变换阵T0

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity(); //对应单位阵I

	glTranslated(0.0, 0.0, -dist); //对应变换阵T1
	glRotatef(x_angle, 1.0f, 0.0f, 0.0f); //对应变换阵T2
	glRotatef(y_angle, 0.0f, 1.0f, 0.0f); //对应变换阵T3
	
	glPushMatrix();
		glScalef(1.5f, 1.5f, 1.5f); //对应变换阵T6
		drawCoordinates();
		drawTetrahedron();
	glPopMatrix();

	glFlush();
	glutSwapBuffers();
}

void drawTetrahedron(void)
{
	float pnt[8][3] = {{0.0,0.0,0.0}, {0.0,1.0,0.0}, {1.0,1.0,0.0}, {1.0,0.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0},{1.0,1.0,1.0},{1.0,0.0,1.0}};
	int tetra[6][4] = {{0,1,2,3}, {1,5,6,2}, {0,3,7,4}, {2,6,7,3},{0,4,5,1},{4,7,6,5}};
	float lit_position1[] = {1.0f, 0.0f, 0.0f, 0.0f};
	float lit_position2[] = {-1.0f, 0.0f, 0.0f, 0.0f};
	float yellow[] = {1.0f, 1.0f, 0.0f, 1.0f};
	float orange[] = {1.0f, 0.5f, 0.0f, 1.0f};
	
	//glNormal3f(0.0f, 0.0f, -1.0f);
	glBegin(GL_QUADS);  //简单颜色绘两个面,一个单一色,一个渐变色
		glColor3f(0.0f,1.0f,0.0f);  //绿色
		glVertex3fv(pnt[tetra[0][0]]); //glVertex3fv(pnt[0]); glVertex3f(0.0f, 0.0f, 0.0f); 
		glVertex3fv(pnt[tetra[0][1]]); //glVertex3fv(pnt[2]); glVertex3f(0.0f, 1.0f, 0.0f); 
		glVertex3fv(pnt[tetra[0][2]]); //glVertex3fv(pnt[1]); glVertex3f(1.0f, 0.0f, 0.0f); 
		glVertex3fv(pnt[tetra[0][3]]);
    glEnd();

	//glNormal3f(0.0f, 1.0f, 0.0f);
	glBegin(GL_QUADS);
		glColor3f(0.0f,1.0f,1.0f); glVertex3fv(pnt[tetra[1][0]]);
		glColor3f(1.0f,0.0f,1.0f); glVertex3fv(pnt[tetra[1][1]]);
		glColor3f(1.0f,1.0f,0.0f); glVertex3fv(pnt[tetra[1][2]]);
		glColor3f(1.0f,1.0f,1.0f); glVertex3fv(pnt[tetra[1][3]]);
	glEnd();


	/* 绘制纹理图案    */
	glNormal3f(0.0f, -1.0f, 0.0f);//一维纹理绘制
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_TEXTURE_1D);
	glBegin(GL_POLYGON); 
		glTexCoord1f(0.0f); glVertex3fv(pnt[tetra[2][0]]);  //设置纹理坐标
		glTexCoord1f(0.0f); glVertex3fv(pnt[tetra[2][1]]);
		glTexCoord1f(1.0f); glVertex3fv(pnt[tetra[2][2]]);
		glTexCoord1f(1.0f); glVertex3fv(pnt[tetra[2][3]]);
	glEnd();

	glNormal3f(0.0f, 0.0f, 1.0f); //二维纹理的绘制
	glDisable(GL_TEXTURE_1D);
	glEnable(GL_TEXTURE_2D);
	glBegin(GL_POLYGON);  // 正对面
	glTexCoord2f(0.0f, 0.0f); glVertex3fv(pnt[tetra[5][0]]);
	glTexCoord2f(1.0f, 0.0f); glVertex3fv(pnt[tetra[5][1]]);
	glTexCoord2f(1.0f, 1.0f); glVertex3fv(pnt[tetra[5][2]]);
	glTexCoord2f(0.0f, 1.0f); glVertex3fv(pnt[tetra[5][3]]);
    glEnd();
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_1D);


	/* 两个光照面  */
	glLightfv(GL_LIGHT0, GL_POSITION, lit_position2);  //光源位置
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);  //之后使用光照模型计算顶点颜色
	glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow);

	glNormal3f(-1.0f,0.0f,0.0f);
	glBegin(GL_QUADS);
	glVertex3fv(pnt[tetra[4][0]]);
	glVertex3fv(pnt[tetra[4][1]]);
	glVertex3fv(pnt[tetra[4][2]]);
	glVertex3fv(pnt[tetra[4][3]]);
	glEnd();
	glDisable(GL_LIGHTING);	//(不能省略)之后顶点颜色为当前颜色,当前颜色可以通过glColor*函数指定。  	

	glLightfv(GL_LIGHT0, GL_POSITION, lit_position1);  //普通光照(橘色)
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);  
	glMaterialfv(GL_FRONT, GL_DIFFUSE, orange);

	glNormal3f(1.0f,0.0f,0.0f);   
	glBegin(GL_QUADS);
		glVertex3fv(pnt[tetra[3][0]]); 
		glVertex3fv(pnt[tetra[3][1]]);
		glVertex3fv(pnt[tetra[3][2]]);
		glVertex3fv(pnt[tetra[3][3]]);
	glEnd();
	glDisable(GL_LIGHTING); 
}

void drawCoordinates(void)
{
	glColor3f(1.0f,0.0f,0.0f); //画红色的x轴
	glBegin(GL_LINES);
	glVertex3f(0.0f, 0.0f, 0.0f);
	glVertex3f(2.0f, 0.0f, 0.0f);
	glEnd();
	glColor3f(0.0,1.0,0.0); //画绿色的y轴
	glBegin(GL_LINES);
	glVertex3f(0.0f, 0.0f, 0.0f);
	glVertex3f(0.0f, 2.0f, 0.0f);
	glEnd();
	glColor3f(0.0,0.0,1.0); //画蓝色的z轴
	glBegin(GL_LINES);
	glVertex3f(0.0f, 0.0f, 0.0f);
	glVertex3f(0.0f, 0.0f, 2.0f);
	glEnd();
}


int main(int argc,char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(500,500);
	glutInitWindowPosition(0,0);
	glutCreateWindow("model & zbuffer");
	init();

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(mouse);
	glutMotionFunc(motion);
	glutMainLoop();

	glDeleteTextures(1, &texDog); //删除纹理
	glDeleteTextures(1, &tex1D);  //删除纹理

	return 0;
}


  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
#include #include "stdafx.h" #define GLUT_DISABLE_ATEXIT_HACK #include //#pragma comment(lib, "glut32.lib") GLfloat AngleX;//旋转向量 GLfloat AngleY; void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); //这个函数其实就是对接下来要做什么进行一下声明 GL_MODELVIEW 模型视图 glLoadIdentity(); glPushMatrix();// 提供了相应的接口 { glRotatef(AngleX, 1.0f, 0.0f, 0.0f); glRotatef(AngleY, 0.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); //前表面 glColor3f(1.0f,1.0f,1.0f);//颜色设置为白色 glVertex3f(50.0f, 50.0f, 50.0f); glColor3f(1.0f,1.0f,0.0f);//颜色设置为黄色 glVertex3f(50.0f, -50.0f, 50.0f); glColor3f(1.0f,0.0f,0.0f);//颜色设置为红色 glVertex3f(-50.0f, -50.0f, 50.0f); glColor3f(1.0f,0.0f,1.0f);//颜色设置为品红色 glVertex3f(-50.0f, 50.0f, 50.0f); glEnd(); glBegin(GL_POLYGON); //后表面 glColor3f(0.0f, 1.0f, 1.0f);//颜色设置为青色 glVertex3f(50.0f, 50.0f, -50.0f); glColor3f(0.0f, 1.0f, 0.0f);//颜色设置为绿色 glVertex3f(50.0f, -50.0f, -50.0f); glColor3f(0.0f, 0.0f, 0.0f);//颜色设置为黑色 glVertex3f(-50.0f, -50.0f, -50.0f); glColor3f(0.0f, 0.0f, 1.0f);//颜色设置为蓝色 glVertex3f(-50.0f, 50.0f, -50.0f); glEnd(); glBegin(GL_POLYGON); //右表面 glColor3ub((GLubyte)255, (GLubyte)255, (GLubyte)255);//颜色设置为白色 glVertex3f(50.0f, 50.0f, 50.0f); glColor3f(0.0f, 1.0f, 1.0f);//颜色设置为青色 glVertex3f(50.0f, 50.0f, -50.0f); glColor3f(0.0f, 1.0f, 0.0f);//颜色设置为绿色 glVertex3f(50.0f, -50.0f, -50.0f); glColor3ub((GLubyte)255, (GLubyte)255, (GLubyte)0);//颜色设置为黄色 glVertex3f(50.0f, -50.0f, 50.0f); glEnd(); glBegin(GL_POLYGON); //左表面 glColor3d(0.0, 0.0, 1.0);//颜色设置为蓝色 glVertex3f(-50.0f, 50.0f, -50.0f); glColor3f(0.0f, 0.0f, 0.0f);//颜色设置为黑色 glVertex3f(-50.0f, -50.0f, -50.0f); glColor3ub((GLubyte)255, (GLubyte)0, (GLubyte)0);//颜色设置为红色 glVertex3f(-50.0f, -50.0f, 50.0f); glColor3f(1.0f, 0.0f, 1.0f);//颜色设置为品红色 glVertex3f(-50.0f, 50.0f, 50.0f); glEnd(); glBegin(GL_POLYGON); //上表面 glColor3d(0.0, 1.0, 1.0);//颜色设置为青色 glVertex3f(50.0f, 50.0f, -50.0f); glColor3d(1.0, 1.0, 1.0);//颜色设置为白色 glVertex3f(50.0f, 50.0f, 50.0f); glColor3d(1.0, 0.0, 1.0);//颜色设置为品红色 glVertex3f(-50.0f, 50.0f, 50.0f); glColor3d(0.0, 0.0, 1.0);//颜色设置为蓝色 glVertex3f(-50.0f, 50.0f, -50.0f); glEnd(); glBegin(GL_POLYGON); //下表面 glColor3f(0.0f, 1.0f, 0.0f);//颜色设置为绿色 glVertex3f(50.0f, -50.0f, -50.0f); glColor3ub((GLubyte)255, (GLubyte)255, (GLubyte)0);//颜色设置为黄色 glVertex3f(50.0f, -50.0f, 50.0f); glColor3f(1.0f, 0.0f, 0.0f);//颜色设置为红色 glVertex3f(-50.0f, -50.0f, 50.0f); glColor3f(0.0f, 0.0f, 0.0f);//颜色设置为黑色 glVertex3f(-50.0f, -50.0f, -50.0f); glEnd(); } glPopMatrix(); glutSwapBuffers(); } void reshape(int w, int h) { GLfloat aspect = (GLfloat)w / (GLfloat)h; GLfloat nRange = 100.0f; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影模式 glLoadIdentity(); //设置三维投影区 if (w 355.0f) { AngleX = 0.0f; } if (AngleX 355.0f) AngleY = 0.0f; if (AngleY < 0.0f) { AngleY = 355.0f; } glutPostRedisplay(); } void init() { AngleX = 45.0f; AngleY = 315.0f; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); //初始化OpenGL glEnable(GL_DITHER); //抖动是激活的。 glShadeModel(GL_SMOOTH);//两点间颜色有过渡效果 } void main(int argc, char* argv[]) { glutInit(&argc;, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); //使用双缓存 使用深度缓存。 glutInitWindowSize(480, 480); glutCreateWindow("OpenGL颜色立方体"); glutReshapeFunc(reshape); //窗口改变的时候调用的函数 glutDisplayFunc(display); glutSpecialFunc(key_board); //函数注册鼠标响应事件 init(); glutMainLoop(); }
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值