blob: b43950b63d6df56b8ea3cd0798fd254dcb3df708 [file] [log] [blame]
Brian Paul601ce1d2001-07-13 20:09:18 +00001/* $Id: osdemo.c,v 1.6 2001/07/13 20:09:18 brianp Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
4 * Demo of off-screen Mesa rendering
5 *
6 * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
7 *
8 * If you want to render BIG images you'll probably have to increase
9 * MAX_WIDTH and MAX_HEIGHT in src/config.h.
10 *
11 * This program is in the public domain.
12 *
13 * Brian Paul
14 *
15 * PPM output provided by Joerg Schmalzl.
16 * ASCII PPM output added by Brian Paul.
17 */
18
19
jtgafb833d1999-08-19 00:55:39 +000020#include <stdio.h>
21#include <stdlib.h>
22#include "GL/osmesa.h"
23#include "GL/glut.h"
24
25
Brian Paule02ffc12000-03-06 23:56:21 +000026#define SAVE_TARGA
27
jtgafb833d1999-08-19 00:55:39 +000028
29#define WIDTH 400
30#define HEIGHT 400
31
32
33
34static void render_image( void )
35{
36 GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
37 GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
38 GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
39 GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
40 GLfloat red_mat[] = { 1.0, 0.2, 0.2, 1.0 };
41 GLfloat green_mat[] = { 0.2, 1.0, 0.2, 1.0 };
42 GLfloat blue_mat[] = { 0.2, 0.2, 1.0, 1.0 };
43
44
45 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
46 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
47 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
48 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
49
50 glEnable(GL_LIGHTING);
51 glEnable(GL_LIGHT0);
52 glEnable(GL_DEPTH_TEST);
53
54 glMatrixMode(GL_PROJECTION);
55 glLoadIdentity();
56 glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
57 glMatrixMode(GL_MODELVIEW);
58
59 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
60
61 glPushMatrix();
62 glRotatef(20.0, 1.0, 0.0, 0.0);
63
64 glPushMatrix();
65 glTranslatef(-0.75, 0.5, 0.0);
66 glRotatef(90.0, 1.0, 0.0, 0.0);
67 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
68 glutSolidTorus(0.275, 0.85, 20, 20);
69 glPopMatrix();
70
71 glPushMatrix();
72 glTranslatef(-0.75, -0.5, 0.0);
73 glRotatef(270.0, 1.0, 0.0, 0.0);
74 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat );
75 glutSolidCone(1.0, 2.0, 16, 1);
76 glPopMatrix();
77
Randy Frank23ee0492000-03-28 16:59:39 +000078#ifdef GL_HP_occlusion_test
Randy Franked236aa2000-01-15 06:11:33 +000079 {
80 GLboolean bRet;
Randy Franked236aa2000-01-15 06:11:33 +000081 glDepthMask(GL_FALSE);
82 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
Randy Frank23ee0492000-03-28 16:59:39 +000083 glEnable(GL_OCCLUSION_TEST_HP);
84 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP,&bRet);
Randy Franked236aa2000-01-15 06:11:33 +000085
86 glPushMatrix();
Randy Frank23ee0492000-03-28 16:59:39 +000087 glTranslatef(0.75, 0.0, -1.0);
Randy Franked236aa2000-01-15 06:11:33 +000088 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
89 glutSolidSphere(1.0, 20, 20);
90 glPopMatrix();
91
Randy Frank23ee0492000-03-28 16:59:39 +000092 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP,&bRet);
Randy Franked236aa2000-01-15 06:11:33 +000093 printf("Occlusion test 1 (result should be 1): %d\n",bRet);
94
95 glDepthMask(GL_TRUE);
96 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
Randy Frank23ee0492000-03-28 16:59:39 +000097 glDisable(GL_OCCLUSION_TEST_HP);
Randy Franked236aa2000-01-15 06:11:33 +000098 }
99#endif
100
jtgafb833d1999-08-19 00:55:39 +0000101 glPushMatrix();
102 glTranslatef(0.75, 0.0, -1.0);
103 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
104 glutSolidSphere(1.0, 20, 20);
105 glPopMatrix();
106
Randy Frank23ee0492000-03-28 16:59:39 +0000107#ifdef GL_HP_occlusion_test
Randy Franked236aa2000-01-15 06:11:33 +0000108 {
109 GLboolean bRet;
110
Randy Franked236aa2000-01-15 06:11:33 +0000111 glDepthMask(GL_FALSE);
112 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
Randy Frank23ee0492000-03-28 16:59:39 +0000113 glEnable(GL_OCCLUSION_TEST_HP);
114 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP,&bRet);
Randy Franked236aa2000-01-15 06:11:33 +0000115
116 /* draw a sphere inside the previous sphere */
117 glPushMatrix();
Randy Frank23ee0492000-03-28 16:59:39 +0000118 glTranslatef(0.75, 0.0, -1.0);
Randy Franked236aa2000-01-15 06:11:33 +0000119 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
120 glutSolidSphere(0.5, 20, 20);
121 glPopMatrix();
122
Randy Frank23ee0492000-03-28 16:59:39 +0000123 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP,&bRet);
Randy Franked236aa2000-01-15 06:11:33 +0000124 printf("Occlusion test 2 (result should be 0): %d\n",bRet);
125
126 glDepthMask(GL_TRUE);
127 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
Randy Frank23ee0492000-03-28 16:59:39 +0000128 glDisable(GL_OCCLUSION_TEST_HP);
Randy Franked236aa2000-01-15 06:11:33 +0000129 }
130#endif
131
jtgafb833d1999-08-19 00:55:39 +0000132 glPopMatrix();
133}
134
135
136
Brian Paule02ffc12000-03-06 23:56:21 +0000137static void
138write_targa(const char *filename, const GLubyte *buffer, int width, int height)
139{
140 FILE *f = fopen( filename, "w" );
141 if (f) {
142 int i, x, y;
143 const GLubyte *ptr = buffer;
144 printf ("osdemo, writing tga file \n");
145 fputc (0x00, f); /* ID Length, 0 => No ID */
146 fputc (0x00, f); /* Color Map Type, 0 => No color map included */
147 fputc (0x02, f); /* Image Type, 2 => Uncompressed, True-color Image */
148 fputc (0x00, f); /* Next five bytes are about the color map entries */
149 fputc (0x00, f); /* 2 bytes Index, 2 bytes length, 1 byte size */
150 fputc (0x00, f);
151 fputc (0x00, f);
152 fputc (0x00, f);
153 fputc (0x00, f); /* X-origin of Image */
154 fputc (0x00, f);
155 fputc (0x00, f); /* Y-origin of Image */
156 fputc (0x00, f);
157 fputc (WIDTH & 0xff, f); /* Image Width */
158 fputc ((WIDTH>>8) & 0xff, f);
159 fputc (HEIGHT & 0xff, f); /* Image Height */
160 fputc ((HEIGHT>>8) & 0xff, f);
161 fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */
162 fputc (0x20, f); /* Image Descriptor */
163 fclose(f);
164 f = fopen( filename, "ab" ); /* reopen in binary append mode */
165 for (y=height-1; y>=0; y--) {
166 for (x=0; x<width; x++) {
167 i = (y*width + x) * 4;
168 fputc(ptr[i+2], f); /* write blue */
169 fputc(ptr[i+1], f); /* write green */
170 fputc(ptr[i], f); /* write red */
171 }
172 }
173 }
174}
175
176
177static void
178write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
179{
180 const int binary = 0;
181 FILE *f = fopen( filename, "w" );
182 if (f) {
183 int i, x, y;
184 const GLubyte *ptr = buffer;
185 if (binary) {
186 fprintf(f,"P6\n");
187 fprintf(f,"# ppm-file created by osdemo.c\n");
188 fprintf(f,"%i %i\n", width,height);
189 fprintf(f,"255\n");
190 fclose(f);
191 f = fopen( filename, "ab" ); /* reopen in binary append mode */
192 for (y=height-1; y>=0; y--) {
193 for (x=0; x<width; x++) {
194 i = (y*width + x) * 4;
195 fputc(ptr[i], f); /* write red */
196 fputc(ptr[i+1], f); /* write green */
197 fputc(ptr[i+2], f); /* write blue */
198 }
199 }
200 }
201 else {
202 /*ASCII*/
203 int counter = 0;
204 fprintf(f,"P3\n");
205 fprintf(f,"# ascii ppm file created by osdemo.c\n");
206 fprintf(f,"%i %i\n", width, height);
207 fprintf(f,"255\n");
208 for (y=height-1; y>=0; y--) {
209 for (x=0; x<width; x++) {
210 i = (y*width + x) * 4;
211 fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
212 counter++;
213 if (counter % 5 == 0)
214 fprintf(f, "\n");
215 }
216 }
217 }
218 fclose(f);
219 }
220}
221
222
223
jtgafb833d1999-08-19 00:55:39 +0000224int main( int argc, char *argv[] )
225{
Brian Paul46dbaec2000-09-08 16:42:06 +0000226 void *buffer;
227
jtgafb833d1999-08-19 00:55:39 +0000228 /* Create an RGBA-mode context */
Brian Paul46dbaec2000-09-08 16:42:06 +0000229#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
230 /* specify Z, stencil, accum sizes */
231 OSMesaContext ctx = OSMesaCreateContextExt( GL_RGBA, 16, 0, 0, NULL );
232#else
Brian Paule02ffc12000-03-06 23:56:21 +0000233 OSMesaContext ctx = OSMesaCreateContext( GL_RGBA, NULL );
Brian Paul46dbaec2000-09-08 16:42:06 +0000234#endif
235 if (!ctx) {
236 printf("OSMesaCreateContext failed!\n");
237 return 0;
238 }
jtgafb833d1999-08-19 00:55:39 +0000239
240 /* Allocate the image buffer */
Brian Paul601ce1d2001-07-13 20:09:18 +0000241 buffer = malloc( WIDTH * HEIGHT * 4 * sizeof(GLubyte) );
Brian Paul46dbaec2000-09-08 16:42:06 +0000242 if (!buffer) {
243 printf("Alloc image buffer failed!\n");
244 return 0;
245 }
jtgafb833d1999-08-19 00:55:39 +0000246
247 /* Bind the buffer to the context and make it current */
Brian Paul601ce1d2001-07-13 20:09:18 +0000248 if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT )) {
249 printf("OSMesaMakeCurrent failed!\n");
250 return 0;
251 }
252
jtgafb833d1999-08-19 00:55:39 +0000253
Brian Paul46dbaec2000-09-08 16:42:06 +0000254 {
255 int z, s, a;
256 glGetIntegerv(GL_DEPTH_BITS, &z);
257 glGetIntegerv(GL_STENCIL_BITS, &s);
258 glGetIntegerv(GL_ACCUM_RED_BITS, &a);
259 printf("%d %d %d\n", z, s, a);
260 }
261
jtgafb833d1999-08-19 00:55:39 +0000262 render_image();
263
264 if (argc>1) {
Brian Paule02ffc12000-03-06 23:56:21 +0000265#ifdef SAVE_TARGA
266 write_targa(argv[1], buffer, WIDTH, HEIGHT);
267#else
268 write_ppm(argv[1], buffer, WIDTH, HEIGHT);
jtgafb833d1999-08-19 00:55:39 +0000269#endif
jtgafb833d1999-08-19 00:55:39 +0000270 }
271 else {
Brian Paule02ffc12000-03-06 23:56:21 +0000272 printf("Specify a filename if you want to make an image file\n");
jtgafb833d1999-08-19 00:55:39 +0000273 }
274
275 printf("all done\n");
276
277 /* free the image buffer */
278 free( buffer );
279
280 /* destroy the context */
281 OSMesaDestroyContext( ctx );
282
283 return 0;
284}