OpenGL 练习11.1 Lighting

本文介绍了一个使用OpenGL和GLUT库实现三维立方体光照效果的例子。通过定义顶点、颜色和光照属性,展示了如何构建和渲染一个带有光照效果的立方体。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<gl/glut.h>
#include<math.h>
#include<stdlib.h>


/* -------------------------------
* v1[],v2[],v3[]  {x,y,z}
* -------------------------------*/
void norm(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], GLfloat *nor )
{
	GLfloat vc1[3],vc2[3];
	GLfloat a,b,c;
	GLdouble r;

	vc1[0]= v2[0] - v1[0]; vc1[1]= v2[1] - v1[1]; vc1[2]= v2[2] - v1[2];
	vc2[0]= v3[0] - v1[0]; vc2[1]= v3[1] - v1[1]; vc2[2]= v3[2] - v1[2];
	a = vc1[1] * vc2[2] - vc2[1] * vc1[2];
	b = vc2[0] * vc1[2] - vc1[0] * vc2[2];
	c = vc1[0] * vc2[1] - vc2[0] * vc1[1];
	r = sqrt( a * a + b* b + c * c);
	nor[0] = a / r;
	nor[1] = b / r;
	nor[2] = c / r;
}

//窗口大小
int width = 600;
int height = 600;

//a point data type
typedef GLfloat point4[4];
typedef GLfloat color4[4];

point4 vertices[8] = {{-0.5, -0.5, 0.5, 1.0}, {-0.5, 0.5, 0.5, 1.0}, {0.5, 0.5, 0.5, 1.0}, {0.5, -0.5, 0.5, 1.0},
					  {-0.5, -0.5, -0.5, 1.0},  {-0.5, 0.5, -0.5, 1.0},  {0.5, 0.5, -0.5, 1.0},  {0.5, -0.5, -0.5, 1.0}};

color4 colors[8] = {{1.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 1.0},
					{0.0, 0.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0}, {0.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}};

color4 quad_color[36];
point4 points[36];

int i = 0;

void quad(int a, int b, int c, int d)
{
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[a][j]; 
		points[i][j] = vertices[a][j];
	}
	glVertex4fv(points[i]);
	i++;
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[b][j]; 
		points[i][j] = vertices[b][j];
	}
	glVertex4fv(points[i]);
	i++;
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[c][j]; 
		points[i][j] = vertices[c][j];
	}
	glVertex4fv(points[i]);
	i++;
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[a][j]; 
		points[i][j] = vertices[a][j];
	}
	glVertex4fv(points[i]);
	i++;
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[c][j]; 
		points[i][j] = vertices[c][j];
	}
	glVertex4fv(points[i]);
	i++;
	for (int j=0; j<4; j++) {
		quad_color[i][j] = colors[d][j]; 
		points[i][j] = vertices[d][j];
	}
	glVertex4fv(points[i]);
	i++;
}

void colorcube()
{
	glNormal3f(0, 0, 1); // 指定法向量才会有光照效果!
	quad(0, 3, 2, 1);
	glNormal3f(1, 0, 0);
	quad(2, 3, 7, 6);
	glNormal3f(0, -1, 0);
	quad(3, 0, 4, 7);
	glNormal3f(0, 1, 0);
	quad(1, 2, 6, 5);
	glNormal3f(0, 0, -1);
	quad(4, 5, 6, 7);
	glNormal3f(-1, 0, 0);
	quad(5, 4, 0, 1);
}

void display(void)
{
	glClearColor(1.0, 1.0, 1.0, 0.0);//注意事项:要在glClear之前设置color!
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除屏幕及深度缓存
	
	glViewport(0,0,(GLsizei)width,(GLsizei)height);

	glMatrixMode(GL_PROJECTION);//投影矩阵
		glLoadIdentity();
		gluPerspective(45, width/height, 1, 1000);
	glMatrixMode(GL_MODELVIEW);//模型矩阵
		glLoadIdentity();
		gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);

		glRotatef(30, 1, 0, 0);//绕x轴旋转
		glRotatef(30, 0, 1, 0);

	glEnable(GL_DEPTH_TEST);

	glEnableClientState(GL_VERTEX_ARRAY);
	colorcube();
	glVertexPointer(4, GL_FLOAT, 0, points);
	glEnableClientState(GL_COLOR_ARRAY);//启用颜色数组
	glColorPointer(4, GL_FLOAT, 0, quad_color);
	glDrawArrays(GL_TRIANGLES, 0, 36);
	
	glFlush();//当窗口模式为双缓存时,此函数的功能就是把后台缓存的内容交换到前台显示。当然,只有单缓存时,使用它的功能跟用glFlush()一样。而使用双缓存是为了把完整图画一次性显示在窗口上,或者是为了实现动画。
}

void init()
{
	/*
	GLfloat gAmbient[] = {0.6, 0,6, 0,6, 1.0};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gAmbient);
	*/
	GLfloat light_ambient[] = { 1.0, 0.0, 0.0, 1.0 };
	GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);

	GLfloat mat_ambient[] = { 0.8, 0.8, 0.8, 1.0 };
	GLfloat mat_diffuse[] = { 0.8, 0.0, 0.8, 1.0 };
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat mat_shininess[] = { 50.0 };
	
	glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
	
	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel (GL_SMOOTH);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	//glEnable(GL_COLOR_MATERIAL);

	glDepthFunc(GL_LESS);
	glEnable(GL_DEPTH_TEST);
}

void reshape(GLsizei w, GLsizei h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (w <= h)
		glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
	else
		glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);//初始化GLUT
	glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);//设置图形显示模式。GLUT_DEPTH:使用深度缓存;GLUT_DOUBLE:使用双缓存;
	glutInitWindowPosition(100, 100);//设置窗口显示位置
	glutInitWindowSize(600,600);//设置窗口大小
	glutCreateWindow("Lighting");//创建带标题的窗口

	init();// 之前一直没有光照效果是因为错把这个函数放在createwindow之前调用了

	glutDisplayFunc(display);//为当前窗口设置显示回调函数

	glutReshapeFunc(reshape);

	glutMainLoop();//进入GLUT事件处理循环
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值