/* Simple Demo for GLSL www.lighthouse3d.com - tweaked by andy */ #include "GL/glew.h" #ifdef __linux__ #include #endif #ifdef __APPLE__ #include #endif #ifdef _WIN32 #include "glut.h" #endif #include #include #include int windowWidth = 500; int windowHeight = 500; float mouseWindowX = 0.0; float mouseWindowY = 0.0; GLuint program; float lpos[4] = {1.0, 0.5, 1.0, 0.0}; // light postion //////////////////////////////////////////////////////////////// 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; } //////////////////////////////////////////////////////////////// void changeSize(int w, int h) { if(h <= 0) // you cant make a window of zero width h = 1; float ratio = w / h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); windowWidth = w; windowHeight = h; gluPerspective(45, ratio, 1, 1000); glMatrixMode(GL_MODELVIEW); } //////////////////////////////////////////////////////////////// void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) // escape key to exit the program exit(0); } //////////////////////////////////////////////////////////////// void PassiveMouseMotion(int x, int y) { if (x < 0) mouseWindowX = -1; else if (x > windowWidth) mouseWindowX = 1; else mouseWindowX = 2 * (x / (float) windowWidth) - 1.0; if (y < 0) mouseWindowY = -1; else if (y > windowHeight) mouseWindowY = 1; else mouseWindowY = 2 * (y / (float) windowHeight) - 1.0; } //////////////////////////////////////////////////////////////// void printShaderLog(GLuint obj) { GLint infoLogLength = 0; GLsizei charsWritten = 0; GLchar *infoLog; glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0){ infoLog = (char *) malloc(infoLogLength); glGetShaderInfoLog(obj, infoLogLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } void printProgramLog(GLuint obj) { GLint infoLogLength = 0; GLsizei charsWritten = 0; GLchar *infoLog; glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0){ infoLog = (char *) malloc(infoLogLength); glGetProgramInfoLog(obj, infoLogLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } //////////////////////////////////////////////////////////////// GLuint setShaders(char * vert, char * frag, char * geom) { GLuint v,f, g, pro; char *vs, *fs, *gs; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); //g = glCreateShader(GL_GEOMETRY_SHADER_EXT); vs = textFileRead(vert); fs = textFileRead(frag); //gs = textFileRead(geom); const char * vv = vs; const char * ff = fs; const char * gg = gs; glShaderSource(v, 1, &vv, NULL); glShaderSource(f, 1, &ff, NULL); //glShaderSource(g, 1, &gg, NULL); free(vs); free(fs); //free(gs); glCompileShader(v); glCompileShader(f); //glCompileShader(g); printf("vertex:\n"); printShaderLog(v); printf("frag:\n"); printShaderLog(f); //printShaderLog(g); pro = glCreateProgram(); glAttachShader(pro,v); glAttachShader(pro,f); //glAttachShader(pro,g); // geometry shader details //glProgramParameteriEXT(pro,GL_GEOMETRY_INPUT_TYPE_EXT,???); //glProgramParameteriEXT(pro,GL_GEOMETRY_OUTPUT_TYPE_EXT,???); //int temp; //glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp); //glProgramParameteriEXT(pro,GL_GEOMETRY_VERTICES_OUT_EXT,temp); glLinkProgram(pro); printf("prog:\n"); printProgramLog(pro); return(pro); } //////////////////////////////////////////////////////////////// void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt( 0.0f, 3.0f, 6.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); glLightfv(GL_LIGHT0, GL_POSITION, lpos); glUseProgram(program); GLint loc1,loc2,loc3,loc4; float specIntensity = 0.98; float sc[4] = {0.8, 0.8, 0.8, 1.0}; float threshold[2] = {0.5, 0.25}; float colors[12] = {0.4, 0.4, 0.8, 1.0, 0.2, 0.2, 0.4, 1.0, 0.1, 0.1, 0.1, 1.0}; glColor3f(1.0, 0.0, 0.0); loc1 = glGetUniformLocation(program,"specIntensity"); glUniform1f(loc1, specIntensity); loc2 = glGetUniformLocation(program,"specColor"); glUniform4fv(loc2,1,sc); // or could have been glUniform4f(loc2,sc[0],sc[1],sc[2],sc[3]); loc3 = glGetUniformLocation(program,"t"); glUniform1fv(loc3,2,threshold); loc4 = glGetUniformLocation(program,"colors"); glUniform4fv(loc4,3,colors); glRotatef(mouseWindowX*90+90,0,1,0); // rotate the teapot glRotatef(mouseWindowY*90,0,0,1); glutSolidTeapot(1); // draw a glut teapot glutSwapBuffers(); } //////////////////////////////////////////////////////////////// int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(windowWidth, windowHeight); glutCreateWindow("GLSL"); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutReshapeFunc(changeSize); glutKeyboardFunc(processNormalKeys); glutPassiveMotionFunc(PassiveMouseMotion); glEnable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f ,0.0f ,1.0f); glewInit(); if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader && GL_EXT_geometry_shader4) printf("Ready for GLSL\n"); else { printf("Not enough GLSL support\n"); exit(1); } program = setShaders( (char *) "./toon.vert", (char *) "./toon.frag", (char *) "./toon.geom"); glutMainLoop(); return 0; } // printed with: // enscript --pretty-print --line-numbers --no-header -M Wall --landscape --color --margins=1:40:1:1 -3jr -T 3 -h -f Courier30 -o foo.ps ogl.cpp // Media: Wall 2100 4200 24 24 2050 4150 // convert foo.ps -negate -rotate 90 foo_neg.pdf