GLSL学习记录,环境:ubuntu12.04 + glut
编译命令: g++ -o 01_demo 01_demo.cpp -lGL -lGLU -lglut -lGLEW
------------------------------------------------------------- Code line -------------------------------------------------------------------shader.h
#ifndef __SHADER_H__
#define __SHADER_H__
#include <stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>
#define MYLOG(x, y...) printf("[%s][%s][%04d]: "x"\n", __FILE__, __FUNCTION__, __LINE__, ##y)
#define printOpenGLError() printOglError(__FILE__, __LINE__)
int printOglError(char *file, int line)
{
GLenum glErr;
int retCode = 0;
glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
MYLOG("glError in file %s @line %d: %s.", file, line, gluErrorString(glErr));
retCode = 1;
glErr = glGetError();
}
return retCode;
}
void printInfoLog(GLhandleARB obj)
{
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
MYLOG("%s.",infoLog);
free(infoLog);
}
}
char *stringFileRead(const char *fn)
{
MYLOG("stringFileRead file[%s]", fn);
FILE *fp;
char *content = NULL;
int count=0;
if (fn != NULL) {
fp = fopen(fn, "rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
GLhandleARB buildShader(const GLchar **code, GLenum shaderType)
{
GLhandleARB handle = glCreateShaderObjectARB(shaderType);
glShaderSourceARB(handle, 1, code, NULL);
glCompileShaderARB(handle);
printInfoLog(handle);
return handle;
}
GLhandleARB buildShaderProgram(GLhandleARB v, GLhandleARB f)
{
GLhandleARB pro = glCreateProgramObjectARB();
glAttachObjectARB(pro, v);
glAttachObjectARB(pro, f);
glLinkProgramARB(pro);
printInfoLog(pro);
return pro;
}
void setShaders(const char *vert, const char *frag, GLhandleARB &pro)
{
char *vs = NULL, *fs = NULL;
GLhandleARB v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
GLhandleARB f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
vs = stringFileRead(vert);
fs = stringFileRead(frag);
//printf("test.vert=[%s]\n", vs);
//printf("test.frag=[%s]\n", fs);
const char *vv = vs;
const char *ff = fs;
glShaderSourceARB(v, 1, &vv, NULL);
glShaderSourceARB(f, 1, &ff, NULL);
free(vs);
free(fs);
glCompileShaderARB(v);
glCompileShaderARB(f);
printInfoLog(v);
printInfoLog(f);
pro = glCreateProgramObjectARB();
glAttachObjectARB(pro, v);
glAttachObjectARB(pro, f);
glLinkProgramARB(pro);
printInfoLog(v);
printInfoLog(f);
printInfoLog(pro);
//glUseProgramObjectARB(pro);
//glUniform3fARB(glGetUniformLocationARB(pro, "LightPosition"), 100.0f, 100.0f, 100.0f);
//glUniform1iARB(glGetUniformLocationARB(pro, "tex01"), 0);
//glUniform1iARB(glGetUniformLocationARB(pro, "tex02"), 1);
}
#endif /* __SHADER_H__ */
------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.cpp
#include "shader.h"
GLfloat ambient[4] = {0.0, 0.0, 1.0, 1.0};
GLfloat lightcolor[4] = {1.0, 1.0, 1.0, 1.0};
GLfloat eyeposition[3] = {0.0, 10.0, 30.0};
GLfloat Ns = 5;
GLfloat attenuation = 0.1;
GLfloat objectSize = 15.0;
GLuint program;
GLuint vShader, fShader;
void myInit()
{
glewInit();
glClearColor(0.0 , 0.0 , 0.0 , 1.0); glEnable(GL_DEPTH_TEST);
const GLchar *vShaderSource = stringFileRead("01_demo.vert");
const GLchar *fShaderSource = stringFileRead("01_demo.frag");
vShader = buildShader(&vShaderSource, GL_VERTEX_SHADER);
fShader = buildShader(&fShaderSource, GL_FRAGMENT_SHADER);
program = buildShaderProgram(vShader, fShader);
//setShaders("01_demo.vert", "01_demo.frag", program);
}
void myReshape(int w , int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeposition[0], eyeposition[1], eyeposition[2], 0.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0 , 1.0 , 1.0);
glUseProgram(program);
glUniform3f(glGetUniformLocation(program , "lightposition"), 30.0, 30.0, 30.0);
glUniform3f(glGetUniformLocation(program , "eyeposition"), eyeposition[0], eyeposition[1], eyeposition[2]);
glUniform4f(glGetUniformLocation(program , "ambient"), ambient[0] , ambient[1] , ambient[2] , ambient[3]);
glUniform4f(glGetUniformLocation(program , "lightcolor"), lightcolor[0] , lightcolor[1] , lightcolor[2] , lightcolor[3]);
glUniform1f(glGetUniformLocation(program , "Ns"), Ns);
glUniform1f(glGetUniformLocation(program , "attenuation") , attenuation);
glutSolidTeapot(objectSize);
glutSwapBuffers();
}
int main(int argc , char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(100 , 100);
glutInitWindowSize(600 , 600);
glutCreateWindow(argv[0]);
myInit();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
glutIdleFunc(myDisplay);
glutMainLoop();
return 0;
}
------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.vert
uniform vec3 lightposition;
uniform vec3 eyeposition;
uniform vec4 ambient;
uniform vec4 lightcolor;
uniform float Ns;
uniform float attenuation;
varying vec4 color;
void main()
{
vec3 ECPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 N = normalize(gl_NormalMatrix * gl_Normal);
vec3 L = normalize(lightposition - ECPosition);
vec3 V = normalize(eyeposition - ECPosition);
vec3 H = normalize(V + L);
vec4 diffuse = lightcolor * max(dot(N , L), 0.0);
vec4 specular = lightcolor * pow(max(dot(N , H) , 0.0) , Ns) * attenuation;
color = vec4(clamp((diffuse + specular), 0.0, 1.0));
color = color + ambient;
gl_Position = ftransform();
}
------------------------------------------------------------- Code line -------------------------------------------------------------------01_demo.frag
varying vec4 color;
void main()
{
gl_FragColor = color;
}