1 | /* $Id: ddsample.c,v 1.2 2000-03-01 18:49:26 jeroen Exp $ */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Mesa 3-D graphics library
|
---|
5 | * Version: 3.1
|
---|
6 | *
|
---|
7 | * Copyright (C) 1999 Brian Paul All Rights Reserved.
|
---|
8 | *
|
---|
9 | * Permission is hereby granted, free of charge, to any person obtaining a
|
---|
10 | * copy of this software and associated documentation files (the "Software"),
|
---|
11 | * to deal in the Software without restriction, including without limitation
|
---|
12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
---|
13 | * and/or sell copies of the Software, and to permit persons to whom the
|
---|
14 | * Software is furnished to do so, subject to the following conditions:
|
---|
15 | *
|
---|
16 | * The above copyright notice and this permission notice shall be included
|
---|
17 | * in all copies or substantial portions of the Software.
|
---|
18 | *
|
---|
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
20 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
22 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
---|
23 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
---|
24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
25 | */
|
---|
26 |
|
---|
27 |
|
---|
28 |
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 | /*
|
---|
33 | * This is a sample template for writing new Mesa device drivers.
|
---|
34 | * You'll have to rewrite much of the code below.
|
---|
35 | *
|
---|
36 | * Let's say you're interfacing Mesa to a window/operating system
|
---|
37 | * called FOO. Replace all occurances of FOOMesa with the real name
|
---|
38 | * you select for your interface (i.e. XMesa, WMesa, AmigaMesa).
|
---|
39 | *
|
---|
40 | * You'll have to design an API for clients to use, defined in a
|
---|
41 | * header called Mesa/include/GL/FooMesa.h Use the sample as an
|
---|
42 | * example. The API should at least have functions for creating
|
---|
43 | * rendering contexts, binding rendering contexts to windows/frame
|
---|
44 | * buffers, etc.
|
---|
45 | *
|
---|
46 | * Next, you'll have to write implementations for the device driver
|
---|
47 | * functions described in dd.h
|
---|
48 | *
|
---|
49 | * Note that you'll usually have to flip Y coordinates since Mesa's
|
---|
50 | * window coordinates start at the bottom and increase upward. Most
|
---|
51 | * window system's Y-axis increases downward
|
---|
52 | *
|
---|
53 | * Functions marked OPTIONAL may be completely omitted by your driver.
|
---|
54 | *
|
---|
55 | * Your Makefile should compile this module along with the rest of
|
---|
56 | * the core Mesa library.
|
---|
57 | */
|
---|
58 |
|
---|
59 | #ifndef XFree86Server
|
---|
60 | #include <stdlib.h>
|
---|
61 | #else
|
---|
62 | #include "GL/xf86glx.h"
|
---|
63 | #endif
|
---|
64 | #include "GL/FooMesa.h"
|
---|
65 | #include "types.h"
|
---|
66 | #include "context.h"
|
---|
67 | #include "matrix.h"
|
---|
68 | #include "vb.h"
|
---|
69 |
|
---|
70 |
|
---|
71 |
|
---|
72 | /*
|
---|
73 | * In C++ terms, this class derives from the GLvisual class.
|
---|
74 | * Add system-specific fields to it.
|
---|
75 | */
|
---|
76 | struct foo_mesa_visual {
|
---|
77 | GLvisual *gl_visual;
|
---|
78 | GLboolean db_flag; /* double buffered? */
|
---|
79 | GLboolean rgb_flag; /* RGB mode? */
|
---|
80 | GLuint depth; /* bits per pixel (1, 8, 24, etc) */
|
---|
81 | };
|
---|
82 |
|
---|
83 |
|
---|
84 | /*
|
---|
85 | * In C++ terms, this class derives from the GLframebuffer class.
|
---|
86 | * Add system-specific fields to it.
|
---|
87 | */
|
---|
88 | struct foo_mesa_buffer {
|
---|
89 | GLframebuffer *gl_buffer; /* The depth, stencil, accum, etc buffers */
|
---|
90 | void *the_window; /* your window handle, etc */
|
---|
91 | int Width, Height;
|
---|
92 | };
|
---|
93 |
|
---|
94 |
|
---|
95 |
|
---|
96 | /*
|
---|
97 | * In C++ terms, this class derives from the GLcontext class.
|
---|
98 | * Add system-specific fields to it.
|
---|
99 | */
|
---|
100 | struct foo_mesa_context {
|
---|
101 | GLcontext *gl_ctx; /* the core library context */
|
---|
102 | FooMesaVisual visual;
|
---|
103 | FooMesaBuffer Buffer;
|
---|
104 | GLuint ClearIndex;
|
---|
105 | GLubyte ClearColor[4];
|
---|
106 | GLuint CurrentIndex;
|
---|
107 | GLubyte CurrentColor[4];
|
---|
108 | /* etc... */
|
---|
109 | };
|
---|
110 |
|
---|
111 |
|
---|
112 | static FooMesaContext CurrentContext = 0;
|
---|
113 | static FooMesaBuffer CurrentBuffer = 0;
|
---|
114 |
|
---|
115 |
|
---|
116 |
|
---|
117 | static void setup_DD_pointers( GLcontext *ctx );
|
---|
118 |
|
---|
119 |
|
---|
120 | /**********************************************************************/
|
---|
121 | /***** Miscellaneous device driver funcs *****/
|
---|
122 | /**********************************************************************/
|
---|
123 |
|
---|
124 |
|
---|
125 | static void finish( GLcontext *ctx )
|
---|
126 | {
|
---|
127 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
128 | /* OPTIONAL FUNCTION: implements glFinish if possible */
|
---|
129 | }
|
---|
130 |
|
---|
131 |
|
---|
132 |
|
---|
133 | static void flush( GLcontext *ctx )
|
---|
134 | {
|
---|
135 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
136 | /* OPTIONAL FUNCTION: implements glFlush if possible */
|
---|
137 | }
|
---|
138 |
|
---|
139 |
|
---|
140 |
|
---|
141 | static void clear_index( GLcontext *ctx, GLuint index )
|
---|
142 | {
|
---|
143 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
144 | foo->ClearIndex = index;
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 |
|
---|
149 | static void clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
---|
150 | {
|
---|
151 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
152 | foo->ClearColor[0] = r;
|
---|
153 | foo->ClearColor[1] = g;
|
---|
154 | foo->ClearColor[2] = b;
|
---|
155 | foo->ClearColor[3] = a;
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 |
|
---|
160 | static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
|
---|
161 | GLint x, GLint y, GLint width, GLint height )
|
---|
162 | {
|
---|
163 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
164 | /*
|
---|
165 | * Clear the specified region of the buffers indicated by 'mask'
|
---|
166 | * using the clear color or index as specified by one of the two
|
---|
167 | * functions above.
|
---|
168 | * If all==GL_TRUE, clear whole buffer, else just clear region defined
|
---|
169 | * by x,y,width,height
|
---|
170 | */
|
---|
171 |
|
---|
172 | return mask; /* return mask of buffers remaining to be cleared */
|
---|
173 | }
|
---|
174 |
|
---|
175 |
|
---|
176 |
|
---|
177 | static void set_index( GLcontext *ctx, GLuint index )
|
---|
178 | {
|
---|
179 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
180 | foo->CurrentIndex = index;
|
---|
181 | }
|
---|
182 |
|
---|
183 |
|
---|
184 |
|
---|
185 | static void set_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
|
---|
186 | {
|
---|
187 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
188 | foo->CurrentColor[0] = r;
|
---|
189 | foo->CurrentColor[1] = g;
|
---|
190 | foo->CurrentColor[2] = b;
|
---|
191 | foo->CurrentColor[3] = a;
|
---|
192 | }
|
---|
193 |
|
---|
194 |
|
---|
195 |
|
---|
196 | /*
|
---|
197 | * OPTIONAL FUNCTION: implement glIndexMask if possible, else
|
---|
198 | * return GL_FALSE
|
---|
199 | */
|
---|
200 | static GLboolean index_mask( GLcontext *ctx, GLuint mask )
|
---|
201 | {
|
---|
202 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
203 | return GL_FALSE;
|
---|
204 | }
|
---|
205 |
|
---|
206 |
|
---|
207 |
|
---|
208 | /*
|
---|
209 | * OPTIONAL FUNCTION: implement glColorMask if possible, else
|
---|
210 | * return GL_FALSE
|
---|
211 | */
|
---|
212 | static GLboolean color_mask( GLcontext *ctx,
|
---|
213 | GLboolean rmask, GLboolean gmask,
|
---|
214 | GLboolean bmask, GLboolean amask)
|
---|
215 | {
|
---|
216 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
217 | return GL_FALSE;
|
---|
218 | }
|
---|
219 |
|
---|
220 |
|
---|
221 |
|
---|
222 | /*
|
---|
223 | * OPTIONAL FUNCTION:
|
---|
224 | * Implements glLogicOp if possible. Return GL_TRUE if the device driver
|
---|
225 | * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
|
---|
226 | * is returned, the logic op will be done in software by Mesa.
|
---|
227 | */
|
---|
228 | static GLboolean logicop( GLcontext *ctx, GLenum op )
|
---|
229 | {
|
---|
230 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
231 | return GL_FALSE;
|
---|
232 | }
|
---|
233 |
|
---|
234 |
|
---|
235 |
|
---|
236 | /*
|
---|
237 | * OPTIONAL FUNCTION: enable/disable dithering if applicable
|
---|
238 | */
|
---|
239 | static void dither( GLcontext *ctx, GLboolean enable )
|
---|
240 | {
|
---|
241 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
242 | }
|
---|
243 |
|
---|
244 |
|
---|
245 |
|
---|
246 | /*
|
---|
247 | * Set the current drawing/reading buffer, return GL_TRUE or GL_FALSE
|
---|
248 | * for success/failure.
|
---|
249 | */
|
---|
250 | static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
|
---|
251 | {
|
---|
252 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
253 | setup_DD_pointers( ctx );
|
---|
254 | return GL_TRUE;
|
---|
255 | }
|
---|
256 |
|
---|
257 |
|
---|
258 |
|
---|
259 | /*
|
---|
260 | * Return the width and height of the current buffer.
|
---|
261 | * If anything special has to been done when the buffer/window is
|
---|
262 | * resized, do it now.
|
---|
263 | */
|
---|
264 | static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
|
---|
265 | {
|
---|
266 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
267 |
|
---|
268 | *width = foo->Buffer->Width = 12345; /* XXX fix these */
|
---|
269 | *height = foo->Buffer->Height = 12345;
|
---|
270 |
|
---|
271 | }
|
---|
272 |
|
---|
273 |
|
---|
274 |
|
---|
275 | /**********************************************************************/
|
---|
276 | /***** Dummy functions *****/
|
---|
277 | /**********************************************************************/
|
---|
278 |
|
---|
279 | static void WriteCIPixel( GLint x, GLint y, GLuint index )
|
---|
280 | {
|
---|
281 | }
|
---|
282 |
|
---|
283 | static void WriteRGBAPixel( GLint x, GLint y, const GLubyte color[4] )
|
---|
284 | {
|
---|
285 | }
|
---|
286 |
|
---|
287 | static void WriteRGBPixel( GLint x, GLint y, const GLubyte color[3] )
|
---|
288 | {
|
---|
289 | }
|
---|
290 |
|
---|
291 | static GLuint ReadCIPixel( GLint x, GLint y )
|
---|
292 | {
|
---|
293 | return 0;
|
---|
294 | }
|
---|
295 |
|
---|
296 | static void ReadRGBAPixel( GLint x, GLint y, GLubyte color[4] )
|
---|
297 | {
|
---|
298 | }
|
---|
299 |
|
---|
300 | #define FLIP(y) foo->Buffer->Height - (y) - 1;
|
---|
301 |
|
---|
302 |
|
---|
303 | /**********************************************************************/
|
---|
304 | /***** Accelerated point, line, triangle rendering *****/
|
---|
305 | /**********************************************************************/
|
---|
306 |
|
---|
307 |
|
---|
308 | /* There may several functions like this, for different screen modes, etc */
|
---|
309 | static void fast_points_function( GLcontext *ctx, GLuint first, GLuint last )
|
---|
310 | {
|
---|
311 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
312 | struct vertex_buffer *VB = ctx->VB;
|
---|
313 | GLint i;
|
---|
314 |
|
---|
315 | for (i=first;i<=last;i++) {
|
---|
316 | if (VB->ClipMask[i]==0) {
|
---|
317 | int x, y;
|
---|
318 | x = (GLint) VB->Win[i][0];
|
---|
319 | y = FLIP( (GLint) VB->Win[i][1] );
|
---|
320 | WriteRGBAPixel( x, y, VB->ColorPtr->data[i] );
|
---|
321 | }
|
---|
322 | }
|
---|
323 | }
|
---|
324 |
|
---|
325 |
|
---|
326 |
|
---|
327 |
|
---|
328 | /* There may several functions like this, for different screen modes, etc */
|
---|
329 | static void fast_line_function( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
|
---|
330 | {
|
---|
331 | /* Render a line by some hardware/OS accerated method */
|
---|
332 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
333 | struct vertex_buffer *VB = ctx->VB;
|
---|
334 | int x0, y0, x1, y1;
|
---|
335 | GLubyte *pixel;
|
---|
336 |
|
---|
337 | pixel = VB->ColorPtr->data[pv];
|
---|
338 |
|
---|
339 | x0 = (int) VB->Win[v0][0];
|
---|
340 | y0 = FLIP( (int) VB->Win[v0][1] );
|
---|
341 | x1 = (int) VB->Win[v1][0];
|
---|
342 | y1 = FLIP( (int) VB->Win[v1][1] );
|
---|
343 |
|
---|
344 | /* Draw line from (x0,y0) to (x1,y1) with current pixel color/index */
|
---|
345 | }
|
---|
346 |
|
---|
347 |
|
---|
348 |
|
---|
349 |
|
---|
350 | /* There may several functions like this, for different screen modes, etc */
|
---|
351 | static void fast_triangle_function( GLcontext *ctx, GLuint v0,
|
---|
352 | GLuint v1, GLuint v2, GLuint pv )
|
---|
353 | {
|
---|
354 | /* Render a triangle by some hardware/OS accerated method */
|
---|
355 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
356 | struct vertex_buffer *VB = ctx->VB;
|
---|
357 | GLubyte *pixel;
|
---|
358 |
|
---|
359 | pixel = VB->ColorPtr->data[pv];
|
---|
360 |
|
---|
361 | /* Draw triangle with current pixel color/index */
|
---|
362 | }
|
---|
363 |
|
---|
364 |
|
---|
365 |
|
---|
366 | /**********************************************************************/
|
---|
367 | /***** Write spans of pixels *****/
|
---|
368 | /**********************************************************************/
|
---|
369 |
|
---|
370 |
|
---|
371 | static void write_index8_span( const GLcontext *ctx,
|
---|
372 | GLuint n, GLint x, GLint y,
|
---|
373 | const GLubyte index[],
|
---|
374 | const GLubyte mask[] )
|
---|
375 | {
|
---|
376 | GLint i;
|
---|
377 | for (i=0;i<n;i++) {
|
---|
378 | if (mask[i]) {
|
---|
379 | WriteCIPixel(x+i, y, index[i]);
|
---|
380 | }
|
---|
381 | }
|
---|
382 | }
|
---|
383 |
|
---|
384 |
|
---|
385 | static void write_index32_span( const GLcontext *ctx,
|
---|
386 | GLuint n, GLint x, GLint y,
|
---|
387 | const GLuint index[],
|
---|
388 | const GLubyte mask[] )
|
---|
389 | {
|
---|
390 | GLint i;
|
---|
391 | for (i=0;i<n;i++) {
|
---|
392 | if (mask[i]) {
|
---|
393 | WriteCIPixel(x+i, y, index[i]);
|
---|
394 | }
|
---|
395 | }
|
---|
396 | }
|
---|
397 |
|
---|
398 |
|
---|
399 |
|
---|
400 | static void write_mono_index_span( const GLcontext *ctx,
|
---|
401 | GLuint n, GLint x, GLint y,
|
---|
402 | const GLubyte mask[] )
|
---|
403 | {
|
---|
404 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
405 | GLuint i;
|
---|
406 | for (i=0;i<n;i++) {
|
---|
407 | if (mask[i]) {
|
---|
408 | WriteCIPixel(x+i, y, foo->CurrentIndex);
|
---|
409 | }
|
---|
410 | }
|
---|
411 | }
|
---|
412 |
|
---|
413 |
|
---|
414 |
|
---|
415 | static void write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
|
---|
416 | const GLubyte rgba[][4], const GLubyte mask[] )
|
---|
417 | {
|
---|
418 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
419 | GLuint i;
|
---|
420 | y = FLIP(y);
|
---|
421 | if (mask) {
|
---|
422 | /* draw some pixels */
|
---|
423 | for (i=0; i<n; i++) {
|
---|
424 | if (mask[i]) {
|
---|
425 | WriteRGBAPixel( x+i, y, foo->CurrentColor );
|
---|
426 | }
|
---|
427 | }
|
---|
428 | }
|
---|
429 | else {
|
---|
430 | /* draw all pixels */
|
---|
431 | for (i=0; i<n; i++) {
|
---|
432 | WriteRGBAPixel( x+i, y, foo->CurrentColor );
|
---|
433 | }
|
---|
434 | }
|
---|
435 | }
|
---|
436 |
|
---|
437 |
|
---|
438 | static void write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
|
---|
439 | const GLubyte rgb[][3], const GLubyte mask[] )
|
---|
440 | {
|
---|
441 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
442 | GLuint i;
|
---|
443 | y = FLIP(y);
|
---|
444 | if (mask) {
|
---|
445 | /* draw some pixels */
|
---|
446 | for (i=0; i<n; i++) {
|
---|
447 | if (mask[i]) {
|
---|
448 | WriteRGBPixel( x+i, y, rgb[i] );
|
---|
449 | }
|
---|
450 | }
|
---|
451 | }
|
---|
452 | else {
|
---|
453 | /* draw all pixels */
|
---|
454 | for (i=0; i<n; i++) {
|
---|
455 | WriteRGBPixel( x+i, y, rgb[i] );
|
---|
456 | }
|
---|
457 | }
|
---|
458 | }
|
---|
459 |
|
---|
460 |
|
---|
461 |
|
---|
462 | static void write_mono_rgba_span( const GLcontext *ctx,
|
---|
463 | GLuint n, GLint x, GLint y,
|
---|
464 | const GLubyte mask[])
|
---|
465 | {
|
---|
466 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
467 | GLint i;
|
---|
468 | y = FLIP(y);
|
---|
469 | for (i=0; i<n; i++) {
|
---|
470 | if (mask[i]) {
|
---|
471 | WriteRGBAPixel( x+i, y, foo->CurrentColor );
|
---|
472 | }
|
---|
473 | }
|
---|
474 | }
|
---|
475 |
|
---|
476 |
|
---|
477 |
|
---|
478 | /**********************************************************************/
|
---|
479 | /***** Read spans of pixels *****/
|
---|
480 | /**********************************************************************/
|
---|
481 |
|
---|
482 |
|
---|
483 | static void read_index_span( const GLcontext *ctx,
|
---|
484 | GLuint n, GLint x, GLint y, GLuint index[])
|
---|
485 | {
|
---|
486 | GLint i;
|
---|
487 | for (i=0; i<n; i++) {
|
---|
488 | index[i] = ReadCIPixel( x+i, y );
|
---|
489 | }
|
---|
490 | }
|
---|
491 |
|
---|
492 |
|
---|
493 |
|
---|
494 | static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
|
---|
495 | GLubyte rgba[][4] )
|
---|
496 | {
|
---|
497 | int i;
|
---|
498 | for (i=0; i<n; i++) {
|
---|
499 | ReadRGBAPixel( x+i, y, rgba[i] );
|
---|
500 | }
|
---|
501 | }
|
---|
502 |
|
---|
503 |
|
---|
504 |
|
---|
505 | /**********************************************************************/
|
---|
506 | /***** Write arrays of pixels *****/
|
---|
507 | /**********************************************************************/
|
---|
508 |
|
---|
509 |
|
---|
510 | static void write_index_pixels( const GLcontext *ctx,
|
---|
511 | GLuint n, const GLint x[], const GLint y[],
|
---|
512 | const GLuint index[], const GLubyte mask[] )
|
---|
513 | {
|
---|
514 | GLint i;
|
---|
515 | for (i=0; i<n; i++) {
|
---|
516 | if (mask[i]) {
|
---|
517 | WriteCIPixel( x[i], y[i], index[i] );
|
---|
518 | }
|
---|
519 | }
|
---|
520 | }
|
---|
521 |
|
---|
522 |
|
---|
523 |
|
---|
524 | static void write_mono_index_pixels( const GLcontext *ctx,
|
---|
525 | GLuint n,
|
---|
526 | const GLint x[], const GLint y[],
|
---|
527 | const GLubyte mask[] )
|
---|
528 | {
|
---|
529 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
530 | GLint i;
|
---|
531 | for (i=0; i<n; i++) {
|
---|
532 | if (mask[i]) {
|
---|
533 | WriteCIPixel( x[i], y[i], foo->CurrentIndex );
|
---|
534 | }
|
---|
535 | }
|
---|
536 | }
|
---|
537 |
|
---|
538 |
|
---|
539 |
|
---|
540 | static void write_rgba_pixels( const GLcontext *ctx,
|
---|
541 | GLuint n, const GLint x[], const GLint y[],
|
---|
542 | const GLubyte rgba[][4], const GLubyte mask[] )
|
---|
543 | {
|
---|
544 | GLint i;
|
---|
545 | for (i=0; i<n; i++) {
|
---|
546 | if (mask[i]) {
|
---|
547 | WriteRGBAPixel( x[i], y[i], rgba[i] );
|
---|
548 | }
|
---|
549 | }
|
---|
550 | }
|
---|
551 |
|
---|
552 |
|
---|
553 |
|
---|
554 | static void write_mono_rgba_pixels( const GLcontext *ctx,
|
---|
555 | GLuint n, const GLint x[], const GLint y[],
|
---|
556 | const GLubyte mask[] )
|
---|
557 | {
|
---|
558 | struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
|
---|
559 | GLint i;
|
---|
560 | for (i=0; i<n; i++) {
|
---|
561 | if (mask[i]) {
|
---|
562 | WriteRGBAPixel( x[i], y[i], foo->CurrentColor );
|
---|
563 | }
|
---|
564 | }
|
---|
565 | }
|
---|
566 |
|
---|
567 |
|
---|
568 |
|
---|
569 |
|
---|
570 | /**********************************************************************/
|
---|
571 | /***** Read arrays of pixels *****/
|
---|
572 | /**********************************************************************/
|
---|
573 |
|
---|
574 | /* Read an array of color index pixels. */
|
---|
575 | static void read_index_pixels( const GLcontext *ctx,
|
---|
576 | GLuint n, const GLint x[], const GLint y[],
|
---|
577 | GLuint index[], const GLubyte mask[] )
|
---|
578 | {
|
---|
579 | GLint i;
|
---|
580 | for (i=0; i<n; i++) {
|
---|
581 | if (mask[i]) {
|
---|
582 | index[i] = ReadCIPixel( x[i], y[i] );
|
---|
583 | }
|
---|
584 | }
|
---|
585 | }
|
---|
586 |
|
---|
587 |
|
---|
588 |
|
---|
589 | static void read_rgba_pixels( const GLcontext *ctx,
|
---|
590 | GLuint n, const GLint x[], const GLint y[],
|
---|
591 | GLubyte rgba[][4], const GLubyte mask[] )
|
---|
592 | {
|
---|
593 | GLint i;
|
---|
594 | for (i=0; i<n; i++) {
|
---|
595 | if (mask[i]) {
|
---|
596 | ReadRGBAPixel( x[i], y[i], rgba[i] );
|
---|
597 | }
|
---|
598 | }
|
---|
599 | }
|
---|
600 |
|
---|
601 |
|
---|
602 |
|
---|
603 |
|
---|
604 | /**********************************************************************/
|
---|
605 | /**********************************************************************/
|
---|
606 |
|
---|
607 |
|
---|
608 | static void setup_DD_pointers( GLcontext *ctx )
|
---|
609 | {
|
---|
610 | /* Initialize all the pointers in the DD struct. Do this whenever */
|
---|
611 | /* a new context is made current or we change buffers via set_buffer! */
|
---|
612 |
|
---|
613 | ctx->Driver.UpdateState = setup_DD_pointers;
|
---|
614 |
|
---|
615 | ctx->Driver.ClearIndex = clear_index;
|
---|
616 | ctx->Driver.ClearColor = clear_color;
|
---|
617 | ctx->Driver.Clear = clear;
|
---|
618 |
|
---|
619 | ctx->Driver.Index = set_index;
|
---|
620 | ctx->Driver.Color = set_color;
|
---|
621 |
|
---|
622 | ctx->Driver.SetBuffer = set_buffer;
|
---|
623 | ctx->Driver.GetBufferSize = get_buffer_size;
|
---|
624 |
|
---|
625 | ctx->Driver.PointsFunc = fast_points_function;
|
---|
626 | ctx->Driver.LineFunc = fast_line_function;
|
---|
627 | ctx->Driver.TriangleFunc = fast_triangle_function;
|
---|
628 |
|
---|
629 | /* Pixel/span writing functions: */
|
---|
630 | ctx->Driver.WriteRGBASpan = write_rgba_span;
|
---|
631 | ctx->Driver.WriteRGBSpan = write_rgb_span;
|
---|
632 | ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span;
|
---|
633 | ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
|
---|
634 | ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels;
|
---|
635 |
|
---|
636 | ctx->Driver.WriteCI32Span = write_index32_span;
|
---|
637 | ctx->Driver.WriteCI8Span = write_index8_span;
|
---|
638 | ctx->Driver.WriteMonoCISpan = write_mono_index_span;
|
---|
639 | ctx->Driver.WriteCI32Pixels = write_index_pixels;
|
---|
640 | ctx->Driver.WriteMonoCIPixels = write_mono_index_pixels;
|
---|
641 |
|
---|
642 | /* Pixel/span reading functions: */
|
---|
643 | ctx->Driver.ReadCI32Span = read_index_span;
|
---|
644 | ctx->Driver.ReadRGBASpan = read_rgba_span;
|
---|
645 | ctx->Driver.ReadCI32Pixels = read_index_pixels;
|
---|
646 | ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
|
---|
647 |
|
---|
648 |
|
---|
649 | /*
|
---|
650 | * OPTIONAL FUNCTIONS: these may be left uninitialized if the device
|
---|
651 | * driver can't/needn't implement them.
|
---|
652 | */
|
---|
653 | ctx->Driver.Finish = finish;
|
---|
654 | ctx->Driver.Flush = flush;
|
---|
655 | ctx->Driver.IndexMask = index_mask;
|
---|
656 | ctx->Driver.ColorMask = color_mask;
|
---|
657 | ctx->Driver.LogicOp = logicop;
|
---|
658 | ctx->Driver.Dither = dither;
|
---|
659 | }
|
---|
660 |
|
---|
661 |
|
---|
662 |
|
---|
663 | /**********************************************************************/
|
---|
664 | /***** FOO/Mesa Public API Functions *****/
|
---|
665 | /**********************************************************************/
|
---|
666 |
|
---|
667 |
|
---|
668 |
|
---|
669 | /*
|
---|
670 | * The exact arguments to this function will depend on your window system
|
---|
671 | */
|
---|
672 | FooMesaVisual FooMesaCreateVisual( GLboolean rgb_mode, GLboolean dbFlag,
|
---|
673 | GLint depthSize, GLint stencilSize,
|
---|
674 | GLint accumSize )
|
---|
675 | {
|
---|
676 | FooMesaVisual v;
|
---|
677 | GLint redBits, greenBits, blueBits, alphaBits, indexBits;
|
---|
678 | GLboolean alphaFlag = GL_FALSE;
|
---|
679 |
|
---|
680 | v = (FooMesaVisual) calloc( 1, sizeof(struct foo_mesa_visual) );
|
---|
681 | if (!v) {
|
---|
682 | return NULL;
|
---|
683 | }
|
---|
684 |
|
---|
685 | if (rgb_mode) {
|
---|
686 | /* RGB(A) mode */
|
---|
687 | redBits = 8; /* XXX 8 is just an example */
|
---|
688 | greenBits = 8;
|
---|
689 | blueBits = 8;
|
---|
690 | alphaBits = 8;
|
---|
691 | indexBits = 0;
|
---|
692 | }
|
---|
693 | else {
|
---|
694 | /* color index mode */
|
---|
695 | redBits = 0;
|
---|
696 | greenBits = 0;
|
---|
697 | blueBits = 0;
|
---|
698 | alphaBits = 0;
|
---|
699 | indexBits = 8; /* XXX 8 is just an example */
|
---|
700 | }
|
---|
701 |
|
---|
702 | /* Create core visual */
|
---|
703 | v->gl_visual = gl_create_visual( rgb_mode,
|
---|
704 | alphaFlag,
|
---|
705 | dbFlag,
|
---|
706 | GL_FALSE, /* stereo */
|
---|
707 | depthSize,
|
---|
708 | stencilSize,
|
---|
709 | accumSize,
|
---|
710 | indexBits,
|
---|
711 | redBits, greenBits, blueBits, alphaBits );
|
---|
712 |
|
---|
713 | return v;
|
---|
714 | }
|
---|
715 |
|
---|
716 |
|
---|
717 |
|
---|
718 | void FooMesaDestroyVisual( FooMesaVisual v )
|
---|
719 | {
|
---|
720 | gl_destroy_visual( v->gl_visual );
|
---|
721 | free( v );
|
---|
722 | }
|
---|
723 |
|
---|
724 |
|
---|
725 |
|
---|
726 |
|
---|
727 | FooMesaBuffer FooMesaCreateBuffer( FooMesaVisual visual,
|
---|
728 | void *your_window_id )
|
---|
729 | {
|
---|
730 | FooMesaBuffer b;
|
---|
731 |
|
---|
732 | b = (FooMesaBuffer) calloc( 1, sizeof(struct foo_mesa_buffer) );
|
---|
733 | if (!b) {
|
---|
734 | return NULL;
|
---|
735 | }
|
---|
736 |
|
---|
737 | b->gl_buffer = gl_create_framebuffer( visual->gl_visual );
|
---|
738 | b->the_window = your_window_id;
|
---|
739 |
|
---|
740 | /* other stuff */
|
---|
741 |
|
---|
742 | return b;
|
---|
743 | }
|
---|
744 |
|
---|
745 |
|
---|
746 |
|
---|
747 | void FooMesaDestroyBuffer( FooMesaBuffer b )
|
---|
748 | {
|
---|
749 | gl_destroy_framebuffer( b->gl_buffer );
|
---|
750 | free( b );
|
---|
751 | }
|
---|
752 |
|
---|
753 |
|
---|
754 |
|
---|
755 |
|
---|
756 | FooMesaContext FooMesaCreateContext( FooMesaVisual visual,
|
---|
757 | FooMesaContext share )
|
---|
758 | {
|
---|
759 | FooMesaContext c;
|
---|
760 | GLboolean direct = GL_FALSE;
|
---|
761 |
|
---|
762 | c = (FooMesaContext) calloc( 1, sizeof(struct foo_mesa_context) );
|
---|
763 | if (!c) {
|
---|
764 | return NULL;
|
---|
765 | }
|
---|
766 |
|
---|
767 | c->gl_ctx = gl_create_context( visual->gl_visual,
|
---|
768 | share ? share->gl_ctx : NULL,
|
---|
769 | (void *) c, direct );
|
---|
770 |
|
---|
771 |
|
---|
772 | /* you probably have to do a bunch of other initializations here. */
|
---|
773 |
|
---|
774 |
|
---|
775 | /* and then, finally let the context examine your initializations */
|
---|
776 | gl_context_initialize( c->gl_ctx );
|
---|
777 |
|
---|
778 |
|
---|
779 | return c;
|
---|
780 | }
|
---|
781 |
|
---|
782 |
|
---|
783 |
|
---|
784 | void FooMesaDestroyContext( FooMesaContext c )
|
---|
785 | {
|
---|
786 | gl_destroy_context( c->gl_ctx );
|
---|
787 | free( c );
|
---|
788 | }
|
---|
789 |
|
---|
790 |
|
---|
791 |
|
---|
792 | /*
|
---|
793 | * Make the specified context and buffer the current one.
|
---|
794 | */
|
---|
795 | void FooMesaMakeCurrent( FooMesaContext c, FooMesaBuffer b )
|
---|
796 | {
|
---|
797 | if (c && b) {
|
---|
798 | gl_make_current( c->gl_ctx, b->gl_buffer );
|
---|
799 | CurrentContext = c;
|
---|
800 | CurrentBuffer = b;
|
---|
801 | if (c->gl_ctx->Viewport.Width==0) {
|
---|
802 | /* initialize viewport to window size */
|
---|
803 | gl_Viewport( c->gl_ctx, 0, 0, c->Buffer->Width, c->Buffer->Height );
|
---|
804 | }
|
---|
805 | }
|
---|
806 | else {
|
---|
807 | /* Detach */
|
---|
808 | gl_make_current( NULL, NULL );
|
---|
809 | CurrentContext = 0;
|
---|
810 | CurrentBuffer = 0;
|
---|
811 | }
|
---|
812 | }
|
---|
813 |
|
---|
814 |
|
---|
815 |
|
---|
816 | void FooMesaSwapBuffers( FooMesaBuffer b )
|
---|
817 | {
|
---|
818 | /* copy/swap back buffer to front if applicable */
|
---|
819 | }
|
---|
820 |
|
---|
821 |
|
---|
822 |
|
---|
823 | /* you may need to add other FOO/Mesa functions too... */
|
---|
824 |
|
---|