/* * Test OSMesa interface at 8, 16 and 32 bits/channel. * * Usage: osdemo [options] * * Options: * -f generate image files * -g render gradient and print color values */ #include #include #include #include #include "GL/osmesa.h" #include "GL/glut.h" #define WIDTH 600 #define HEIGHT 600 static GLboolean WriteFiles = GL_FALSE; static GLboolean Gradient = GL_FALSE; /** * Draw red/green gradient across bottom of image. * Read pixels to check deltas. */ static void render_gradient(void) { GLfloat row[WIDTH][4]; int i; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, 1, -1, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_POLYGON); glColor3f(1, 0, 0); glVertex2f(-1, -1.0); glVertex2f(-1, -0.9); glColor3f(0, 1, 0); glVertex2f(1, -0.9); glVertex2f(1, -1.0); glEnd(); glFinish(); glReadPixels(0, 0, WIDTH, 1, GL_RGBA, GL_FLOAT, row); for (i = 0; i < 4; i++) { printf("row[i] = %f, %f, %f\n", row[i][0], row[i][1], row[i][2]); } } static void render_image(void) { static const GLfloat light_ambient[4] = { 0.0, 0.0, 0.0, 1.0 }; static const GLfloat light_diffuse[4] = { 1.0, 1.0, 1.0, 1.0 }; static const GLfloat light_specular[4] = { 1.0, 1.0, 1.0, 1.0 }; static const GLfloat light_position[4] = { 1.0, 1.0, 1.0, 0.0 }; static const GLfloat red_mat[4] = { 1.0, 0.2, 0.2, 1.0 }; static const GLfloat green_mat[4] = { 0.2, 1.0, 0.2, 1.0 }; static const GLfloat blue_mat[4] = { 0.2, 0.2, 1.0, 1.0 }; static const GLfloat yellow_mat[4] = { 0.8, 0.8, 0.0, 1.0 }; static const GLfloat purple_mat[4] = { 0.8, 0.4, 0.8, 0.6 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 50.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0, 0.5, -7); glClearColor(0.3, 0.3, 0.7, 0.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix(); glRotatef(20.0, 1.0, 0.0, 0.0); /* ground */ glEnable(GL_TEXTURE_2D); glBegin(GL_POLYGON); glNormal3f(0, 1, 0); glTexCoord2f(0, 0); glVertex3f(-5, -1, -5); glTexCoord2f(1, 0); glVertex3f( 5, -1, -5); glTexCoord2f(1, 1); glVertex3f( 5, -1, 5); glTexCoord2f(0, 1); glVertex3f(-5, -1, 5); glEnd(); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glPushMatrix(); glTranslatef(-1.5, 0.5, 0.0); glRotatef(90.0, 1.0, 0.0, 0.0); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat ); glutSolidTorus(0.275, 0.85, 20, 20); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, -0.5, 0.0); glRotatef(270.0, 1.0, 0.0, 0.0); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat ); glutSolidCone(1.0, 2.0, 16, 1); glPopMatrix(); glPushMatrix(); glTranslatef(0.75, 0.0, -1.0); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat ); glutSolidSphere(1.0, 20, 20); glPopMatrix(); glPushMatrix(); glTranslatef(0.75, 0.0, 1.3); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow_mat ); glutWireTeapot(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(-0.5, 0.0, 2.5); glRotatef(40, 0, 1, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, purple_mat ); glutSolidCube(1.0); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glPopMatrix(); glDisable(GL_LIGHTING); glPopMatrix(); glDisable(GL_DEPTH_TEST); } static void init_context(void) { const GLint texWidth = 64, texHeight = 64; GLubyte *texImage; int i, j; /* checker image */ texImage = malloc(texWidth * texHeight * 4); for (i = 0; i < texHeight; i++) { for (j = 0; j < texWidth; j++) { int k = (i * texWidth + j) * 4; if ((i % 5) == 0 || (j % 5) == 0) { texImage[k+0] = 200; texImage[k+1] = 200; texImage[k+2] = 200; texImage[k+3] = 255; } else { if ((i % 5) == 1 || (j % 5) == 1) { texImage[k+0] = 50; texImage[k+1] = 50; texImage[k+2] = 50; texImage[k+3] = 255; } else { texImage[k+0] = 100; texImage[k+1] = 100; texImage[k+2] = 100; texImage[k+3] = 255; } } } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); free(texImage); } static void write_ppm(const char *filename, const GLubyte *buffer, int width, int height) { const int binary = 0; FILE *f = fopen( filename, "w" ); if (f) { int i, x, y; const GLubyte *ptr = buffer; 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=0; y--) { for (x=0; x> 8; write_ppm(filename, buffer8, WIDTH, HEIGHT); free(buffer8); } else if (type == GL_FLOAT) { GLfloat *buffer32 = (GLfloat *) buffer; GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4); int i; for (i = 0; i < WIDTH * HEIGHT * 4; i++) buffer8[i] = (GLubyte) (buffer32[i] * 255.0); write_ppm(filename, buffer8, WIDTH, HEIGHT); free(buffer8); } else { write_ppm(filename, buffer, WIDTH, HEIGHT); } } OSMesaDestroyContext(ctx); return 1; } int main( int argc, char *argv[] ) { int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-f") == 0) WriteFiles = GL_TRUE; else if (strcmp(argv[i], "-g") == 0) Gradient = GL_TRUE; } test(GL_UNSIGNED_BYTE, 8, "image8.ppm"); test(GL_UNSIGNED_SHORT, 16, "image16.ppm"); test(GL_FLOAT, 32, "image32.ppm"); return 0; }