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