Commit fd02ca77 authored by Brian Paul's avatar Brian Paul

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.
parent e35b9058
...@@ -14,7 +14,8 @@ OSMESA32_LIBS = -L$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS) ...@@ -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) LIB_DEP = $(LIB_DIR)/$(GL_LIB_NAME) $(LIB_DIR)/$(GLU_LIB_NAME) $(LIB_DIR)/$(GLUT_LIB_NAME)
PROGS = \ PROGS = \
osdemo osdemo \
ostest1
##### RULES ##### ##### RULES #####
...@@ -57,6 +58,10 @@ showbuffer.o: showbuffer.c showbuffer.h ...@@ -57,6 +58,10 @@ showbuffer.o: showbuffer.c showbuffer.h
osdemo: osdemo.c osdemo: osdemo.c
$(CC) -I$(INCDIR) $(CFLAGS) osdemo.c $(OSMESA_LIBS) -o $@ $(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: # another special case: need the -lOSMesa16 library:
osdemo16: osdemo16.c osdemo16: osdemo16.c
$(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@ $(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@
......
/*
* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment