/* 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); //fprintf(stderr, "vertex\n"); printShaderLog(v); //fprintf(stderr, "fragment\n"); printShaderLog(f); //fprintf(stderr, "geometry\n"); printShaderLog(g); pro = glCreateProgram(); glAttachShader(pro,v); glAttachShader(pro,f); glAttachShader(pro,g); // geometry shader details // input: GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_EXT, GL_TRIANGLES, GL_TRIANGLES_ADJACENCY_EXT // output: GL_POINTS, GL_LINE_STRIP, GL_TRIANGLE_STRIP glProgramParameteriEXT(pro,GL_GEOMETRY_INPUT_TYPE_EXT,GL_LINES); glProgramParameteriEXT(pro,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_LINE_STRIP); int temp; glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp); glProgramParameteriEXT(pro,GL_GEOMETRY_VERTICES_OUT_EXT,temp); glLinkProgram(pro); printProgramLog(pro); return(pro); } //////////////////////////////////////////////////////////////// void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt( 0.0f, 0.0f, 10.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); glLightfv(GL_LIGHT0, GL_POSITION, lpos); glUseProgram(program); glRotatef(mouseWindowX*90+90,0,1,0); // rotate the teapot glRotatef(mouseWindowY*90,0,0,1); glutWireTeapot(2.0); 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