diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-05-19 03:43:39 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-05-19 03:43:39 +0000 |
commit | fd02ca7711b57b903f33654aabe5c0aaa52f641d (patch) | |
tree | 4f2c90f7398684a415eda9fc4d237ef27e6d2f73 | |
parent | e35b9058ce5b0cacfa962c05e038292ed1136fc9 (diff) |
Demonstrate rendering 8, 16 and 32-bit/channel images all in one program.
Like older osdemo.c program, but test more OpenGL features like texturing,
blending, lines.
-rw-r--r-- | progs/osdemos/Makefile | 7 | ||||
-rw-r--r-- | progs/osdemos/ostest1.c | 344 |
2 files changed, 350 insertions, 1 deletions
diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile index 03ab78ac08..7d1bc08a4e 100644 --- a/progs/osdemos/Makefile +++ b/progs/osdemos/Makefile @@ -14,7 +14,8 @@ OSMESA32_LIBS = -L$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS) LIB_DEP = $(LIB_DIR)/$(GL_LIB_NAME) $(LIB_DIR)/$(GLU_LIB_NAME) $(LIB_DIR)/$(GLUT_LIB_NAME) PROGS = \ - osdemo + osdemo \ + ostest1 ##### RULES ##### @@ -57,6 +58,10 @@ showbuffer.o: showbuffer.c showbuffer.h osdemo: osdemo.c $(CC) -I$(INCDIR) $(CFLAGS) osdemo.c $(OSMESA_LIBS) -o $@ +# special case: need the -lOSMesa library: +ostest1: ostest1.c + $(CC) -I$(INCDIR) $(CFLAGS) ostest1.c $(OSMESA_LIBS) -o $@ + # another special case: need the -lOSMesa16 library: osdemo16: osdemo16.c $(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@ diff --git a/progs/osdemos/ostest1.c b/progs/osdemos/ostest1.c new file mode 100644 index 0000000000..61f0f3da29 --- /dev/null +++ b/progs/osdemos/ostest1.c @@ -0,0 +1,344 @@ +/* + * 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 <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#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<width; x++) { + i = (y*width + x) * 4; + fputc(ptr[i], f); /* write red */ + fputc(ptr[i+1], f); /* write green */ + fputc(ptr[i+2], f); /* write blue */ + } + } + } + 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<width; x++) { + i = (y*width + x) * 4; + fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]); + counter++; + if (counter % 5 == 0) + fprintf(f, "\n"); + } + } + } + fclose(f); + } +} + + +static GLboolean +test(GLenum type, GLint bits, const char *filename) +{ + const GLint z = 16, stencil = 0, accum = 0; + OSMesaContext ctx; + void *buffer; + GLint cBits; + + assert(bits == 8 || + bits == 16 || + bits == 32); + + assert(type == GL_UNSIGNED_BYTE || + type == GL_UNSIGNED_SHORT || + type == GL_FLOAT); + + ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL ); + if (!ctx) { + printf("OSMesaCreateContextExt() failed!\n"); + return 0; + } + + /* Allocate the image buffer */ + buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8); + if (!buffer) { + printf("Alloc image buffer failed!\n"); + return 0; + } + + /* Bind the buffer to the context and make it current */ + if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) { + printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits); + return 0; + } + + /* sanity checks */ + glGetIntegerv(GL_RED_BITS, &cBits); + assert(cBits == bits); + glGetIntegerv(GL_GREEN_BITS, &cBits); + assert(cBits == bits); + glGetIntegerv(GL_BLUE_BITS, &cBits); + assert(cBits == bits); + glGetIntegerv(GL_ALPHA_BITS, &cBits); + assert(cBits == bits); + + printf("Rendering %d bit/channel image: %s\n", bits, filename); + + init_context(); + render_image(); + if (Gradient) + render_gradient(); + + /* Make sure buffered commands are finished! */ + glFinish(); + + + if (WriteFiles && filename != NULL) { + if (type == GL_UNSIGNED_SHORT) { + GLushort *buffer16 = (GLushort *) buffer; + GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4); + int i; + for (i = 0; i < WIDTH * HEIGHT * 4; i++) + buffer8[i] = buffer16[i] >> 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; +} |