//A.17 GLSL程序
/* display teapot with vertex and fragment shaders */
/* sets up elapsed time parameter for use by shaders */
#include<stdio.h>
#include<stdlib.h>
#include<gl/glut.h>
const float nearVal =1.0f;
const float farVal =300.0f ;
const float lightPos[3] ={3.0f,3.0f,3.0f};
int width =512;
int height =512;
GLint program =0;
GLint timeParam;
/* shader reader */
/* create nulll terminated string from file */
char *readShaderSource(const char *shaderFile)
{
struct stat statBuf;
FILE *fp =fopen(shaderFile,"r");
char *buf;
stat(shaderFile,&statBuf);
buf=(char *)malloc(statBuf.st_size+1*sizeof(char));
fread(buf,1,statBuf.st_size,fp);
buf[statBuf.st_size]=' ';
fclose(fp);
return buf;
}
/* error printing function */
static void chechError(GLint status,const char *msg)
{
if(!status)
{
printf("%s\n",msg);
exit(EXIT_FAILURE);
}
}
/* standard OpenGL initialization */
static void init()
{
const float teapotColor[] ={0.3f,0.5f,0.4f,1.0f};
const float teapotSpecular[] ={0.8f,0.8f,0.8f,1.0f};
const float teapotShininess[]={80.0f};
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,teapotColor);
glMaterialfv(GL_FRONT,GL_SPECULAR,teapotSpecular);
glMaterialfv(GL_FRONT,GL_SHININESS,teapotShininess);
glClearColor(1.0f,1.0f,1.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f,10.0f);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
134
录 附 A 实 例 例程序
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
/* GLSL initialization */
static void initShader(const char *vShaderFile,const char
*fShaderFile)
{
GLintvShader =0;
GLintfShader =0;
GLintstatus =0;
/* read shader file */
char *vSource = readShaderSource(vShaderFile);
char *fSource = readShaderSource(fShaderFile);
/* created program and shader objects */
vShader = glCreateShaderObject(GL_VERTEX_SHADER);
fShader = glCreateShaderObject(GL_FRAGMENT_SHADER);
program = glCreateProgramObject();
/* attach shaders to the program object */
glAttachObject(program,vShader);
glAttachObject(program,fShader);
/* read shaders */
glShaderSource(vShader,1,&vShaderFile,NULL);
checkError(status,"Fail to read vertex shader");
glShaderSource(fShader,1,&fShaderFile,NULL);
checkError(status,"Fail to read vertex shader");
/* compile shaders */
glCompileShader(vShader);
glCompileShader(fShader);
/* error check */
glGetObjectParameteriv(vShader,GL_OBJECT_COMPILE_STATUS,&status);
checkError(status,"Failed to compile the vertx shader");
glGetObjectParameteriv(fShader,GL_OBJECT_COMPILE_STATUS,&status);
checkError(status,"Failed to compile the fragment shader.");
/* link */
glLinkProgam(program);
glGetObjectParameteriv(program,GL_OBJECT_LINK_STATUS,&status);
checkError(status,"Failed to link the shader program object.");
/* use program object */
glUseProgramObject(program);
/* set up uniform parameter */
timeParam = glGetUniformLocation(program,"time");
}
static void draw()
{
/* send elapsed time to shaders */
glUniform1f(timeParam,gltuGet(GL_ELAPSED_TIME));
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glTranslatef(0.0f,0.0f,-10.0f);
glutSolidTeapot(2.0);
glutSwapBuffers();
}
static void reshape(int w,int h)
{
width =w;
height =h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(double)width/(double)height,nearVal,farVal);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,width,height);
glutPostRedisplay();
}
static void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 27 :
case 'Q':
case 'q':
exit(EXIT_SUCCESS);
break;
default:
break;
}
}
void main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(width,height);
glutCreateWindow("Simple GLSL example");
glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
init();
initShader("vPhong.glsl","fPassThrough.glsl");
glutMainLoop();
}
/* the following code is for the vertex and fragment shaders */
/* shader code is assumed to be in separate files */
//Vphong.glsl
//modified Phong vertex shader
uniform float time;
void main(int argc, char *argv[])
{
gl_Position = gl_ModelviewProjectionMatrix * gl_Vertex;
vec4 eyePosition =gl_ModelVewMatrix * gl_Vertex;
vec4 eyeLightPos = gl_LightSource[0].postion;
vec3 eyeNormalVec = normalize(gl_NormalMatrix * gl_Normal);
vec3 eyeLightVec = normalize(eyeLightPos.xyz-eyePosition.xyz);
vec3 eyeViewVec = -normalize(eyePosition.xyz);
vec3 eyeHalfVec = normalize(eyeLightVec+eyeViewVec);
float Kd = max(dot(eyeLightVec,eyeNormalVec),0.0);
float Ks =
pow(dot(eyeNormalVec,eyeHalfVec),gl_FrontMaterial.shininess);
float Ka = 1.0;
gl_FrontColor = Kd * gl_FrontLightProduct[0].diffuse+
Ks * gl_FrontLightProduct[0].specular+
gl_FrontLightModelProduct.sceneColor;
}
// fPassThrough.glsl
// Pass through fragment shader.
void main()
{
gl_FragColor = gl_Color;
}
[OpenGL]课后案例17:GLSL程序
最新推荐文章于 2023-02-22 19:53:46 发布