1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class SoGLPolygonOffsetElement Inventor/elements/SoGLPolygonOffsetElement.h
35   \brief The SoGLPolygonOffsetElement class is yet to be documented.
36 
37   \ingroup elements
38 
39   FIXME: write doc.
40 */
41 
42 #include <Inventor/elements/SoGLPolygonOffsetElement.h>
43 #include "coindefs.h"
44 
45 #include <cassert>
46 #include <cstdlib>
47 
48 #include <Inventor/C/tidbits.h>
49 #include <Inventor/errors/SoDebugError.h>
50 #include <Inventor/misc/SoGLDriverDatabase.h>
51 
52 #include "rendering/SoGL.h"
53 
54 SO_ELEMENT_SOURCE(SoGLPolygonOffsetElement);
55 
56 /*!
57   This static method initializes static data for the
58   SoGLPolygonOffsetElement class.
59 */
60 
61 void
initClass(void)62 SoGLPolygonOffsetElement::initClass(void)
63 {
64   SO_ELEMENT_INIT_CLASS(SoGLPolygonOffsetElement, inherited);
65 }
66 
67 /*!
68   The destructor.
69 */
70 
~SoGLPolygonOffsetElement(void)71 SoGLPolygonOffsetElement::~SoGLPolygonOffsetElement(void)
72 {
73 }
74 
75 //! FIXME: write doc.
76 
77 void
init(SoState * stateptr)78 SoGLPolygonOffsetElement::init(SoState * stateptr)
79 {
80   inherited::init(stateptr);
81   this->state = stateptr;
82 }
83 
84 //! FIXME: write doc.
85 
86 void
push(SoState * stateptr)87 SoGLPolygonOffsetElement::push(SoState * stateptr)
88 {
89   SoGLPolygonOffsetElement * prev = (SoGLPolygonOffsetElement*)this->getNextInStack();
90 
91   this->style = prev->style;
92   this->active = prev->active;
93   this->offsetfactor = prev->offsetfactor;
94   this->offsetunits = prev->offsetunits;
95   this->state = stateptr;
96   // capture previous element since we might or might not change the
97   // GL state in set/pop
98   prev->capture(stateptr);
99 }
100 
101 //! FIXME: write doc.
102 
103 void
pop(SoState * COIN_UNUSED_ARG (stateptr),const SoElement * prevTopElement)104 SoGLPolygonOffsetElement::pop(SoState * COIN_UNUSED_ARG(stateptr), const SoElement * prevTopElement)
105 {
106   const SoGLPolygonOffsetElement * prev =
107     (const SoGLPolygonOffsetElement*)prevTopElement;
108 
109   if (this->style != prev->style ||
110       this->active != prev->active ||
111       this->offsetfactor != prev->offsetfactor ||
112       this->offsetunits != prev->offsetunits) {
113     this->updategl();
114   }
115 }
116 
117 //! FIXME: write doc.
118 
119 void
setElt(float factor,float units,Style styles,SbBool on)120 SoGLPolygonOffsetElement::setElt(float factor, float units,
121                                  Style styles, SbBool on)
122 {
123   if (on != this->active ||
124       styles != this->style ||
125       factor != this->offsetfactor ||
126       units != this->offsetunits) {
127     this->active = on;
128     this->style = styles;
129     this->offsetfactor = factor;
130     this->offsetunits = units;
131     this->updategl();
132   }
133 }
134 
135 
136 //! FIXME: write doc.
137 
138 void
updategl(void)139 SoGLPolygonOffsetElement::updategl(void)
140 {
141   const cc_glglue * w = sogl_glue_instance(this->state);
142   if (!SoGLDriverDatabase::isSupported(w, SO_GL_POLYGON_OFFSET)) {
143     static SbBool first = TRUE;
144     if (first) {
145       SoDebugError::postWarning("SoGLPolygonOffsetElement::updategl",
146                                 "OpenGL driver doesn't support z-buffer "
147                                 "offsetting");
148       first = FALSE;
149     }
150     return;
151   }
152 
153 
154   if (this->active) {
155     int styles = 0;
156     styles |= (this->style & FILLED) ? cc_glglue_FILLED : 0;
157     styles |= (this->style & LINES) ? cc_glglue_LINES : 0;
158     styles |= (this->style & POINTS) ? cc_glglue_POINTS : 0;
159     cc_glglue_glPolygonOffsetEnable(w, TRUE, styles);
160 
161     cc_glglue_glPolygonOffset(w, this->offsetfactor, this->offsetunits);
162   }
163   else { // ! active
164     int all = cc_glglue_FILLED | cc_glglue_LINES | cc_glglue_POINTS;
165     cc_glglue_glPolygonOffsetEnable(w, FALSE, all);
166   }
167 }
168