Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SkyDomeNode.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
5 * www.openflipper.org *
6 * *
7 *--------------------------------------------------------------------------- *
8 * This file is part of OpenFlipper. *
9 * *
10 * OpenFlipper is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenFlipper is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenFlipper. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36 * *
37 * $Revision: 10745 $ *
38 * $LastChangedBy: moebius $ *
39 * $Date: 2011-01-26 10:23:50 +0100 (Mi, 26 Jan 2011) $ *
40 * *
41 \*===========================================================================*/
42 
43 #include <ACG/GL/acg_glew.hh>
44 #include "SkyDomeNode.hh"
45 #include <ACG/GL/gl.hh>
46 #include <iostream>
49 
50 #include <QGLWidget>
51 
52 //== IMPLEMENTATION ==========================================================
53 
54 
55 SkyDomeNode::SkyDomeNode(SkyDome& _dome, BaseNode *_parent, std::string _name)
56 :BaseNode(_parent, _name),
57  dome_(_dome),
58  vbo_(0),
59  textureId_(0),
60  updateBuffers_(true)
61 {
62  vertexDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION);
63 }
64 
66 {
67  if ( vbo_)
68  glDeleteBuffers(1,&vbo_);
69 
70 }
71 
73 {
74 
75 // ACG::Vec3d pos = plane_.position - plane_.xDirection * 0.5 - plane_.yDirection * 0.5;
76 //
77 // //add a little offset in normal direction
78 // ACG::Vec3d pos0 = ACG::Vec3d( pos + plane_.normal * 0.1 );
79 // ACG::Vec3d pos1 = ACG::Vec3d( pos - plane_.normal * 0.1 );
80 //
81 // ACG::Vec3d xDird = ACG::Vec3d( plane_.xDirection );
82 // ACG::Vec3d yDird = ACG::Vec3d( plane_.yDirection );
83 //
84 // _bbMin.minimize( pos0 );
85 // _bbMin.minimize( pos0 + xDird);
86 // _bbMin.minimize( pos0 + yDird);
87 // _bbMin.minimize( pos0 + xDird + yDird);
88 // _bbMax.maximize( pos1 );
89 // _bbMax.maximize( pos1 + xDird);
90 // _bbMax.maximize( pos1 + yDird);
91 // _bbMax.maximize( pos1 + xDird + yDird);
92 }
93 
94 //----------------------------------------------------------------------------
95 
98 {
101 }
102 
103 //----------------------------------------------------------------------------
104 
105 
106 
107 //----------------------------------------------------------------------------
108 
109 void SkyDomeNode::drawSkyDome( ACG::GLState& _state) {
110 
111 // const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
112 //
113 // // Array of coordinates for the plane
114 // float vboData_[9 * 3 ] = { 0.0,0.0,0.0,
115 // (float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
116 // (float)xy[0],(float)xy[1],(float)xy[2],
117 // (float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
118 // 0.0,0.0,0.0,
119 // (float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2],
120 // (float)xy[0],(float)xy[1],(float)xy[2],
121 // (float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
122 // 0.0,0.0,0.0 };
123 //
124 // // Enable the arrays
125 // _state.enableClientState(GL_VERTEX_ARRAY);
126 // _state.vertexPointer(3,GL_FLOAT,0,&vboData_[0]);
127 //
128 // //first draw the lines
129 // _state.set_color(ACG::Vec4f(1.0, 1.0, 1.0 , 1.0) );
130 // glLineWidth(2.0);
131 //
132 // glDrawArrays(GL_LINE_STRIP,0,5);
133 //
134 // glLineWidth(1.0);
135 //
136 // // Remember blending state
137 // bool blending = _state.blending();
138 //
139 // //then the red front side
140 // ACG::GLState::enable (GL_BLEND);
141 // ACG::GLState::blendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
142 //
143 // _state.set_color(ACG::Vec4f( 0.6, 0.15, 0.2, 0.5));
144 // glDrawArrays(GL_QUADS,0,4);
145 //
146 //
147 // //finally the green back side
148 // _state.set_color(ACG::Vec4f(0.1, 0.8, 0.2, 0.5 ));
149 //
150 // glDrawArrays(GL_QUADS,4,4);
151 //
152 // if ( !blending )
153 // ACG::GLState::disable(GL_BLEND);
154 //
155 // // deactivate vertex arrays after drawing
156 // _state.disableClientState(GL_VERTEX_ARRAY);
157 
158 }
159 
160 //----------------------------------------------------------------
161 
162 void SkyDomeNode::drawSkyDomePick( ACG::GLState& _state) {
163 
164 // _state.pick_set_maximum(1);
165 // _state.pick_set_name(0);
166 //
167 // const ACG::Vec3d xy = plane_.xDirection + plane_.yDirection;
168 //
169 // // Array of coordinates for the plane
170 // float vboData_[4* 3 ] = { 0.0,0.0,0.0,
171 // (float)plane_.xDirection[0],(float)plane_.xDirection[1],(float)plane_.xDirection[2],
172 // (float)xy[0],(float)xy[1],(float)xy[2],
173 // (float)plane_.yDirection[0],(float)plane_.yDirection[1],(float)plane_.yDirection[2] };
174 //
175 // // Enable the arrays
176 // _state.enableClientState(GL_VERTEX_ARRAY);
177 // _state.vertexPointer(3,GL_FLOAT,0,&vboData_[0]);
178 //
179 // glDrawArrays(GL_QUADS,0,4);
180 //
181 // // deactivate vertex arrays after drawing
182 // _state.disableClientState(GL_VERTEX_ARRAY);
183 
184 }
185 
186 //----------------------------------------------------------------
187 
189 {
190 
191 // _state.push_modelview_matrix();
192 // glPushAttrib(GL_COLOR_BUFFER_BIT);
193 // glPushAttrib(GL_LIGHTING_BIT);
194 //
195 // glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
196 // ACG::GLState::enable(GL_COLOR_MATERIAL);
197 //
198 // // plane_.position represents the center of the plane.
199 // // Compute the corner position
200 // ACG::Vec3d pos = plane_.position - plane_.xDirection*0.5 - plane_.yDirection*0.5;
201 //
202 // // translate to corner position
203 // _state.translate(pos[0], pos[1], pos[2]);
204 //
205 // // draw the plane
206 // drawPlane(_state);
207 //
208 // glPopAttrib();
209 // glPopAttrib();
210 // _state.pop_modelview_matrix();
211 }
212 
213 
214 //----------------------------------------------------------------
215 
216 void
218 {
219 // if (_target == ACG::SceneGraph::PICK_ANYTHING) {
220 //
221 // _state.push_modelview_matrix();
222 //
223 // ACG::Vec3d pos = plane_.position - plane_.xDirection*0.5 - plane_.yDirection*0.5;
224 //
225 // _state.translate(pos[0], pos[1], pos[2]);
226 //
227 // drawPlanePick(_state);
228 //
229 // _state.pop_modelview_matrix();
230 // }
231 }
232 
233 //----------------------------------------------------------------
234 
235 void
238 
239  if ( updateBuffers_ ) {
240 
241  QFileInfo info(dome_.textureFileName());
242 
243  QString filename = dome_.textureFileName();
244 
245  // Fallback image
246  if ( !info.exists() ) {
247  std::cerr << "Did not find image!" << filename.toStdString() << std::endl;
248  filename = OpenFlipper::Options::iconDirStr() + QDir::separator() + "EmptySkyDome.png";
249 
250  }
251 
252  // Test: Load texture image
253  QImage texture(filename);
254 
255  GLuint textureId;
256 
257  QImage GL_formatted_image;
258  GL_formatted_image = QGLWidget::convertToGLFormat(texture);
259 
260  if( GL_formatted_image.isNull() )
261  {
262  std::cerr << "error GL_formatted_image" << std::endl ;
263  }
264 
265  //generate the texture name
266  if ( !textureId_ )
267  glGenTextures(1, &textureId_);
268 
269  //bind the texture ID
270  glBindTexture(GL_TEXTURE_2D, textureId_);
271 
272  //generate the texture
273  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, GL_formatted_image.width(),
274  GL_formatted_image.height(),
275  0, GL_RGBA, GL_UNSIGNED_BYTE, GL_formatted_image.bits() );
276 
277  //texture parameters
278  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
279  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
280 
281  glBindTexture(GL_TEXTURE_2D,0);
282 
283  updateBuffers_ = false;
284  }
285 
286  // init base render object
288 
289  // We simply take the data from the texture! -> No Lighting
290  _state.disable(GL_LIGHTING);
291  ro.initFromState(&_state);
292  ro.debugName = "SkyDome";
293  ro.priority = 100;
294 
296  tex.id = textureId_;
297 
298  ro.addTexture(tex);
299 
300  // Render with depth test enabled
301  ro.depthTest = true;
302  ro.blending = false;
303 
304  // Compute a screen aligned quad ( Depth doesn't matter, as we compute depth in shader anyway, but we set it to the far plane)
305  ACG::Vec3d bottomLeft ( 0.0 , 0.0 , 0.99 );
306  ACG::Vec3d bottomRight( _state.viewport_width() , 0.0 , 0.99 );
307  ACG::Vec3d topLeft ( 0.0 , _state.viewport_height() , 0.99 );
308  ACG::Vec3d topRight ( _state.viewport_width() , _state.viewport_height() , 0.99 );
309 
310  ACG::Vec3f unprojectedBottomLeft = ACG::Vec3f(_state.unproject(bottomLeft));
311  ACG::Vec3f unprojectedBottomRight = ACG::Vec3f(_state.unproject(bottomRight));
312  ACG::Vec3f unprojectedtopLeft = ACG::Vec3f(_state.unproject(topLeft));
313  ACG::Vec3f unprojectedtopRight = ACG::Vec3f(_state.unproject(topRight));
314 
315  // Array of coordinates for the quad
316  float vboData_[4 * 3 * 4 ] = { unprojectedBottomLeft[0] , unprojectedBottomLeft[1] , unprojectedBottomLeft[2],
317  unprojectedBottomRight[0] , unprojectedBottomRight[1] , unprojectedBottomRight[2],
318  unprojectedtopRight[0] , unprojectedtopRight[1] , unprojectedtopRight[2],
319  unprojectedtopLeft[0] , unprojectedtopLeft[1] , unprojectedtopLeft[2]
320  };
321 
322  if ( ! vbo_ ) {
323  glGenBuffersARB(1, &vbo_);
324  }
325 
326  // Bind buffer
327  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
328 
329  // Upload to buffer ( 4 vertices with 3 coordinates for point and normal of 4 byte sized floats)
330  glBufferDataARB(GL_ARRAY_BUFFER_ARB, 4 * 3 * 4, &vboData_[0], GL_STATIC_DRAW_ARB);
331 
332  // Set the buffers for rendering
333  ro.shaderDesc.shadeMode = ACG::SG_SHADE_UNLIT;
334  ro.shaderDesc.vertexTemplateFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + "SkyDome" + QDir::separator() + "SkyDomeVertexShader.glsl";
335  ro.shaderDesc.fragmentTemplateFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + "SkyDome" + QDir::separator() + "SkyDomeFragmentShader.glsl";
336  ro.vertexBuffer = vbo_;
337  ro.vertexDecl = &vertexDecl_;
338 
339  ACG::SceneGraph::Material localMaterial = *_mat;
340  localMaterial.baseColor(ACG::Vec4f(1.0,0.0,0.0,1.0) );
341 
342  ro.setMaterial(&localMaterial);
343  ro.glDrawArrays(GL_QUADS, 0, 4);
344 
345  ro.setUniform("uUpperCutOff" , dome_.topOffset() );
346  ro.setUniform("uHorizontalFOV" , dome_.horizontalFOV() );
347  ro.setUniform("uVerticalFOV" , dome_.verticalFOV() );
348 
349  ro.setUniform("uVP_width" , float(_state.viewport_width()) );
350  ro.setUniform("uVP_height" , float(_state.viewport_height()) );
351 
352  _renderer->addRenderObject(&ro);
353 }
354 
355 
356 //=============================================================================
ACG::SceneGraph::DrawModes::DrawMode availableDrawModes() const
return available draw modes
Definition: SkyDomeNode.cc:97
int viewport_width() const
get viewport width
Definition: GLState.hh:825
Texture to be used.
void boundingBox(ACG::Vec3d &_bbMin, ACG::Vec3d &_bbMax)
update bounding box
Definition: SkyDomeNode.cc:72
void setUniform(const char *_name, GLint _value)
set values for int uniforms
QString textureFileName()
Returns the texture that will be used.
Definition: SkyDomeType.cc:75
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Definition: GLState.cc:1518
void getRenderObjects(ACG::IRenderer *_renderer, ACG::GLState &_state, const ACG::SceneGraph::DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat)
Add the objects to the given renderer.
Definition: SkyDomeNode.cc:237
void draw(ACG::GLState &_state, const ACG::SceneGraph::DrawModes::DrawMode &_drawMode)
draw SkyDome
Definition: SkyDomeNode.cc:188
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:88
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:125
unsigned int vbo_
VBO used to render the dome.
Definition: SkyDomeNode.hh:120
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:108
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void baseColor(const Vec4f &_c)
set the base color
SkyDomeNode(SkyDome &_dome, BaseNode *_parent=0, std::string _name="<PlaneNode>")
Construct a SkyDome rendering node.
Definition: SkyDomeNode.cc:55
int viewport_height() const
get viewport height
Definition: GLState.hh:827
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
int priority
Priority to allow sorting of objects.
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:87
void addElement(const VertexElement *_pElement)
void pick(ACG::GLState &_state, ACG::SceneGraph::PickTarget _target)
draw SkyDome for object picking
Definition: SkyDomeNode.cc:217
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
~SkyDomeNode()
destructor
Definition: SkyDomeNode.cc:65
Interface class between scenegraph and renderer.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:69
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:650
ShaderGenDesc shaderDesc
Drawmode and other shader params.