blob: b8170dd46860eaecfc7c4fba38c28527c366ce9d [file] [log] [blame]
Keith Whitwell6dc85572003-07-17 13:43:59 +00001/**
2 * \file blend.c
3 * Blending operations.
4 */
jtgafb833d1999-08-19 00:55:39 +00005
6/*
7 * Mesa 3-D graphics library
Brian Paul813e56d2006-07-18 19:15:40 +00008 * Version: 6.5.1
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00009 *
Brian Paul813e56d2006-07-18 19:15:40 +000010 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000011 *
jtgafb833d1999-08-19 00:55:39 +000012 * 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:
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000018 *
jtgafb833d1999-08-19 00:55:39 +000019 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000021 *
jtgafb833d1999-08-19 00:55:39 +000022 * 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.
28 */
29
30
Keith Whitwell6dc85572003-07-17 13:43:59 +000031
Brian Paulfbd8f211999-11-11 01:22:25 +000032#include "glheader.h"
jtgafb833d1999-08-19 00:55:39 +000033#include "blend.h"
34#include "context.h"
35#include "enums.h"
36#include "macros.h"
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000037#include "mtypes.h"
Brian Paul2dbc5152008-06-13 16:45:15 -060038#include "glapi/glapitable.h"
jtgafb833d1999-08-19 00:55:39 +000039
40
Keith Whitwell6dc85572003-07-17 13:43:59 +000041/**
42 * Specify the blending operation.
43 *
44 * \param sfactor source factor operator.
45 * \param dfactor destination factor operator.
46 *
Ian Romanick20a17e42004-01-21 16:08:43 +000047 * \sa glBlendFunc, glBlendFuncSeparateEXT
Keith Whitwell6dc85572003-07-17 13:43:59 +000048 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +000049void GLAPIENTRY
Brian Paulb34024b2000-02-02 22:08:26 +000050_mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
jtgafb833d1999-08-19 00:55:39 +000051{
Brian Paul3a4bed82008-06-20 11:05:00 -060052 _mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor);
jtgafb833d1999-08-19 00:55:39 +000053}
54
55
Keith Whitwell6dc85572003-07-17 13:43:59 +000056/**
57 * Process GL_EXT_blend_func_separate().
58 *
59 * \param sfactorRGB RGB source factor operator.
60 * \param dfactorRGB RGB destination factor operator.
61 * \param sfactorA alpha source factor operator.
62 * \param dfactorA alpha destination factor operator.
63 *
64 * Verifies the parameters and updates gl_colorbuffer_attrib.
65 * On a change, flush the vertices and notify the driver via
66 * dd_function_table::BlendFuncSeparate.
67 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +000068void GLAPIENTRY
Brian Paulead285a2000-02-24 22:04:03 +000069_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
70 GLenum sfactorA, GLenum dfactorA )
jtgafb833d1999-08-19 00:55:39 +000071{
Brian Paulfbd8f211999-11-11 01:22:25 +000072 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +000073 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +000074
Brian Pauld66965c2009-10-23 13:06:13 -060075 if (MESA_VERBOSE & VERBOSE_API)
Brian Paul4753d602002-06-15 02:38:15 +000076 _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
77 _mesa_lookup_enum_by_nr(sfactorRGB),
78 _mesa_lookup_enum_by_nr(dfactorRGB),
79 _mesa_lookup_enum_by_nr(sfactorA),
80 _mesa_lookup_enum_by_nr(dfactorA));
jtgafb833d1999-08-19 00:55:39 +000081
82 switch (sfactorRGB) {
Brian Paulad68f172000-05-30 02:28:03 +000083 case GL_SRC_COLOR:
84 case GL_ONE_MINUS_SRC_COLOR:
Keith Whitwella96308c2000-10-30 13:31:59 +000085 if (!ctx->Extensions.NV_blend_square) {
Ian Romanickff2cc412004-01-23 07:57:32 +000086 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
Brian Paulad68f172000-05-30 02:28:03 +000087 return;
88 }
89 /* fall-through */
jtgafb833d1999-08-19 00:55:39 +000090 case GL_ZERO:
91 case GL_ONE:
92 case GL_DST_COLOR:
93 case GL_ONE_MINUS_DST_COLOR:
94 case GL_SRC_ALPHA:
95 case GL_ONE_MINUS_SRC_ALPHA:
96 case GL_DST_ALPHA:
97 case GL_ONE_MINUS_DST_ALPHA:
98 case GL_SRC_ALPHA_SATURATE:
99 case GL_CONSTANT_COLOR:
100 case GL_ONE_MINUS_CONSTANT_COLOR:
101 case GL_CONSTANT_ALPHA:
102 case GL_ONE_MINUS_CONSTANT_ALPHA:
jtgafb833d1999-08-19 00:55:39 +0000103 break;
104 default:
Ian Romanickff2cc412004-01-23 07:57:32 +0000105 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorRGB)");
jtgafb833d1999-08-19 00:55:39 +0000106 return;
107 }
108
109 switch (dfactorRGB) {
Brian Paulad68f172000-05-30 02:28:03 +0000110 case GL_DST_COLOR:
111 case GL_ONE_MINUS_DST_COLOR:
Keith Whitwella96308c2000-10-30 13:31:59 +0000112 if (!ctx->Extensions.NV_blend_square) {
Ian Romanickff2cc412004-01-23 07:57:32 +0000113 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
Brian Paulad68f172000-05-30 02:28:03 +0000114 return;
115 }
116 /* fall-through */
jtgafb833d1999-08-19 00:55:39 +0000117 case GL_ZERO:
118 case GL_ONE:
119 case GL_SRC_COLOR:
120 case GL_ONE_MINUS_SRC_COLOR:
121 case GL_SRC_ALPHA:
122 case GL_ONE_MINUS_SRC_ALPHA:
123 case GL_DST_ALPHA:
124 case GL_ONE_MINUS_DST_ALPHA:
125 case GL_CONSTANT_COLOR:
126 case GL_ONE_MINUS_CONSTANT_COLOR:
127 case GL_CONSTANT_ALPHA:
128 case GL_ONE_MINUS_CONSTANT_ALPHA:
jtgafb833d1999-08-19 00:55:39 +0000129 break;
130 default:
Ian Romanickff2cc412004-01-23 07:57:32 +0000131 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorRGB)");
jtgafb833d1999-08-19 00:55:39 +0000132 return;
133 }
134
135 switch (sfactorA) {
Brian Paulad68f172000-05-30 02:28:03 +0000136 case GL_SRC_COLOR:
137 case GL_ONE_MINUS_SRC_COLOR:
Keith Whitwella96308c2000-10-30 13:31:59 +0000138 if (!ctx->Extensions.NV_blend_square) {
Ian Romanickff2cc412004-01-23 07:57:32 +0000139 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
Brian Paulad68f172000-05-30 02:28:03 +0000140 return;
141 }
142 /* fall-through */
jtgafb833d1999-08-19 00:55:39 +0000143 case GL_ZERO:
144 case GL_ONE:
145 case GL_DST_COLOR:
146 case GL_ONE_MINUS_DST_COLOR:
147 case GL_SRC_ALPHA:
148 case GL_ONE_MINUS_SRC_ALPHA:
149 case GL_DST_ALPHA:
150 case GL_ONE_MINUS_DST_ALPHA:
151 case GL_SRC_ALPHA_SATURATE:
152 case GL_CONSTANT_COLOR:
153 case GL_ONE_MINUS_CONSTANT_COLOR:
154 case GL_CONSTANT_ALPHA:
155 case GL_ONE_MINUS_CONSTANT_ALPHA:
jtgafb833d1999-08-19 00:55:39 +0000156 break;
157 default:
Ian Romanickff2cc412004-01-23 07:57:32 +0000158 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (sfactorA)");
jtgafb833d1999-08-19 00:55:39 +0000159 return;
160 }
161
162 switch (dfactorA) {
Brian Paulad68f172000-05-30 02:28:03 +0000163 case GL_DST_COLOR:
164 case GL_ONE_MINUS_DST_COLOR:
Keith Whitwella96308c2000-10-30 13:31:59 +0000165 if (!ctx->Extensions.NV_blend_square) {
Ian Romanickff2cc412004-01-23 07:57:32 +0000166 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)");
Brian Paulad68f172000-05-30 02:28:03 +0000167 return;
168 }
169 /* fall-through */
jtgafb833d1999-08-19 00:55:39 +0000170 case GL_ZERO:
171 case GL_ONE:
172 case GL_SRC_COLOR:
173 case GL_ONE_MINUS_SRC_COLOR:
174 case GL_SRC_ALPHA:
175 case GL_ONE_MINUS_SRC_ALPHA:
176 case GL_DST_ALPHA:
177 case GL_ONE_MINUS_DST_ALPHA:
178 case GL_CONSTANT_COLOR:
179 case GL_ONE_MINUS_CONSTANT_COLOR:
180 case GL_CONSTANT_ALPHA:
181 case GL_ONE_MINUS_CONSTANT_ALPHA:
jtgafb833d1999-08-19 00:55:39 +0000182 break;
183 default:
Ian Romanickff2cc412004-01-23 07:57:32 +0000184 _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc or glBlendFuncSeparate (dfactorA)" );
jtgafb833d1999-08-19 00:55:39 +0000185 return;
186 }
187
Keith Whitwellcab974c2000-12-26 05:09:27 +0000188 if (ctx->Color.BlendSrcRGB == sfactorRGB &&
189 ctx->Color.BlendDstRGB == dfactorRGB &&
190 ctx->Color.BlendSrcA == sfactorA &&
191 ctx->Color.BlendDstA == dfactorA)
192 return;
193
194 FLUSH_VERTICES(ctx, _NEW_COLOR);
195
196 ctx->Color.BlendSrcRGB = sfactorRGB;
197 ctx->Color.BlendDstRGB = dfactorRGB;
198 ctx->Color.BlendSrcA = sfactorA;
199 ctx->Color.BlendDstA = dfactorA;
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000200
201 if (ctx->Driver.BlendFuncSeparate) {
202 (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
203 sfactorA, dfactorA );
204 }
jtgafb833d1999-08-19 00:55:39 +0000205}
206
207
Ian Romanick20a17e42004-01-21 16:08:43 +0000208#if _HAVE_FULL_GL
209
Ian Romanickc93105e2004-01-27 18:52:40 +0000210static GLboolean
211_mesa_validate_blend_equation( GLcontext *ctx,
212 GLenum mode, GLboolean is_separate )
213{
Brian Paula760ccf2004-12-03 15:24:34 +0000214 switch (mode) {
Ian Romanickc93105e2004-01-27 18:52:40 +0000215 case GL_FUNC_ADD:
216 break;
217 case GL_MIN:
218 case GL_MAX:
219 if (!ctx->Extensions.EXT_blend_minmax &&
220 !ctx->Extensions.ARB_imaging) {
221 return GL_FALSE;
222 }
223 break;
224 /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
225 */
226 case GL_LOGIC_OP:
227 if (!ctx->Extensions.EXT_blend_logic_op || is_separate) {
228 return GL_FALSE;
229 }
230 break;
231 case GL_FUNC_SUBTRACT:
232 case GL_FUNC_REVERSE_SUBTRACT:
233 if (!ctx->Extensions.EXT_blend_subtract &&
234 !ctx->Extensions.ARB_imaging) {
235 return GL_FALSE;
236 }
237 break;
238 default:
239 return GL_FALSE;
240 }
241
242 return GL_TRUE;
243}
244
245
jtgafb833d1999-08-19 00:55:39 +0000246/* This is really an extension function! */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000247void GLAPIENTRY
Brian Paulead285a2000-02-24 22:04:03 +0000248_mesa_BlendEquation( GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000249{
Brian Paulfbd8f211999-11-11 01:22:25 +0000250 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000251 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +0000252
Brian Pauld66965c2009-10-23 13:06:13 -0600253 if (MESA_VERBOSE & VERBOSE_API)
Brian Paul4753d602002-06-15 02:38:15 +0000254 _mesa_debug(ctx, "glBlendEquation %s\n",
255 _mesa_lookup_enum_by_nr(mode));
jtgafb833d1999-08-19 00:55:39 +0000256
Ian Romanickc93105e2004-01-27 18:52:40 +0000257 if ( ! _mesa_validate_blend_equation( ctx, mode, GL_FALSE ) ) {
258 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
259 return;
jtgafb833d1999-08-19 00:55:39 +0000260 }
261
Ian Romanickc93105e2004-01-27 18:52:40 +0000262 if ( (ctx->Color.BlendEquationRGB == mode) &&
263 (ctx->Color.BlendEquationA == mode) )
Keith Whitwellcab974c2000-12-26 05:09:27 +0000264 return;
Brian Paulbe3d5392001-03-07 00:21:32 +0000265
Keith Whitwellcab974c2000-12-26 05:09:27 +0000266 FLUSH_VERTICES(ctx, _NEW_COLOR);
Ian Romanickc93105e2004-01-27 18:52:40 +0000267 ctx->Color.BlendEquationRGB = mode;
268 ctx->Color.BlendEquationA = mode;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000269
Ian Romanickc93105e2004-01-27 18:52:40 +0000270 if (ctx->Driver.BlendEquationSeparate)
271 (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
jtgafb833d1999-08-19 00:55:39 +0000272}
273
Brian Paula760ccf2004-12-03 15:24:34 +0000274
Ian Romanickc93105e2004-01-27 18:52:40 +0000275void GLAPIENTRY
276_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
277{
278 GET_CURRENT_CONTEXT(ctx);
279 ASSERT_OUTSIDE_BEGIN_END(ctx);
280
Brian Pauld66965c2009-10-23 13:06:13 -0600281 if (MESA_VERBOSE & VERBOSE_API)
Ian Romanickc93105e2004-01-27 18:52:40 +0000282 _mesa_debug(ctx, "glBlendEquationSeparateEXT %s %s\n",
283 _mesa_lookup_enum_by_nr(modeRGB),
284 _mesa_lookup_enum_by_nr(modeA));
285
286 if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
287 _mesa_error(ctx, GL_INVALID_OPERATION,
288 "glBlendEquationSeparateEXT not supported by driver");
289 return;
290 }
291
292 if ( ! _mesa_validate_blend_equation( ctx, modeRGB, GL_TRUE ) ) {
293 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
294 return;
295 }
296
297 if ( ! _mesa_validate_blend_equation( ctx, modeA, GL_TRUE ) ) {
298 _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
299 return;
300 }
301
302
303 if ( (ctx->Color.BlendEquationRGB == modeRGB) &&
304 (ctx->Color.BlendEquationA == modeA) )
305 return;
306
307 FLUSH_VERTICES(ctx, _NEW_COLOR);
308 ctx->Color.BlendEquationRGB = modeRGB;
309 ctx->Color.BlendEquationA = modeA;
310
Ian Romanickc93105e2004-01-27 18:52:40 +0000311 if (ctx->Driver.BlendEquationSeparate)
312 (*ctx->Driver.BlendEquationSeparate)( ctx, modeRGB, modeA );
313}
Keith Whitwell6dc85572003-07-17 13:43:59 +0000314#endif
jtgafb833d1999-08-19 00:55:39 +0000315
316
Keith Whitwell6dc85572003-07-17 13:43:59 +0000317/**
318 * Set the blending color.
319 *
320 * \param red red color component.
321 * \param green green color component.
322 * \param blue blue color component.
323 * \param alpha alpha color component.
324 *
325 * \sa glBlendColor().
326 *
327 * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a
328 * change, flushes the vertices and notifies the driver via
329 * dd_function_table::BlendColor callback.
330 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000331void GLAPIENTRY
Brian Paulead285a2000-02-24 22:04:03 +0000332_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
jtgafb833d1999-08-19 00:55:39 +0000333{
Keith Whitwellcab974c2000-12-26 05:09:27 +0000334 GLfloat tmp[4];
Brian Paulfbd8f211999-11-11 01:22:25 +0000335 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000336 ASSERT_OUTSIDE_BEGIN_END(ctx);
337
Brian Paul7c276322001-09-14 21:36:43 +0000338 tmp[0] = CLAMP( red, 0.0F, 1.0F );
339 tmp[1] = CLAMP( green, 0.0F, 1.0F );
340 tmp[2] = CLAMP( blue, 0.0F, 1.0F );
341 tmp[3] = CLAMP( alpha, 0.0F, 1.0F );
Keith Whitwellcab974c2000-12-26 05:09:27 +0000342
343 if (TEST_EQ_4V(tmp, ctx->Color.BlendColor))
344 return;
345
346 FLUSH_VERTICES(ctx, _NEW_COLOR);
347 COPY_4FV( ctx->Color.BlendColor, tmp );
Brian Paulbe3d5392001-03-07 00:21:32 +0000348
349 if (ctx->Driver.BlendColor)
350 (*ctx->Driver.BlendColor)(ctx, tmp);
jtgafb833d1999-08-19 00:55:39 +0000351}
Brian Paul1b258982001-06-18 17:26:08 +0000352
353
Keith Whitwell6dc85572003-07-17 13:43:59 +0000354/**
355 * Specify the alpha test function.
356 *
357 * \param func alpha comparison function.
358 * \param ref reference value.
359 *
360 * Verifies the parameters and updates gl_colorbuffer_attrib.
361 * On a change, flushes the vertices and notifies the driver via
362 * dd_function_table::AlphaFunc callback.
363 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000364void GLAPIENTRY
Brian Paul1b258982001-06-18 17:26:08 +0000365_mesa_AlphaFunc( GLenum func, GLclampf ref )
366{
367 GET_CURRENT_CONTEXT(ctx);
Brian Paul1b258982001-06-18 17:26:08 +0000368 ASSERT_OUTSIDE_BEGIN_END(ctx);
369
370 switch (func) {
371 case GL_NEVER:
372 case GL_LESS:
373 case GL_EQUAL:
374 case GL_LEQUAL:
375 case GL_GREATER:
376 case GL_NOTEQUAL:
377 case GL_GEQUAL:
378 case GL_ALWAYS:
Brian Paulfc80ad62002-10-04 19:10:06 +0000379 ref = CLAMP(ref, 0.0F, 1.0F);
Brian Paul1b258982001-06-18 17:26:08 +0000380
Brian Paulfc80ad62002-10-04 19:10:06 +0000381 if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == ref)
382 return; /* no change */
Brian Paul1b258982001-06-18 17:26:08 +0000383
384 FLUSH_VERTICES(ctx, _NEW_COLOR);
385 ctx->Color.AlphaFunc = func;
Brian Paulfc80ad62002-10-04 19:10:06 +0000386 ctx->Color.AlphaRef = ref;
Brian Paul1b258982001-06-18 17:26:08 +0000387
388 if (ctx->Driver.AlphaFunc)
Brian Paulfc80ad62002-10-04 19:10:06 +0000389 ctx->Driver.AlphaFunc(ctx, func, ref);
Brian Paul1b258982001-06-18 17:26:08 +0000390 return;
391
392 default:
393 _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
394 return;
395 }
396}
397
398
Keith Whitwell6dc85572003-07-17 13:43:59 +0000399/**
400 * Specify a logic pixel operation for color index rendering.
401 *
402 * \param opcode operation.
403 *
404 * Verifies that \p opcode is a valid enum and updates
405gl_colorbuffer_attrib::LogicOp.
406 * On a change, flushes the vertices and notifies the driver via the
407 * dd_function_table::LogicOpcode callback.
408 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000409void GLAPIENTRY
Brian Paul1b258982001-06-18 17:26:08 +0000410_mesa_LogicOp( GLenum opcode )
411{
412 GET_CURRENT_CONTEXT(ctx);
413 ASSERT_OUTSIDE_BEGIN_END(ctx);
414
415 switch (opcode) {
416 case GL_CLEAR:
417 case GL_SET:
418 case GL_COPY:
419 case GL_COPY_INVERTED:
420 case GL_NOOP:
421 case GL_INVERT:
422 case GL_AND:
423 case GL_NAND:
424 case GL_OR:
425 case GL_NOR:
426 case GL_XOR:
427 case GL_EQUIV:
428 case GL_AND_REVERSE:
429 case GL_AND_INVERTED:
430 case GL_OR_REVERSE:
431 case GL_OR_INVERTED:
432 break;
433 default:
434 _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
435 return;
436 }
437
438 if (ctx->Color.LogicOp == opcode)
439 return;
440
441 FLUSH_VERTICES(ctx, _NEW_COLOR);
442 ctx->Color.LogicOp = opcode;
443
444 if (ctx->Driver.LogicOpcode)
445 ctx->Driver.LogicOpcode( ctx, opcode );
446}
447
Keith Whitwell6dc85572003-07-17 13:43:59 +0000448#if _HAVE_FULL_GL
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000449void GLAPIENTRY
Brian Paul1b258982001-06-18 17:26:08 +0000450_mesa_IndexMask( GLuint mask )
451{
452 GET_CURRENT_CONTEXT(ctx);
453 ASSERT_OUTSIDE_BEGIN_END(ctx);
454
455 if (ctx->Color.IndexMask == mask)
456 return;
457
458 FLUSH_VERTICES(ctx, _NEW_COLOR);
459 ctx->Color.IndexMask = mask;
460
461 if (ctx->Driver.IndexMask)
462 ctx->Driver.IndexMask( ctx, mask );
463}
Keith Whitwell6dc85572003-07-17 13:43:59 +0000464#endif
Brian Paul1b258982001-06-18 17:26:08 +0000465
466
Keith Whitwell6dc85572003-07-17 13:43:59 +0000467/**
468 * Enable or disable writing of frame buffer color components.
469 *
470 * \param red whether to mask writing of the red color component.
471 * \param green whether to mask writing of the green color component.
472 * \param blue whether to mask writing of the blue color component.
473 * \param alpha whether to mask writing of the alpha color component.
474 *
475 * \sa glColorMask().
476 *
477 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a
478 * change, flushes the vertices and notifies the driver via the
479 * dd_function_table::ColorMask callback.
480 */
Kendall Bennettc40d1dd2003-10-21 22:22:17 +0000481void GLAPIENTRY
Brian Paul1b258982001-06-18 17:26:08 +0000482_mesa_ColorMask( GLboolean red, GLboolean green,
483 GLboolean blue, GLboolean alpha )
484{
485 GET_CURRENT_CONTEXT(ctx);
486 GLubyte tmp[4];
Brian Paulfd5511d2009-12-29 16:17:14 -0700487 GLuint i;
488 GLboolean flushed;
Brian Paul1b258982001-06-18 17:26:08 +0000489 ASSERT_OUTSIDE_BEGIN_END(ctx);
490
491 if (MESA_VERBOSE & VERBOSE_API)
Brian Paul4753d602002-06-15 02:38:15 +0000492 _mesa_debug(ctx, "glColorMask %d %d %d %d\n", red, green, blue, alpha);
Brian Paul1b258982001-06-18 17:26:08 +0000493
494 /* Shouldn't have any information about channel depth in core mesa
495 * -- should probably store these as the native booleans:
496 */
497 tmp[RCOMP] = red ? 0xff : 0x0;
498 tmp[GCOMP] = green ? 0xff : 0x0;
499 tmp[BCOMP] = blue ? 0xff : 0x0;
500 tmp[ACOMP] = alpha ? 0xff : 0x0;
501
Brian Paulfd5511d2009-12-29 16:17:14 -0700502 flushed = GL_FALSE;
503 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
504 if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
505 if (!flushed) {
506 FLUSH_VERTICES(ctx, _NEW_COLOR);
507 }
508 flushed = GL_TRUE;
509 COPY_4UBV(ctx->Color.ColorMask[i], tmp);
510 }
511 }
Brian Paul1b258982001-06-18 17:26:08 +0000512
513 if (ctx->Driver.ColorMask)
514 ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
515}
Keith Whitwell6dc85572003-07-17 13:43:59 +0000516
Brian Paula760ccf2004-12-03 15:24:34 +0000517
Brian Paulfd5511d2009-12-29 16:17:14 -0700518/**
519 * For GL_EXT_draw_buffers2 and GL3
520 */
521void GLAPIENTRY
522_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
523 GLboolean blue, GLboolean alpha )
524{
525 GLubyte tmp[4];
526 GET_CURRENT_CONTEXT(ctx);
527 ASSERT_OUTSIDE_BEGIN_END(ctx);
528
529 if (MESA_VERBOSE & VERBOSE_API)
530 _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n",
531 buf, red, green, blue, alpha);
532
533 if (buf >= ctx->Const.MaxDrawBuffers) {
534 _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf);
535 return;
536 }
537
538 /* Shouldn't have any information about channel depth in core mesa
539 * -- should probably store these as the native booleans:
540 */
541 tmp[RCOMP] = red ? 0xff : 0x0;
542 tmp[GCOMP] = green ? 0xff : 0x0;
543 tmp[BCOMP] = blue ? 0xff : 0x0;
544 tmp[ACOMP] = alpha ? 0xff : 0x0;
545
546 if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf]))
547 return;
548
549 FLUSH_VERTICES(ctx, _NEW_COLOR);
550 COPY_4UBV(ctx->Color.ColorMask[buf], tmp);
551
552 if (ctx->Driver.ColorMaskIndexed)
553 ctx->Driver.ColorMaskIndexed(ctx, buf, red, green, blue, alpha);
554}
555
556
Brian Paul0b26e822006-10-22 17:18:50 +0000557extern void GLAPIENTRY
558_mesa_ClampColorARB(GLenum target, GLenum clamp)
559{
560 GET_CURRENT_CONTEXT(ctx);
561
562 ASSERT_OUTSIDE_BEGIN_END(ctx);
563
564 if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) {
565 _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)");
566 return;
567 }
568
569 switch (target) {
570 case GL_CLAMP_VERTEX_COLOR_ARB:
571 ctx->Light.ClampVertexColor = clamp;
572 break;
573 case GL_CLAMP_FRAGMENT_COLOR_ARB:
574 ctx->Color.ClampFragmentColor = clamp;
575 break;
576 case GL_CLAMP_READ_COLOR_ARB:
577 ctx->Color.ClampReadColor = clamp;
578 break;
579 default:
580 _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)");
581 return;
582 }
583}
584
585
586
587
Keith Whitwell6dc85572003-07-17 13:43:59 +0000588/**********************************************************************/
589/** \name Initialization */
590/*@{*/
591
592/**
Brian Paul894844a2004-03-21 17:05:03 +0000593 * Initialization of the context's Color attribute group.
Keith Whitwell6dc85572003-07-17 13:43:59 +0000594 *
595 * \param ctx GL context.
596 *
597 * Initializes the related fields in the context color attribute group,
598 * __GLcontextRec::Color.
599 */
600void _mesa_init_color( GLcontext * ctx )
601{
602 /* Color buffer group */
Brian Paula760ccf2004-12-03 15:24:34 +0000603 ctx->Color.IndexMask = ~0u;
Brian Paulfd5511d2009-12-29 16:17:14 -0700604 memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
Keith Whitwell6dc85572003-07-17 13:43:59 +0000605 ctx->Color.ClearIndex = 0;
606 ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
Keith Whitwell6dc85572003-07-17 13:43:59 +0000607 ctx->Color.AlphaEnabled = GL_FALSE;
608 ctx->Color.AlphaFunc = GL_ALWAYS;
609 ctx->Color.AlphaRef = 0;
Brian Paul37286732009-12-29 15:04:03 -0700610 ctx->Color.BlendEnabled = 0x0;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000611 ctx->Color.BlendSrcRGB = GL_ONE;
612 ctx->Color.BlendDstRGB = GL_ZERO;
613 ctx->Color.BlendSrcA = GL_ONE;
614 ctx->Color.BlendDstA = GL_ZERO;
Ian Romanickc93105e2004-01-27 18:52:40 +0000615 ctx->Color.BlendEquationRGB = GL_FUNC_ADD;
616 ctx->Color.BlendEquationA = GL_FUNC_ADD;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000617 ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
618 ctx->Color.IndexLogicOpEnabled = GL_FALSE;
619 ctx->Color.ColorLogicOpEnabled = GL_FALSE;
Brian Paul57857ca2003-11-12 15:27:52 +0000620 ctx->Color._LogicOpEnabled = GL_FALSE;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000621 ctx->Color.LogicOp = GL_COPY;
622 ctx->Color.DitherFlag = GL_TRUE;
623
624 if (ctx->Visual.doubleBufferMode) {
Brian Paul53f82c52004-10-02 16:39:09 +0000625 ctx->Color.DrawBuffer[0] = GL_BACK;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000626 }
627 else {
Brian Paul53f82c52004-10-02 16:39:09 +0000628 ctx->Color.DrawBuffer[0] = GL_FRONT;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000629 }
Brian Paulba3da612005-11-12 18:44:29 +0000630
631 ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
632 ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
Keith Whitwell6dc85572003-07-17 13:43:59 +0000633}
634
635/*@}*/