GLSL shader中光照的计算

顶点shader代码:
float LightIntensity;//光照属性
void main()
{
    vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);//将物体进行模型视图中的一些变换(旋转 缩放 平移)
    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal);//将顶点法线转换到模型视图中,因为对于法线没有缩放操作,所以不能使用gl_ModelViewMatrix矩阵,使用gl_NormalMatrix
    vec3 lightVec   = normalize(gl_LightSource[0].position.xyz - ecPosition);//顶点到光源位置的单位向量L
    vec3 reflectVec = lightVec+ecPosition;//L和顶点指向观察点的向量和==S半向量
    vec3 viewVec    = normalize(reflectVec);//单位化
	//可以直接使用viewVec = gl_LightSource[0].halfVector.xyz;
    float diffuse   = max(dot(lightVec, tnorm), 0.0);//散射光计算公式=(max{L*n,0})*diffuseLight*diffuseMatrial
    float spec      = 0.0;
    if (diffuse > 0.0)//如果L*n<=0,顶点就不存在镜面光(光线位于表面的另一面)
    {
        spec = max(dot(viewVec, tnorm), 0.0);//计算公式=(max{S*n,0}^shiness)*specularLight*specularMaterial
        spec = pow(spec, 0.0);
    }
	LightIntensity =  gl_LightModel.ambient+gl_LightSource[0].ambient*gl_FrontMaterial.ambient+gl_LightSource[0].diffuse*gl_FrontMaterial.diffuse*diffuse+gl_LightSource[0].specular*gl_FrontMaterial.specular*spec;
    gl_Position     = ftransform();
	gl_FrontColor = gl_Color * LightIntensity;
}
片元shader
void main()
{	
    gl_FragColor = gl_Color;
}

效果:


完整程序:

#include<stdio.h>
#include<stdlib.h>
#include<gl\glew.h>
#include <gl\glut.h>
//#pragma comment(lib,"GLAUT.lib")
#pragma comment(lib,"glew32.lib")
#pragma comment(lib,"glew32s.lib")

char *vdata = NULL;
char *fdata = NULL;
GLuint v,f,p;
float a = 0;
GLfloat position[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat ambient[] = { 0.0, 0.0, 0.0, 0.0 };
GLfloat ambient2[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat specular[] = { 1.0, 0.0, 0.0, 0.0 };
void init()
{
	glEnable(GL_DEPTH_TEST);
	glClearColor(0, 0, 0, 1);
	glColor3f(1, 1, 1);
	glEnable(GL_CULL_FACE);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_COLOR_MATERIAL);
	glLightfv(GL_LIGHT0, GL_POSITION, position);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
	//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient2);
	glLightModeli(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
}
char* ReadFile(char *filename)
{
	FILE *file = NULL;
	fopen_s(&file, filename, "rb");
	if (file == NULL)
	{
		return NULL;
	}
	fseek(file, 0, SEEK_END);
	long count = ftell(file);
	rewind(file);
	char *fileData = NULL;
	if (count > 0)
	{
		fileData = new char[count + 1];
		fread(fileData, sizeof(char), count, file);
		fileData[count] = '\0';
	}
	return fileData;
}
void setShader()//设置着色器
{
	glewInit();
	v = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
	f = glCreateShader(GL_FRAGMENT_SHADER);//创建片元着色器
	vdata = ReadFile("vertex.v");//读取顶点着色器内容
	fdata = ReadFile("fragment.f");//读取片元着色器内容
	char *vv = vdata;
	char *ff = fdata;
	glShaderSource(v, 1, &vv, NULL);//添加到着色器中
	glShaderSource(f, 1, &ff, NULL);
	glCompileShader(v);//编译着色器
	glCompileShader(f);
	p = glCreateProgram();//创建程序处理着色器
	glAttachShader(p, v);//将待处理着色器添加到程序中
	glAttachShader(p, f);
	glLinkProgram(p);//链接
	int result;
	glGetProgramiv(p, GL_LINK_STATUS, &result);//获取程序编译状态
	if (result != GL_TRUE)//如果失败获取失败信息
	{
		GLsizei length;
		glGetProgramiv(p, GL_INFO_LOG_LENGTH, &length);
		char *info = new char [length];
		glGetProgramInfoLog(p, 255, &length, info);
		fprintf(stderr, "link log = '%s'\n", info);
		delete[]info;
	}

	
	glUseProgram(p);//使用着色器程序

}
void display(void)
{
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();
	
	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);

	glBegin(GL_LINES);
	glColor3f(1, 0, 0);
	glVertex3d(-10, 0, 0);//X轴
	glVertex3d(10, 0, 0);
	glColor3f(0, 1, 0);//Y轴
	glVertex3d(0, -10, 0);
	glVertex3d(0, 10, 0);
	glColor3f(0, 0, 1);//Z轴
	glVertex3d(0, 0, -10);
	glVertex3d(0, 0, 10);
	glEnd();
	glRotatef(a, 0, 1, 0);

	glColor3f(1, 0, 1);
	glutSolidTeapot(1);
	a += 1;
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	if (h == 0) h = 1;
	float ratio = 1.0*w / h;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	
	gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.0, 1000.0);
	glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	glutDisplayFunc(display);
	glutIdleFunc(display);
	glutReshapeFunc(reshape);
	init();	
	glewInit();
	setShader();
	glutMainLoop();
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值