1 /* $Id: blend.c,v 1.27 2000/12/26 05:09:27 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 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.
42 _mesa_BlendFunc( GLenum sfactor
, GLenum dfactor
)
45 GET_CURRENT_CONTEXT(ctx
);
46 ASSERT_OUTSIDE_BEGIN_END(ctx
);
48 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
49 fprintf(stderr
, "glBlendFunc %s %s\n",
50 gl_lookup_enum_by_nr(sfactor
),
51 gl_lookup_enum_by_nr(dfactor
));
55 case GL_ONE_MINUS_SRC_COLOR
:
56 if (!ctx
->Extensions
.NV_blend_square
) {
57 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
64 case GL_ONE_MINUS_DST_COLOR
:
66 case GL_ONE_MINUS_SRC_ALPHA
:
68 case GL_ONE_MINUS_DST_ALPHA
:
69 case GL_SRC_ALPHA_SATURATE
:
70 case GL_CONSTANT_COLOR
:
71 case GL_ONE_MINUS_CONSTANT_COLOR
:
72 case GL_CONSTANT_ALPHA
:
73 case GL_ONE_MINUS_CONSTANT_ALPHA
:
76 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
82 case GL_ONE_MINUS_DST_COLOR
:
83 if (!ctx
->Extensions
.NV_blend_square
) {
84 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
91 case GL_ONE_MINUS_SRC_COLOR
:
93 case GL_ONE_MINUS_SRC_ALPHA
:
95 case GL_ONE_MINUS_DST_ALPHA
:
96 case GL_CONSTANT_COLOR
:
97 case GL_ONE_MINUS_CONSTANT_COLOR
:
98 case GL_CONSTANT_ALPHA
:
99 case GL_ONE_MINUS_CONSTANT_ALPHA
:
102 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
106 if (ctx
->Color
.BlendDstRGB
== dfactor
&&
107 ctx
->Color
.BlendSrcRGB
== sfactor
&&
108 ctx
->Color
.BlendDstA
== dfactor
&&
109 ctx
->Color
.BlendSrcA
== sfactor
)
112 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
113 ctx
->Color
.BlendDstRGB
= ctx
->Color
.BlendDstA
= dfactor
;
114 ctx
->Color
.BlendSrcRGB
= ctx
->Color
.BlendSrcA
= sfactor
;
116 if (ctx
->Driver
.BlendFunc
)
117 ctx
->Driver
.BlendFunc( ctx
, sfactor
, dfactor
);
121 /* GL_EXT_blend_func_separate */
123 _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB
, GLenum dfactorRGB
,
124 GLenum sfactorA
, GLenum dfactorA
)
126 GET_CURRENT_CONTEXT(ctx
);
127 ASSERT_OUTSIDE_BEGIN_END(ctx
);
129 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
130 fprintf(stderr
, "glBlendFuncSeperate %s %s %s %s\n",
131 gl_lookup_enum_by_nr(sfactorRGB
),
132 gl_lookup_enum_by_nr(dfactorRGB
),
133 gl_lookup_enum_by_nr(sfactorA
),
134 gl_lookup_enum_by_nr(dfactorA
));
136 switch (sfactorRGB
) {
138 case GL_ONE_MINUS_SRC_COLOR
:
139 if (!ctx
->Extensions
.NV_blend_square
) {
140 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
147 case GL_ONE_MINUS_DST_COLOR
:
149 case GL_ONE_MINUS_SRC_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
:
159 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)");
163 switch (dfactorRGB
) {
165 case GL_ONE_MINUS_DST_COLOR
:
166 if (!ctx
->Extensions
.NV_blend_square
) {
167 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
174 case GL_ONE_MINUS_SRC_COLOR
:
176 case GL_ONE_MINUS_SRC_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
:
185 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)");
191 case GL_ONE_MINUS_SRC_COLOR
:
192 if (!ctx
->Extensions
.NV_blend_square
) {
193 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
200 case GL_ONE_MINUS_DST_COLOR
:
202 case GL_ONE_MINUS_SRC_ALPHA
:
204 case GL_ONE_MINUS_DST_ALPHA
:
205 case GL_SRC_ALPHA_SATURATE
:
206 case GL_CONSTANT_COLOR
:
207 case GL_ONE_MINUS_CONSTANT_COLOR
:
208 case GL_CONSTANT_ALPHA
:
209 case GL_ONE_MINUS_CONSTANT_ALPHA
:
212 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)");
218 case GL_ONE_MINUS_DST_COLOR
:
219 if (!ctx
->Extensions
.NV_blend_square
) {
220 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)");
227 case GL_ONE_MINUS_SRC_COLOR
:
229 case GL_ONE_MINUS_SRC_ALPHA
:
231 case GL_ONE_MINUS_DST_ALPHA
:
232 case GL_CONSTANT_COLOR
:
233 case GL_ONE_MINUS_CONSTANT_COLOR
:
234 case GL_CONSTANT_ALPHA
:
235 case GL_ONE_MINUS_CONSTANT_ALPHA
:
238 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)" );
242 if (ctx
->Color
.BlendSrcRGB
== sfactorRGB
&&
243 ctx
->Color
.BlendDstRGB
== dfactorRGB
&&
244 ctx
->Color
.BlendSrcA
== sfactorA
&&
245 ctx
->Color
.BlendDstA
== dfactorA
)
248 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
250 ctx
->Color
.BlendSrcRGB
= sfactorRGB
;
251 ctx
->Color
.BlendDstRGB
= dfactorRGB
;
252 ctx
->Color
.BlendSrcA
= sfactorA
;
253 ctx
->Color
.BlendDstA
= dfactorA
;
255 if (ctx
->Driver
.BlendFuncSeparate
) {
256 (*ctx
->Driver
.BlendFuncSeparate
)( ctx
, sfactorRGB
, dfactorRGB
,
257 sfactorA
, dfactorA
);
263 /* This is really an extension function! */
265 _mesa_BlendEquation( GLenum mode
)
267 GET_CURRENT_CONTEXT(ctx
);
268 ASSERT_OUTSIDE_BEGIN_END(ctx
);
270 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
271 fprintf(stderr
, "glBlendEquation %s\n",
272 gl_lookup_enum_by_nr(mode
));
277 case GL_FUNC_ADD_EXT
:
278 if (!ctx
->Extensions
.EXT_blend_minmax
) {
279 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
284 case GL_FUNC_SUBTRACT_EXT
:
285 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
286 if (!ctx
->Extensions
.EXT_blend_subtract
) {
287 gl_error(ctx
, GL_INVALID_ENUM
, "glBlendEquation");
292 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendEquation" );
296 if (ctx
->Color
.BlendEquation
== mode
)
299 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
300 ctx
->Color
.BlendEquation
= mode
;
302 /* This is needed to support 1.1's RGB logic ops AND
303 * 1.0's blending logicops.
305 ctx
->Color
.ColorLogicOpEnabled
= (mode
==GL_LOGIC_OP
&&
306 ctx
->Color
.BlendEnabled
);
308 if (ctx
->Driver
.BlendEquation
)
309 ctx
->Driver
.BlendEquation( ctx
, mode
);
315 _mesa_BlendColor( GLclampf red
, GLclampf green
, GLclampf blue
, GLclampf alpha
)
318 GET_CURRENT_CONTEXT(ctx
);
319 ASSERT_OUTSIDE_BEGIN_END(ctx
);
321 tmp
[0] = CLAMP( red
, 0.0, 1.0 );
322 tmp
[1] = CLAMP( green
, 0.0, 1.0 );
323 tmp
[2] = CLAMP( blue
, 0.0, 1.0 );
324 tmp
[3] = CLAMP( alpha
, 0.0, 1.0 );
326 if (TEST_EQ_4V(tmp
, ctx
->Color
.BlendColor
))
329 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
330 COPY_4FV( ctx
->Color
.BlendColor
, tmp
);