ReactOS 0.4.15-dev-7788-g1ad9096
pb.c
Go to the documentation of this file.
1/* $Id: pb.c,v 1.14 1997/11/13 02:16:48 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 2.4
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24/*
25 * $Log: pb.c,v $
26 * Revision 1.14 1997/11/13 02:16:48 brianp
27 * added lambda array, initialized to zeros
28 *
29 * Revision 1.13 1997/07/24 01:24:11 brianp
30 * changed precompiled header symbol from PCH to PC_HEADER
31 *
32 * Revision 1.12 1997/05/28 03:26:02 brianp
33 * added precompiled header (PCH) support
34 *
35 * Revision 1.11 1997/05/09 22:40:19 brianp
36 * added gl_alloc_pb()
37 *
38 * Revision 1.10 1997/05/03 00:51:30 brianp
39 * new texturing function call: gl_texture_pixels()
40 *
41 * Revision 1.9 1997/05/01 02:10:33 brianp
42 * removed manually unrolled loop to stop Purify uninitialized memory read
43 *
44 * Revision 1.8 1997/04/16 23:54:11 brianp
45 * do per-pixel fog if texturing is enabled
46 *
47 * Revision 1.7 1997/02/09 19:53:43 brianp
48 * now use TEXTURE_xD enable constants
49 *
50 * Revision 1.6 1997/02/09 18:43:14 brianp
51 * added GL_EXT_texture3D support
52 *
53 * Revision 1.5 1997/02/03 20:30:54 brianp
54 * added a few DEFARRAY macros for BeOS
55 *
56 * Revision 1.4 1997/01/28 22:17:44 brianp
57 * new RGBA mode logic op support
58 *
59 * Revision 1.3 1996/09/25 03:21:10 brianp
60 * added NO_DRAW_BIT support
61 *
62 * Revision 1.2 1996/09/15 14:18:37 brianp
63 * now use GLframebuffer and GLvisual
64 *
65 * Revision 1.1 1996/09/13 01:38:16 brianp
66 * Initial revision
67 *
68 */
69
70
71/*
72 * Pixel buffer:
73 *
74 * As fragments are produced (by point, line, and bitmap drawing) they
75 * are accumlated in a buffer. When the buffer is full or has to be
76 * flushed (glEnd), we apply all enabled rasterization functions to the
77 * pixels and write the results to the display buffer. The goal is to
78 * maximize the number of pixels processed inside loops and to minimize
79 * the number of function calls.
80 */
81
82
83
84#ifdef PC_HEADER
85#include "all.h"
86#else
87#include <stdlib.h>
88#include <string.h>
89#include "alpha.h"
90#include "alphabuf.h"
91#include "blend.h"
92#include "depth.h"
93#include "fog.h"
94#include "logic.h"
95#include "macros.h"
96#include "masking.h"
97#include "pb.h"
98#include "scissor.h"
99#include "stencil.h"
100#include "texture.h"
101#include "types.h"
102#endif
103
104
105
106/*
107 * Allocate and initialize a new pixel buffer structure.
108 */
110{
111 struct pixel_buffer *pb;
112 pb = (struct pixel_buffer *) calloc(sizeof(struct pixel_buffer), 1);
113 if (pb) {
114 int i;
115 /* set non-zero fields */
116 pb->primitive = GL_BITMAP;
117 /* Set all lambda values to 0.0 since we don't do mipmapping for
118 * points or lines and want to use the level 0 texture image.
119 */
120 for (i=0; i<PB_SIZE; i++) {
121 pb->lambda[i] = 0.0;
122 }
123 }
124 return pb;
125}
126
127
128
129
130/*
131 * When the pixel buffer is full, or needs to be flushed, call this
132 * function. All the pixels in the pixel buffer will be subjected
133 * to texturing, scissoring, stippling, alpha testing, stenciling,
134 * depth testing, blending, and finally written to the frame buffer.
135 */
137{
138 struct pixel_buffer* PB = ctx->PB;
139
141 DEFARRAY(GLubyte, rsave, PB_SIZE);
142 DEFARRAY(GLubyte, gsave, PB_SIZE);
143 DEFARRAY(GLubyte, bsave, PB_SIZE);
144 DEFARRAY(GLubyte, asave, PB_SIZE);
145
146 if (PB->count==0) goto CleanUp;
147
148 /* initialize mask array and clip pixels simultaneously */
149 {
150 GLint xmin = ctx->Buffer->Xmin;
151 GLint xmax = ctx->Buffer->Xmax;
152 GLint ymin = ctx->Buffer->Ymin;
153 GLint ymax = ctx->Buffer->Ymax;
154 GLint *x = PB->x;
155 GLint *y = PB->y;
156 GLuint i, n = PB->count;
157 for (i=0;i<n;i++) {
158 mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
159 }
160 }
161
162 if (ctx->Visual->RGBAflag) {
163 /* RGBA COLOR PIXELS */
164 if (PB->mono && ctx->MutablePixels) {
165 /* Copy flat color to all pixels */
166 MEMSET( PB->r, PB->color[0], PB->count );
167 MEMSET( PB->g, PB->color[1], PB->count );
168 MEMSET( PB->b, PB->color[2], PB->count );
169 MEMSET( PB->a, PB->color[3], PB->count );
170 }
171
172 /* If each pixel can be of a different color... */
173 if (ctx->MutablePixels || !PB->mono) {
174
175 if (ctx->Texture.Enabled) {
176 /* TODO: need texture lambda valus */
177 gl_texture_pixels( ctx, PB->count, PB->s, PB->t, PB->u,
178 PB->lambda, PB->r, PB->g, PB->b, PB->a);
179 }
180
181 if (ctx->Fog.Enabled
182 && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP
183 || ctx->Texture.Enabled)) {
184 gl_fog_color_pixels( ctx, PB->count, PB->z,
185 PB->r, PB->g, PB->b, PB->a );
186 }
187
188 /* Scissoring already done above */
189
190 if (ctx->Color.AlphaEnabled) {
191 if (gl_alpha_test( ctx, PB->count, PB->a, mask )==0) {
192 goto CleanUp;
193 }
194 }
195
196 if (ctx->Stencil.Enabled) {
197 /* first stencil test */
198 if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
199 goto CleanUp;
200 }
201 /* depth buffering w/ stencil */
202 gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
203 }
204 else if (ctx->Depth.Test) {
205 /* regular depth testing */
206 (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
207 }
208
209 if (ctx->RasterMask & NO_DRAW_BIT) {
210 goto CleanUp;
211 }
212
213 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
214 /* make a copy of the colors */
215 MEMCPY( rsave, PB->r, PB->count * sizeof(GLubyte) );
216 MEMCPY( gsave, PB->r, PB->count * sizeof(GLubyte) );
217 MEMCPY( bsave, PB->r, PB->count * sizeof(GLubyte) );
218 MEMCPY( asave, PB->r, PB->count * sizeof(GLubyte) );
219 }
220
221 if (ctx->Color.SWLogicOpEnabled) {
222 gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
223 PB->r, PB->g, PB->b, PB->a, mask);
224 }
225 else if (ctx->Color.BlendEnabled) {
226 gl_blend_pixels( ctx, PB->count, PB->x, PB->y,
227 PB->r, PB->g, PB->b, PB->a, mask);
228 }
229
230 if (ctx->Color.SWmasking) {
231 gl_mask_color_pixels( ctx, PB->count, PB->x, PB->y,
232 PB->r, PB->g, PB->b, PB->a, mask );
233 }
234
235 /* write pixels */
236 (*ctx->Driver.WriteColorPixels)( ctx, PB->count, PB->x, PB->y,
237 PB->r, PB->g, PB->b, PB->a, mask );
238 if (ctx->RasterMask & ALPHABUF_BIT) {
239 gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, PB->a, mask );
240 }
241
242 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
243 /*** Also draw to back buffer ***/
244 (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
245 if (ctx->Color.SWLogicOpEnabled) {
246 gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
247 PB->r, PB->g, PB->b, PB->a, mask);
248 }
249 else if (ctx->Color.BlendEnabled) {
250 gl_blend_pixels( ctx, PB->count, PB->x, PB->y,
251 rsave, gsave, bsave, asave, mask );
252 }
253 if (ctx->Color.SWmasking) {
254 gl_mask_color_pixels( ctx, PB->count, PB->x, PB->y,
255 rsave, gsave, bsave, asave, mask);
256 }
257 (*ctx->Driver.WriteColorPixels)( ctx, PB->count, PB->x, PB->y,
258 rsave, gsave, bsave, asave, mask);
259 if (ctx->RasterMask & ALPHABUF_BIT) {
260 ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
261 gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y,
262 asave, mask );
263 ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
264 }
265 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
266 /*** ALL DONE ***/
267 }
268 }
269 else {
270 /* Same color for all pixels */
271
272 /* Scissoring already done above */
273
274 if (ctx->Color.AlphaEnabled) {
275 if (gl_alpha_test( ctx, PB->count, PB->a, mask )==0) {
276 goto CleanUp;
277 }
278 }
279
280 if (ctx->Stencil.Enabled) {
281 /* first stencil test */
282 if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
283 goto CleanUp;
284 }
285 /* depth buffering w/ stencil */
286 gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
287 }
288 else if (ctx->Depth.Test) {
289 /* regular depth testing */
290 (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
291 }
292
293 if (ctx->RasterMask & NO_DRAW_BIT) {
294 goto CleanUp;
295 }
296
297 /* write pixels */
298 {
300 red = PB->color[0];
301 green = PB->color[1];
302 blue = PB->color[2];
303 alpha = PB->color[3];
304 (*ctx->Driver.Color)( ctx, red, green, blue, alpha );
305 }
306 (*ctx->Driver.WriteMonocolorPixels)( ctx, PB->count, PB->x, PB->y, mask );
307 if (ctx->RasterMask & ALPHABUF_BIT) {
308 gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
309 PB->color[3], mask );
310 }
311
312 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
313 /*** Also render to back buffer ***/
314 (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
315 (*ctx->Driver.WriteMonocolorPixels)( ctx, PB->count, PB->x, PB->y, mask );
316 if (ctx->RasterMask & ALPHABUF_BIT) {
317 ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
318 gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
319 PB->color[3], mask );
320 ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
321 }
322 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
323 }
324 /*** ALL DONE ***/
325 }
326 }
327 else {
328 /* COLOR INDEX PIXELS */
329
330 /* If we may be writting pixels with different indexes... */
331 if (PB->mono && ctx->MutablePixels) {
332 /* copy index to all pixels */
333 GLuint n = PB->count, indx = PB->index;
334 GLuint *pbindex = PB->i;
335 do {
336 *pbindex++ = indx;
337 n--;
338 } while (n);
339 }
340
341 if (ctx->MutablePixels || !PB->mono) {
342 /* Pixel color index may be modified */
343 GLuint isave[PB_SIZE];
344
345 if (ctx->Fog.Enabled
346 && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP)) {
347 gl_fog_index_pixels( ctx, PB->count, PB->z, PB->i );
348 }
349
350 /* Scissoring already done above */
351
352 if (ctx->Stencil.Enabled) {
353 /* first stencil test */
354 if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
355 goto CleanUp;
356 }
357 /* depth buffering w/ stencil */
358 gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
359 }
360 else if (ctx->Depth.Test) {
361 /* regular depth testing */
362 (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
363 }
364
365 if (ctx->RasterMask & NO_DRAW_BIT) {
366 goto CleanUp;
367 }
368
369 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
370 /* make a copy of the indexes */
371 MEMCPY( isave, PB->i, PB->count * sizeof(GLuint) );
372 }
373
374 if (ctx->Color.SWLogicOpEnabled) {
375 gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
376 }
377
378 if (ctx->Color.SWmasking) {
379 gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
380 }
381
382 /* write pixels */
383 (*ctx->Driver.WriteIndexPixels)( ctx, PB->count, PB->x, PB->y,
384 PB->i, mask );
385
386 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
387 /*** Also write to back buffer ***/
388 (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
389 MEMCPY( PB->i, isave, PB->count * sizeof(GLuint) );
390 if (ctx->Color.SWLogicOpEnabled) {
391 gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
392 }
393 if (ctx->Color.SWmasking) {
394 gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y,
395 PB->i, mask );
396 }
397 (*ctx->Driver.WriteIndexPixels)( ctx, PB->count, PB->x, PB->y,
398 PB->i, mask );
399 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
400 }
401
402 /*** ALL DONE ***/
403 }
404 else {
405 /* Same color index for all pixels */
406
407 /* Scissoring already done above */
408
409 if (ctx->Stencil.Enabled) {
410 /* first stencil test */
411 if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
412 goto CleanUp;
413 }
414 /* depth buffering w/ stencil */
415 gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
416 }
417 else if (ctx->Depth.Test) {
418 /* regular depth testing */
419 (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
420 }
421
422 if (ctx->RasterMask & NO_DRAW_BIT) {
423 goto CleanUp;
424 }
425
426 /* write pixels */
427 (*ctx->Driver.Index)( ctx, PB->index );
428 (*ctx->Driver.WriteMonoindexPixels)( ctx, PB->count, PB->x, PB->y, mask );
429
430 if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
431 /*** Also write to back buffer ***/
432 (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
433 (*ctx->Driver.WriteMonoindexPixels)( ctx, PB->count, PB->x, PB->y, mask );
434 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
435 }
436 /*** ALL DONE ***/
437 }
438 }
439
440CleanUp:
441 PB->count = 0;
443 UNDEFARRAY(rsave);
444 UNDEFARRAY(gsave);
445 UNDEFARRAY(bsave);
446 UNDEFARRAY(asave);
447}
448
449
GLint gl_alpha_test(GLcontext *ctx, GLuint n, const GLubyte alpha[], GLubyte mask[])
Definition: alpha.c:92
void gl_write_alpha_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte alpha[], const GLubyte mask[])
Definition: alphabuf.c:199
void gl_write_mono_alpha_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte alpha, const GLubyte mask[])
Definition: alphabuf.c:222
void gl_blend_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], GLubyte mask[])
Definition: blend.c:532
void gl_texture_pixels(GLcontext *ctx, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat r[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1678
#define FRONT_AND_BACK_BIT
Definition: types.h:1225
#define NO_DRAW_BIT
Definition: types.h:1226
#define ALPHABUF_BIT
Definition: types.h:1223
#define PB
void gl_fog_color_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: fog.c:252
void gl_fog_index_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLuint index[])
Definition: fog.c:333
unsigned char GLubyte
Definition: gl.h:157
#define GL_NICEST
Definition: gl.h:585
GLclampf green
Definition: gl.h:1740
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
#define GL_BACK
Definition: gl.h:271
unsigned int GLuint
Definition: gl.h:159
#define GL_BITMAP
Definition: gl.h:497
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLclampf GLclampf blue
Definition: gl.h:1740
int GLint
Definition: gl.h:156
#define GL_FRONT
Definition: gl.h:270
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define red
Definition: linetest.c:67
void gl_logicop_rgba_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], GLubyte mask[])
Definition: logic.c:548
void gl_logicop_ci_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLuint index[], GLubyte mask[])
Definition: logic.c:234
#define DEFARRAY(TYPE, NAME, SIZE)
Definition: macros.h:256
#define MEMSET(DST, VAL, N)
Definition: macros.h:241
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define UNDEFARRAY(NAME)
Definition: macros.h:257
void gl_mask_color_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], const GLubyte mask[])
Definition: masking.c:125
void gl_mask_index_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLuint index[], const GLubyte mask[])
Definition: masking.c:183
struct pixel_buffer * gl_alloc_pb(void)
Definition: pb.c:109
void gl_flush_pb(GLcontext *ctx)
Definition: pb.c:136
#define PB_SIZE
Definition: pb.h:52
#define calloc
Definition: rosglue.h:14
void gl_depth_stencil_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], const GLdepth z[], GLubyte mask[])
Definition: stencil.c:882
GLint gl_stencil_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte mask[])
Definition: stencil.c:702
GLfloat lambda[PB_SIZE]
Definition: pb.h:67
GLenum primitive
Definition: pb.h:72