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

Last change on this file since 3597 was 2962, checked in by jeroen, 25 years ago

* empty log message *

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