changed: gcc8 base update
[opensg.git] / Source / System / State / Base / OSGBlendChunk.cpp
bloba97f17119d2328c51cc719e4f7fc7e58b8930f1f
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
48 #include "OSGGL.h"
50 #include "OSGWindow.h"
52 #include "OSGBlendChunk.h"
53 #include "OSGDrawEnv.h"
55 #include "OSGGLFuncProtos.h"
57 OSG_USING_NAMESPACE
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 /***************************************************************************\
65 * Class variables *
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 /***************************************************************************\
83 * Class methods *
84 \***************************************************************************/
86 void BlendChunk::initMethod(InitPhase ePhase)
88 Inherited::initMethod(ePhase);
90 if(ePhase == TypeObject::SystemPost)
92 _extBlend =
93 Window::registerExtension("GL_EXT_blend_color");
94 _extImaging =
95 Window::registerExtension("GL_ARB_imaging");
96 _extBlendSubtract =
97 Window::registerExtension("GL_EXT_blend_subtract");
98 _extBlendMinMax =
99 Window::registerExtension("GL_EXT_blend_minmax");
100 _extBlendLogicOp =
101 Window::registerExtension("GL_EXT_blend_logic_op");
102 _extBlendFuncSeparate =
103 Window::registerExtension("GL_EXT_blend_func_separate");
105 _funcBlendColor =
106 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBlendColorEXT",
107 _extBlend);
108 _funcBlendEquation =
109 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBlendEquation",
110 _extImaging);
111 _funcBlendEquationExt =
112 Window::registerFunction (OSG_DLSYM_UNDERSCORE"glBlendEquationEXT",
113 _extBlendLogicOp);
115 _funcBlendFuncSeparateExt = Window::registerFunction(
116 OSG_DLSYM_UNDERSCORE"glBlendFuncSeparateEXT",
117 _extBlendFuncSeparate);
121 /***************************************************************************\
122 * Instance methods *
123 \***************************************************************************/
125 /*-------------------------------------------------------------------------*\
126 - private -
127 \*-------------------------------------------------------------------------*/
129 /*------------- constructors & destructors --------------------------------*/
131 BlendChunk::BlendChunk(void) :
132 Inherited()
136 BlendChunk::BlendChunk(const BlendChunk &source) :
137 Inherited(source)
141 BlendChunk::~BlendChunk(void)
145 /*------------------------- Chunk Class Access ---------------------------*/
147 const StateChunkClass *BlendChunk::getClass(void) const
149 return &_class;
152 /*------------------------------- Sync -----------------------------------*/
154 void BlendChunk::changed(ConstFieldMaskArg whichField,
155 UInt32 origin,
156 BitVector details)
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,
196 0x0104,
197 0x0200 ))
199 // get "glBlendFuncSeparate" function pointer
200 OSGGETGLFUNCBYID_GL3_ES( glBlendFuncSeparate,
201 osgGlBlendFuncSeparate,
202 _funcBlendFuncSeparateExt,
203 pWin);
205 osgGlBlendFuncSeparate(src, dest, asrc, adest);
207 else
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);
216 else
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,
236 osgGlBlendColor,
237 _funcBlendColor,
238 pWin);
240 osgGlBlendColor(_sfColor.getValue().red(),
241 _sfColor.getValue().green(),
242 _sfColor.getValue().blue(),
243 _sfColor.getValue().alpha());
246 glEnable(GL_BLEND);
249 if(_sfEquation.getValue() != GL_NONE)
251 if(pWin->hasExtOrVersion(_extImaging, 0x0104, 0x0200))
253 // get "glBlendEquation" function pointer
254 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation,
255 osgGlBlendEquation,
256 _funcBlendEquation,
257 pWin);
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,
267 osgGlBlendEquation,
268 _funcBlendEquation,
269 pWin);
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);
281 #endif
284 void BlendChunk::changeFrom(DrawEnv *pEnv,
285 StateChunk *old_chunk,
286 UInt32 )
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,
317 0x0104,
318 0x0200 ))
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,
327 pWin);
329 osgGlBlendFuncSeparate(src, dest, asrc, adest);
332 else
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,
361 osgGlBlendColor,
362 _funcBlendColor,
363 pWin);
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)
372 glEnable(GL_BLEND);
374 else
376 if((osrc != GL_ONE || odest != GL_ZERO) ||
377 (oasrc != OSG_GL_UNUSED && oasrc != GL_ONE ) ||
378 (oadest != OSG_GL_UNUSED && oadest != GL_ZERO) )
380 glDisable(GL_BLEND);
384 if(_sfEquation.getValue() != old->_sfEquation.getValue())
386 if(pWin->hasExtOrVersion(_extImaging, 0x0104, 0x0200))
388 // get "glBlendEquation" function pointer
389 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation,
390 osgGlBlendEquation,
391 _funcBlendEquation,
392 pWin);
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,
402 osgGlBlendEquation,
403 _funcBlendEquation,
404 pWin);
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);
422 else
424 if(old->_sfAlphaFunc.getValue() != GL_NONE)
425 glDisable(GL_ALPHA_TEST);
427 #endif
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) )
443 glDisable(GL_BLEND);
446 if(_sfEquation.getValue() != GL_NONE)
448 if(pWin->hasExtOrVersion(_extImaging, 0x0104, 0x0200))
450 // get "glBlendEquation" function pointer
451 OSGGETGLFUNCBYID_GL3_ES( glBlendEquation,
452 osgGlBlendEquation,
453 _funcBlendEquation,
454 pWin);
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,
464 osgGlBlendEquation,
465 _funcBlendEquationExt,
466 pWin);
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);
477 #endif
480 /*-------------------------- Comparison -----------------------------------*/
482 bool BlendChunk::isTransparent(void) const
484 return getDestFactor() != GL_ZERO;
487 Real32 BlendChunk::switchCost(StateChunk *)
489 return 0;
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);
501 if(!tother)
502 return false;
504 if(tother == this)
505 return true;
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() )
513 return false;
515 return true;
518 bool BlendChunk::operator != (const StateChunk &other) const
520 return ! (*this == other);