source: trunk/src/opengl/mesa/glmisc.c@ 2961

Last change on this file since 2961 was 2938, checked in by sandervl, 25 years ago

created

File size: 18.1 KB
Line 
1/* $Id: glmisc.c,v 1.1 2000-02-29 00:50:04 sandervl 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/* $XFree86: xc/lib/GL/mesa/src/glmisc.c,v 1.2 1999/04/04 00:20:25 dawes Exp $ */
29
30#ifdef PC_HEADER
31#include "all.h"
32#else
33#ifndef XFree86Server
34#include <stdlib.h>
35#include <string.h>
36#include <stdio.h>
37#else
38#include "GL/xf86glx.h"
39#endif
40#include "accum.h"
41#include "alphabuf.h"
42#include "context.h"
43#include "depth.h"
44#include "enums.h"
45#include "extensions.h"
46#include "glmisc.h"
47#include "macros.h"
48#include "masking.h"
49#include "stencil.h"
50#include "types.h"
51#endif
52
53
54
55void gl_ClearIndex( GLcontext *ctx, GLfloat c )
56{
57 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearIndex");
58 ctx->Color.ClearIndex = (GLuint) c;
59 if (!ctx->Visual->RGBAflag) {
60 /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
61 (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
62 }
63}
64
65
66
67void gl_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green,
68 GLclampf blue, GLclampf alpha )
69{
70 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearColor");
71
72 ctx->Color.ClearColor[0] = CLAMP( red, 0.0F, 1.0F );
73 ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
74 ctx->Color.ClearColor[2] = CLAMP( blue, 0.0F, 1.0F );
75 ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
76
77 if (ctx->Visual->RGBAflag) {
78 GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
79 GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
80 GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
81 GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F);
82 (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
83 }
84}
85
86
87
88
89/*
90 * Clear the color buffer when glColorMask or glIndexMask is in effect.
91 */
92static void clear_color_buffer_with_masking( GLcontext *ctx )
93{
94 GLint x, y, height, width;
95
96 /* Compute region to clear */
97 if (ctx->Scissor.Enabled) {
98 x = ctx->Buffer->Xmin;
99 y = ctx->Buffer->Ymin;
100 height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
101 width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
102 }
103 else {
104 x = 0;
105 y = 0;
106 height = ctx->Buffer->Height;
107 width = ctx->Buffer->Width;
108 }
109
110 if (ctx->Visual->RGBAflag) {
111 /* RGBA mode */
112 GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
113 GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
114 GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
115 GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F);
116 GLint i;
117 for (i=0;i<height;i++,y++) {
118 GLubyte rgba[MAX_WIDTH][4];
119 GLint j;
120 for (j=0; j<width; j++) {
121 rgba[j][RCOMP] = r;
122 rgba[j][GCOMP] = g;
123 rgba[j][BCOMP] = b;
124 rgba[j][ACOMP] = a;
125 }
126 gl_mask_rgba_span( ctx, width, x, y, rgba );
127 (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y,
128 (const GLubyte (*)[4])rgba, NULL );
129 }
130 }
131 else {
132 /* Color index mode */
133 GLuint indx[MAX_WIDTH];
134 GLubyte mask[MAX_WIDTH];
135 GLint i, j;
136 MEMSET( mask, 1, width );
137 for (i=0;i<height;i++,y++) {
138 for (j=0;j<width;j++) {
139 indx[j] = ctx->Color.ClearIndex;
140 }
141 gl_mask_index_span( ctx, width, x, y, indx );
142 (*ctx->Driver.WriteCI32Span)( ctx, width, x, y, indx, mask );
143 }
144 }
145}
146
147
148
149/*
150 * Clear the front and/or back color buffers. Also clear the alpha
151 * buffer(s) if present.
152 */
153static void clear_color_buffers( GLcontext *ctx )
154{
155
156 if (ctx->RasterMask & MULTI_DRAW_BIT) {
157 GLuint bufferBit;
158
159 if (ctx->Color.DrawBuffer == GL_NONE)
160 return;
161
162 /* loop over four possible dest color buffers */
163 for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
164 if (bufferBit & ctx->Color.DrawDestMask) {
165 if (bufferBit == FRONT_LEFT_BIT) {
166 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT_LEFT);
167 ctx->Buffer->Alpha = ctx->Buffer->FrontLeftAlpha;
168 }
169 else if (bufferBit == FRONT_RIGHT_BIT) {
170 (*ctx->Driver.SetBuffer)( ctx, GL_FRONT_RIGHT);
171 ctx->Buffer->Alpha = ctx->Buffer->FrontRightAlpha;
172 }
173 else if (bufferBit == BACK_LEFT_BIT) {
174 (*ctx->Driver.SetBuffer)( ctx, GL_BACK_LEFT);
175 ctx->Buffer->Alpha = ctx->Buffer->BackLeftAlpha;
176 }
177 else {
178 (*ctx->Driver.SetBuffer)( ctx, GL_BACK_RIGHT);
179 ctx->Buffer->Alpha = ctx->Buffer->BackRightAlpha;
180 }
181
182 if (ctx->Color.SWmasking) {
183 clear_color_buffer_with_masking( ctx );
184 }
185 else {
186 GLint x = ctx->Buffer->Xmin;
187 GLint y = ctx->Buffer->Ymin;
188 GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
189 GLint width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
190 (void) (*ctx->Driver.Clear)( ctx, GL_COLOR_BUFFER_BIT,
191 !ctx->Scissor.Enabled,
192 x, y, width, height );
193 }
194 }
195 }
196
197 /* restore default dest buffer */
198 (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
199 }
200 else {
201 /* normal case: clear exactly one color buffer */
202
203 if (ctx->Color.SWmasking) {
204 clear_color_buffer_with_masking( ctx );
205 }
206 else {
207 GLint x = ctx->Buffer->Xmin;
208 GLint y = ctx->Buffer->Ymin;
209 GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
210 GLint width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
211 (void) (*ctx->Driver.Clear)( ctx, GL_COLOR_BUFFER_BIT,
212 !ctx->Scissor.Enabled,
213 x, y, width, height );
214 }
215 }
216}
217
218
219
220void gl_Clear( GLcontext *ctx, GLbitfield mask )
221{
222#ifdef PROFILE
223 GLdouble t0 = gl_time();
224#endif
225
226 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClear");
227
228 if (MESA_VERBOSE & VERBOSE_API)
229 fprintf(stderr, "glClear 0x%x\n", mask);
230
231 if (ctx->RenderMode==GL_RENDER) {
232 GLint x, y, width, height;
233 GLbitfield newMask;
234
235 if (ctx->NewState) {
236 gl_update_state( ctx );
237 }
238
239 x = ctx->Buffer->Xmin;
240 y = ctx->Buffer->Ymin;
241 height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
242 width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
243
244 /* clear software alpha buffer(s) */
245 if ( (mask & GL_COLOR_BUFFER_BIT) && (ctx->RasterMask & ALPHABUF_BIT) ) {
246 gl_clear_alpha_buffers( ctx );
247 }
248
249 /* let device driver try to clear the buffers */
250 if ((mask & GL_COLOR_BUFFER_BIT) != 0
251 && (ctx->Color.SWmasking || (ctx->RasterMask & MULTI_DRAW_BIT))) {
252 /* Driver can't clear color buffer for some reason, let it try
253 * to clear the other ancillary buffers.
254 */
255 GLbitfield mask2 = mask & (~GL_COLOR_BUFFER_BIT);
256 newMask = (*ctx->Driver.Clear)( ctx, mask2, !ctx->Scissor.Enabled,
257 x, y, width, height );
258 newMask |= GL_COLOR_BUFFER_BIT;
259 }
260 else {
261 newMask = (*ctx->Driver.Clear)( ctx, mask, !ctx->Scissor.Enabled,
262 x, y, width, height );
263 }
264
265 if (newMask & GL_COLOR_BUFFER_BIT) clear_color_buffers( ctx );
266 if (newMask & GL_DEPTH_BUFFER_BIT) gl_clear_depth_buffer( ctx );
267 if (newMask & GL_ACCUM_BUFFER_BIT) gl_clear_accum_buffer( ctx );
268 if (newMask & GL_STENCIL_BUFFER_BIT) gl_clear_stencil_buffer( ctx );
269
270#ifdef PROFILE
271 ctx->ClearTime += gl_time() - t0;
272 ctx->ClearCount++;
273#endif
274 }
275}
276
277
278
279void gl_Finish( GLcontext *ctx )
280{
281 /* Don't compile into display list */
282 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFinish");
283 if (ctx->Driver.Finish) {
284 (*ctx->Driver.Finish)( ctx );
285 }
286}
287
288
289
290void gl_Flush( GLcontext *ctx )
291{
292 /* Don't compile into display list */
293 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFlush");
294 if (ctx->Driver.Flush) {
295 (*ctx->Driver.Flush)( ctx );
296 }
297}
298
299
300
301GLboolean gl_Hint( GLcontext *ctx, GLenum target, GLenum mode )
302{
303 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glHint", GL_FALSE);
304
305 if (MESA_VERBOSE & VERBOSE_API)
306 fprintf(stderr, "glHint %s %d\n", gl_lookup_enum_by_nr(target), mode);
307
308 switch (target) {
309 case GL_FOG_HINT:
310 ctx->Hint.Fog = mode;
311 break;
312 case GL_LINE_SMOOTH_HINT:
313 ctx->Hint.LineSmooth = mode;
314 break;
315 case GL_PERSPECTIVE_CORRECTION_HINT:
316 ctx->Hint.PerspectiveCorrection = mode;
317 break;
318 case GL_POINT_SMOOTH_HINT:
319 ctx->Hint.PointSmooth = mode;
320 break;
321 case GL_POLYGON_SMOOTH_HINT:
322 ctx->Hint.PolygonSmooth = mode;
323 break;
324 case GL_PREFER_DOUBLEBUFFER_HINT_PGI:
325 case GL_STRICT_DEPTHFUNC_HINT_PGI:
326 break;
327 case GL_STRICT_LIGHTING_HINT_PGI:
328 ctx->Hint.StrictLighting = mode;
329 break;
330 case GL_STRICT_SCISSOR_HINT_PGI:
331 case GL_FULL_STIPPLE_HINT_PGI:
332 case GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI:
333 case GL_NATIVE_GRAPHICS_END_HINT_PGI:
334 case GL_CONSERVE_MEMORY_HINT_PGI:
335 case GL_RECLAIM_MEMORY_HINT_PGI:
336 break;
337 case GL_ALWAYS_FAST_HINT_PGI:
338 if (mode) {
339 ctx->Hint.AllowDrawWin = GL_TRUE;
340 ctx->Hint.AllowDrawSpn = GL_FALSE;
341 ctx->Hint.AllowDrawMem = GL_FALSE;
342 } else {
343 ctx->Hint.AllowDrawWin = GL_TRUE;
344 ctx->Hint.AllowDrawSpn = GL_TRUE;
345 ctx->Hint.AllowDrawMem = GL_TRUE;
346 }
347 break;
348 case GL_ALWAYS_SOFT_HINT_PGI:
349 ctx->Hint.AllowDrawWin = GL_TRUE;
350 ctx->Hint.AllowDrawSpn = GL_TRUE;
351 ctx->Hint.AllowDrawMem = GL_TRUE;
352 break;
353 case GL_ALLOW_DRAW_OBJ_HINT_PGI:
354 break;
355 case GL_ALLOW_DRAW_WIN_HINT_PGI:
356 ctx->Hint.AllowDrawWin = mode;
357 break;
358 case GL_ALLOW_DRAW_SPN_HINT_PGI:
359 ctx->Hint.AllowDrawSpn = mode;
360 break;
361 case GL_ALLOW_DRAW_MEM_HINT_PGI:
362 ctx->Hint.AllowDrawMem = mode;
363 break;
364 case GL_CLIP_NEAR_HINT_PGI:
365 case GL_CLIP_FAR_HINT_PGI:
366 case GL_WIDE_LINE_HINT_PGI:
367 case GL_BACK_NORMALS_HINT_PGI:
368 case GL_NATIVE_GRAPHICS_HANDLE_PGI:
369 break;
370
371 /* GL_EXT_clip_volume_hint */
372 case GL_CLIP_VOLUME_CLIPPING_HINT_EXT:
373 ctx->Hint.ClipVolumeClipping = mode;
374 break;
375
376 default:
377 gl_error( ctx, GL_INVALID_ENUM, "glHint(target)" );
378 return GL_FALSE;
379 }
380 ctx->NewState |= NEW_ALL; /* just to be safe */
381
382 if (ctx->Driver.Hint) {
383 (*ctx->Driver.Hint)( ctx, target, mode );
384 }
385
386 return GL_TRUE;
387}
388
389
390
391void gl_DrawBuffer( GLcontext *ctx, GLenum mode )
392{
393 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawBuffer");
394
395 if (MESA_VERBOSE & VERBOSE_API)
396 fprintf(stderr, "glDrawBuffer %s\n", gl_lookup_enum_by_nr(mode));
397
398 switch (mode) {
399 case GL_AUX0:
400 case GL_AUX1:
401 case GL_AUX2:
402 case GL_AUX3:
403 /* AUX buffers not implemented in Mesa at this time */
404 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
405 return;
406 case GL_RIGHT:
407 if (!ctx->Visual->StereoFlag) {
408 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
409 return;
410 }
411 if (ctx->Visual->DBflag)
412 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
413 else
414 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT;
415 break;
416 case GL_FRONT_RIGHT:
417 if (!ctx->Visual->StereoFlag) {
418 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
419 return;
420 }
421 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT;
422 break;
423 case GL_BACK_RIGHT:
424 if (!ctx->Visual->StereoFlag) {
425 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
426 return;
427 }
428 if (!ctx->Visual->DBflag) {
429 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
430 return;
431 }
432 ctx->Color.DrawDestMask = BACK_RIGHT_BIT;
433 break;
434 case GL_BACK_LEFT:
435 if (!ctx->Visual->DBflag) {
436 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
437 return;
438 }
439 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
440 break;
441 case GL_FRONT_AND_BACK:
442 if (!ctx->Visual->DBflag) {
443 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
444 return;
445 }
446 if (ctx->Visual->StereoFlag)
447 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT
448 | FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
449 else
450 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
451 break;
452 case GL_BACK:
453 if (!ctx->Visual->DBflag) {
454 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
455 return;
456 }
457 if (ctx->Visual->StereoFlag)
458 ctx->Color.DrawDestMask = BACK_LEFT_BIT | BACK_RIGHT_BIT;
459 else
460 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
461 break;
462 case GL_LEFT:
463 /* never an error */
464 if (ctx->Visual->DBflag)
465 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
466 else
467 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
468 break;
469 case GL_FRONT_LEFT:
470 /* never an error */
471 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
472 break;
473 case GL_FRONT:
474 /* never an error */
475 if (ctx->Visual->StereoFlag)
476 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | FRONT_RIGHT_BIT;
477 else
478 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
479 break;
480 case GL_NONE:
481 /* never an error */
482 ctx->Color.DrawDestMask = 0;
483 break;
484 default:
485 gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
486 return;
487 }
488
489 /*
490 * Make the dest buffer mode more precise if possible
491 */
492 if (mode == GL_LEFT && !ctx->Visual->DBflag)
493 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
494 else if (mode == GL_RIGHT && !ctx->Visual->DBflag)
495 ctx->Color.DriverDrawBuffer = GL_FRONT_RIGHT;
496 else if (mode == GL_FRONT && !ctx->Visual->StereoFlag)
497 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
498 else if (mode == GL_BACK && !ctx->Visual->StereoFlag)
499 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
500 else
501 ctx->Color.DriverDrawBuffer = mode;
502
503 /*
504 * Set current alpha buffer pointer
505 */
506 if (ctx->Visual->SoftwareAlpha) {
507 if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT)
508 ctx->Buffer->Alpha = ctx->Buffer->FrontLeftAlpha;
509 else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT)
510 ctx->Buffer->Alpha = ctx->Buffer->BackLeftAlpha;
511 else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT)
512 ctx->Buffer->Alpha = ctx->Buffer->FrontRightAlpha;
513 else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT)
514 ctx->Buffer->Alpha = ctx->Buffer->BackRightAlpha;
515 }
516
517 /*
518 * If we get here there can't have been an error.
519 * Now see if device driver can implement the drawing to the target
520 * buffer(s). The driver may not be able to do GL_FRONT_AND_BACK mode
521 * for example. We'll take care of that in the core code by looping
522 * over the individual buffers.
523 */
524 ASSERT(ctx->Driver.SetBuffer);
525 if ( (*ctx->Driver.SetBuffer)(ctx, ctx->Color.DriverDrawBuffer) ) {
526 /* All OK, the driver will do all buffer writes */
527 ctx->Color.MultiDrawBuffer = GL_FALSE;
528 }
529 else {
530 /* We'll have to loop over the multiple draw buffer targets */
531 ctx->Color.MultiDrawBuffer = GL_TRUE;
532 /* Set drawing buffer to front for now */
533 (*ctx->Driver.SetBuffer)(ctx, GL_FRONT_LEFT);
534 }
535
536 ctx->Color.DrawBuffer = mode;
537 ctx->NewState |= NEW_RASTER_OPS;
538}
539
540
541
542void gl_ReadBuffer( GLcontext *ctx, GLenum mode )
543{
544 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glReadBuffer");
545
546 if (MESA_VERBOSE & VERBOSE_API)
547 fprintf(stderr, "glReadBuffer %s\n", gl_lookup_enum_by_nr(mode));
548
549 switch (mode) {
550 case GL_AUX0:
551 case GL_AUX1:
552 case GL_AUX2:
553 case GL_AUX3:
554 /* AUX buffers not implemented in Mesa at this time */
555 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
556 return;
557 case GL_LEFT:
558 case GL_FRONT:
559 case GL_FRONT_LEFT:
560 /* Front-Left buffer, always exists */
561 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
562 break;
563 case GL_BACK:
564 case GL_BACK_LEFT:
565 /* Back-Left buffer, requires double buffering */
566 if (!ctx->Visual->DBflag) {
567 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
568 return;
569 }
570 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
571 break;
572 case GL_FRONT_RIGHT:
573 case GL_RIGHT:
574 if (!ctx->Visual->StereoFlag) {
575 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
576 return;
577 }
578 ctx->Pixel.DriverReadBuffer = GL_FRONT_RIGHT;
579 break;
580 case GL_BACK_RIGHT:
581 if (!ctx->Visual->StereoFlag || !ctx->Visual->DBflag) {
582 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
583 return;
584 }
585 ctx->Pixel.DriverReadBuffer = GL_BACK_RIGHT;
586 break;
587 default:
588 gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
589 return;
590 }
591
592 ctx->Pixel.ReadBuffer = mode;
593 ctx->NewState |= NEW_RASTER_OPS;
594}
Note: See TracBrowser for help on using the repository browser.