Developer Documentation

ClippingNode.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44
45
46
47 //=============================================================================
48 //
49 // CLASS ClippingNode - IMPLEMENTATION
50 //
51 //=============================================================================
52
53
54 //== INCLUDES =================================================================
55
56
57 #include "ClippingNode.hh"
58
59 #include <ACG/GL/IRenderer.hh>
60
61 #include <OpenMesh/Core/Utils/vector_cast.hh>
62
63 #include <QImage>
64
65
66 //== NAMESPACES ===============================================================
67
68
69 namespace ACG {
70 namespace SceneGraph {
71
72
73 //== IMPLEMENTATION ==========================================================
74
75
76 void
77 ClippingNode::set_plane(const Vec3f& _position,
78 const Vec3f& _normal,
79 float _eps)
80 {
81 position_ = _position;
82 normal_ = _normal; normal_.normalize();
83 slice_width_ = _eps;
84
85
86 // one clipping plane
87 if (slice_width_ == 0.0)
88 {
89 plane0_[0] = normal_[0];
90 plane0_[1] = normal_[1];
91 plane0_[2] = normal_[2];
92 plane0_[3] = -(normal_|position_);
93 }
94
95
96 // two planes -> slice
97 else
98 {
99 float d = -(normal_|position_);
100 if (d > 0) { normal_ = -normal_; d = -d; }
101
102 plane0_[0] = normal_[0];
103 plane0_[1] = normal_[1];
104 plane0_[2] = normal_[2];
105 plane0_[3] = d + 0.5f*slice_width_;
106
107 plane1_[0] = -normal_[0];
108 plane1_[1] = -normal_[1];
109 plane1_[2] = -normal_[2];
110 plane1_[3] = -(d - 0.5f*slice_width_);
111 }
112
113
114 set_offset(offset_);
115 }
116
117
118 //----------------------------------------------------------------------------
119
120
121 void
122 ClippingNode::set_offset(float _offset)
123 {
124 offset_ = _offset;
125
126 offset_plane0_[0] = plane0_[0];
127 offset_plane0_[1] = plane0_[1];
128 offset_plane0_[2] = plane0_[2];
129 offset_plane0_[3] = plane0_[3] - offset_;
130
131 offset_plane1_[0] = plane1_[0];
132 offset_plane1_[1] = plane1_[1];
133 offset_plane1_[2] = plane1_[2];
134 offset_plane1_[3] = plane1_[3] + offset_;
135 }
136
137
138 //----------------------------------------------------------------------------
139
140
141 void ClippingNode::enter(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
142 {
143 // one clipping plane
144 if (slice_width_ == 0.0)
145 {
146 glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
147 ACG::GLState::enable(GL_CLIP_PLANE0);
148 }
149
150 // two planes -> slice
151 else
152 {
153 glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
154 ACG::GLState::enable(GL_CLIP_PLANE0);
155 glClipPlane(GL_CLIP_PLANE1, offset_plane1_);
156 ACG::GLState::enable(GL_CLIP_PLANE1);
157 }
158 }
159
160
161 //----------------------------------------------------------------------------
162
163
164 void ClippingNode::leave(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
165 {
166 ACG::GLState::disable(GL_CLIP_PLANE0);
167 if (slice_width_ > 0.0)
168 ACG::GLState::disable(GL_CLIP_PLANE1);
169 }
170
171
172 //----------------------------------------------------------------------------
173
174
175 void ClippingNode::enter(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
176 {
177 _renderer->addRenderObjectModifier(&mod_);
178 }
179
180
181 //----------------------------------------------------------------------------
182
183
184 void ClippingNode::leave(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
185 {
186 _renderer->removeRenderObjectModifier(&mod_);
187 }
188
189 //=============================================================================
190
191 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod1_(1);
192 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod2_(2);
193
194 ClippingNode::ClippingShaderModifier::ClippingShaderModifier(int _numClipPlanes)
195 : numClipPlanes_(_numClipPlanes)
196 {
197 ShaderProgGenerator::registerModifier(this);
198 }
199
200
201 void ClippingNode::ClippingShaderModifier::modifyVertexIO(ShaderGenerator* _shader)
202 {
203 for (int i = 0; i < numClipPlanes_; ++i)
204 _shader->addUniform(QString("vec4 g_SlicePlane%1").arg(i));
205 }
206
207
208 void ClippingNode::ClippingShaderModifier::modifyVertexEndCode(QStringList* _code)
209 {
210 for (int i = 0; i < numClipPlanes_; ++i)
211 _code->push_back(QString("gl_ClipDistance[%1] = dot(inverse(g_mWV) * sg_vPosVS, g_SlicePlane%1);").arg(i));
212 }
213
214 //=============================================================================
215
216 ClippingNode::ClippingObjectModifier::ClippingObjectModifier(const ClippingNode* _node)
217 : RenderObjectModifier("ClippingNode"), node_(_node)
218 {
219 }
220
221 //=============================================================================
222
223 void ClippingNode::ClippingObjectModifier::apply(RenderObject* _obj)
224 {
225 // set clipping plane equation as uniform and set shader mod id to the object
226 Vec4f p0 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane0());
227
228 _obj->setUniform("g_SlicePlane0", p0);
229 _obj->clipDistanceMask |= 0x1;
230
231 unsigned int shaderModID = shaderMod1_.getID();
232
233 if (node_->slice_width() > 0.0f)
234 {
235 Vec4f p1 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane1());
236 _obj->setUniform("g_SlicePlane1", p1);
237 _obj->clipDistanceMask |= 0x2;
238
239 shaderModID = shaderMod2_.getID();
240 }
241
242 // set shader modifier
243 _obj->shaderDesc.shaderMods.push_back(shaderModID);
244
245 // enable clip distance pass through in geometry shader
246 _obj->shaderDesc.clipDistanceMask = _obj->clipDistanceMask;
247 }
248
249 //=============================================================================
250
251
252 } // namespace SceneGraph
253 } // namespace ACG
254 //=============================================================================
OpenMesh::vector_cast
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:81
ACG::RenderObject::setUniform
void setUniform(const char *_name, GLint _value)
set values for int uniforms
Definition: RenderObject.cc:413
ACG::GLState
Definition: GLState.hh:213
ACG::SceneGraph::ClippingNode::ClippingObjectModifier::apply
void apply(RenderObject *_obj)
apply the modifier
Definition: ClippingNode.cc:223
ACG::IRenderer::removeRenderObjectModifier
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer...
Definition: IRenderer.cc:1203
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::RenderObjectModifier
Interface for modifying render objects.
Definition: RenderObject.hh:540
ACG::Vec4f
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
ACG::SceneGraph::ACG::GLState::disable
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
ACG::RenderObject::shaderDesc
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: RenderObject.hh:225
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::ShaderModifier::getID
unsigned int getID()
Returns the modifier ID.
Definition: ShaderGenerator.hh:1132
ACG::IRenderer
Definition: IRenderer.hh:78
ACG::ShaderGenerator
Definition: ShaderGenerator.hh:557
SceneGraph
Definition: QtPrincipalAxisDialog.hh:67
ACG::SceneGraph::ClippingNode
Definition: ClippingNode.hh:82
ACG::SceneGraph::ClippingNode::enter
void enter(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode) override
enable clipping plane
Definition: ClippingNode.cc:175
ACG::SceneGraph::ClippingNode::leave
void leave(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode) override
disable clipping plane
Definition: ClippingNode.cc:184
ACG::ShaderGenerator::addUniform
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
Definition: ShaderGenerator.cc:528
ACG::SceneGraph::ClippingNode::ClippingShaderModifier
Definition: ClippingNode.hh:163
ACG::IRenderer::addRenderObjectModifier
virtual void addRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which adds a render object modifier to the renderer via this funct...
Definition: IRenderer.cc:1198
ACG::SceneGraph::ClippingNode::ClippingShaderModifier::modifyVertexEndCode
void modifyVertexEndCode(QStringList *_code)
Append code the the vertex shader.
Definition: ClippingNode.cc:208
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:288
ACG::SceneGraph::ACG::GLState::enable
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
ACG::ShaderProgGenerator::registerModifier
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
Definition: ShaderGenerator.cc:2457
ACG::SceneGraph::ClippingNode::ClippingShaderModifier::modifyVertexIO
void modifyVertexIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the vertex shader.
Definition: ClippingNode.cc:201
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:434
ACG::RenderObject
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
ACG::SceneGraph::ClippingNode::set_plane
void set_plane(const Vec3f &_position, const Vec3f &_normal, float _eps=0.0)
set position and normal of plane
Definition: ClippingNode.cc:77
ACG::SceneGraph::ClippingNode::set_offset
void set_offset(float _dist)
sweep plane along normal by _dist
Definition: ClippingNode.cc:122