1 /* $Id: osdemo.c,v 1.5 2000/09/08 16:42:06 brianp Exp $ */
4 * Demo of off-screen Mesa rendering
6 * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
8 * If you want to render BIG images you'll probably have to increase
9 * MAX_WIDTH and MAX_HEIGHT in src/config.h.
11 * This program is in the public domain.
15 * PPM output provided by Joerg Schmalzl.
16 * ASCII PPM output added by Brian Paul.
22 #include "GL/osmesa.h"
34 static void render_image( void )
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 };
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
);
50 glEnable(GL_LIGHTING
);
52 glEnable(GL_DEPTH_TEST
);
54 glMatrixMode(GL_PROJECTION
);
56 glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
57 glMatrixMode(GL_MODELVIEW
);
59 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
62 glRotatef(20.0, 1.0, 0.0, 0.0);
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);
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);
78 #ifdef GL_HP_occlusion_test
81 glDepthMask(GL_FALSE
);
82 glColorMask(GL_FALSE
,GL_FALSE
,GL_FALSE
,GL_FALSE
);
83 glEnable(GL_OCCLUSION_TEST_HP
);
84 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP
,&bRet
);
87 glTranslatef(0.75, 0.0, -1.0);
88 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, blue_mat
);
89 glutSolidSphere(1.0, 20, 20);
92 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP
,&bRet
);
93 printf("Occlusion test 1 (result should be 1): %d\n",bRet
);
96 glColorMask(GL_TRUE
,GL_TRUE
,GL_TRUE
,GL_TRUE
);
97 glDisable(GL_OCCLUSION_TEST_HP
);
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);
107 #ifdef GL_HP_occlusion_test
111 glDepthMask(GL_FALSE
);
112 glColorMask(GL_FALSE
,GL_FALSE
,GL_FALSE
,GL_FALSE
);
113 glEnable(GL_OCCLUSION_TEST_HP
);
114 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP
,&bRet
);
116 /* draw a sphere inside the previous sphere */
118 glTranslatef(0.75, 0.0, -1.0);
119 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, blue_mat
);
120 glutSolidSphere(0.5, 20, 20);
123 glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP
,&bRet
);
124 printf("Occlusion test 2 (result should be 0): %d\n",bRet
);
126 glDepthMask(GL_TRUE
);
127 glColorMask(GL_TRUE
,GL_TRUE
,GL_TRUE
,GL_TRUE
);
128 glDisable(GL_OCCLUSION_TEST_HP
);
138 write_targa(const char *filename
, const GLubyte
*buffer
, int width
, int height
)
140 FILE *f
= fopen( filename
, "w" );
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 */
153 fputc (0x00, f
); /* X-origin of Image */
155 fputc (0x00, f
); /* Y-origin of Image */
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 */
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 */
178 write_ppm(const char *filename
, const GLubyte
*buffer
, int width
, int height
)
180 const int binary
= 0;
181 FILE *f
= fopen( filename
, "w" );
184 const GLubyte
*ptr
= buffer
;
187 fprintf(f
,"# ppm-file created by osdemo.c\n");
188 fprintf(f
,"%i %i\n", width
,height
);
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 */
205 fprintf(f
,"# ascii ppm file created by osdemo.c\n");
206 fprintf(f
,"%i %i\n", width
, height
);
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]);
213 if (counter
% 5 == 0)
224 int main( int argc
, char *argv
[] )
228 /* Create an RGBA-mode context */
229 #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
);
233 OSMesaContext ctx
= OSMesaCreateContext( GL_RGBA
, NULL
);
236 printf("OSMesaCreateContext failed!\n");
240 /* Allocate the image buffer */
241 buffer
= malloc( WIDTH
* HEIGHT
* 4 );
243 printf("Alloc image buffer failed!\n");
247 /* Bind the buffer to the context and make it current */
248 OSMesaMakeCurrent( ctx
, buffer
, GL_UNSIGNED_BYTE
, WIDTH
, HEIGHT
);
252 glGetIntegerv(GL_DEPTH_BITS
, &z
);
253 glGetIntegerv(GL_STENCIL_BITS
, &s
);
254 glGetIntegerv(GL_ACCUM_RED_BITS
, &a
);
255 printf("%d %d %d\n", z
, s
, a
);
262 write_targa(argv
[1], buffer
, WIDTH
, HEIGHT
);
264 write_ppm(argv
[1], buffer
, WIDTH
, HEIGHT
);
268 printf("Specify a filename if you want to make an image file\n");
271 printf("all done\n");
273 /* free the image buffer */
276 /* destroy the context */
277 OSMesaDestroyContext( ctx
);