2 * Demo of off-screen Mesa rendering
4 * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
6 * If you want to render BIG images you'll probably have to increase
7 * MAX_WIDTH and MAX_Height in src/config.h.
9 * This program is in the public domain.
13 * PPM output provided by Joerg Schmalzl.
14 * ASCII PPM output added by Brian Paul.
16 * Usage: osdemo [filename]
24 #include "GL/osmesa.h"
30 static int Width
= 400;
31 static int Height
= 400;
35 Sphere(float radius
, int slices
, int stacks
)
37 GLUquadric
*q
= gluNewQuadric();
38 gluQuadricNormals(q
, GLU_SMOOTH
);
39 gluSphere(q
, radius
, slices
, stacks
);
45 Cone(float base
, float height
, int slices
, int stacks
)
47 GLUquadric
*q
= gluNewQuadric();
48 gluQuadricDrawStyle(q
, GLU_FILL
);
49 gluQuadricNormals(q
, GLU_SMOOTH
);
50 gluCylinder(q
, base
, 0.0, height
, slices
, stacks
);
56 Torus(float innerRadius
, float outerRadius
, int sides
, int rings
)
60 GLfloat theta
, phi
, theta1
;
61 GLfloat cosTheta
, sinTheta
;
62 GLfloat cosTheta1
, sinTheta1
;
63 const GLfloat ringDelta
= 2.0 * M_PI
/ rings
;
64 const GLfloat sideDelta
= 2.0 * M_PI
/ sides
;
69 for (i
= rings
- 1; i
>= 0; i
--) {
70 theta1
= theta
+ ringDelta
;
71 cosTheta1
= cos(theta1
);
72 sinTheta1
= sin(theta1
);
73 glBegin(GL_QUAD_STRIP
);
75 for (j
= sides
; j
>= 0; j
--) {
76 GLfloat cosPhi
, sinPhi
, dist
;
81 dist
= outerRadius
+ innerRadius
* cosPhi
;
83 glNormal3f(cosTheta1
* cosPhi
, -sinTheta1
* cosPhi
, sinPhi
);
84 glVertex3f(cosTheta1
* dist
, -sinTheta1
* dist
, innerRadius
* sinPhi
);
85 glNormal3f(cosTheta
* cosPhi
, -sinTheta
* cosPhi
, sinPhi
);
86 glVertex3f(cosTheta
* dist
, -sinTheta
* dist
, innerRadius
* sinPhi
);
99 GLfloat light_ambient
[] = { 0.0, 0.0, 0.0, 1.0 };
100 GLfloat light_diffuse
[] = { 1.0, 1.0, 1.0, 1.0 };
101 GLfloat light_specular
[] = { 1.0, 1.0, 1.0, 1.0 };
102 GLfloat light_position
[] = { 1.0, 1.0, 1.0, 0.0 };
103 GLfloat red_mat
[] = { 1.0, 0.2, 0.2, 1.0 };
104 GLfloat green_mat
[] = { 0.2, 1.0, 0.2, 1.0 };
105 GLfloat blue_mat
[] = { 0.2, 0.2, 1.0, 1.0 };
108 glLightfv(GL_LIGHT0
, GL_AMBIENT
, light_ambient
);
109 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, light_diffuse
);
110 glLightfv(GL_LIGHT0
, GL_SPECULAR
, light_specular
);
111 glLightfv(GL_LIGHT0
, GL_POSITION
, light_position
);
113 glEnable(GL_LIGHTING
);
115 glEnable(GL_DEPTH_TEST
);
117 glMatrixMode(GL_PROJECTION
);
119 glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
120 glMatrixMode(GL_MODELVIEW
);
122 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
125 glRotatef(20.0, 1.0, 0.0, 0.0);
128 glTranslatef(-0.75, 0.5, 0.0);
129 glRotatef(90.0, 1.0, 0.0, 0.0);
130 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, red_mat
);
131 Torus(0.275, 0.85, 20, 20);
135 glTranslatef(-0.75, -0.5, 0.0);
136 glRotatef(270.0, 1.0, 0.0, 0.0);
137 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, green_mat
);
138 Cone(1.0, 2.0, 16, 1);
142 glTranslatef(0.75, 0.0, -1.0);
143 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, blue_mat
);
149 /* This is very important!!!
150 * Make sure buffered commands are finished!!!
159 write_targa(const char *filename
, const GLubyte
*buffer
, int width
, int height
)
161 FILE *f
= fopen( filename
, "w" );
164 const GLubyte
*ptr
= buffer
;
165 printf ("osdemo, writing tga file \n");
166 fputc (0x00, f
); /* ID Length, 0 => No ID */
167 fputc (0x00, f
); /* Color Map Type, 0 => No color map included */
168 fputc (0x02, f
); /* Image Type, 2 => Uncompressed, True-color Image */
169 fputc (0x00, f
); /* Next five bytes are about the color map entries */
170 fputc (0x00, f
); /* 2 bytes Index, 2 bytes length, 1 byte size */
174 fputc (0x00, f
); /* X-origin of Image */
176 fputc (0x00, f
); /* Y-origin of Image */
178 fputc (Width
& 0xff, f
); /* Image Width */
179 fputc ((Width
>>8) & 0xff, f
);
180 fputc (Height
& 0xff, f
); /* Image Height */
181 fputc ((Height
>>8) & 0xff, f
);
182 fputc (0x18, f
); /* Pixel Depth, 0x18 => 24 Bits */
183 fputc (0x20, f
); /* Image Descriptor */
185 f
= fopen( filename
, "ab" ); /* reopen in binary append mode */
186 for (y
=height
-1; y
>=0; y
--) {
187 for (x
=0; x
<width
; x
++) {
188 i
= (y
*width
+ x
) * 4;
189 fputc(ptr
[i
+2], f
); /* write blue */
190 fputc(ptr
[i
+1], f
); /* write green */
191 fputc(ptr
[i
], f
); /* write red */
200 write_ppm(const char *filename
, const GLubyte
*buffer
, int width
, int height
)
202 const int binary
= 0;
203 FILE *f
= fopen( filename
, "w" );
206 const GLubyte
*ptr
= buffer
;
209 fprintf(f
,"# ppm-file created by osdemo.c\n");
210 fprintf(f
,"%i %i\n", width
,height
);
213 f
= fopen( filename
, "ab" ); /* reopen in binary append mode */
214 for (y
=height
-1; y
>=0; y
--) {
215 for (x
=0; x
<width
; x
++) {
216 i
= (y
*width
+ x
) * 4;
217 fputc(ptr
[i
], f
); /* write red */
218 fputc(ptr
[i
+1], f
); /* write green */
219 fputc(ptr
[i
+2], f
); /* write blue */
227 fprintf(f
,"# ascii ppm file created by osdemo.c\n");
228 fprintf(f
,"%i %i\n", width
, height
);
230 for (y
=height
-1; y
>=0; y
--) {
231 for (x
=0; x
<width
; x
++) {
232 i
= (y
*width
+ x
) * 4;
233 fprintf(f
, " %3d %3d %3d", ptr
[i
], ptr
[i
+1], ptr
[i
+2]);
235 if (counter
% 5 == 0)
249 main(int argc
, char *argv
[])
253 char *filename
= NULL
;
256 fprintf(stderr
, "Usage:\n");
257 fprintf(stderr
, " osdemo filename [width height]\n");
263 Width
= atoi(argv
[2]);
264 Height
= atoi(argv
[3]);
267 /* Create an RGBA-mode context */
268 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
269 /* specify Z, stencil, accum sizes */
270 ctx
= OSMesaCreateContextExt( OSMESA_RGBA
, 16, 0, 0, NULL
);
272 ctx
= OSMesaCreateContext( OSMESA_RGBA
, NULL
);
275 printf("OSMesaCreateContext failed!\n");
279 /* Allocate the image buffer */
280 buffer
= malloc( Width
* Height
* 4 * sizeof(GLubyte
) );
282 printf("Alloc image buffer failed!\n");
286 /* Bind the buffer to the context and make it current */
287 if (!OSMesaMakeCurrent( ctx
, buffer
, GL_UNSIGNED_BYTE
, Width
, Height
)) {
288 printf("OSMesaMakeCurrent failed!\n");
295 glGetIntegerv(GL_DEPTH_BITS
, &z
);
296 glGetIntegerv(GL_STENCIL_BITS
, &s
);
297 glGetIntegerv(GL_ACCUM_RED_BITS
, &a
);
298 printf("Depth=%d Stencil=%d Accum=%d\n", z
, s
, a
);
303 if (filename
!= NULL
) {
305 write_targa(filename
, buffer
, Width
, Height
);
307 write_ppm(filename
, buffer
, Width
, Height
);
311 printf("Specify a filename if you want to make an image file\n");
314 printf("all done\n");
316 /* free the image buffer */
319 /* destroy the context */
320 OSMesaDestroyContext( ctx
);