1 /*
2 * This the Mesa driver for Allegro 4.0
3 * It is based on the work of Bernhard Tsirren
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #define GL_GLEXT_PROTOTYPES
9 #include "GL/gl.h"
10 #include "GL/glext.h"
11 #include "GL/amesa.h"
12 #include "raster.h"
13
14
15 typedef struct _amesa_extension_data {
16 void* proc;
17 char* name;
18 } amesa_extension_data;
19
20 amesa_extension_data amesa_extension[] = {
21 #ifdef GL_EXT_polygon_offset
22 { (void*)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
23 #endif
24 { (void*)glBlendEquationEXT, "glBlendEquationEXT" },
25 { (void*)glBlendColorEXT, "glBlendColorExt" },
26 { (void*)glVertexPointerEXT, "glVertexPointerEXT" },
27 { (void*)glNormalPointerEXT, "glNormalPointerEXT" },
28 { (void*)glColorPointerEXT, "glColorPointerEXT" },
29 { (void*)glIndexPointerEXT, "glIndexPointerEXT" },
30 { (void*)glTexCoordPointerEXT, "glTexCoordPointer" },
31 { (void*)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
32 { (void*)glGetPointervEXT, "glGetPointervEXT" },
33 { (void*)glArrayElementEXT, "glArrayElementEXT" },
34 { (void*)glDrawArraysEXT, "glDrawArrayEXT" },
35 { (void*)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
36 { (void*)glBindTextureEXT, "glBindTextureEXT" },
37 { (void*)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
38 { (void*)glGenTexturesEXT, "glGenTexturesEXT" },
39 { (void*)glIsTextureEXT, "glIsTextureEXT" },
40 { (void*)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
41 { (void*)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
42 { (void*)glTexImage3DEXT, "glTexImage3DEXT" },
43 { (void*)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
44 { (void*)glColorTableEXT, "glColorTableEXT" },
45 { (void*)glColorSubTableEXT, "glColorSubTableEXT" },
46 { (void*)glGetColorTableEXT, "glGetColorTableEXT" },
47 { (void*)glGetColorTableParameterfvEXT, "glGetColorTableParameterfvEXT" },
48 { (void*)glGetColorTableParameterivEXT, "glGetColorTableParameterivEXT" },
49 { (void*)glPointParameterfEXT, "glPointParameterfEXT" },
50 { (void*)glPointParameterfvEXT, "glPointParameterfvEXT" },
51 { (void*)glBlendFuncSeparateEXT, "glBlendFuncSeparateEXT" },
52 { (void*)glLockArraysEXT, "glLockArraysEXT" },
53 { (void*)glUnlockArraysEXT, "glUnlockArraysEXT" },
54 { NULL, '\0' }
55 };
56
57 #define AMESA_NEW_LINE (_NEW_LINE | \
58 _NEW_TEXTURE | \
59 _NEW_LIGHT | \
60 _NEW_DEPTH | \
61 _NEW_RENDERMODE | \
62 _SWRAST_NEW_RASTERMASK)
63
64 #define AMESA_NEW_TRIANGLE (_NEW_POLYGON | \
65 _NEW_TEXTURE | \
66 _NEW_LIGHT | \
67 _NEW_DEPTH | \
68 _NEW_RENDERMODE | \
69 _SWRAST_NEW_RASTERMASK)
70
71 AMesaContext AMesa = NULL; /* the current context */
72
73 /**********************************************************************/
74 /***** AMesa Public API Functions *****/
75 /**********************************************************************/
76
77 AMesaVisual GLAPIENTRY
AMesaCreateVisual(GLboolean dbFlag,GLint depth,GLint rgba,GLint depthSize,GLint stencilSize,GLint accumSizeRed,GLint accumSizeGreen,GLint accumSizeBlue,GLint accumSizeAlpha)78 AMesaCreateVisual(GLboolean dbFlag, GLint depth, GLint rgba,
79 GLint depthSize, GLint stencilSize, GLint accumSizeRed,
80 GLint accumSizeGreen, GLint accumSizeBlue, GLint accumSizeAlpha)
81 {
82 AMesaVisual visual;
83 GLbyte redBits, greenBits, blueBits, alphaBits, indexBits;
84
85 if ((!rgba) && (depthSize != 8))
86 return NULL;
87
88 visual = (AMesaVisual) malloc(sizeof(struct amesa_visual));
89 if (!visual)
90 return NULL;
91
92 switch (depth) {
93
94 case 8:
95 if (rgba) {
96 redBits = 3;
97 greenBits = 3;
98 blueBits = 2;
99 alphaBits = 0;
100 indexBits = 0;
101 }
102 else {
103 redBits = 0;
104 greenBits = 0;
105 blueBits = 0;
106 alphaBits = 0;
107 indexBits = 8;
108 }
109 break;
110
111 case 15:
112 redBits = 5;
113 greenBits = 5;
114 blueBits = 5;
115 alphaBits = 0;
116 indexBits = 0;
117 break;
118
119 case 16:
120 redBits = 5;
121 greenBits = 6;
122 blueBits = 5;
123 alphaBits = 0;
124 indexBits = 0;
125 break;
126
127 case 24:
128 redBits = 8;
129 greenBits = 8;
130 blueBits = 8;
131 alphaBits = 0;
132 indexBits = 0;
133 break;
134
135 case 32:
136 redBits = 8;
137 greenBits = 8;
138 blueBits = 8;
139 alphaBits = 8;
140 indexBits = 0;
141 break;
142
143 default:
144 free(visual);
145 return NULL;
146 }
147
148 if (depthSize)
149 depthSize = 16;
150
151 visual->DBFlag = dbFlag;
152 visual->Depth = depth;
153 visual->GLVisual = _mesa_create_visual(rgba, /* rgb mode */
154 dbFlag, /* double buffer */
155 GL_FALSE, /* stereo*/
156 redBits,
157 greenBits,
158 blueBits,
159 alphaBits,
160 indexBits,
161 depthSize,
162 stencilSize,
163 accumSizeBlue,
164 accumSizeRed,
165 accumSizeGreen,
166 alphaBits ? accumSizeAlpha : 0,
167 1);
168 if (!visual->GLVisual) {
169 free(visual);
170 return NULL;
171 }
172
173 return visual;
174 }
175
176
177
AMesaDestroyVisual(AMesaVisual visual)178 void GLAPIENTRY AMesaDestroyVisual(AMesaVisual visual)
179 {
180 _mesa_destroy_visual(visual->GLVisual);
181 free(visual);
182 }
183
184
185
AMesaCreateBuffer(AMesaVisual visual,BITMAP * bmp)186 AMesaBuffer GLAPIENTRY AMesaCreateBuffer(AMesaVisual visual, BITMAP* bmp)
187 {
188 AMesaBuffer buffer;
189
190 /* Buffer and visual must share the same color depth */
191 if (bitmap_color_depth(bmp) != visual->Depth)
192 return NULL;
193
194 buffer = (AMesaBuffer) malloc(sizeof(struct amesa_buffer));
195 if (!buffer)
196 return NULL;
197
198 buffer->FrontBuffer = bmp;
199 buffer->BackBuffer = NULL;
200 buffer->Active = NULL;
201 buffer->ReadActive = NULL;
202 buffer->DepthBuffer = NULL;
203
204 if (visual->DBFlag) {
205 buffer->BackBuffer = create_bitmap_ex(visual->Depth, bmp->w, bmp->h);
206 if (!buffer->BackBuffer) {
207 free(buffer);
208 return NULL;
209 }
210 }
211
212 if (visual->GLVisual->depthBits > 0) {
213 buffer->DepthBuffer = create_zbuffer(bmp);
214 if (!buffer->DepthBuffer) {
215 if (buffer->BackBuffer)
216 destroy_bitmap(buffer->BackBuffer);
217 free(buffer);
218 return NULL;
219 }
220 set_zbuffer(buffer->DepthBuffer);
221 }
222
223 buffer->GLBuffer = _mesa_create_framebuffer(visual->GLVisual,
224 0, /*depth buffer is handled by Allegro */
225 visual->GLVisual->stencilBits > 0, /*software stencil buffer*/
226 visual->GLVisual->accumRedBits > 0,/*software accum buffer*/
227 GL_FALSE ); /*software alpha buffer*/
228
229 if (!buffer->GLBuffer) {
230 if (buffer->BackBuffer)
231 destroy_bitmap(buffer->BackBuffer);
232 if (buffer->DepthBuffer)
233 destroy_zbuffer(buffer->DepthBuffer);
234 free(buffer);
235 return NULL;
236 }
237
238 buffer->Width = bmp->w;
239 buffer->Height = bmp->h;
240
241 return buffer;
242 }
243
244
245
AMesaDestroyBuffer(AMesaBuffer buffer)246 void GLAPIENTRY AMesaDestroyBuffer(AMesaBuffer buffer)
247 {
248 if (buffer->BackBuffer)
249 destroy_bitmap(buffer->BackBuffer);
250 if (buffer->DepthBuffer)
251 destroy_zbuffer(buffer->DepthBuffer);
252
253 _mesa_destroy_framebuffer(buffer->GLBuffer);
254 free(buffer);
255 }
256
257
258
259 /* Extend the software rasterizer with our line and triangle
260 * functions.
261 */
AMesaRegisterSwrastFunctions(GLcontext * ctx)262 static void AMesaRegisterSwrastFunctions( GLcontext *ctx )
263 {
264 SWcontext *swrast = SWRAST_CONTEXT( ctx );
265
266 swrast->choose_line = AMesaChooseLine;
267 swrast->choose_triangle = AMesaChooseTriangle;
268
269 swrast->invalidate_line |= AMESA_NEW_LINE;
270 swrast->invalidate_triangle |= AMESA_NEW_TRIANGLE;
271 }
272
273
274
AMesaCreateContext(AMesaVisual visual,AMesaContext share)275 AMesaContext GLAPIENTRY AMesaCreateContext(AMesaVisual visual, AMesaContext share)
276 {
277 AMesaContext context;
278 GLboolean direct = GL_FALSE;
279 GLcontext *ctx;
280
281 context = (AMesaContext) malloc(sizeof(struct amesa_context));
282 if (!context)
283 return NULL;
284
285 context->GLContext = _mesa_create_context(visual->GLVisual,
286 share ? share->GLContext : NULL,
287 (void*)context,
288 direct);
289 if (!context->GLContext) {
290 free(context);
291 return NULL;
292 }
293
294 context->Visual = visual;
295
296 ctx = context->GLContext;
297 _mesa_enable_sw_extensions(ctx);
298 _mesa_enable_1_3_extensions(ctx);
299
300 /* Initialize the software rasterizer and helper modules. */
301
302 _swrast_CreateContext( ctx );
303 _ac_CreateContext( ctx );
304 _tnl_CreateContext( ctx );
305 _swsetup_CreateContext( ctx );
306
307 _swsetup_Wakeup( ctx );
308 /*AMesaRegisterSwrastFunctions(ctx);*/
309
310 return context;
311 }
312
313
314
AMesaDestroyContext(AMesaContext context)315 void GLAPIENTRY AMesaDestroyContext(AMesaContext context)
316 {
317 if (context) {
318 _swsetup_DestroyContext(context->GLContext);
319 _tnl_DestroyContext(context->GLContext);
320 _ac_DestroyContext(context->GLContext);
321 _swrast_DestroyContext(context->GLContext);
322
323 _mesa_free_context_data(context->GLContext);
324 free(context);
325 }
326 }
327
328
329
330 /*
331 * Make the specified context and buffer the current one.
332 */
AMesaMakeCurrent(AMesaContext context,AMesaBuffer buffer)333 GLboolean GLAPIENTRY AMesaMakeCurrent(AMesaContext context, AMesaBuffer buffer)
334 {
335 if (context && buffer) {
336 context->Buffer = buffer;
337 buffer->Active = buffer->BackBuffer ? buffer->BackBuffer : buffer->FrontBuffer;
338 buffer->ReadActive = buffer->Active;
339 context->ClearDepth = 2 << context->Visual->GLVisual->depthBits;
340 context->zNear = 0.;
341 context->zFar = 1.;
342 context->ClearColor = 0;
343 context->ClearIndex = 0;
344 context->ColorIndex = 0;
345
346 AMesaUpdateState(context->GLContext, ~0);
347 _mesa_make_current(context->GLContext, buffer->GLBuffer);
348 if (context->GLContext->Viewport.Width == 0 ||
349 context->GLContext->Viewport.Height == 0) {
350 /* initialize viewport and scissor box to buffer size */
351 _mesa_Viewport(0, 0, buffer->Width, buffer->Height);
352 context->GLContext->Scissor.Width = buffer->Width;
353 context->GLContext->Scissor.Height = buffer->Height;
354 }
355 AMesa = context;
356 }
357 else {
358 if (context) {
359 /* Detach */
360 context->Buffer->Active = NULL;
361 context->Buffer->ReadActive = NULL;
362 context->Buffer = NULL;
363 _mesa_make_current(NULL, NULL);
364 AMesa = NULL;
365 }
366 else
367 return GL_FALSE;
368 }
369
370 return GL_TRUE;
371 }
372
373
374
AMesaSwapBuffers(AMesaBuffer buffer)375 void GLAPIENTRY AMesaSwapBuffers(AMesaBuffer buffer)
376 {
377 if (buffer->BackBuffer)
378 blit(buffer->BackBuffer, buffer->FrontBuffer,
379 0, 0, 0, 0, buffer->Width, buffer->Height);
380 }
381
382
383
AMesaGetCurrentContext(void)384 AMesaContext GLAPIENTRY AMesaGetCurrentContext (void)
385 {
386 return AMesa;
387 }
388
389
390
AMesaGetColorBuffer(AMesaBuffer buffer,GLenum mode)391 BITMAP* GLAPIENTRY AMesaGetColorBuffer(AMesaBuffer buffer, GLenum mode)
392 {
393 switch (mode) {
394 case AMESA_FRONT:
395 return buffer->FrontBuffer;
396
397 case AMESA_BACK:
398 if (buffer->BackBuffer)
399 return buffer->BackBuffer;
400 else
401 return NULL;
402
403 case AMESA_ACTIVE:
404 return buffer->Active;
405
406 default:
407 return NULL;
408 }
409 }
410
AMesaGetProcAddress(AL_CONST char * name)411 void* GLAPIENTRY AMesaGetProcAddress(AL_CONST char *name)
412 {
413 int i = 0;
414
415 while (amesa_extension[i].proc) {
416 if (ustrcmp(amesa_extension[i].name, name) == 0)
417 return amesa_extension[i].proc;
418 i++;
419 }
420
421 return NULL;
422 }
423