blend.c revision 3a4bed8f088d6f7c558ad187c338cbcd6c692b5d
1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/**
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * \file blend.c
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Blending operations.
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Mesa 3-D graphics library
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Version:  6.5.1
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Permission is hereby granted, free of charge, to any person obtaining a
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * copy of this software and associated documentation files (the "Software"),
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * to deal in the Software without restriction, including without limitation
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * and/or sell copies of the Software, and to permit persons to whom the
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Software is furnished to do so, subject to the following conditions:
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The above copyright notice and this permission notice shall be included
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * in all copies or substantial portions of the Software.
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
32#include "glheader.h"
33#include "blend.h"
34#include "colormac.h"
35#include "context.h"
36#include "enums.h"
37#include "macros.h"
38#include "mtypes.h"
39#include "glapi/glapitable.h"
40
41
42/**
43 * Specify the blending operation.
44 *
45 * \param sfactor source factor operator.
46 * \param dfactor destination factor operator.
47 *
48 * \sa glBlendFunc, glBlendFuncSeparateEXT
49 */
50void GLAPIENTRY
51_mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
52{
53   _mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor);
54}
55
56
57/**
58 * Process GL_EXT_blend_func_separate().
59 *
60 * \param sfactorRGB RGB source factor operator.
61 * \param dfactorRGB RGB destination factor operator.
62 * \param sfactorA alpha source factor operator.
63 * \param dfactorA alpha destination factor operator.
64 *
65 * Verifies the parameters and updates gl_colorbuffer_attrib.
66 * On a change, flush the vertices and notify the driver via
67 * dd_function_table::BlendFuncSeparate.
68 */
69void GLAPIENTRY
70_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
71                            GLenum sfactorA, GLenum dfactorA )
72{
73   GET_CURRENT_CONTEXT(ctx);
74   ASSERT_OUTSIDE_BEGIN_END(ctx);
75
76   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
77      _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
78                  _mesa_lookup_enum_by_nr(sfactorRGB),
79                  _mesa_lookup_enum_by_nr(dfactorRGB),
80                  _mesa_lookup_enum_by_nr(sfactorA),
81                  _mesa_lookup_enum_by_nr(dfactorA));
82
83   switch (sfactorRGB) {
84      case GL_SRC_COLOR:
85      case GL_ONE_MINUS_SRC_COLOR:
86         if (!ctx->Extensions.NV_blend_square) {
87            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
88            return;
89         }
90         /* fall-through */
91      case GL_ZERO:
92      case GL_ONE:
93      case GL_DST_COLOR:
94      case GL_ONE_MINUS_DST_COLOR:
95      case GL_SRC_ALPHA:
96      case GL_ONE_MINUS_SRC_ALPHA:
97      case GL_DST_ALPHA:
98      case GL_ONE_MINUS_DST_ALPHA:
99      case GL_SRC_ALPHA_SATURATE:
100      case GL_CONSTANT_COLOR:
101      case GL_ONE_MINUS_CONSTANT_COLOR:
102      case GL_CONSTANT_ALPHA:
103      case GL_ONE_MINUS_CONSTANT_ALPHA:
104         break;
105      default:
106         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
107         return;
108   }
109
110   switch (dfactorRGB) {
111      case GL_DST_COLOR:
112      case GL_ONE_MINUS_DST_COLOR:
113         if (!ctx->Extensions.NV_blend_square) {
114            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
115            return;
116         }
117         /* fall-through */
118      case GL_ZERO:
119      case GL_ONE:
120      case GL_SRC_COLOR:
121      case GL_ONE_MINUS_SRC_COLOR:
122      case GL_SRC_ALPHA:
123      case GL_ONE_MINUS_SRC_ALPHA:
124      case GL_DST_ALPHA:
125      case GL_ONE_MINUS_DST_ALPHA:
126      case GL_CONSTANT_COLOR:
127      case GL_ONE_MINUS_CONSTANT_COLOR:
128      case GL_CONSTANT_ALPHA:
129      case GL_ONE_MINUS_CONSTANT_ALPHA:
130         break;
131      default:
132         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
133         return;
134   }
135
136   switch (sfactorA) {
137      case GL_SRC_COLOR:
138      case GL_ONE_MINUS_SRC_COLOR:
139         if (!ctx->Extensions.NV_blend_square) {
140            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
141            return;
142         }
143         /* fall-through */
144      case GL_ZERO:
145      case GL_ONE:
146      case GL_DST_COLOR:
147      case GL_ONE_MINUS_DST_COLOR:
148      case GL_SRC_ALPHA:
149      case GL_ONE_MINUS_SRC_ALPHA:
150      case GL_DST_ALPHA:
151      case GL_ONE_MINUS_DST_ALPHA:
152      case GL_SRC_ALPHA_SATURATE:
153      case GL_CONSTANT_COLOR:
154      case GL_ONE_MINUS_CONSTANT_COLOR:
155      case GL_CONSTANT_ALPHA:
156      case GL_ONE_MINUS_CONSTANT_ALPHA:
157         break;
158      default:
159         _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
160         return;
161   }
162
163   switch (dfactorA) {
164      case GL_DST_COLOR:
165      case GL_ONE_MINUS_DST_COLOR:
166         if (!ctx->Extensions.NV_blend_square) {
167            _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)");
168            return;
169         }
170         /* fall-through */
171      case GL_ZERO:
172      case GL_ONE:
173      case GL_SRC_COLOR:
174      case GL_ONE_MINUS_SRC_COLOR:
175      case GL_SRC_ALPHA:
176      case GL_ONE_MINUS_SRC_ALPHA:
177      case GL_DST_ALPHA:
178      case GL_ONE_MINUS_DST_ALPHA:
179      case GL_CONSTANT_COLOR:
180      case GL_ONE_MINUS_CONSTANT_COLOR:
181      case GL_CONSTANT_ALPHA:
182      case GL_ONE_MINUS_CONSTANT_ALPHA:
183         break;
184      default:
185         _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)" );
186         return;
187   }
188
189   if (ctx->Color.BlendSrcRGB == sfactorRGB &&
190       ctx->Color.BlendDstRGB == dfactorRGB &&
191       ctx->Color.BlendSrcA == sfactorA &&
192       ctx->Color.BlendDstA == dfactorA)
193      return;
194
195   FLUSH_VERTICES(ctx, _NEW_COLOR);
196
197   ctx->Color.BlendSrcRGB = sfactorRGB;
198   ctx->Color.BlendDstRGB = dfactorRGB;
199   ctx->Color.BlendSrcA = sfactorA;
200   ctx->Color.BlendDstA = dfactorA;
201
202   if (ctx->Driver.BlendFuncSeparate) {
203      (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
204					sfactorA, dfactorA );
205   }
206}
207
208
209#if _HAVE_FULL_GL
210
211static GLboolean
212_mesa_validate_blend_equation( GLcontext *ctx,
213			       GLenum mode, GLboolean is_separate )
214{
215   switch (mode) {
216      case GL_FUNC_ADD:
217         break;
218      case GL_MIN:
219      case GL_MAX:
220         if (!ctx->Extensions.EXT_blend_minmax &&
221             !ctx->Extensions.ARB_imaging) {
222            return GL_FALSE;
223         }
224         break;
225      /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
226       */
227      case GL_LOGIC_OP:
228         if (!ctx->Extensions.EXT_blend_logic_op || is_separate) {
229            return GL_FALSE;
230         }
231         break;
232      case GL_FUNC_SUBTRACT:
233      case GL_FUNC_REVERSE_SUBTRACT:
234         if (!ctx->Extensions.EXT_blend_subtract &&
235             !ctx->Extensions.ARB_imaging) {
236            return GL_FALSE;
237         }
238         break;
239      default:
240         return GL_FALSE;
241   }
242
243   return GL_TRUE;
244}
245
246
247/* This is really an extension function! */
248void GLAPIENTRY
249_mesa_BlendEquation( GLenum mode )
250{
251   GET_CURRENT_CONTEXT(ctx);
252   ASSERT_OUTSIDE_BEGIN_END(ctx);
253
254   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
255      _mesa_debug(ctx, "glBlendEquation %s\n",
256                  _mesa_lookup_enum_by_nr(mode));
257
258   if ( ! _mesa_validate_blend_equation( ctx, mode, GL_FALSE ) ) {
259      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
260      return;
261   }
262
263   if ( (ctx->Color.BlendEquationRGB == mode) &&
264	(ctx->Color.BlendEquationA == mode) )
265      return;
266
267   FLUSH_VERTICES(ctx, _NEW_COLOR);
268   ctx->Color.BlendEquationRGB = mode;
269   ctx->Color.BlendEquationA = mode;
270
271   if (ctx->Driver.BlendEquationSeparate)
272      (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
273}
274
275
276void GLAPIENTRY
277_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
278{
279   GET_CURRENT_CONTEXT(ctx);
280   ASSERT_OUTSIDE_BEGIN_END(ctx);
281
282   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
283      _mesa_debug(ctx, "glBlendEquationSeparateEXT %s %s\n",
284                  _mesa_lookup_enum_by_nr(modeRGB),
285                  _mesa_lookup_enum_by_nr(modeA));
286
287   if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
288      _mesa_error(ctx, GL_INVALID_OPERATION,
289		  "glBlendEquationSeparateEXT not supported by driver");
290      return;
291   }
292
293   if ( ! _mesa_validate_blend_equation( ctx, modeRGB, GL_TRUE ) ) {
294      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
295      return;
296   }
297
298   if ( ! _mesa_validate_blend_equation( ctx, modeA, GL_TRUE ) ) {
299      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
300      return;
301   }
302
303
304   if ( (ctx->Color.BlendEquationRGB == modeRGB) &&
305	(ctx->Color.BlendEquationA == modeA) )
306      return;
307
308   FLUSH_VERTICES(ctx, _NEW_COLOR);
309   ctx->Color.BlendEquationRGB = modeRGB;
310   ctx->Color.BlendEquationA = modeA;
311
312   if (ctx->Driver.BlendEquationSeparate)
313      (*ctx->Driver.BlendEquationSeparate)( ctx, modeRGB, modeA );
314}
315#endif
316
317
318/**
319 * Set the blending color.
320 *
321 * \param red red color component.
322 * \param green green color component.
323 * \param blue blue color component.
324 * \param alpha alpha color component.
325 *
326 * \sa glBlendColor().
327 *
328 * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor.  On a
329 * change, flushes the vertices and notifies the driver via
330 * dd_function_table::BlendColor callback.
331 */
332void GLAPIENTRY
333_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
334{
335   GLfloat tmp[4];
336   GET_CURRENT_CONTEXT(ctx);
337   ASSERT_OUTSIDE_BEGIN_END(ctx);
338
339   tmp[0] = CLAMP( red,   0.0F, 1.0F );
340   tmp[1] = CLAMP( green, 0.0F, 1.0F );
341   tmp[2] = CLAMP( blue,  0.0F, 1.0F );
342   tmp[3] = CLAMP( alpha, 0.0F, 1.0F );
343
344   if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
345      return;
346
347   FLUSH_VERTICES(ctx, _NEW_COLOR);
348   COPY_4FV( ctx->Color.BlendColor, tmp );
349
350   if (ctx->Driver.BlendColor)
351      (*ctx->Driver.BlendColor)(ctx, tmp);
352}
353
354
355/**
356 * Specify the alpha test function.
357 *
358 * \param func alpha comparison function.
359 * \param ref reference value.
360 *
361 * Verifies the parameters and updates gl_colorbuffer_attrib.
362 * On a change, flushes the vertices and notifies the driver via
363 * dd_function_table::AlphaFunc callback.
364 */
365void GLAPIENTRY
366_mesa_AlphaFunc( GLenum func, GLclampf ref )
367{
368   GET_CURRENT_CONTEXT(ctx);
369   ASSERT_OUTSIDE_BEGIN_END(ctx);
370
371   switch (func) {
372   case GL_NEVER:
373   case GL_LESS:
374   case GL_EQUAL:
375   case GL_LEQUAL:
376   case GL_GREATER:
377   case GL_NOTEQUAL:
378   case GL_GEQUAL:
379   case GL_ALWAYS:
380      ref = CLAMP(ref, 0.0F, 1.0F);
381
382      if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == ref)
383         return; /* no change */
384
385      FLUSH_VERTICES(ctx, _NEW_COLOR);
386      ctx->Color.AlphaFunc = func;
387      ctx->Color.AlphaRef = ref;
388
389      if (ctx->Driver.AlphaFunc)
390         ctx->Driver.AlphaFunc(ctx, func, ref);
391      return;
392
393   default:
394      _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
395      return;
396   }
397}
398
399
400/**
401 * Specify a logic pixel operation for color index rendering.
402 *
403 * \param opcode operation.
404 *
405 * Verifies that \p opcode is a valid enum and updates
406gl_colorbuffer_attrib::LogicOp.
407 * On a change, flushes the vertices and notifies the driver via the
408 * dd_function_table::LogicOpcode callback.
409 */
410void GLAPIENTRY
411_mesa_LogicOp( GLenum opcode )
412{
413   GET_CURRENT_CONTEXT(ctx);
414   ASSERT_OUTSIDE_BEGIN_END(ctx);
415
416   switch (opcode) {
417      case GL_CLEAR:
418      case GL_SET:
419      case GL_COPY:
420      case GL_COPY_INVERTED:
421      case GL_NOOP:
422      case GL_INVERT:
423      case GL_AND:
424      case GL_NAND:
425      case GL_OR:
426      case GL_NOR:
427      case GL_XOR:
428      case GL_EQUIV:
429      case GL_AND_REVERSE:
430      case GL_AND_INVERTED:
431      case GL_OR_REVERSE:
432      case GL_OR_INVERTED:
433	 break;
434      default:
435         _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
436	 return;
437   }
438
439   if (ctx->Color.LogicOp == opcode)
440      return;
441
442   FLUSH_VERTICES(ctx, _NEW_COLOR);
443   ctx->Color.LogicOp = opcode;
444
445   if (ctx->Driver.LogicOpcode)
446      ctx->Driver.LogicOpcode( ctx, opcode );
447}
448
449#if _HAVE_FULL_GL
450void GLAPIENTRY
451_mesa_IndexMask( GLuint mask )
452{
453   GET_CURRENT_CONTEXT(ctx);
454   ASSERT_OUTSIDE_BEGIN_END(ctx);
455
456   if (ctx->Color.IndexMask == mask)
457      return;
458
459   FLUSH_VERTICES(ctx, _NEW_COLOR);
460   ctx->Color.IndexMask = mask;
461
462   if (ctx->Driver.IndexMask)
463      ctx->Driver.IndexMask( ctx, mask );
464}
465#endif
466
467
468/**
469 * Enable or disable writing of frame buffer color components.
470 *
471 * \param red whether to mask writing of the red color component.
472 * \param green whether to mask writing of the green color component.
473 * \param blue whether to mask writing of the blue color component.
474 * \param alpha whether to mask writing of the alpha color component.
475 *
476 * \sa glColorMask().
477 *
478 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask.  On a
479 * change, flushes the vertices and notifies the driver via the
480 * dd_function_table::ColorMask callback.
481 */
482void GLAPIENTRY
483_mesa_ColorMask( GLboolean red, GLboolean green,
484                 GLboolean blue, GLboolean alpha )
485{
486   GET_CURRENT_CONTEXT(ctx);
487   GLubyte tmp[4];
488   ASSERT_OUTSIDE_BEGIN_END(ctx);
489
490   if (MESA_VERBOSE & VERBOSE_API)
491      _mesa_debug(ctx, "glColorMask %d %d %d %d\n", red, green, blue, alpha);
492
493   /* Shouldn't have any information about channel depth in core mesa
494    * -- should probably store these as the native booleans:
495    */
496   tmp[RCOMP] = red    ? 0xff : 0x0;
497   tmp[GCOMP] = green  ? 0xff : 0x0;
498   tmp[BCOMP] = blue   ? 0xff : 0x0;
499   tmp[ACOMP] = alpha  ? 0xff : 0x0;
500
501   if (TEST_EQ_4UBV(tmp, ctx->Color.ColorMask))
502      return;
503
504   FLUSH_VERTICES(ctx, _NEW_COLOR);
505   COPY_4UBV(ctx->Color.ColorMask, tmp);
506
507   if (ctx->Driver.ColorMask)
508      ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
509}
510
511
512extern void GLAPIENTRY
513_mesa_ClampColorARB(GLenum target, GLenum clamp)
514{
515   GET_CURRENT_CONTEXT(ctx);
516
517   ASSERT_OUTSIDE_BEGIN_END(ctx);
518
519   if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) {
520      _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)");
521      return;
522   }
523
524   switch (target) {
525   case GL_CLAMP_VERTEX_COLOR_ARB:
526      ctx->Light.ClampVertexColor = clamp;
527      break;
528   case GL_CLAMP_FRAGMENT_COLOR_ARB:
529      ctx->Color.ClampFragmentColor = clamp;
530      break;
531   case GL_CLAMP_READ_COLOR_ARB:
532      ctx->Color.ClampReadColor = clamp;
533      break;
534   default:
535      _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)");
536      return;
537   }
538}
539
540
541
542
543/**********************************************************************/
544/** \name Initialization */
545/*@{*/
546
547/**
548 * Initialization of the context's Color attribute group.
549 *
550 * \param ctx GL context.
551 *
552 * Initializes the related fields in the context color attribute group,
553 * __GLcontextRec::Color.
554 */
555void _mesa_init_color( GLcontext * ctx )
556{
557   /* Color buffer group */
558   ctx->Color.IndexMask = ~0u;
559   ctx->Color.ColorMask[0] = 0xff;
560   ctx->Color.ColorMask[1] = 0xff;
561   ctx->Color.ColorMask[2] = 0xff;
562   ctx->Color.ColorMask[3] = 0xff;
563   ctx->Color.ClearIndex = 0;
564   ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
565   ctx->Color.AlphaEnabled = GL_FALSE;
566   ctx->Color.AlphaFunc = GL_ALWAYS;
567   ctx->Color.AlphaRef = 0;
568   ctx->Color.BlendEnabled = GL_FALSE;
569   ctx->Color.BlendSrcRGB = GL_ONE;
570   ctx->Color.BlendDstRGB = GL_ZERO;
571   ctx->Color.BlendSrcA = GL_ONE;
572   ctx->Color.BlendDstA = GL_ZERO;
573   ctx->Color.BlendEquationRGB = GL_FUNC_ADD;
574   ctx->Color.BlendEquationA = GL_FUNC_ADD;
575   ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
576   ctx->Color.IndexLogicOpEnabled = GL_FALSE;
577   ctx->Color.ColorLogicOpEnabled = GL_FALSE;
578   ctx->Color._LogicOpEnabled = GL_FALSE;
579   ctx->Color.LogicOp = GL_COPY;
580   ctx->Color.DitherFlag = GL_TRUE;
581
582   if (ctx->Visual.doubleBufferMode) {
583      ctx->Color.DrawBuffer[0] = GL_BACK;
584   }
585   else {
586      ctx->Color.DrawBuffer[0] = GL_FRONT;
587   }
588
589   ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
590   ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
591}
592
593/*@}*/
594