1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
50 #include "OSGWindow.h"
52 #include "OSGBlendChunk.h"
53 #include "OSGDrawEnv.h"
55 #include "OSGGLFuncProtos.h"
59 // Documentation for this class is emited in the
60 // OSGBlendChunkBase.cpp file.
61 // To modify it, please change the .fcd file (OSGBlendChunk.fcd) and
62 // regenerate the base file.
64 /***************************************************************************\
66 \***************************************************************************/
68 StateChunkClass
BlendChunk::_class("Blend", 1, 50);
70 UInt32
BlendChunk::_extBlend
= Window::invalidExtensionID
;
71 UInt32
BlendChunk::_extImaging
= Window::invalidExtensionID
;
72 UInt32
BlendChunk::_extBlendSubtract
= Window::invalidExtensionID
;
73 UInt32
BlendChunk::_extBlendMinMax
= Window::invalidExtensionID
;
74 UInt32
BlendChunk::_extBlendLogicOp
= Window::invalidExtensionID
;
75 UInt32
BlendChunk::_extBlendFuncSeparate
= Window::invalidExtensionID
;
77 UInt32
BlendChunk::_funcBlendColor
= Window::invalidFunctionID
;
78 UInt32
BlendChunk::_funcBlendEquation
= Window::invalidFunctionID
;
79 UInt32
BlendChunk::_funcBlendEquationExt
= Window::invalidFunctionID
;
80 UInt32
BlendChunk::_funcBlendFuncSeparateExt
= Window::invalidFunctionID
;
82 /***************************************************************************\
84 \***************************************************************************/
86 void BlendChunk::initMethod(InitPhase ePhase
)
88 Inherited::initMethod(ePhase
);
90 if(ePhase
== TypeObject::SystemPost
)
93 Window::registerExtension("GL_EXT_blend_color");
95 Window::registerExtension("GL_ARB_imaging");
97 Window::registerExtension("GL_EXT_blend_subtract");
99 Window::registerExtension("GL_EXT_blend_minmax");
101 Window::registerExtension("GL_EXT_blend_logic_op");
102 _extBlendFuncSeparate
=
103 Window::registerExtension("GL_EXT_blend_func_separate");
106 Window::registerFunction (OSG_DLSYM_UNDERSCORE
"glBlendColorEXT",
109 Window::registerFunction (OSG_DLSYM_UNDERSCORE
"glBlendEquation",
111 _funcBlendEquationExt
=
112 Window::registerFunction (OSG_DLSYM_UNDERSCORE
"glBlendEquationEXT",
115 _funcBlendFuncSeparateExt
= Window::registerFunction(
116 OSG_DLSYM_UNDERSCORE
"glBlendFuncSeparateEXT",
117 _extBlendFuncSeparate
);
121 /***************************************************************************\
123 \***************************************************************************/
125 /*-------------------------------------------------------------------------*\
127 \*-------------------------------------------------------------------------*/
129 /*------------- constructors & destructors --------------------------------*/
131 BlendChunk::BlendChunk(void) :
136 BlendChunk::BlendChunk(const BlendChunk
&source
) :
141 BlendChunk::~BlendChunk(void)
145 /*------------------------- Chunk Class Access ---------------------------*/
147 const StateChunkClass
*BlendChunk::getClass(void) const
152 /*------------------------------- Sync -----------------------------------*/
154 void BlendChunk::changed(ConstFieldMaskArg whichField
,
158 Inherited::changed(whichField
, origin
, details
);
161 /*------------------------------ Output ----------------------------------*/
163 void BlendChunk::dump( UInt32
OSG_CHECK_ARG(uiIndent
),
164 const BitVector
OSG_CHECK_ARG(bvFlags
)) const
166 SLOG
<< "Dump BlendChunk NI" << std::endl
;
169 /*------------------------------ State ------------------------------------*/
171 void BlendChunk::activate(DrawEnv
*pEnv
, UInt32
)
173 pEnv
->incNumChunkChanges();
175 GLenum src
= _sfSrcFactor
.getValue();
176 GLenum dest
= _sfDestFactor
.getValue();
177 GLenum asrc
= _sfAlphaSrcFactor
.getValue();
178 GLenum adest
= _sfAlphaDestFactor
.getValue();
180 Window
*pWin
= pEnv
->getWindow();
182 if((src
!= GL_ONE
|| dest
!= GL_ZERO
) ||
183 (asrc
!= OSG_GL_UNUSED
&& asrc
!= GL_ONE
) ||
184 (adest
!= OSG_GL_UNUSED
&& adest
!= GL_ZERO
) )
186 if(asrc
!= OSG_GL_UNUSED
|| adest
!= OSG_GL_UNUSED
)
188 if(asrc
== OSG_GL_UNUSED
|| adest
== OSG_GL_UNUSED
)
190 FWARNING(("BlendChunk::activate: only one of alpha src and"
191 " alpha dest is set. Ignored.\n"));
193 glBlendFunc(src
, dest
);
195 else if(pWin
->hasExtOrVersion(_extBlendFuncSeparate
,
199 // get "glBlendFuncSeparate" function pointer
200 OSGGETGLFUNCBYID_GL3_ES( glBlendFuncSeparate
,
201 osgGlBlendFuncSeparate
,
202 _funcBlendFuncSeparateExt
,
205 osgGlBlendFuncSeparate(src
, dest
, asrc
, adest
);
209 FWARNING(("BlendChunk::activate: Window %p doesn't "
210 "support EXT_blend_func_separate, ignored.\n",
211 static_cast<void *>(pWin
)));
213 glBlendFunc(src
, dest
);
218 glBlendFunc(src
, dest
);
221 // This is not nice, but efficient
222 // As the OpenGL constants are fixed it should be safe
223 if((src
>= GL_CONSTANT_COLOR_EXT
&&
224 src
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
225 (dest
>= GL_CONSTANT_COLOR_EXT
&&
226 dest
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
227 (asrc
>= GL_CONSTANT_COLOR_EXT
&&
228 asrc
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
229 (adest
>= GL_CONSTANT_COLOR_EXT
&&
230 adest
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) )
232 if(pWin
->hasExtOrVersion(_extBlend
, 0x0102, 0x0200))
234 // get "glBlendColorEXT" function pointer
235 OSGGETGLFUNCBYID_GL3_ES( glBlendColor
,
240 osgGlBlendColor(_sfColor
.getValue().red(),
241 _sfColor
.getValue().green(),
242 _sfColor
.getValue().blue(),
243 _sfColor
.getValue().alpha());
249 if(_sfEquation
.getValue() != GL_NONE
)
251 if(pWin
->hasExtOrVersion(_extImaging
, 0x0104, 0x0200))
253 // get "glBlendEquation" function pointer
254 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
259 osgGlBlendEquation(_sfEquation
.getValue());
261 else if(pWin
->hasExtOrVersion(_extBlendSubtract
, 0x0102, 0x0200) ||
262 pWin
->hasExtOrVersion(_extBlendMinMax
, 0x0102, 0x0200) ||
263 pWin
->hasExtOrVersion(_extBlendLogicOp
, 0x0101, 0x0200) )
265 // get "glBlendEquationEXT" function pointer
266 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
271 osgGlBlendEquation(_sfEquation
.getValue());
275 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
276 if(_sfAlphaFunc
.getValue() != GL_NONE
)
278 glAlphaFunc(_sfAlphaFunc
.getValue(), _sfAlphaValue
.getValue());
279 glEnable(GL_ALPHA_TEST
);
284 void BlendChunk::changeFrom(DrawEnv
*pEnv
,
285 StateChunk
*old_chunk
,
288 pEnv
->incNumChunkChanges();
290 BlendChunk
*old
= dynamic_cast<BlendChunk
*>(old_chunk
);
292 GLenum src
= _sfSrcFactor
.getValue();
293 GLenum dest
= _sfDestFactor
.getValue();
294 GLenum osrc
= old
->_sfSrcFactor
.getValue();
295 GLenum odest
= old
->_sfDestFactor
.getValue();
296 GLenum asrc
= _sfAlphaSrcFactor
.getValue();
297 GLenum adest
= _sfAlphaDestFactor
.getValue();
298 GLenum oasrc
= old
->_sfAlphaSrcFactor
.getValue();
299 GLenum oadest
= old
->_sfAlphaDestFactor
.getValue();
301 Window
*pWin
= pEnv
->getWindow();
303 if((src
!= GL_ONE
|| dest
!= GL_ZERO
) ||
304 (asrc
!= OSG_GL_UNUSED
&& asrc
!= GL_ONE
) ||
305 (adest
!= OSG_GL_UNUSED
&& adest
!= GL_ZERO
) )
307 if(asrc
!= OSG_GL_UNUSED
|| adest
!= OSG_GL_UNUSED
)
309 if(asrc
== OSG_GL_UNUSED
|| adest
== OSG_GL_UNUSED
)
311 FWARNING(("BlendChunk::changeFrom: only one of alpha src and"
312 " alpha dest is set. Ignored.\n"));
314 glBlendFunc(src
, dest
);
316 else if(pWin
->hasExtOrVersion(_extBlendFuncSeparate
,
320 if(osrc
!= src
|| odest
!= dest
||
321 oasrc
!= asrc
|| oadest
!= adest
)
323 // get "glBlendFuncSeparate" function pointer
324 OSGGETGLFUNCBYID_GL3_ES( glBlendFuncSeparate
,
325 osgGlBlendFuncSeparate
,
326 _funcBlendFuncSeparateExt
,
329 osgGlBlendFuncSeparate(src
, dest
, asrc
, adest
);
334 FWARNING(("BlendChunk::changeFrom: Window %p doesn't "
335 "support EXT_blend_func_separate, ignored.\n",
336 static_cast<void *>(pEnv
->getWindow())));
338 glBlendFunc(src
, dest
);
341 else if(osrc
!= src
|| odest
!= dest
)
343 glBlendFunc(src
, dest
);
346 // This is not nice, but efficient
347 // As the OpenGL constants are fixed it should be safe
348 if((src
>= GL_CONSTANT_COLOR_EXT
&&
349 src
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
350 (dest
>= GL_CONSTANT_COLOR_EXT
&&
351 dest
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
352 (asrc
>= GL_CONSTANT_COLOR_EXT
&&
353 asrc
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) ||
354 (adest
>= GL_CONSTANT_COLOR_EXT
&&
355 adest
<= GL_ONE_MINUS_CONSTANT_ALPHA_EXT
) )
357 if(pWin
->hasExtOrVersion(_extBlend
, 0x0102, 0x0200))
359 // get "glBlendColorEXT" function pointer
360 OSGGETGLFUNCBYID_GL3_ES( glBlendColor
,
365 osgGlBlendColor(_sfColor
.getValue().red(),
366 _sfColor
.getValue().green(),
367 _sfColor
.getValue().blue(),
368 _sfColor
.getValue().alpha());
371 if(osrc
== GL_ONE
&& odest
== GL_ZERO
)
376 if((osrc
!= GL_ONE
|| odest
!= GL_ZERO
) ||
377 (oasrc
!= OSG_GL_UNUSED
&& oasrc
!= GL_ONE
) ||
378 (oadest
!= OSG_GL_UNUSED
&& oadest
!= GL_ZERO
) )
384 if(_sfEquation
.getValue() != old
->_sfEquation
.getValue())
386 if(pWin
->hasExtOrVersion(_extImaging
, 0x0104, 0x0200))
388 // get "glBlendEquation" function pointer
389 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
394 osgGlBlendEquation(_sfEquation
.getValue());
396 else if(pWin
->hasExtOrVersion(_extBlendSubtract
, 0x0102, 0x0200) ||
397 pWin
->hasExtOrVersion(_extBlendMinMax
, 0x0102, 0x0200) ||
398 pWin
->hasExtOrVersion(_extBlendLogicOp
, 0x0101, 0x0200))
400 // get "glBlendEquationEXT" function pointer
401 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
406 osgGlBlendEquation(_sfEquation
.getValue());
410 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
411 if(_sfAlphaFunc
.getValue() != GL_NONE
)
413 if(old
->_sfAlphaFunc
.getValue() != _sfAlphaFunc
.getValue() ||
414 old
->_sfAlphaValue
.getValue() != _sfAlphaValue
.getValue())
416 glAlphaFunc(_sfAlphaFunc
.getValue(), _sfAlphaValue
.getValue());
419 if(old
->_sfAlphaFunc
.getValue() == GL_NONE
)
420 glEnable(GL_ALPHA_TEST
);
424 if(old
->_sfAlphaFunc
.getValue() != GL_NONE
)
425 glDisable(GL_ALPHA_TEST
);
430 void BlendChunk::deactivate(DrawEnv
*pEnv
, UInt32
)
432 GLenum src
= _sfSrcFactor
.getValue();
433 GLenum dest
= _sfDestFactor
.getValue();
434 GLenum asrc
= _sfAlphaSrcFactor
.getValue();
435 GLenum adest
= _sfAlphaDestFactor
.getValue();
437 Window
*pWin
= pEnv
->getWindow();
439 if((src
!= GL_ONE
|| dest
!= GL_ZERO
) ||
440 (asrc
!= OSG_GL_UNUSED
&& asrc
!= GL_ONE
) ||
441 (adest
!= OSG_GL_UNUSED
&& adest
!= GL_ZERO
) )
446 if(_sfEquation
.getValue() != GL_NONE
)
448 if(pWin
->hasExtOrVersion(_extImaging
, 0x0104, 0x0200))
450 // get "glBlendEquation" function pointer
451 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
456 osgGlBlendEquation(GL_FUNC_ADD
);
458 else if(pWin
->hasExtOrVersion(_extBlendSubtract
, 0x0102, 0x0200) ||
459 pWin
->hasExtOrVersion(_extBlendMinMax
, 0x0102, 0x0200) ||
460 pWin
->hasExtOrVersion(_extBlendLogicOp
, 0x0101, 0x0200) )
462 // get "glBlendEquationEXT" function pointer
463 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation
,
465 _funcBlendEquationExt
,
468 osgGlBlendEquation(GL_FUNC_ADD_EXT
);
472 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
473 if(_sfAlphaFunc
.getValue() != GL_NONE
)
475 glDisable(GL_ALPHA_TEST
);
480 /*-------------------------- Comparison -----------------------------------*/
482 bool BlendChunk::isTransparent(void) const
484 return getDestFactor() != GL_ZERO
;
487 Real32
BlendChunk::switchCost(StateChunk
*)
492 bool BlendChunk::operator < (const StateChunk
&other
) const
494 return this < &other
;
497 bool BlendChunk::operator == (const StateChunk
&other
) const
499 BlendChunk
const *tother
= dynamic_cast<BlendChunk
const*>(&other
);
507 if(getSrcFactor() != tother
->getSrcFactor() ||
508 getDestFactor() != tother
->getDestFactor() ||
509 getEquation() != tother
->getEquation() ||
510 getColor() != tother
->getColor() ||
511 getAlphaFunc() != tother
->getAlphaFunc() ||
512 getAlphaValue() != tother
->getAlphaValue() )
518 bool BlendChunk::operator != (const StateChunk
&other
) const
520 return ! (*this == other
);