/* Simple Demo for GLSL www.lighthouse3d.com tweaked a bit by andy */ #include "GL/glew.h" #ifdef __linux__ #include #endif #ifdef __APPLE__ #include #endif #ifdef _WIN32 #include "glut.h" #endif #include #include #include #include char tex0Data[800000]; char tex1Data[800000]; char tex2Data[800000]; GLuint texNumOn, texNumOff, texNumBack; //////////////////////////////////////////////////////////////////////////////// char *textFileRead(char *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); } } if (content == NULL) { fprintf(stderr, "ERROR: could not load in file %s\n", fn); exit(1); } return content; } //////////////////////////////////////////////////////////////////////////////// GLuint p; float lpos[4] = {1.0, 0.5, 1.0, 0.0}; void changeSize(int w, int h) { // Prevent a divide by zero, when window is too short // (you cant make a window of zero width). if(h == 0) h = 1; float ratio = 1.0* w / h; // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the viewport to be the entire window glViewport(0, 0, w, h); // Set the correct perspective. gluPerspective(45, ratio, 1, 1000); glMatrixMode(GL_MODELVIEW); } //////////////////////////////////////////////////////////////////////////////// void printShaderLog(GLuint prog) { GLint infoLogLength = 0; GLsizei charsWritten = 0; GLchar *infoLog; glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0) { infoLog = (char *) malloc(infoLogLength); glGetShaderInfoLog(prog, infoLogLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } void printProgramLog(GLuint shad) { GLint infoLogLength = 0; GLsizei charsWritten = 0; GLchar *infoLog; glGetProgramiv(shad, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0) { infoLog = (char *) malloc(infoLogLength); glGetProgramInfoLog(shad, infoLogLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } //////////////////////////////////////////////////////////////////////////////// float rotAmount = 0; void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0.0,0.0,6.0, 0.0,0.0,-1.0, 0.0f,1.0f,0.0f); glLightfv(GL_LIGHT0, GL_POSITION, lpos); glRotatef(rotAmount,0,1,0); glUseProgram(p); // printProgramLog(p); GLint tex0Loc, tex1Loc, tex2Loc, alphaLoc; static float blender = 0.0; // note // You can't send a GL texture ID as your sampler. // A sampler should be from 0 to the max number of texture image units. // GL texture IDs are not necessarily 0 to n tex0Loc = glGetUniformLocation(p, "tex0"); glUniform1i(tex0Loc, 0); // should match GL_TEXTURE0 above tex1Loc = glGetUniformLocation(p, "tex1"); glUniform1i(tex1Loc, 1); // should match GL_TEXTURE1 above tex2Loc = glGetUniformLocation(p, "tex2"); glUniform1i(tex2Loc, 2); // should match GL_TEXTURE2 above alphaLoc = glGetUniformLocation(p, "Alpha"); glUniform1f(alphaLoc, blender); blender += 0.001; glColor3f(1.0, 1.0, 1.0); glBegin( GL_POLYGON ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -2.0f, -2.0f, 0.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 2.0f, -2.0f, 0.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 2.0f, 2.0f, 0.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -2.0f, 2.0f, 0.0f ); glEnd(); glutSwapBuffers(); } //////////////////////////////////////////////////////////////////////////////// void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) exit(0); } //////////////////////////////////////////////////////////////////////////////// GLuint setShaders(char * vert, char * frag) { GLuint v,f, pro; char *vs,*fs; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead(vert); fs = textFileRead(frag); const char * vv = vs; const char * ff = fs; glShaderSource(v, 1, &vv,NULL); glShaderSource(f, 1, &ff,NULL); free(vs);free(fs); printf("compiling vertex\n"); glCompileShader(v); printShaderLog(v); printf("compiling fragment\n"); glCompileShader(f); printShaderLog(f); pro = glCreateProgram(); glAttachShader(pro,v); glAttachShader(pro,f); glLinkProgram(pro); printf("linking program\n"); printProgramLog(pro); return(pro); } //////////////////////////////////////////////////////////////////////////////// GLuint setupTexture(char * texData) { GLuint textureNum[1]; glGenTextures(1, textureNum); glBindTexture(GL_TEXTURE_2D, textureNum[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, (const GLvoid *) texData); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return(textureNum[0]); } //////////////////////////////////////////////////////////////////////////////// void doTexStuff(char * dataPath, char * fileName, int width, int height, char * TheArray) { char fullPath[256]; FILE * imageFile; strcpy(fullPath, dataPath); strcat(fullPath, fileName); imageFile = fopen(fullPath, "r"); if (imageFile == NULL) fprintf(stderr,"Cannot find texture file in data directory"); else { fread(TheArray, sizeof(char), height*width*3, imageFile); fclose(imageFile); } } //////////////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(320,320); glutCreateWindow("GLSL demo"); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutReshapeFunc(changeSize); glutKeyboardFunc(processNormalKeys); glEnable(GL_DEPTH_TEST); glClearColor(0.0, 0.0, 0.0, 1.0); doTexStuff((char *) "./", (char *) "joes_red.raw", 512, 512, tex0Data); texNumOn = setupTexture(tex0Data); doTexStuff((char *) "./", (char *) "joes_grey.raw", 512, 512, tex1Data); texNumOff = setupTexture(tex1Data); doTexStuff((char *) "./", (char *) "environmentmap.raw", 512, 512, tex2Data); texNumBack = setupTexture(tex2Data); glewInit(); if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader) printf("Ready for GLSL\n"); else { printf("No GLSL support\n"); exit(1); } p = setShaders((char *) "./joe.vert", (char *) "./joe.frag"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texNumOn); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texNumOff); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texNumBack); glutMainLoop(); return 0; }