1 /* $Id: blend.c,v 1.31 2001/03/12 00:48:37 gareth Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
41 _mesa_BlendFunc( GLenum sfactor
, GLenum dfactor
)
44 GET_CURRENT_CONTEXT(ctx
);
45 ASSERT_OUTSIDE_BEGIN_END(ctx
);
47 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
48 fprintf(stderr
, "glBlendFunc %s %s\n",
49 _mesa_lookup_enum_by_nr(sfactor
),
50 _mesa_lookup_enum_by_nr(dfactor
));
54 case GL_ONE_MINUS_SRC_COLOR
:
55 if (!ctx
->Extensions
.NV_blend_square
) {
56 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
63 case GL_ONE_MINUS_DST_COLOR
:
65 case GL_ONE_MINUS_SRC_ALPHA
:
67 case GL_ONE_MINUS_DST_ALPHA
:
68 case GL_SRC_ALPHA_SATURATE
:
69 case GL_CONSTANT_COLOR
:
70 case GL_ONE_MINUS_CONSTANT_COLOR
:
71 case GL_CONSTANT_ALPHA
:
72 case GL_ONE_MINUS_CONSTANT_ALPHA
:
75 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
81 case GL_ONE_MINUS_DST_COLOR
:
82 if (!ctx
->Extensions
.NV_blend_square
) {
83 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
90 case GL_ONE_MINUS_SRC_COLOR
:
92 case GL_ONE_MINUS_SRC_ALPHA
:
94 case GL_ONE_MINUS_DST_ALPHA
:
95 case GL_CONSTANT_COLOR
:
96 case GL_ONE_MINUS_CONSTANT_COLOR
:
97 case GL_CONSTANT_ALPHA
:
98 case GL_ONE_MINUS_CONSTANT_ALPHA
:
101 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
105 if (ctx
->Color
.BlendDstRGB
== dfactor
&&
106 ctx
->Color
.BlendSrcRGB
== sfactor
&&
107 ctx
->Color
.BlendDstA
== dfactor
&&
108 ctx
->Color
.BlendSrcA
== sfactor
)
111 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
112 ctx
->Color
.BlendDstRGB
= ctx
->Color
.BlendDstA
= dfactor
;
113 ctx
->Color
.BlendSrcRGB
= ctx
->Color
.BlendSrcA
= sfactor
;
115 if (ctx
->Driver
.BlendFunc
)
116 ctx
->Driver
.BlendFunc( ctx
, sfactor
, dfactor
);
120 /* GL_EXT_blend_func_separate */
122 _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB
, GLenum dfactorRGB
,
123 GLenum sfactorA
, GLenum dfactorA
)
125 GET_CURRENT_CONTEXT(ctx
);
126 ASSERT_OUTSIDE_BEGIN_END(ctx
);
128 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
129 fprintf(stderr
, "glBlendFuncSeperate %s %s %s %s\n",
130 _mesa_lookup_enum_by_nr(sfactorRGB
),
131 _mesa_lookup_enum_by_nr(dfactorRGB
),
132 _mesa_lookup_enum_by_nr(sfactorA
),
133 _mesa_lookup_enum_by_nr(dfactorA
));
135 switch (sfactorRGB
) {
137 case GL_ONE_MINUS_SRC_COLOR
:
138 if (!ctx
->Extensions
.NV_blend_square
) {
139 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
146 case GL_ONE_MINUS_DST_COLOR
:
148 case GL_ONE_MINUS_SRC_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
:
158 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
162 switch (dfactorRGB
) {
164 case GL_ONE_MINUS_DST_COLOR
:
165 if (!ctx
->Extensions
.NV_blend_square
) {
166 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
173 case GL_ONE_MINUS_SRC_COLOR
:
175 case GL_ONE_MINUS_SRC_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
:
184 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
190 case GL_ONE_MINUS_SRC_COLOR
:
191 if (!ctx
->Extensions
.NV_blend_square
) {
192 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
199 case GL_ONE_MINUS_DST_COLOR
:
201 case GL_ONE_MINUS_SRC_ALPHA
:
203 case GL_ONE_MINUS_DST_ALPHA
:
204 case GL_SRC_ALPHA_SATURATE
:
205 case GL_CONSTANT_COLOR
:
206 case GL_ONE_MINUS_CONSTANT_COLOR
:
207 case GL_CONSTANT_ALPHA
:
208 case GL_ONE_MINUS_CONSTANT_ALPHA
:
211 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
217 case GL_ONE_MINUS_DST_COLOR
:
218 if (!ctx
->Extensions
.NV_blend_square
) {
219 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)");
226 case GL_ONE_MINUS_SRC_COLOR
:
228 case GL_ONE_MINUS_SRC_ALPHA
:
230 case GL_ONE_MINUS_DST_ALPHA
:
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(dfactorA)" );
241 if (ctx
->Color
.BlendSrcRGB
== sfactorRGB
&&
242 ctx
->Color
.BlendDstRGB
== dfactorRGB
&&
243 ctx
->Color
.BlendSrcA
== sfactorA
&&
244 ctx
->Color
.BlendDstA
== dfactorA
)
247 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
249 ctx
->Color
.BlendSrcRGB
= sfactorRGB
;
250 ctx
->Color
.BlendDstRGB
= dfactorRGB
;
251 ctx
->Color
.BlendSrcA
= sfactorA
;
252 ctx
->Color
.BlendDstA
= dfactorA
;
254 if (ctx
->Driver
.BlendFuncSeparate
) {
255 (*ctx
->Driver
.BlendFuncSeparate
)( ctx
, sfactorRGB
, dfactorRGB
,
256 sfactorA
, dfactorA
);
262 /* This is really an extension function! */
264 _mesa_BlendEquation( GLenum mode
)
266 GET_CURRENT_CONTEXT(ctx
);
267 ASSERT_OUTSIDE_BEGIN_END(ctx
);
269 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
270 fprintf(stderr
, "glBlendEquation %s\n",
271 _mesa_lookup_enum_by_nr(mode
));
274 case GL_FUNC_ADD_EXT
:
278 if (!ctx
->Extensions
.EXT_blend_minmax
&&
279 !ctx
->Extensions
.ARB_imaging
) {
280 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
285 if (!ctx
->Extensions
.EXT_blend_logic_op
) {
286 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
290 case GL_FUNC_SUBTRACT_EXT
:
291 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
292 if (!ctx
->Extensions
.EXT_blend_subtract
&&
293 !ctx
->Extensions
.ARB_imaging
) {
294 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
299 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBlendEquation" );
303 if (ctx
->Color
.BlendEquation
== mode
)
306 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
307 ctx
->Color
.BlendEquation
= mode
;
309 /* This is needed to support 1.1's RGB logic ops AND
310 * 1.0's blending logicops.
312 ctx
->Color
.ColorLogicOpEnabled
= (mode
==GL_LOGIC_OP
&&
313 ctx
->Color
.BlendEnabled
);
315 if (ctx
->Driver
.BlendEquation
)
316 (*ctx
->Driver
.BlendEquation
)( ctx
, mode
);
322 _mesa_BlendColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
325 GET_CURRENT_CONTEXT(ctx
);
326 ASSERT_OUTSIDE_BEGIN_END(ctx
);
328 tmp
[0] = CLAMP( red
, 0.0, 1.0 );
329 tmp
[1] = CLAMP( green
, 0.0, 1.0 );
330 tmp
[2] = CLAMP( blue
, 0.0, 1.0 );
331 tmp
[3] = CLAMP( alpha
, 0.0, 1.0 );
333 if (TEST_EQ_4V(tmp
, ctx
->Color
.BlendColor
))
336 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
337 COPY_4FV( ctx
->Color
.BlendColor
, tmp
);
339 if (ctx
->Driver
.BlendColor
)
340 (*ctx
->Driver
.BlendColor
)(ctx
, tmp
);