/*----------------------------- * stex3d.c GL example of the mesa 3d-texture extention to simulate procedural * texturing, it uses a perlin noise and turbulence functions. * * Author: Daniel Barrero * barrero@irit.fr * dbarrero@pegasus.uniandes.edu.co * * Converted to GLUT by brianp on 1/1/98 * Massive clean-up on 2002/10/23 by brianp * * * cc stex3d.c -o stex3d -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lm * *---------------------------- */ #include #include #include #include #include #include #include #include "GL/osmesa.h" #include #include #include "GL/gl.h" typedef int bool; #ifdef USE_OSMESA16 GLushort *buffer; #else GLfloat *buffer; #endif static GLuint fragShader; static GLuint vertShader; static GLuint program; char outputFile[255]; double startT, endT, deltaT; struct timespec startTime, endTime; bool writeFile; static float normalNoise[3]; const int true = 1; const int false = 2; int numFrames = 25; int lastFrameCnt = 0; double elapsedT = 0; double elapsedStartT = 0; int numOutputFile = 0; #define WIDTH 400 #define HEIGHT 400 static bool useShaders = 1; static GLint t0 = 0; static GLint frames = 0; #define TORUS 1 #define SPHERE 2 static float angx=0, angy=0, angz=0; static int texgen = 2, animate = 1, smooth = 1, wireframe = 0; static int CurObject = TORUS; static const char *vertShaderText = { "varying vec4 color;\n" "varying vec3 vertexPos;\n" "void main(void)\n" "{\n" " color = gl_Color;\n" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " vertexPos = vec3(gl_Vertex[0], gl_Vertex[1], gl_Vertex[2]);\n" "}\n" }; static const char *fragShaderText = { "varying vec4 color;\n" "varying vec3 vertexPos;\n" "uniform gl_FogParameters gl_Fog;\n" "void main(void)\n" "{\n" " float c = gl_Fog.density;\n" " //gl_FragColor = vec4(c, 0.0, 0.0, 1.0);\n" " gl_FragColor = gl_Fog.color;\n" " //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n" }; static void BuildTorus(void) { GLint i, j; float theta1, phi1, theta2, phi2, rings, sides; float v0[03], v1[3], v2[3], v3[3]; float t0[03], t1[3], t2[3], t3[3]; float n0[3], n1[3], n2[3], n3[3]; float innerRadius = 0.25; float outerRadius = 0.5; float scalFac; rings = 16; sides = 12; scalFac = 1 / (outerRadius * 2); glNewList(TORUS, GL_COMPILE); for (i = 0; i < rings; i++) { theta1 = (float) i *2.0 * M_PI / rings; theta2 = (float) (i + 1) * 2.0 * M_PI / rings; for (j = 0; j < sides; j++) { phi1 = (float) j *2.0 * M_PI / sides; phi2 = (float) (j + 1) * 2.0 * M_PI / sides; v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1)); v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1)); v0[2] = innerRadius * sin(phi1); v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1)); v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1)); v1[2] = innerRadius * sin(phi1); v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2)); v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2)); v2[2] = innerRadius * sin(phi2); v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2)); v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2)); v3[2] = innerRadius * sin(phi2); n0[0] = cos(theta1) * (cos(phi1)); n0[1] = -sin(theta1) * (cos(phi1)); n0[2] = sin(phi1); n1[0] = cos(theta2) * (cos(phi1)); n1[1] = -sin(theta2) * (cos(phi1)); n1[2] = sin(phi1); n2[0] = cos(theta2) * (cos(phi2)); n2[1] = -sin(theta2) * (cos(phi2)); n2[2] = sin(phi2); n3[0] = cos(theta1) * (cos(phi2)); n3[1] = -sin(theta1) * (cos(phi2)); n3[2] = sin(phi2); t0[0] = v0[0] * scalFac + 0.5; t0[1] = v0[1] * scalFac + 0.5; t0[2] = v0[2] * scalFac + 0.5; t1[0] = v1[0] * scalFac + 0.5; t1[1] = v1[1] * scalFac + 0.5; t1[2] = v1[2] * scalFac + 0.5; t2[0] = v2[0] * scalFac + 0.5; t2[1] = v2[1] * scalFac + 0.5; t2[2] = v2[2] * scalFac + 0.5; t3[0] = v3[0] * scalFac + 0.5; t3[1] = v3[1] * scalFac + 0.5; t3[2] = v3[2] * scalFac + 0.5; glBegin(GL_POLYGON); glNormal3fv(n3); glTexCoord3fv(t3); glVertex3fv(v3); glNormal3fv(n2); glTexCoord3fv(t2); glVertex3fv(v2); glNormal3fv(n1); glTexCoord3fv(t1); glVertex3fv(v1); glNormal3fv(n0); glTexCoord3fv(t0); glVertex3fv(v0); glEnd(); } } glEndList(); } static void printOsMesaHelp(void) { printf("\nUsage: stex3d_shader \n"); printf(" cmd line options:\n"); printf(" -h or -help Print this message\n"); printf(" -ns Disable shaders\n"); printf(" -f### Sets the number of frames to run, defined by ###\n"); printf("\n"); } static GLenum parseOsMesaCmdLine(int argc, char **argv) { GLint i, j; char num[5]; int count = 0; bool outputFileSet = false; for (i = 1; i < argc; i++) { if(argv[i][0] == '-') { if (strcmp(argv[i], "-help") == 0) { printOsMesaHelp(); return GL_FALSE; } else if (strstr(argv[i], "-h") != NULL) { printOsMesaHelp(); return GL_FALSE; } else if (argv[i][1] == 'f') { for(j = 2; j <= sizeof(argv[i]), j < 6; j++) { num[j-2] = argv[i][j]; count++; } num[count] = '\0'; numFrames = atoi(num); } else if (strstr(argv[i], "-ns") != NULL) { useShaders = false; } } else if (outputFileSet == false) { sprintf(outputFile, "%s", argv[i]); writeFile = true; outputFileSet == true; } else { printf("%s (Bad option).\n", argv[i]); return GL_FALSE; } } return GL_TRUE; } static void printHelp(void) { printf("\nUsage: stex3d \n"); printf(" cmd line options:\n"); printf(" -wxxx Width of the texture (Default=64)\n"); printf(" -hxxx Height of the texture (Default=64)\n"); printf(" -dxxx Depth of the texture (Default=64)\n"); printf(" Keyboard Options:\n"); printf(" up/down rotate around X\n"); printf(" left/right rotate around Y\n"); printf(" z/Z rotate around Z\n"); printf(" a toggle animation\n"); printf(" s toggle smooth shading\n"); printf(" t toggle texgen mode\n"); printf(" o toggle object: torus/sphere\n"); printf(" i toggle texture image: noise/gradient\n"); } static GLenum parseCmdLine(int argc, char **argv) { GLint i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-help") == 0) { printHelp(); return GL_FALSE; } else if (strstr(argv[i], "-ns") != NULL) { useShaders = false; } else { printf("%s (Bad option).\n", argv[i]); printHelp(); return GL_FALSE; } } return GL_TRUE; } static void drawScene(void) { static const GLfloat sPlane[4] = { 0.5, 0, 0, -.5 }; static const GLfloat tPlane[4] = { 0, 0.5, 0, -.5 }; static const GLfloat rPlane[4] = { 0, 0, 0.5, -.5 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); if (texgen == 2) { glTexGenfv(GL_S, GL_EYE_PLANE, sPlane); glTexGenfv(GL_T, GL_EYE_PLANE, tPlane); glTexGenfv(GL_R, GL_EYE_PLANE, rPlane); } glRotatef(angx, 1.0, 0.0, 0.0); glRotatef(angy, 0.0, 1.0, 0.0); glRotatef(angz, 0.0, 0.0, 1.0); if (texgen == 1) { glTexGenfv(GL_S, GL_EYE_PLANE, sPlane); glTexGenfv(GL_T, GL_EYE_PLANE, tPlane); glTexGenfv(GL_R, GL_EYE_PLANE, rPlane); } if (texgen) { glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); } else { glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); } glCallList(CurObject); glPopMatrix(); #if defined USE_OSMESA16 || defined USE_OSMESA32 glFinish(); #else glutSwapBuffers(); #endif } static void resize(int w, int h) { float ar = (float) w / (float) h; float ax = 0.6 * ar; float ay = 0.6; glViewport(0, 0, (GLint) w, (GLint) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-ax, ax, -ay, ay, 2, 20); /*glOrtho(-2, 2, -2, 2, -10, 10);*/ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -4); } static void Idle(void) { static int warningDisplayed = 2; float t = glutGet(GLUT_ELAPSED_TIME); angx = 0.01 * t; angy = 0.03 * t; angz += 0; glutPostRedisplay(); } static void SpecialKey(int k, int x, int y) { switch (k) { case GLUT_KEY_UP: angx += 5.0; break; case GLUT_KEY_DOWN: angx -= 5.0; break; case GLUT_KEY_LEFT: angy += 5.0; break; case GLUT_KEY_RIGHT: angy -= 5.0; break; default: return; } glutPostRedisplay(); } static void KeyHandler(unsigned char key, int x, int y) { static const char *mode[] = { "glTexCoord3f (no texgen)", "texgen fixed to object coords", "texgen fixed to eye coords" }; (void) x; (void) y; switch (key) { case 27: case 'q': case 'Q': /* quit game. */ exit(0); break; case 'z': angz += 10; break; case 'Z': angz -= 10; break; case 's': smooth = !smooth; if (smooth) glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); break; case 't': texgen++; if (texgen > 2) texgen = 0; printf("Texgen: %s\n", mode[texgen]); break; case 'o': if (CurObject == TORUS) CurObject = SPHERE; else CurObject = TORUS; break; case 'a': animate = !animate; if (animate) glutIdleFunc(Idle); else glutIdleFunc(NULL); break; case 'w': wireframe = !wireframe; if (wireframe) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; default: break; } glutPostRedisplay(); } static bool isGLExtensionSupported(const char *extension) { bool status = false; char *rendererString; const GLubyte* renderer; const char* extensions; const char *startOfWord; const char *endOfWord; /* set up the renderer */ renderer = (glGetString(GL_RENDERER)); if(renderer!=NULL) rendererString = (char*)renderer; else rendererString = ""; /* get the extension list from OpenGL.*/ extensions = (const char*)glGetString(GL_EXTENSIONS); if (extensions==NULL) return status; /* insert the ' ' delimiated extensions words into the extensionSet.*/ startOfWord = extensions; if((endOfWord = strstr(startOfWord, extension))!=NULL) { status = true; } return status; } static bool getInfoLog(GLuint shader, char *result) { int copyLen = 0; GLsizei bufLen = 0; /* length of buffer to allocate */ GLsizei strLen = 0; /* strlen GL actually wrote to buffer */ glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &bufLen ); if( bufLen > 1 ) { GLchar* infoLog = (GLchar *)malloc( sizeof(GLchar) * bufLen); glGetShaderInfoLog( shader, bufLen, &strLen, infoLog ); copyLen = (bufLen > 2045) ? 2045 : bufLen; if( strLen > 0 ) strncpy(result, infoLog, copyLen); free(infoLog); } return (strLen > 0); } void initShaders(void) { float _glVersion; float _glslLanguageVersion; bool _isShaderObjectsSupported; bool _isVertexShaderSupported; bool _isFragmentShaderSupported; bool _isLanguage100Supported; bool _glSupported; const char* version; char *procName; GLint status; char statusString[5]; char infoLog[2048]; GLsizei sourceLength, maxLength; char shaderSource[2056]; bool printInfoLog = false; bool continueRun = true; maxLength = 2056; version = (const char*) glGetString( GL_VERSION ); printf("version=%s\n", version); if (!version) { printf("Error: OpenGL version test failed, requires valid graphics context.\n"); exit(1); } _glVersion = atof( version ); _glslLanguageVersion = 0.0f; _isShaderObjectsSupported = isGLExtensionSupported("GL__shader_objects"); _isVertexShaderSupported = isGLExtensionSupported("GL__vertex_shader"); _isFragmentShaderSupported = isGLExtensionSupported("GL__fragment_shader"); _isLanguage100Supported = isGLExtensionSupported("GL__shading_language_100"); _glSupported = false; if((_glVersion >= 2.0f) || (_isShaderObjectsSupported && _isVertexShaderSupported && _isFragmentShaderSupported && _isLanguage100Supported)) { const char* langVerStr; /* If glGetString raises an error, assume initial release "1.00"*/ while(glGetError() != GL_NO_ERROR) {} /* reset error flag*/ langVerStr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); if( (glGetError() == GL_NO_ERROR) && langVerStr ) _glslLanguageVersion = atof( langVerStr ); else _glslLanguageVersion = 1.0f; _glSupported = true; } else { if (!_isFragmentShaderSupported) { printf ("Sorry, this demo requires GL__fragment_shader\n"); } if (!_isShaderObjectsSupported) { printf ("Sorry, this demo requires GL__shader_objects\n"); } if (!_isLanguage100Supported) { printf ("Sorry, this demo requires GL__shading_language_100\n"); } if (!_isVertexShaderSupported) { printf ("Sorry, this demo requires GL__vertex_shader\n"); } exit(0); } printf("glVersion=%3.1f, isGlslSupported=%s, glslLanguageVersion=%3.1f\n", _glVersion, (_glSupported ? "YES" : "NO"), _glslLanguageVersion); fragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource (fragShader, 1, &fragShaderText, NULL); glGetShaderSource(fragShader, maxLength, &sourceLength, (GLchar *)&shaderSource); printf("Length of currently loaded fragment shader: %d\n", sourceLength); if(sourceLength>0) printf("Source Currently loaded for fragment shader: \n%s\n", shaderSource); glCompileShader (fragShader); #if 0 glGetObjectParameteriv(fragShader, GL_OBJECT_COMPILE_STATUS_, &status); if(status == GL_FALSE) { sprintf(statusString, "NO"); if(getInfoLog(fragShader, infoLog)) { printInfoLog = true; } } else { sprintf(statusString, "YES"); } #endif printf("Fragment shader compiled: %s\n", statusString); if(printInfoLog == true) { printf("InfoLog for Fragment Shader:\n%s\n\n", infoLog); continueRun = false; } vertShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource (vertShader, 1, &vertShaderText, NULL); glGetShaderSource(vertShader, maxLength, &sourceLength, (GLchar *)&shaderSource); printf("Length of currently loaded vertex shader: %d\n", sourceLength); if(sourceLength>0) printf("Source Currently loaded for vertex shader: \n%s\n", shaderSource); glCompileShader (vertShader); #if 0 glGetObjectParameteriv(vertShader, GL_OBJECT_COMPILE_STATUS_, &status); printInfoLog = false; if(status == GL_FALSE) { sprintf(statusString, "NO"); if(getInfoLog(vertShader, infoLog)) { printInfoLog = true; } } else { sprintf(statusString, "YES"); } #endif printf("Vertex shader compiled: %s\n", statusString); if(printInfoLog == true) { printf("InfoLog for Vertex Shader:\n%s\n\n", infoLog); continueRun = false; } if(continueRun == false) exit(0); program = glCreateProgram(); glAttachShader (program, fragShader); glAttachShader (program, vertShader); glLinkProgram (program); #if 1 /*NEW*/ glGetProgramiv(program, GL_LINK_STATUS, &status); printf("Link status %d\n", status); if (!status) { GLchar log[1000]; GLsizei len; glGetProgramInfoLog(program, 1000, &len, log); fprintf(stderr, "Linker error:\n%s\n", log); } #endif glUseProgram(program); printf ("GL_RENDERER = %s\n", (const char *) glGetString (GL_RENDERER)); } static void init(void) { GLfloat fogColor[4] = {0.25, 0.5, 1.0, 1.0}; GLuint fogMode = GL_EXP; static const GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; static const GLfloat mat_shininess[] = { 25.0 }; static const GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 }; static const GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 }; static const GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 }; int max; /* see if we have OpenGL 1.2 or later, for 3D texturing */ { const char *version = (const char *) glGetString(GL_VERSION); if (strncmp(version, "1.0", 3) == 0 || strncmp(version, "1.1", 3) == 0) { printf("Sorry, OpenGL 1.2 or later is required\n"); exit(1); } } printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); /* init light */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT1, GL_POSITION, light_position); glLightfv(GL_LIGHT1, GL_AMBIENT, gray); glLightfv(GL_LIGHT1, GL_DIFFUSE, white); glLightfv(GL_LIGHT1, GL_SPECULAR, white); glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT1); glClearColor(.5, .5, .5, 0); { GLUquadricObj *q; q = gluNewQuadric(); gluQuadricTexture( q, GL_TRUE ); glNewList(SPHERE, GL_COMPILE); gluSphere( q, 0.95, 30, 15 ); glEndList(); gluDeleteQuadric(q); } BuildTorus(); /* glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA); glEnable(GL_BLEND); */ glEnable(GL_DEPTH_TEST); glColor3f(0.6, 0.7, 0.8); glEnable(GL_FOG); glFogi(GL_FOG_MODE, fogMode); glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_DENSITY, 0.5); if(useShaders == true) initShaders(); } #if defined USE_OSMESA16 || defined USE_OSMESA32 /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ static void #ifdef USE_OSMESA16 write_targa(const char *filename, const GLushort *buffer, int width, int height) #else write_targa(const char *filename, const GLfloat *buffer, int width, int height) #endif { FILE *f = fopen( filename, "w" ); if (f) { int i, x, y; #ifdef USE_OSMESA16 const GLushort *ptr = buffer; #else const GLfloat *ptr = buffer; #endif #ifdef PRINT_DEBUG_INFO printf ("osdemo, writing tga file \n"); #endif fputc (0x00, f); /* ID Length, 0 => No ID */ fputc (0x00, f); /* Color Map Type, 0 => No color map included */ fputc (0x02, f); /* Image Type, 2 => Uncompressed, True-color Image */ fputc (0x00, f); /* Next five bytes are about the color map entries */ fputc (0x00, f); /* 2 bytes Index, 2 bytes length, 1 byte size */ fputc (0x00, f); fputc (0x00, f); fputc (0x00, f); fputc (0x00, f); /* X-origin of Image */ fputc (0x00, f); fputc (0x00, f); /* Y-origin of Image */ fputc (0x00, f); fputc (WIDTH & 0xff, f); /* Image Width */ fputc ((WIDTH>>8) & 0xff, f); fputc (HEIGHT & 0xff, f); /* Image Height */ fputc ((HEIGHT>>8) & 0xff, f); fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */ fputc (0x20, f); /* Image Descriptor */ fclose(f); f = fopen( filename, "ab" ); /* reopen in binary append mode */ for (y=height-1; y>=0; y--) { for (x=0; x> 8, f); /* write blue */ fputc(ptr[i+1] >> 8, f); /* write green */ fputc(ptr[i] >> 8, f); /* write red */ #else int r, g, b; i = (y*width + x) * 4; r = (int) (ptr[i+0] * 255.0); g = (int) (ptr[i+1] * 255.0); b = (int) (ptr[i+2] * 255.0); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; fputc(b, f); /* write blue */ fputc(g, f); /* write green */ fputc(r, f); /* write red */ #endif } } fclose(f); } } static void #ifdef USE_OSMESA16 write_ppm(const char *filename, const GLushort *buffer, int width, int height) #else write_ppm(const char *filename, const GLfloat *buffer, int width, int height) #endif { const int binary = 0; FILE *f = fopen( filename, "w" ); if (f) { int i, x, y; #ifdef USE_OSMESA16 const GLushort *ptr = buffer; #else const GLfloat *ptr = buffer; #endif if (binary) { fprintf(f,"P6\n"); fprintf(f,"# ppm-file created by osdemo.c\n"); fprintf(f,"%i %i\n", width,height); fprintf(f,"255\n"); fclose(f); f = fopen( filename, "ab" ); /* reopen in binary append mode */ for (y=height-1; y>=0; y--) { for (x=0; x> 8, f); /* write red */ fputc(ptr[i+1] >> 8, f); /* write green */ fputc(ptr[i+2] >> 8, f); /* write blue */ #else int r, g, b; i = (y*width + x) * 4; r = (int) (ptr[i+0] * 255.0); g = (int) (ptr[i+1] * 255.0); b = (int) (ptr[i+2] * 255.0); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; fputc(r, f); /* write red */ fputc(g, f); /* write green */ fputc(b, f); /* write blue */ #endif } } } else { /*ASCII*/ int counter = 0; fprintf(f,"P3\n"); fprintf(f,"# ascii ppm file created by osdemo.c\n"); fprintf(f,"%i %i\n", width, height); fprintf(f,"255\n"); for (y=height-1; y>=0; y--) { for (x=0; x> 8, ptr[i+1] >> 8, ptr[i+2] >> 8); #else int r, g, b; i = (y*width + x) * 4; r = (int) (ptr[i+0] * 255.0); g = (int) (ptr[i+1] * 255.0); b = (int) (ptr[i+2] * 255.0); if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; fprintf(f, " %3d %3d %3d", r, g, b); #endif counter++; if (counter % 5 == 0) fprintf(f, "\n"); } } } fclose(f); } } void output_image() { char newFilename[255]; printf("In output\n"); /* If output files are to be saved create one for the last iteration */ if (writeFile == true) { printf("Saving file\n"); numOutputFile++; sprintf(newFilename, "%s%04d.tga", outputFile, numOutputFile); #ifdef SAVE_TARGA write_targa(newFilename, buffer, WIDTH, HEIGHT); #else write_ppm(newFilename, buffer, WIDTH, HEIGHT); #endif } } void Render(double time) { static int warningDisplayed = 2; angx = 10.0 * time; angy = 30.0 * time; angz += 0; drawScene(); output_image(); } /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ #endif int main(int argc, char **argv) { #if defined USE_OSMESA16 || defined USE_OSMESA32 OSMesaContext ctx; int frameCnt; /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 /* specify Z, stencil, accum sizes */ ctx = OSMesaCreateContextExt( GL_RGBA, 16, 0, 0, NULL ); #else ctx = OSMesaCreateContext( GL_RGBA, NULL ); #endif if (!ctx) { printf("OSMesaCreateContext failed!\n"); return 0; } /* Allocate the image buffer */ #ifdef USE_OSMESA16 buffer = (GLushort *) malloc( WIDTH * HEIGHT * 4 * sizeof(GLushort)); #else buffer = (GLfloat *) malloc( WIDTH * HEIGHT * 4 * sizeof(GLfloat)); #endif if (!buffer) { printf("Alloc image buffer failed!\n"); return 0; } /* Bind the buffer to the context and make it current */ #ifdef USE_OSMESA16 if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_SHORT, WIDTH, HEIGHT )) { #else if (!OSMesaMakeCurrent( ctx, buffer, GL_FLOAT, WIDTH, HEIGHT )) { #endif printf("OSMesaMakeCurrent failed!\n"); return 0; } writeFile = false; if (argc>1) { if(parseOsMesaCmdLine(argc, argv) == GL_FALSE) exit(0); } init(); if(writeFile == false) { printf("\nSpecify a filename if you want to generate an image file\n"); } clock_gettime(CLOCK_REALTIME, &startTime); startT = (double)startTime.tv_sec + ((double)startTime.tv_nsec * 1.0e-9); elapsedStartT = startT; printf("\nApplication will run for %d frames and then exit...\n", numFrames); for(frameCnt = 0; frameCnt < numFrames; frameCnt++) { printf("frameCnt: %d\n", frameCnt); clock_gettime(CLOCK_REALTIME, &endTime); endT = (double)endTime.tv_sec + ((double)endTime.tv_nsec * 1.0e-9); deltaT = endT - startT; elapsedT = endT - elapsedStartT; Render(elapsedT); if(deltaT > 5.0) { int frames = frameCnt - lastFrameCnt; double fps = frames / deltaT; printf("\tframes %d frames in %f seconds ==> %f FPS\n", frames, deltaT, fps); startT = endT; lastFrameCnt = frameCnt; } } printf("all done\n"); /* free the image buffer */ free( buffer ); /* destroy the context */ OSMesaDestroyContext( ctx ); #else glutInit(&argc, argv); if (parseCmdLine(argc, argv) == GL_FALSE) { exit(0); } glutInitWindowPosition(0, 0); glutInitWindowSize(400, 400); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); if (glutCreateWindow("stex3d") <= 0) { exit(0); } init(); printHelp(); glutReshapeFunc(resize); glutKeyboardFunc(KeyHandler); glutSpecialFunc(SpecialKey); glutDisplayFunc(drawScene); if (animate) glutIdleFunc(Idle); glutMainLoop(); #endif return 0; }