blob: 61f0f3da29c85ce2503e11af821978558c6a9456 [file] [log] [blame]
Brian Paulfd02ca72006-05-19 03:43:39 +00001/*
2 * Test OSMesa interface at 8, 16 and 32 bits/channel.
3 *
4 * Usage: osdemo [options]
5 *
6 * Options:
7 * -f generate image files
8 * -g render gradient and print color values
9 */
10
11#include <assert.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "GL/osmesa.h"
16#include "GL/glut.h"
17
18
19#define WIDTH 600
20#define HEIGHT 600
21
22static GLboolean WriteFiles = GL_FALSE;
23static GLboolean Gradient = GL_FALSE;
24
25
26/**
27 * Draw red/green gradient across bottom of image.
28 * Read pixels to check deltas.
29 */
30static void
31render_gradient(void)
32{
33 GLfloat row[WIDTH][4];
34 int i;
35
36 glMatrixMode(GL_PROJECTION);
37 glLoadIdentity();
38 glOrtho(-1, 1, -1, 1, -1, 1);
39 glMatrixMode(GL_MODELVIEW);
40 glLoadIdentity();
41
42 glBegin(GL_POLYGON);
43 glColor3f(1, 0, 0);
44 glVertex2f(-1, -1.0);
45 glVertex2f(-1, -0.9);
46 glColor3f(0, 1, 0);
47 glVertex2f(1, -0.9);
48 glVertex2f(1, -1.0);
49 glEnd();
50 glFinish();
51
52 glReadPixels(0, 0, WIDTH, 1, GL_RGBA, GL_FLOAT, row);
53 for (i = 0; i < 4; i++) {
54 printf("row[i] = %f, %f, %f\n", row[i][0], row[i][1], row[i][2]);
55 }
56}
57
58
59static void
60render_image(void)
61{
62 static const GLfloat light_ambient[4] = { 0.0, 0.0, 0.0, 1.0 };
63 static const GLfloat light_diffuse[4] = { 1.0, 1.0, 1.0, 1.0 };
64 static const GLfloat light_specular[4] = { 1.0, 1.0, 1.0, 1.0 };
65 static const GLfloat light_position[4] = { 1.0, 1.0, 1.0, 0.0 };
66 static const GLfloat red_mat[4] = { 1.0, 0.2, 0.2, 1.0 };
67 static const GLfloat green_mat[4] = { 0.2, 1.0, 0.2, 1.0 };
68 static const GLfloat blue_mat[4] = { 0.2, 0.2, 1.0, 1.0 };
69 static const GLfloat yellow_mat[4] = { 0.8, 0.8, 0.0, 1.0 };
70 static const GLfloat purple_mat[4] = { 0.8, 0.4, 0.8, 0.6 };
71
72 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
73 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
74 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
75 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
76
77 glEnable(GL_DEPTH_TEST);
78 glEnable(GL_LIGHT0);
79
80 glMatrixMode(GL_PROJECTION);
81 glLoadIdentity();
82 glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 50.0);
83 glMatrixMode(GL_MODELVIEW);
84 glTranslatef(0, 0.5, -7);
85
86 glClearColor(0.3, 0.3, 0.7, 0.0);
87 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
88
89 glPushMatrix();
90 glRotatef(20.0, 1.0, 0.0, 0.0);
91
92 /* ground */
93 glEnable(GL_TEXTURE_2D);
94 glBegin(GL_POLYGON);
95 glNormal3f(0, 1, 0);
96 glTexCoord2f(0, 0); glVertex3f(-5, -1, -5);
97 glTexCoord2f(1, 0); glVertex3f( 5, -1, -5);
98 glTexCoord2f(1, 1); glVertex3f( 5, -1, 5);
99 glTexCoord2f(0, 1); glVertex3f(-5, -1, 5);
100 glEnd();
101 glDisable(GL_TEXTURE_2D);
102
103 glEnable(GL_LIGHTING);
104
105 glPushMatrix();
106 glTranslatef(-1.5, 0.5, 0.0);
107 glRotatef(90.0, 1.0, 0.0, 0.0);
108 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
109 glutSolidTorus(0.275, 0.85, 20, 20);
110 glPopMatrix();
111
112 glPushMatrix();
113 glTranslatef(-1.5, -0.5, 0.0);
114 glRotatef(270.0, 1.0, 0.0, 0.0);
115 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat );
116 glutSolidCone(1.0, 2.0, 16, 1);
117 glPopMatrix();
118
119 glPushMatrix();
120 glTranslatef(0.75, 0.0, -1.0);
121 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
122 glutSolidSphere(1.0, 20, 20);
123 glPopMatrix();
124
125 glPushMatrix();
126 glTranslatef(0.75, 0.0, 1.3);
127 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow_mat );
128 glutWireTeapot(1.0);
129 glPopMatrix();
130
131 glPushMatrix();
132 glTranslatef(-0.5, 0.0, 2.5);
133 glRotatef(40, 0, 1, 0);
134 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
135 glEnable(GL_BLEND);
136 glEnable(GL_CULL_FACE);
137 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, purple_mat );
138 glutSolidCube(1.0);
139 glDisable(GL_BLEND);
140 glDisable(GL_CULL_FACE);
141 glPopMatrix();
142
143 glDisable(GL_LIGHTING);
144
145 glPopMatrix();
146
147 glDisable(GL_DEPTH_TEST);
148}
149
150
151static void
152init_context(void)
153{
154 const GLint texWidth = 64, texHeight = 64;
155 GLubyte *texImage;
156 int i, j;
157
158 /* checker image */
159 texImage = malloc(texWidth * texHeight * 4);
160 for (i = 0; i < texHeight; i++) {
161 for (j = 0; j < texWidth; j++) {
162 int k = (i * texWidth + j) * 4;
163 if ((i % 5) == 0 || (j % 5) == 0) {
164 texImage[k+0] = 200;
165 texImage[k+1] = 200;
166 texImage[k+2] = 200;
167 texImage[k+3] = 255;
168 }
169 else {
170 if ((i % 5) == 1 || (j % 5) == 1) {
171 texImage[k+0] = 50;
172 texImage[k+1] = 50;
173 texImage[k+2] = 50;
174 texImage[k+3] = 255;
175 }
176 else {
177 texImage[k+0] = 100;
178 texImage[k+1] = 100;
179 texImage[k+2] = 100;
180 texImage[k+3] = 255;
181 }
182 }
183 }
184 }
185
186 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0,
187 GL_RGBA, GL_UNSIGNED_BYTE, texImage);
188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
190
191 free(texImage);
192}
193
194
195static void
196write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
197{
198 const int binary = 0;
199 FILE *f = fopen( filename, "w" );
200 if (f) {
201 int i, x, y;
202 const GLubyte *ptr = buffer;
203 if (binary) {
204 fprintf(f,"P6\n");
205 fprintf(f,"# ppm-file created by osdemo.c\n");
206 fprintf(f,"%i %i\n", width,height);
207 fprintf(f,"255\n");
208 fclose(f);
209 f = fopen( filename, "ab" ); /* reopen in binary append mode */
210 for (y=height-1; y>=0; y--) {
211 for (x=0; x<width; x++) {
212 i = (y*width + x) * 4;
213 fputc(ptr[i], f); /* write red */
214 fputc(ptr[i+1], f); /* write green */
215 fputc(ptr[i+2], f); /* write blue */
216 }
217 }
218 }
219 else {
220 /*ASCII*/
221 int counter = 0;
222 fprintf(f,"P3\n");
223 fprintf(f,"# ascii ppm file created by osdemo.c\n");
224 fprintf(f,"%i %i\n", width, height);
225 fprintf(f,"255\n");
226 for (y=height-1; y>=0; y--) {
227 for (x=0; x<width; x++) {
228 i = (y*width + x) * 4;
229 fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
230 counter++;
231 if (counter % 5 == 0)
232 fprintf(f, "\n");
233 }
234 }
235 }
236 fclose(f);
237 }
238}
239
240
241static GLboolean
242test(GLenum type, GLint bits, const char *filename)
243{
244 const GLint z = 16, stencil = 0, accum = 0;
245 OSMesaContext ctx;
246 void *buffer;
247 GLint cBits;
248
249 assert(bits == 8 ||
250 bits == 16 ||
251 bits == 32);
252
253 assert(type == GL_UNSIGNED_BYTE ||
254 type == GL_UNSIGNED_SHORT ||
255 type == GL_FLOAT);
256
257 ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
258 if (!ctx) {
259 printf("OSMesaCreateContextExt() failed!\n");
260 return 0;
261 }
262
263 /* Allocate the image buffer */
264 buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8);
265 if (!buffer) {
266 printf("Alloc image buffer failed!\n");
267 return 0;
268 }
269
270 /* Bind the buffer to the context and make it current */
271 if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) {
272 printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
273 return 0;
274 }
275
276 /* sanity checks */
277 glGetIntegerv(GL_RED_BITS, &cBits);
278 assert(cBits == bits);
279 glGetIntegerv(GL_GREEN_BITS, &cBits);
280 assert(cBits == bits);
281 glGetIntegerv(GL_BLUE_BITS, &cBits);
282 assert(cBits == bits);
283 glGetIntegerv(GL_ALPHA_BITS, &cBits);
284 assert(cBits == bits);
285
286 printf("Rendering %d bit/channel image: %s\n", bits, filename);
287
288 init_context();
289 render_image();
290 if (Gradient)
291 render_gradient();
292
293 /* Make sure buffered commands are finished! */
294 glFinish();
295
296
297 if (WriteFiles && filename != NULL) {
298 if (type == GL_UNSIGNED_SHORT) {
299 GLushort *buffer16 = (GLushort *) buffer;
300 GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4);
301 int i;
302 for (i = 0; i < WIDTH * HEIGHT * 4; i++)
303 buffer8[i] = buffer16[i] >> 8;
304 write_ppm(filename, buffer8, WIDTH, HEIGHT);
305 free(buffer8);
306 }
307 else if (type == GL_FLOAT) {
308 GLfloat *buffer32 = (GLfloat *) buffer;
309 GLubyte *buffer8 = malloc(WIDTH * HEIGHT * 4);
310 int i;
311 for (i = 0; i < WIDTH * HEIGHT * 4; i++)
312 buffer8[i] = (GLubyte) (buffer32[i] * 255.0);
313 write_ppm(filename, buffer8, WIDTH, HEIGHT);
314 free(buffer8);
315 }
316 else {
317 write_ppm(filename, buffer, WIDTH, HEIGHT);
318 }
319 }
320
321 OSMesaDestroyContext(ctx);
322
323 return 1;
324}
325
326
327int
328main( int argc, char *argv[] )
329{
330 int i;
331
332 for (i = 1; i < argc; i++) {
333 if (strcmp(argv[i], "-f") == 0)
334 WriteFiles = GL_TRUE;
335 else if (strcmp(argv[i], "-g") == 0)
336 Gradient = GL_TRUE;
337 }
338
339 test(GL_UNSIGNED_BYTE, 8, "image8.ppm");
340 test(GL_UNSIGNED_SHORT, 16, "image16.ppm");
341 test(GL_FLOAT, 32, "image32.ppm");
342
343 return 0;
344}