2 * Demo of off-screen Mesa rendering with 32-bit float color channels.
3 * This requires the libOSMesa32.so library.
5 * Compile with something like this:
7 * gcc osdemo32.c -I../../include -L../../lib -lglut -lGLU -lOSMesa32 -lm -o osdemo32
13 #include "GL/osmesa.h"
25 static void render_image( void )
27 GLfloat light_ambient
[] = { 0.0, 0.0, 0.0, 1.0 };
28 GLfloat light_diffuse
[] = { 1.0, 1.0, 1.0, 1.0 };
29 GLfloat light_specular
[] = { 1.0, 1.0, 1.0, 1.0 };
30 GLfloat light_position
[] = { 1.0, 1.0, 1.0, 0.0 };
31 GLfloat red_mat
[] = { 1.0, 0.2, 0.2, 1.0 };
32 GLfloat green_mat
[] = { 0.2, 1.0, 0.2, 0.5 };
33 GLfloat blue_mat
[] = { 0.2, 0.2, 1.0, 1.0 };
34 GLfloat white_mat
[] = { 1.0, 1.0, 1.0, 1.0 };
35 GLfloat purple_mat
[] = { 1.0, 0.2, 1.0, 1.0 };
36 GLUquadricObj
*qobj
= gluNewQuadric();
38 glLightfv(GL_LIGHT0
, GL_AMBIENT
, light_ambient
);
39 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, light_diffuse
);
40 glLightfv(GL_LIGHT0
, GL_SPECULAR
, light_specular
);
41 glLightfv(GL_LIGHT0
, GL_POSITION
, light_position
);
43 glEnable(GL_LIGHTING
);
45 glEnable(GL_DEPTH_TEST
);
47 glMatrixMode(GL_PROJECTION
);
49 glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
50 glMatrixMode(GL_MODELVIEW
);
52 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
55 glRotatef(20.0, 1.0, 0.0, 0.0);
59 glTranslatef(-0.75, 0.5, 0.0);
60 glRotatef(90.0, 1.0, 0.0, 0.0);
61 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, red_mat
);
62 glutSolidTorus(0.275, 0.85, 20, 20);
68 glTranslatef(0.0, -0.5, 0.0);
69 glRotatef(90, 1, 0.5, 0);
71 glDisable(GL_LIGHTING
);
72 glColor4f(1, 0, 0, 0.5);
79 glEnable(GL_LIGHTING
);
85 glTranslatef(0.0, 0.5, 0.1);
86 glDisable(GL_LIGHTING
);
94 glEnable(GL_LIGHTING
);
99 glTranslatef(0.75, 0.5, 0.3);
100 glDisable(GL_LIGHTING
);
101 glColor3f(0, 0, 0.5);
108 glEnable(GL_LIGHTING
);
112 glTranslatef(-0.75, -0.5, 0.0);
113 glRotatef(270.0, 1.0, 0.0, 0.0);
114 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, green_mat
);
115 glColor4f(0,1,0,0.5);
117 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
118 gluCylinder(qobj
, 1.0, 0.0, 2.0, 16, 1);
123 glTranslatef(0.75, 1.0, 1.0);
124 glMaterialfv( GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, blue_mat
);
125 gluSphere(qobj
, 1.0, 20, 20);
130 /* This is very important!!!
131 * Make sure buffered commands are finished!!!
135 gluDeleteQuadric(qobj
);
139 glGetIntegerv(GL_RED_BITS
, &r
);
140 glGetIntegerv(GL_GREEN_BITS
, &g
);
141 glGetIntegerv(GL_BLUE_BITS
, &b
);
142 glGetIntegerv(GL_ALPHA_BITS
, &a
);
143 printf("channel sizes: %d %d %d %d\n", r
, g
, b
, a
);
150 write_targa(const char *filename
, const GLfloat
*buffer
, int width
, int height
)
152 FILE *f
= fopen( filename
, "w" );
155 const GLfloat
*ptr
= buffer
;
156 printf ("osdemo, writing tga file \n");
157 fputc (0x00, f
); /* ID Length, 0 => No ID */
158 fputc (0x00, f
); /* Color Map Type, 0 => No color map included */
159 fputc (0x02, f
); /* Image Type, 2 => Uncompressed, True-color Image */
160 fputc (0x00, f
); /* Next five bytes are about the color map entries */
161 fputc (0x00, f
); /* 2 bytes Index, 2 bytes length, 1 byte size */
165 fputc (0x00, f
); /* X-origin of Image */
167 fputc (0x00, f
); /* Y-origin of Image */
169 fputc (WIDTH
& 0xff, f
); /* Image Width */
170 fputc ((WIDTH
>>8) & 0xff, f
);
171 fputc (HEIGHT
& 0xff, f
); /* Image Height */
172 fputc ((HEIGHT
>>8) & 0xff, f
);
173 fputc (0x18, f
); /* Pixel Depth, 0x18 => 24 Bits */
174 fputc (0x20, f
); /* Image Descriptor */
176 f
= fopen( filename
, "ab" ); /* reopen in binary append mode */
177 for (y
=height
-1; y
>=0; y
--) {
178 for (x
=0; x
<width
; x
++) {
180 i
= (y
*width
+ x
) * 4;
181 r
= (int) (ptr
[i
+0] * 255.0);
182 g
= (int) (ptr
[i
+1] * 255.0);
183 b
= (int) (ptr
[i
+2] * 255.0);
184 if (r
> 255) r
= 255;
185 if (g
> 255) g
= 255;
186 if (b
> 255) b
= 255;
187 fputc(b
, f
); /* write blue */
188 fputc(g
, f
); /* write green */
189 fputc(r
, f
); /* write red */
197 write_ppm(const char *filename
, const GLfloat
*buffer
, int width
, int height
)
199 const int binary
= 0;
200 FILE *f
= fopen( filename
, "w" );
203 const GLfloat
*ptr
= buffer
;
206 fprintf(f
,"# ppm-file created by osdemo.c\n");
207 fprintf(f
,"%i %i\n", width
,height
);
210 f
= fopen( filename
, "ab" ); /* reopen in binary append mode */
211 for (y
=height
-1; y
>=0; y
--) {
212 for (x
=0; x
<width
; x
++) {
214 i
= (y
*width
+ x
) * 4;
215 r
= (int) (ptr
[i
+0] * 255.0);
216 g
= (int) (ptr
[i
+1] * 255.0);
217 b
= (int) (ptr
[i
+2] * 255.0);
218 if (r
> 255) r
= 255;
219 if (g
> 255) g
= 255;
220 if (b
> 255) b
= 255;
221 fputc(r
, f
); /* write red */
222 fputc(g
, f
); /* write green */
223 fputc(b
, f
); /* write blue */
231 fprintf(f
,"# ascii ppm file created by osdemo.c\n");
232 fprintf(f
,"%i %i\n", width
, height
);
234 for (y
=height
-1; y
>=0; y
--) {
235 for (x
=0; x
<width
; x
++) {
237 i
= (y
*width
+ x
) * 4;
238 r
= (int) (ptr
[i
+0] * 255.0);
239 g
= (int) (ptr
[i
+1] * 255.0);
240 b
= (int) (ptr
[i
+2] * 255.0);
241 if (r
> 255) r
= 255;
242 if (g
> 255) g
= 255;
243 if (b
> 255) b
= 255;
244 fprintf(f
, " %3d %3d %3d", r
, g
, b
);
246 if (counter
% 5 == 0)
257 int main( int argc
, char *argv
[] )
261 /* Create an RGBA-mode context */
262 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
263 /* specify Z, stencil, accum sizes */
264 OSMesaContext ctx
= OSMesaCreateContextExt( GL_RGBA
, 16, 0, 0, NULL
);
266 OSMesaContext ctx
= OSMesaCreateContext( GL_RGBA
, NULL
);
269 printf("OSMesaCreateContext failed!\n");
273 /* Allocate the image buffer */
274 buffer
= (GLfloat
*) malloc( WIDTH
* HEIGHT
* 4 * sizeof(GLfloat
));
276 printf("Alloc image buffer failed!\n");
280 /* Bind the buffer to the context and make it current */
281 if (!OSMesaMakeCurrent( ctx
, buffer
, GL_FLOAT
, WIDTH
, HEIGHT
)) {
282 printf("OSMesaMakeCurrent failed!\n");
290 write_targa(argv
[1], buffer
, WIDTH
, HEIGHT
);
292 write_ppm(argv
[1], buffer
, WIDTH
, HEIGHT
);
296 printf("Specify a filename if you want to make an image file\n");
299 printf("all done\n");
301 /* free the image buffer */
304 /* destroy the context */
305 OSMesaDestroyContext( ctx
);