图形学OpenGL基本光照

Posted 敲代码两年半的练习生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形学OpenGL基本光照相关的知识,希望对你有一定的参考价值。

【图形学】OpenGL基本光照

1.绘制目标

  • 设置两个点光源,点光源的颜色属性及位置可以自由设置
  • 立方体的材质属性:
    • shininess: 50
    • diffuse以及ambient都设为:0.5,0.5,0.5,1.0
    • specular设为: 1.0,1.0,1.0,1.0
  • 支持键盘操作:
    • x:绕x轴旋转;
    • y:绕y轴旋转;
    • z:绕z轴旋转·
    • r:复位
    • 设置按键分别响应对光源0和光源1的开启和关闭

2.核心代码

#define GLEW_STATIC
#define FREEGLUT_STATIC

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>

#include <string>
#include <iostream>
using namespace std;

float XROT(0.f), YROT(0.f), ZROT(0.f); float view(60);
float nul(1.0);
//改变图形大小 
bool flag_0 = true, flag_1 = true;

//光源0属性 
float light_ambient_color0[] = { 0.f, 1.f, 0.f, 1.f };
float light_diffuse_and_specular0[] = { 1.f, 1.f, 1.f, 1.f };
float light_position0[] = { 600.f, 600.f, 600.f, 1.f };
//光源1属性 
float light_ambient_color1[] = { 1.f, 0.f, 0.f, 1.f };
float light_diffuse_and_specular1[] = { 1.f, 1.f, 1.f, 1.f };
float light_position1[] = { 0.f, 0.f, 600.f, 1.f };
//物体属性,要求的立方体材质属性 
float material_ambient_and_diffuse[] = { 0.5f, 0.5f, 0.5f, 1.f };
float material_specular[] = { 1.f, 1.f, 1.f, 1.f };
float material_shininess[] = { 50.f };

float global_ambient[] = { 0.25f, 0.25f, 0.25f, 1.f };


GLfloat CUBE_VERTICES1[8][3] = 
{
	100, 100, 100,
	-100, 100, 100,
	-100, -100, 100,
	100, -100, 100,
	100, -100, -100,
	100, 100, -100,
	-100, 100, -100,
	-100, 100, 100,
};

GLfloat CUBE_VERTICES2[8][3] = 
{
	-100, -100, -100,
	-100, -100, 100,
	100, -100, 100,
	100, -100, -100,
	100, 100, -100,
	-100, 100, -100,
	-100, 100, 100,
	-100, -100, 100
};

void init() 
{
	glClearColor(0.0, 0.0, 0.0, 0.0);

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient_color0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse_and_specular0);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_diffuse_and_specular0);
	glLightfv(GL_LIGHT0, GL_POSITION, light_position0);

	glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient_color1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse_and_specular1);
	glLightfv(GL_LIGHT1, GL_SPECULAR, light_diffuse_and_specular1);
	glLightfv(GL_LIGHT1, GL_POSITION, light_position1);

	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material_ambient_and_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, material_shininess);

	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);


	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);  glEnable(GL_LIGHT1);
	//glEnable(GL_COLOR_MATERIAL);//颜色追踪
}

void drawCube() 
{//绘制立方体 

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();

	//绘制坐标系  
	glColor3f(1.0, 0.0, 1.0);

	glBegin(GL_TRIANGLE_FAN);
	glNormal3f(1.f, 1.f, 1.f); glVertex3fv(CUBE_VERTICES1[0]);
	glNormal3f(-1.f, 1.f, 1.f); glVertex3fv(CUBE_VERTICES1[1]);
	glNormal3f(-1.f, -1.f, 1.f); glVertex3fv(CUBE_VERTICES1[2]);
	glNormal3f(1.f, -1.f, 1.f); glVertex3fv(CUBE_VERTICES1[3]);
	glNormal3f(1.f, -1.f, -1.f); glVertex3fv(CUBE_VERTICES1[4]);
	glNormal3f(1.f, 1.f, -1.f); glVertex3fv(CUBE_VERTICES1[5]);
	glNormal3f(-1.f, 1.f, -1.f); glVertex3fv(CUBE_VERTICES1[6]);
	glNormal3f(-1.f, 1.f, 1.f); glVertex3fv(CUBE_VERTICES1[7]);
	glEnd();

	glBegin(GL_TRIANGLE_FAN);
	glNormal3f(-1.f, -1.f, -1.f); glVertex3fv(CUBE_VERTICES2[0]);
	glNormal3f(-1.f, -1.f, 1.f); glVertex3fv(CUBE_VERTICES2[1]);
	glNormal3f(1.f, -1.f, 1.f); glVertex3fv(CUBE_VERTICES2[2]);
	glNormal3f(1.f, -1.f, -1.f); glVertex3fv(CUBE_VERTICES2[3]);
	glNormal3f(1.f, 1.f, -1.f); glVertex3fv(CUBE_VERTICES2[4]);
	glNormal3f(-1.f, 1.f, -1.f); glVertex3fv(CUBE_VERTICES2[5]);
	glNormal3f(-1.f, 1.f, 1.f); glVertex3fv(CUBE_VERTICES2[6]);
	glNormal3f(-1.f, -1.f, 1.f); glVertex3fv(CUBE_VERTICES2[7]);
	glEnd();

}

void display() 
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	gluLookAt(0.0, 0.0, 600.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	glRotatef(ZROT, 0.f, 0.f, 1.f);
	glRotatef(YROT, 0.f, 1.f, 0.f);
	glRotatef(XROT, 1.f, 0.f, 0.f);

	glScalef(nul, nul, nul);

	drawCube();

	glutSwapBuffers();
	glFlush();
}


void keyboard(unsigned char key, int x, int y) 
{
	switch (key) {
	case 'x':
		XROT += 1;
		glutPostRedisplay();
		break;
	case 'y':
		YROT += 1;
		glutPostRedisplay();
		break;
	case 'z':
		ZROT += 1;
		glutPostRedisplay();
		break;
	case 'r':
		XROT = 0;
		YROT = 0;
		ZROT = 0;
		glutPostRedisplay();
		break;
	case 'a':
		nul += 0.2;
		glutPostRedisplay();
		break;
	case 'd':
		nul -= 0.2;
		glutPostRedisplay();
		break;
	case '0':
		//控制光源0是否存在   
		if (flag_0)
		{
			glDisable(GL_LIGHT0);
			flag_0 = false;
		}
		else
		{
			flag_0 = true;
			glEnable(GL_LIGHT0);
		}
		glutPostRedisplay();
		break;
	case '1':
		//控制光源1是否存在  
		if (flag_1)
		{
			flag_1 = false;
			glDisable(GL_LIGHT1);
		}
		else
		{
			flag_1 = true;
			glEnable(GL_LIGHT1);
		}
		glutPostRedisplay();
		break;
	default:
		break;
	}
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	//加载投影矩阵  
	glLoadIdentity();
	gluPerspective(view, float(w) / float(h), 10.0, 1000.0);

}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);

	glutInitContextVersion(3, 2);
	glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);

	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(800, 600);
	glutCreateWindow("LiCube");

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);

	init();

	glutMainLoop();

	return 0;
}

3.运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

以上是关于图形学OpenGL基本光照的主要内容,如果未能解决你的问题,请参考以下文章

计算机图形学(OPENGL):PBR理论

图形学计算机图形学知识点提纲10

拓幻图形学工程师教学手册(第六讲)|一字一字敲出OpenGL学习教程

计算机图形学_图元的属性_1_OpenGL状态变量

计算机图形学_图元的属性_1_OpenGL状态变量

图形学纹理贴图光照计算