tweaked the animation rate
[mesa.git] / progs / demos / osdemo.c
1 /* $Id: osdemo.c,v 1.3 2000/03/06 23:56:21 brianp Exp $ */
2
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
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "GL/osmesa.h"
23 #include "GL/glut.h"
24
25
26 #define SAVE_TARGA
27
28
29 #define WIDTH 400
30 #define HEIGHT 400
31
32
33
34 static 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
78 #ifdef OSMESA_OCCLUSION_TEST_RESULT_HP
79 {
80 GLboolean bRet;
81 OSMesaGetBooleanv(OSMESA_OCCLUSION_TEST_RESULT_HP,&bRet);
82 glDepthMask(GL_FALSE);
83 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
84
85 glPushMatrix();
86 glTranslatef(0.75, 0.0, -1.0);
87 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
88 glutSolidSphere(1.0, 20, 20);
89 glPopMatrix();
90
91 OSMesaGetBooleanv(OSMESA_OCCLUSION_TEST_RESULT_HP,&bRet);
92 printf("Occlusion test 1 (result should be 1): %d\n",bRet);
93
94 glDepthMask(GL_TRUE);
95 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
96 }
97 #endif
98
99 glPushMatrix();
100 glTranslatef(0.75, 0.0, -1.0);
101 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
102 glutSolidSphere(1.0, 20, 20);
103 glPopMatrix();
104
105 #ifdef OSMESA_OCCLUSION_TEST_RESULT_HP
106 {
107 GLboolean bRet;
108
109 OSMesaGetBooleanv(OSMESA_OCCLUSION_TEST_RESULT_HP,&bRet);
110 glDepthMask(GL_FALSE);
111 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
112
113 /* draw a sphere inside the previous sphere */
114 glPushMatrix();
115 glTranslatef(0.75, 0.0, -1.0);
116 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
117 glutSolidSphere(0.5, 20, 20);
118 glPopMatrix();
119
120 OSMesaGetBooleanv(OSMESA_OCCLUSION_TEST_RESULT_HP,&bRet);
121 printf("Occlusion test 2 (result should be 0): %d\n",bRet);
122
123 glDepthMask(GL_TRUE);
124 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
125 }
126 #endif
127
128 glPopMatrix();
129 }
130
131
132
133 static void
134 write_targa(const char *filename, const GLubyte *buffer, int width, int height)
135 {
136 FILE *f = fopen( filename, "w" );
137 if (f) {
138 int i, x, y;
139 const GLubyte *ptr = buffer;
140 printf ("osdemo, writing tga file \n");
141 fputc (0x00, f); /* ID Length, 0 => No ID */
142 fputc (0x00, f); /* Color Map Type, 0 => No color map included */
143 fputc (0x02, f); /* Image Type, 2 => Uncompressed, True-color Image */
144 fputc (0x00, f); /* Next five bytes are about the color map entries */
145 fputc (0x00, f); /* 2 bytes Index, 2 bytes length, 1 byte size */
146 fputc (0x00, f);
147 fputc (0x00, f);
148 fputc (0x00, f);
149 fputc (0x00, f); /* X-origin of Image */
150 fputc (0x00, f);
151 fputc (0x00, f); /* Y-origin of Image */
152 fputc (0x00, f);
153 fputc (WIDTH & 0xff, f); /* Image Width */
154 fputc ((WIDTH>>8) & 0xff, f);
155 fputc (HEIGHT & 0xff, f); /* Image Height */
156 fputc ((HEIGHT>>8) & 0xff, f);
157 fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */
158 fputc (0x20, f); /* Image Descriptor */
159 fclose(f);
160 f = fopen( filename, "ab" ); /* reopen in binary append mode */
161 for (y=height-1; y>=0; y--) {
162 for (x=0; x<width; x++) {
163 i = (y*width + x) * 4;
164 fputc(ptr[i+2], f); /* write blue */
165 fputc(ptr[i+1], f); /* write green */
166 fputc(ptr[i], f); /* write red */
167 }
168 }
169 }
170 }
171
172
173 static void
174 write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
175 {
176 const int binary = 0;
177 FILE *f = fopen( filename, "w" );
178 if (f) {
179 int i, x, y;
180 const GLubyte *ptr = buffer;
181 if (binary) {
182 fprintf(f,"P6\n");
183 fprintf(f,"# ppm-file created by osdemo.c\n");
184 fprintf(f,"%i %i\n", width,height);
185 fprintf(f,"255\n");
186 fclose(f);
187 f = fopen( filename, "ab" ); /* reopen in binary append mode */
188 for (y=height-1; y>=0; y--) {
189 for (x=0; x<width; x++) {
190 i = (y*width + x) * 4;
191 fputc(ptr[i], f); /* write red */
192 fputc(ptr[i+1], f); /* write green */
193 fputc(ptr[i+2], f); /* write blue */
194 }
195 }
196 }
197 else {
198 /*ASCII*/
199 int counter = 0;
200 fprintf(f,"P3\n");
201 fprintf(f,"# ascii ppm file created by osdemo.c\n");
202 fprintf(f,"%i %i\n", width, height);
203 fprintf(f,"255\n");
204 for (y=height-1; y>=0; y--) {
205 for (x=0; x<width; x++) {
206 i = (y*width + x) * 4;
207 fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
208 counter++;
209 if (counter % 5 == 0)
210 fprintf(f, "\n");
211 }
212 }
213 }
214 fclose(f);
215 }
216 }
217
218
219
220 int main( int argc, char *argv[] )
221 {
222 /* Create an RGBA-mode context */
223 OSMesaContext ctx = OSMesaCreateContext( GL_RGBA, NULL );
224
225 /* Allocate the image buffer */
226 void *buffer = malloc( WIDTH * HEIGHT * 4 );
227
228 /* Bind the buffer to the context and make it current */
229 OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT );
230
231 render_image();
232
233 if (argc>1) {
234 #ifdef SAVE_TARGA
235 write_targa(argv[1], buffer, WIDTH, HEIGHT);
236 #else
237 write_ppm(argv[1], buffer, WIDTH, HEIGHT);
238 #endif
239 }
240 else {
241 printf("Specify a filename if you want to make an image file\n");
242 }
243
244 printf("all done\n");
245
246 /* free the image buffer */
247 free( buffer );
248
249 /* destroy the context */
250 OSMesaDestroyContext( ctx );
251
252 return 0;
253 }