这是橙宝书《opengl着色语言》提供的源代码,我对其进行了修改,以便可以运行。原来的程序是不完整的,很难运行。
// shader_book.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/glext.h>
const GLint screenWeight=800,screenHeight=600;
#define printOpenGLError() printOglError(__FILE__, __LINE__)
int printOglError(char *file, int line)
{
GLenum glErr;
int retCode = 0;
glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
retCode = 1;
glErr = glGetError();
}
return retCode;
}
void printInfoLog(GLhandleARB obj)
{
int infologLength = 0;
int charsWritten = 0;
GLcharARB *infoLog;
printOpenGLError();
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
printOpenGLError();
if(infologLength > 0)
{
infoLog = (GLcharARB*)malloc(infologLength);
if(infoLog == NULL)
{
printf("ERROR: Could not allocate InfoLog buffer\n");
exit(1);
}
glGetInfoLogARB(obj,infologLength,&charsWritten,infoLog);
printf("InfoLog:\n%s\n\n",infoLog);
free(infoLog);
}
printOpenGLError();
}
int readShaderSource(GLhandleARB shader, const char *file)
{
FILE *fp;
const GLcharARB *source;
GLsizei length;
int ret;
fp = fopen(file, "r");
if (fp == NULL) {
perror(file);
return -1;
}
fseek(fp, 0L, SEEK_END);
length = ftell(fp);
source = (GLcharARB *)malloc(length);
if (source == NULL) {
fprintf(stderr, "Could not allocate read buffer.\n");
return -1;
}
fseek(fp, 0L, SEEK_SET);
ret = fread((void *)source, sizeof(GLcharARB), length, fp) != (size_t)length;
fclose(fp);
if (ret)
fprintf(stderr, "Could not read file: %s.\n", file);
else
glShaderSource(shader, 1, &source, &length);
free((void *)source);
return ret;
}
void init(void)
{
glClearColor(1.0,1.0,1.0,1.0);
}
int installBrickShaders(void)
{
GLhandleARB brickVS, brickFS, brickProg; //对象句柄
GLint vertCompiled, fragCompiled; //状态值
GLint linked;
//创建顶点着色器对象和片元着色器对象
brickVS = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
brickFS = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
//将源代码字符串加载到着色器中//F:\\vs_tmp_program\\shader_book
readShaderSource(brickVS,"verShaderFile.txt");
readShaderSource(brickFS,"fragShaderFile.txt");
//编译码块顶点着色器并打印编译器日志文件
glCompileShaderARB(brickVS);
printOpenGLError(); //检查opengl错误
glGetObjectParameterivARB(brickVS,GL_OBJECT_COMPILE_STATUS_ARB, &vertCompiled);
printInfoLog(brickVS);
//编译码块片元着色器并打印编译器日志文件
glCompileShaderARB(brickFS);
printOpenGLError(); //检查opengl错误
glGetObjectParameterivARB(brickFS,GL_OBJECT_COMPILE_STATUS_ARB, &fragCompiled);
printInfoLog(brickFS);
if(!vertCompiled || !fragCompiled)
return 0;
//创建一个程序对象并附加两个编译好的着色器
brickProg = glCreateProgramObjectARB();
glAttachObjectARB(brickProg, brickVS);
glAttachObjectARB(brickProg, brickFS);
//链接程序对象并打印信息日志
glLinkProgramARB(brickProg);
printOpenGLError(); //检查opengl错误
glGetObjectParameterivARB(brickProg, GL_OBJECT_LINK_STATUS_ARB, &linked);
printInfoLog(brickProg);
if(!linked)
return 0;
//将程序对象安装为当前状态的一部分
glUseProgramObjectARB(brickProg);
//设置初始一致变量
glUniform3fARB(glGetUniformLocation(brickProg, "BrickColor"), 1.0, 0.3, 0.2);
glUniform3fARB(glGetUniformLocation(brickProg, "MortatColor"), 0.85, 0.86, 0.84);
glUniform2fARB(glGetUniformLocation(brickProg, "BrickSize"), 0.30, 0.15);
glUniform2fARB(glGetUniformLocation(brickProg, "BrickPct"), 0.90, 0.85);
glUniform3fARB(glGetUniformLocation(brickProg, "LightPosition"), 0.0, 0.0, 4.0);
return 1;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRectf(-25.0, -25.0, 25.0, 25.0);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( screenWeight, screenHeight );
glutInitWindowPosition(100,100);
glutCreateWindow("test window");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glewInit();
init();
if(!installBrickShaders())
printf("Failed to run shader.\n");
glutMainLoop();
return 0;
}
其fragShaderFile.txt为:
void main(){
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}
其verShaderFile.txt文件内容为:
void main(){
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}
最后程序运行的结果为: