7 * Mesa 3-D graphics library
10 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 * Specify the blending operation.
44 * \param sfactor source factor operator.
45 * \param dfactor destination factor operator.
49 * Verifies the parameters and updates gl_colorbuffer_attrib. On a change,
50 * flushes the vertices and notifies the driver via
51 * dd_function_table::BlendFunc callback.
54 _mesa_BlendFunc( GLenum sfactor
, GLenum dfactor
)
57 GET_CURRENT_CONTEXT(ctx
);
58 ASSERT_OUTSIDE_BEGIN_END(ctx
);
60 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
61 _mesa_debug(ctx
, "glBlendFunc %s %s\n",
62 _mesa_lookup_enum_by_nr(sfactor
),
63 _mesa_lookup_enum_by_nr(dfactor
));
67 case GL_ONE_MINUS_SRC_COLOR
:
68 if (!ctx
->Extensions
.NV_blend_square
) {
69 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
76 case GL_ONE_MINUS_DST_COLOR
:
78 case GL_ONE_MINUS_SRC_ALPHA
:
80 case GL_ONE_MINUS_DST_ALPHA
:
81 case GL_SRC_ALPHA_SATURATE
:
82 case GL_CONSTANT_COLOR
:
83 case GL_ONE_MINUS_CONSTANT_COLOR
:
84 case GL_CONSTANT_ALPHA
:
85 case GL_ONE_MINUS_CONSTANT_ALPHA
:
88 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
94 case GL_ONE_MINUS_DST_COLOR
:
95 if (!ctx
->Extensions
.NV_blend_square
) {
96 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
103 case GL_ONE_MINUS_SRC_COLOR
:
105 case GL_ONE_MINUS_SRC_ALPHA
:
107 case GL_ONE_MINUS_DST_ALPHA
:
108 case GL_CONSTANT_COLOR
:
109 case GL_ONE_MINUS_CONSTANT_COLOR
:
110 case GL_CONSTANT_ALPHA
:
111 case GL_ONE_MINUS_CONSTANT_ALPHA
:
114 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
118 if (ctx
->Color
.BlendDstRGB
== dfactor
&&
119 ctx
->Color
.BlendSrcRGB
== sfactor
&&
120 ctx
->Color
.BlendDstA
== dfactor
&&
121 ctx
->Color
.BlendSrcA
== sfactor
)
124 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
125 ctx
->Color
.BlendDstRGB
= ctx
->Color
.BlendDstA
= dfactor
;
126 ctx
->Color
.BlendSrcRGB
= ctx
->Color
.BlendSrcA
= sfactor
;
128 if (ctx
->Driver
.BlendFunc
)
129 ctx
->Driver
.BlendFunc( ctx
, sfactor
, dfactor
);
136 * Process GL_EXT_blend_func_separate().
138 * \param sfactorRGB RGB source factor operator.
139 * \param dfactorRGB RGB destination factor operator.
140 * \param sfactorA alpha source factor operator.
141 * \param dfactorA alpha destination factor operator.
143 * Verifies the parameters and updates gl_colorbuffer_attrib.
144 * On a change, flush the vertices and notify the driver via
145 * dd_function_table::BlendFuncSeparate.
148 _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB
, GLenum dfactorRGB
,
149 GLenum sfactorA
, GLenum dfactorA
)
151 GET_CURRENT_CONTEXT(ctx
);
152 ASSERT_OUTSIDE_BEGIN_END(ctx
);
154 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
155 _mesa_debug(ctx
, "glBlendFuncSeparate %s %s %s %s\n",
156 _mesa_lookup_enum_by_nr(sfactorRGB
),
157 _mesa_lookup_enum_by_nr(dfactorRGB
),
158 _mesa_lookup_enum_by_nr(sfactorA
),
159 _mesa_lookup_enum_by_nr(dfactorA
));
161 switch (sfactorRGB
) {
163 case GL_ONE_MINUS_SRC_COLOR
:
164 if (!ctx
->Extensions
.NV_blend_square
) {
165 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
172 case GL_ONE_MINUS_DST_COLOR
:
174 case GL_ONE_MINUS_SRC_ALPHA
:
176 case GL_ONE_MINUS_DST_ALPHA
:
177 case GL_SRC_ALPHA_SATURATE
:
178 case GL_CONSTANT_COLOR
:
179 case GL_ONE_MINUS_CONSTANT_COLOR
:
180 case GL_CONSTANT_ALPHA
:
181 case GL_ONE_MINUS_CONSTANT_ALPHA
:
184 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
188 switch (dfactorRGB
) {
190 case GL_ONE_MINUS_DST_COLOR
:
191 if (!ctx
->Extensions
.NV_blend_square
) {
192 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
199 case GL_ONE_MINUS_SRC_COLOR
:
201 case GL_ONE_MINUS_SRC_ALPHA
:
203 case GL_ONE_MINUS_DST_ALPHA
:
204 case GL_CONSTANT_COLOR
:
205 case GL_ONE_MINUS_CONSTANT_COLOR
:
206 case GL_CONSTANT_ALPHA
:
207 case GL_ONE_MINUS_CONSTANT_ALPHA
:
210 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
216 case GL_ONE_MINUS_SRC_COLOR
:
217 if (!ctx
->Extensions
.NV_blend_square
) {
218 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
225 case GL_ONE_MINUS_DST_COLOR
:
227 case GL_ONE_MINUS_SRC_ALPHA
:
229 case GL_ONE_MINUS_DST_ALPHA
:
230 case GL_SRC_ALPHA_SATURATE
:
231 case GL_CONSTANT_COLOR
:
232 case GL_ONE_MINUS_CONSTANT_COLOR
:
233 case GL_CONSTANT_ALPHA
:
234 case GL_ONE_MINUS_CONSTANT_ALPHA
:
237 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
243 case GL_ONE_MINUS_DST_COLOR
:
244 if (!ctx
->Extensions
.NV_blend_square
) {
245 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)");
252 case GL_ONE_MINUS_SRC_COLOR
:
254 case GL_ONE_MINUS_SRC_ALPHA
:
256 case GL_ONE_MINUS_DST_ALPHA
:
257 case GL_CONSTANT_COLOR
:
258 case GL_ONE_MINUS_CONSTANT_COLOR
:
259 case GL_CONSTANT_ALPHA
:
260 case GL_ONE_MINUS_CONSTANT_ALPHA
:
263 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)" );
267 if (ctx
->Color
.BlendSrcRGB
== sfactorRGB
&&
268 ctx
->Color
.BlendDstRGB
== dfactorRGB
&&
269 ctx
->Color
.BlendSrcA
== sfactorA
&&
270 ctx
->Color
.BlendDstA
== dfactorA
)
273 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
275 ctx
->Color
.BlendSrcRGB
= sfactorRGB
;
276 ctx
->Color
.BlendDstRGB
= dfactorRGB
;
277 ctx
->Color
.BlendSrcA
= sfactorA
;
278 ctx
->Color
.BlendDstA
= dfactorA
;
280 if (ctx
->Driver
.BlendFuncSeparate
) {
281 (*ctx
->Driver
.BlendFuncSeparate
)( ctx
, sfactorRGB
, dfactorRGB
,
282 sfactorA
, dfactorA
);
287 /* This is really an extension function! */
289 _mesa_BlendEquation( GLenum mode
)
291 GET_CURRENT_CONTEXT(ctx
);
292 ASSERT_OUTSIDE_BEGIN_END(ctx
);
294 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
295 _mesa_debug(ctx
, "glBlendEquation %s\n",
296 _mesa_lookup_enum_by_nr(mode
));
299 case GL_FUNC_ADD_EXT
:
303 if (!ctx
->Extensions
.EXT_blend_minmax
&&
304 !ctx
->Extensions
.ARB_imaging
) {
305 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
310 if (!ctx
->Extensions
.EXT_blend_logic_op
) {
311 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
315 case GL_FUNC_SUBTRACT_EXT
:
316 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
317 if (!ctx
->Extensions
.EXT_blend_subtract
&&
318 !ctx
->Extensions
.ARB_imaging
) {
319 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
324 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendEquation" );
328 if (ctx
->Color
.BlendEquation
== mode
)
331 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
332 ctx
->Color
.BlendEquation
= mode
;
334 /* This is needed to support 1.1's RGB logic ops AND
335 * 1.0's blending logicops.
337 ctx
->Color
._LogicOpEnabled
= (ctx
->Color
.ColorLogicOpEnabled
||
338 (ctx
->Color
.BlendEnabled
&&
339 mode
== GL_LOGIC_OP
));
341 if (ctx
->Driver
.BlendEquation
)
342 (*ctx
->Driver
.BlendEquation
)( ctx
, mode
);
349 * Set the blending color.
351 * \param red red color component.
352 * \param green green color component.
353 * \param blue blue color component.
354 * \param alpha alpha color component.
356 * \sa glBlendColor().
358 * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a
359 * change, flushes the vertices and notifies the driver via
360 * dd_function_table::BlendColor callback.
363 _mesa_BlendColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
366 GET_CURRENT_CONTEXT(ctx
);
367 ASSERT_OUTSIDE_BEGIN_END(ctx
);
369 tmp
[0] = CLAMP( red
, 0.0F
, 1.0F
);
370 tmp
[1] = CLAMP( green
, 0.0F
, 1.0F
);
371 tmp
[2] = CLAMP( blue
, 0.0F
, 1.0F
);
372 tmp
[3] = CLAMP( alpha
, 0.0F
, 1.0F
);
374 if (TEST_EQ_4V(tmp
, ctx
->Color
.BlendColor
))
377 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
378 COPY_4FV( ctx
->Color
.BlendColor
, tmp
);
380 if (ctx
->Driver
.BlendColor
)
381 (*ctx
->Driver
.BlendColor
)(ctx
, tmp
);
386 * Specify the alpha test function.
388 * \param func alpha comparison function.
389 * \param ref reference value.
391 * Verifies the parameters and updates gl_colorbuffer_attrib.
392 * On a change, flushes the vertices and notifies the driver via
393 * dd_function_table::AlphaFunc callback.
396 _mesa_AlphaFunc( GLenum func
, GLclampf ref
)
398 GET_CURRENT_CONTEXT(ctx
);
399 ASSERT_OUTSIDE_BEGIN_END(ctx
);
410 ref
= CLAMP(ref
, 0.0F
, 1.0F
);
412 if (ctx
->Color
.AlphaFunc
== func
&& ctx
->Color
.AlphaRef
== ref
)
413 return; /* no change */
415 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
416 ctx
->Color
.AlphaFunc
= func
;
417 ctx
->Color
.AlphaRef
= ref
;
419 if (ctx
->Driver
.AlphaFunc
)
420 ctx
->Driver
.AlphaFunc(ctx
, func
, ref
);
424 _mesa_error( ctx
, GL_INVALID_ENUM
, "glAlphaFunc(func)" );
431 * Specify a logic pixel operation for color index rendering.
433 * \param opcode operation.
435 * Verifies that \p opcode is a valid enum and updates
436 gl_colorbuffer_attrib::LogicOp.
437 * On a change, flushes the vertices and notifies the driver via the
438 * dd_function_table::LogicOpcode callback.
441 _mesa_LogicOp( GLenum opcode
)
443 GET_CURRENT_CONTEXT(ctx
);
444 ASSERT_OUTSIDE_BEGIN_END(ctx
);
450 case GL_COPY_INVERTED
:
460 case GL_AND_INVERTED
:
465 _mesa_error( ctx
, GL_INVALID_ENUM
, "glLogicOp" );
469 if (ctx
->Color
.LogicOp
== opcode
)
472 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
473 ctx
->Color
.LogicOp
= opcode
;
475 if (ctx
->Driver
.LogicOpcode
)
476 ctx
->Driver
.LogicOpcode( ctx
, opcode
);
481 _mesa_IndexMask( GLuint mask
)
483 GET_CURRENT_CONTEXT(ctx
);
484 ASSERT_OUTSIDE_BEGIN_END(ctx
);
486 if (ctx
->Color
.IndexMask
== mask
)
489 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
490 ctx
->Color
.IndexMask
= mask
;
492 if (ctx
->Driver
.IndexMask
)
493 ctx
->Driver
.IndexMask( ctx
, mask
);
499 * Enable or disable writing of frame buffer color components.
501 * \param red whether to mask writing of the red color component.
502 * \param green whether to mask writing of the green color component.
503 * \param blue whether to mask writing of the blue color component.
504 * \param alpha whether to mask writing of the alpha color component.
508 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a
509 * change, flushes the vertices and notifies the driver via the
510 * dd_function_table::ColorMask callback.
513 _mesa_ColorMask( GLboolean red
, GLboolean green
,
514 GLboolean blue
, GLboolean alpha
)
516 GET_CURRENT_CONTEXT(ctx
);
518 ASSERT_OUTSIDE_BEGIN_END(ctx
);
520 if (MESA_VERBOSE
& VERBOSE_API
)
521 _mesa_debug(ctx
, "glColorMask %d %d %d %d\n", red
, green
, blue
, alpha
);
523 /* Shouldn't have any information about channel depth in core mesa
524 * -- should probably store these as the native booleans:
526 tmp
[RCOMP
] = red
? 0xff : 0x0;
527 tmp
[GCOMP
] = green
? 0xff : 0x0;
528 tmp
[BCOMP
] = blue
? 0xff : 0x0;
529 tmp
[ACOMP
] = alpha
? 0xff : 0x0;
531 if (TEST_EQ_4UBV(tmp
, ctx
->Color
.ColorMask
))
534 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
535 COPY_4UBV(ctx
->Color
.ColorMask
, tmp
);
537 if (ctx
->Driver
.ColorMask
)
538 ctx
->Driver
.ColorMask( ctx
, red
, green
, blue
, alpha
);
541 /**********************************************************************/
542 /** \name Initialization */
546 * Initialization of the context color data.
548 * \param ctx GL context.
550 * Initializes the related fields in the context color attribute group,
551 * __GLcontextRec::Color.
553 void _mesa_init_color( GLcontext
* ctx
)
555 /* Color buffer group */
556 ctx
->Color
.IndexMask
= 0xffffffff;
557 ctx
->Color
.ColorMask
[0] = 0xff;
558 ctx
->Color
.ColorMask
[1] = 0xff;
559 ctx
->Color
.ColorMask
[2] = 0xff;
560 ctx
->Color
.ColorMask
[3] = 0xff;
561 ctx
->Color
.ClearIndex
= 0;
562 ASSIGN_4V( ctx
->Color
.ClearColor
, 0, 0, 0, 0 );
563 ctx
->Color
.DrawBuffer
= GL_FRONT
;
564 ctx
->Color
.AlphaEnabled
= GL_FALSE
;
565 ctx
->Color
.AlphaFunc
= GL_ALWAYS
;
566 ctx
->Color
.AlphaRef
= 0;
567 ctx
->Color
.BlendEnabled
= GL_FALSE
;
568 ctx
->Color
.BlendSrcRGB
= GL_ONE
;
569 ctx
->Color
.BlendDstRGB
= GL_ZERO
;
570 ctx
->Color
.BlendSrcA
= GL_ONE
;
571 ctx
->Color
.BlendDstA
= GL_ZERO
;
572 ctx
->Color
.BlendEquation
= GL_FUNC_ADD_EXT
;
573 ASSIGN_4V( ctx
->Color
.BlendColor
, 0.0, 0.0, 0.0, 0.0 );
574 ctx
->Color
.IndexLogicOpEnabled
= GL_FALSE
;
575 ctx
->Color
.ColorLogicOpEnabled
= GL_FALSE
;
576 ctx
->Color
._LogicOpEnabled
= GL_FALSE
;
577 ctx
->Color
.LogicOp
= GL_COPY
;
578 ctx
->Color
.DitherFlag
= GL_TRUE
;
580 if (ctx
->Visual
.doubleBufferMode
) {
581 ctx
->Color
.DrawBuffer
= GL_BACK
;
582 ctx
->Color
._DrawDestMask
= BACK_LEFT_BIT
;
585 ctx
->Color
.DrawBuffer
= GL_FRONT
;
586 ctx
->Color
._DrawDestMask
= FRONT_LEFT_BIT
;