Developer Documentation
ClassicDepthPeeling_glew.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 #include <ACG/GL/acg_glew.hh>
44 #include "ClassicDepthPeeling.hh"
45 
46 #include <ACG/GL/GLError.hh>
49 
51  // called in constructor and resizeEvent()
52 
54 
55  ViewerResources* p = &viewerRes_[_viewerId];
56 
57  if (!p->glWidth_ || !p->glHeight_) return;
58 
59  destroyResources(_viewerId);
60 
61  // dual depth peeling rt's
62  glGenTextures(7, p->blendDualPeelTexID_);
63  GLint DualPeelIntFmt[] = {GL_RG32F, GL_RG32F, // depth0, depth1
64  GL_RGBA, GL_RGBA, // front blender0, ..._1
65  GL_RGBA, GL_RGBA, // back_temp_tex0, ..._1,
66  GL_RGB}; // back_blender
67 
68  for (int i = 0; i < 7; ++i)
69  {
70  GLint fmt = GL_RGB; // fmt for depth textures
71 
72  if (i >= 2) fmt = GL_RGBA; // fmt for front_blender01 and back_temp01
73  if (i == 6) fmt = GL_RGB; // fmt for back_blender
74 
75  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, p->blendDualPeelTexID_[i]);
76  // texture access: clamped
77  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP);
78  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP);
79  // filter: none
80  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
82 
83  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, DualPeelIntFmt[i], p->glWidth_, p->glHeight_, 0, fmt, GL_FLOAT, 0);
84 
85 
86 
87 
89  }
90 
91  p->rtWidth_ = p->glWidth_;
92  p->rtHeight_ = p->glHeight_;
93 
94  // dual depth peeling fbo's
95  glGenFramebuffers(1, &p->blendDualPeelFbo_);
96  {
97  // layer_peel fbo
99 
100  // color_attachment order:
101  // depth0, front_blend0, back_temp0, depth1, front_blend1, back_temp1, back_blender_tex_id
102 
103  for (int i = 0; i < 6; ++i)
104  {
105  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i,
106  GL_TEXTURE_RECTANGLE_EXT, p->blendDualPeelTexID_[i < 3 ? 2*i : 2*(i-3) +1], 0);
107  }
108 
109  // back_blender_tex_id
110  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT6, GL_TEXTURE_RECTANGLE_EXT,
111  p->blendDualPeelTexID_[6], 0);
112  }
113 
114  ACG::GLState::bindFramebuffer(GL_FRAMEBUFFER, 0);
115 
116 
117  // load shaders
118 
119  const char* ShaderFiles[] = {"Blending/dual_peeling_init_vertex.glsl",
120  "Blending/dual_peeling_init_fragment.glsl",
121  "Blending/dual_peeling_blend_vertex.glsl",
122  "Blending/dual_peeling_blend_fragment.glsl",
123  "Blending/dual_peeling_final_vertex.glsl",
124  "Blending/dual_peeling_final_fragment.glsl"};
125 
126  for (int i = 0; i < 6; ++i)
127  {
128  QString shaderFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + QString(ShaderFiles[i]);
129 
130  if (blendShaders_[i]) continue;
131 
132  if (i & 1) // alternating vertex/fragment shader
133  blendShaders_[i] = GLSL::loadFragmentShader(shaderFile.toUtf8());
134  else
135  blendShaders_[i] = GLSL::loadVertexShader(shaderFile.toUtf8());
136 
137  if (!blendShaders_[i]) {
138  log(LOGERR, QString(ShaderFiles[i]) + QString(" could not be loaded and compiled"));
139  return;
140  }
141  }
142 
143  // dual depth peeling programs
144 
145  if (!blendDualPeelProg_[0])
146  {
147  for (int i = 0; i < 4; ++i)
148  {
149  if (i != 1)
151  }
152 
153  // init shaders
156  blendDualPeelProg_[0]->link();
157 
158  // blend shaders
161  blendDualPeelProg_[2]->link();
162 
163  // final shaders
166  blendDualPeelProg_[3]->link();
167  }
168 
169  if (!blendQueryID_)
170  glGenQueries(1, &blendQueryID_);
171 
173 }
174 
176 {
177  ViewerResources* p = &viewerRes_[_viewerId];
178 
179  if (p->blendDualPeelFbo_) glDeleteFramebuffers(1, &p->blendDualPeelFbo_);
180  p->blendDualPeelFbo_ = 0;
181 
182  if (p->blendDualPeelTexID_[0]) glDeleteTextures(7, p->blendDualPeelTexID_);
183  memset(p->blendDualPeelTexID_, 0, sizeof(p->blendDualPeelTexID_));
184 }
185 
187  // called in destructor and reloadBlendingTech()
188 
189  if (blendQueryID_)
190  glDeleteQueries(1, &blendQueryID_);
191  blendQueryID_ = 0;
192 
193  for (int i = 0; i < 4; ++i)
194  {
195  delete blendDualPeelProg_[i]; blendDualPeelProg_[i] = 0;
196  }
197 
198  for (unsigned int i = 0; i < sizeof(blendShaders_) / sizeof(blendShaders_[0]); ++i)
199  {
200  delete blendShaders_[i];
201  blendShaders_[i] = 0;
202  }
203 
204  for (unsigned int i = 0; i < sizeof(peelShaders_) / sizeof(peelShaders_[0]); ++i)
205  {
206  delete peelShaders_[i]; peelShaders_[i] = 0;
207  }
208 
209  for (unsigned int i = 0; i < sizeof(peelProgs_) / sizeof(peelProgs_[0]); ++i)
210  {
211  delete peelProgs_[i]; peelProgs_[i] = 0;
212  }
213 
214  // free all viewer specific resources
215  std::map<int, ViewerResources>::iterator resIt = viewerRes_.begin();
216  for (; resIt != viewerRes_.end(); ++resIt)
217  destroyResources(resIt->first);
218 }
219 
220 void DepthPeelingPlugin::render(ACG::GLState* _glState, Viewer::ViewerProperties& _properties)
221 {
222  glStateTmp_ = _glState;
223 
224  glPushAttrib(GL_ALL_ATTRIB_BITS);
225 
226  const GLuint targetFbo = ACG::GLState::getFramebufferDraw();
227 
228  int viewerId = _properties.viewerId();
229 
230  ViewerResources* pViewer = &viewerRes_[viewerId];
231  pViewer->glWidth_ = _glState->viewport_width();
232  pViewer->glHeight_ = _glState->viewport_height();
233 
234  if (pViewer->glWidth_ != pViewer->rtWidth_ || pViewer->glHeight_ != pViewer->rtHeight_)
235  reloadResources(viewerId);
236 
237 // updatePeelingShaderSet(viewerId, _properties.drawMode());
240 
241  ACG::GLState::depthFunc(GL_LESS);
242 
243 
244  ACG::GLState::disable(GL_CULL_FACE);
245  ACG::GLState::disable(GL_LIGHTING);
246  ACG::GLState::disable(GL_NORMALIZE);
247 
248  ACG::GLState::lockDepthFunc();
249  ACG::GLState::lockState(GL_CULL_FACE);
250  ACG::GLState::lockState(GL_LIGHTING);
251  ACG::GLState::lockState(GL_NORMALIZE);
252 
253  // from nvidia demo code:
254  // needed some minor adjustments
255 
256  GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT,
257  GL_COLOR_ATTACHMENT1_EXT,
258  GL_COLOR_ATTACHMENT2_EXT,
259  GL_COLOR_ATTACHMENT3_EXT,
260  GL_COLOR_ATTACHMENT4_EXT,
261  GL_COLOR_ATTACHMENT5_EXT,
262  GL_COLOR_ATTACHMENT6_EXT};
263 
264  // the farthest depth value possible in the depth buffer
265  const float maxDepth = 1.0f;
266 
267  ACG::GLState::disable(GL_DEPTH_TEST);
268  ACG::GLState::enable(GL_BLEND);
269 
270  ACG::GLState::lockState(GL_DEPTH_TEST);
271  ACG::GLState::lockState(GL_BLEND);
272 
273 
274 
275  /* FIXED: VIEWPORT BUG
276 
277  log-window causes viewport shift by 16 units upward in window's y axis
278  therefore the scene gets rendered only in the upper part of the viewport:
279  -> glViewport(0, 16, glWidht, glHeight_)
280 
281  glHeight_() is NOT the height of the back buffer (i.e. glViewer window),
282  but the height of scene target view
283  -> glHeight_() is 16 units less than the back buffer
284 
285  -> all render targets are 16 units less in height than back buffer
286 
287  since the scene has to use the full render targets size,
288  use glViewport(0, 0, glWidth_, glHeight_) for all offscreen rendering
289 
290  in the final pass, shift the viewport up by 16 units and use the shift amount
291  in the shader (uniform g_Offset), to finally get the correct sampling coordinates
292 
293 
294  note: shift amount is not hardcoded, but fetched from glGetIntegerv(GL_VIEWPORT)
295  */
296 
297 
298  GLint old_viewport[4];
299  glGetIntegerv(GL_VIEWPORT, old_viewport);
300  glViewport(0, 0, pViewer->glWidth_, pViewer->glHeight_);
301 
302  for (int i = 0; i < 6; ++i)
303  {
304  ACG::GLState::activeTexture(GL_TEXTURE0 + i);
305  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
306  }
307 
308 
309  // ---------------------------------------------------------------------
310  // 1. Initialize Min-Max Depth Buffer
311  // ---------------------------------------------------------------------
312 
313  ACG::GLState::bindFramebuffer(GL_FRAMEBUFFER_EXT, pViewer->blendDualPeelFbo_);
314 
315  // Render targets 1 and 2 store the front and back colors
316  // Clear to 0.0 and use MAX blending to filter written color
317  // At most one front color and one back color can be written every pass
318  ACG::GLState::drawBuffers(2, &drawBuffers[1]);
319  glClearColor(0, 0, 0, 0);
320  glClear(GL_COLOR_BUFFER_BIT);
321 
322  // Render target 0 stores (-minDepth, maxDepth, alphaMultiplier)
323  ACG::GLState::drawBuffer(drawBuffers[0]);
324  glClearColor(-maxDepth, -maxDepth, 0, 0);
325  glClear(GL_COLOR_BUFFER_BIT);
326  ACG::GLState::blendEquation(GL_MAX_EXT);
328 
329  blendDualPeelProg_[0]->use();
331  drawScenePass(_glState, _properties.drawMode(), sceneGraphRoot);
333 
334 
335 
336  int currId = 0;
337 
338  // ---------------------------------------------------------------------
339  // 2. Dual Depth Peeling + Blending
340  // ---------------------------------------------------------------------
341 
342  // Since we cannot blend the back colors in the geometry passes,
343  // we use another render target to do the alpha blending
344  //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_dualBackBlenderFboId);
345  ACG::GLState::drawBuffer(drawBuffers[6]);
346  glClearColor(_glState->clear_color()[0], _glState->clear_color()[1], _glState->clear_color()[2], 0);
347 
348  glClear(GL_COLOR_BUFFER_BIT);
349 
350  // Geometry layers are peeled until the sample query returns 0
351  GLuint sampleCount = 1;
352  for (int pass = 1; sampleCount; ++pass)
353  {
354  currId = pass % 2;
355  int prevId = 1 - currId;
356  int bufId = currId * 3;
357 
358  ACG::GLState::drawBuffers(2, &drawBuffers[bufId+1]);
359  glClearColor(0, 0, 0, 0);
360  glClear(GL_COLOR_BUFFER_BIT);
361 
362  ACG::GLState::drawBuffer(drawBuffers[bufId+0]);
363  glClearColor(-maxDepth, -maxDepth, 0, 0);
364  glClear(GL_COLOR_BUFFER_BIT);
365 
366  // Render target 0: RG32F MAX blending
367  // Render target 1: RGBA MAX blending
368  // Render target 2: RGBA MAX blending
369  ACG::GLState::drawBuffers(3, &drawBuffers[bufId+0]);
371  ACG::GLState::blendEquation(GL_MAX_EXT);
373 
374  ACG::GLState::activeTexture(GL_TEXTURE5); // front_blender_tex base_offset: 2
375  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, pViewer->blendDualPeelTexID_[2 + prevId]);
376 
377  ACG::GLState::activeTexture(GL_TEXTURE4); // depth_tex base_offset: 0
378  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, pViewer->blendDualPeelTexID_[0 + prevId]);
379 
380 
381  // scene geometry peeling pass
382  // note that the peel shader is set right before rendering in the traverser, based on a node's drawmode
383  ACG::GLState::activeTexture(GL_TEXTURE0);
384 
385  ACG::GLState::shadeModel(GL_SMOOTH); // flat shading is emulated in Geometry Shader, which only works with interpolated vertex shader output
387  drawScenePeelPass(_glState, _properties.drawMode(), sceneGraphRoot, pass);
389 
390 
391  // Full screen pass to alpha-blend the back color
392  ACG::GLState::drawBuffer(drawBuffers[6]);
393 
395  ACG::GLState::blendEquation(GL_FUNC_ADD);
397  ACG::GLState::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
398 
399  // start samples counter query
400  glBeginQuery(GL_SAMPLES_PASSED_ARB, blendQueryID_);
401 
402  blendDualPeelProg_[2]->use();
403  blendDualPeelProg_[2]->setUniform("TempTex", 4);
404 
405  ACG::GLState::activeTexture(GL_TEXTURE4); // back_temp_tex base_offset: 4
406  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, pViewer->blendDualPeelTexID_[4 + currId]);
407 
408  drawQuadProj(); // full screen quad, already projected
409 
410  glEndQuery(GL_SAMPLES_PASSED_ARB);
411  glGetQueryObjectuiv(blendQueryID_, GL_QUERY_RESULT_ARB, &sampleCount);
412  }
413 
415 
416  ACG::GLState::unlockState(GL_BLEND);
417  ACG::GLState::disable(GL_BLEND);
418 
419 
420 
421  // ---------------------------------------------------------------------
422  // 3. Final Pass
423  // operates on screen pixels only
424  // ---------------------------------------------------------------------
425 
426  // enable back buffer
427  ACG::GLState::bindFramebuffer(GL_FRAMEBUFFER_EXT, targetFbo);
428  if(targetFbo == 0) //if the default fbo is bound use GL_BACK
429  ACG::GLState::drawBuffer(GL_BACK);
430  else //if no default FBO is bound (e.g. with QOpenGLWindow use color attachment0 since only color attachment and none are allowed)
431  ACG::GLState::drawBuffer(GL_COLOR_ATTACHMENT0);
432 
433  // program id 3
434  blendDualPeelProg_[3]->use();
435  blendDualPeelProg_[3]->setUniform("FrontBlenderTex", 4);
436  blendDualPeelProg_[3]->setUniform("BackBlenderTex", 5);
437 
438  // bugfix for multiple viewports:
439  // gl_FragCoord represents the screen space coordinate of a pixel into the back buffer
440  // this has to be back-shifted by the upper left viewport coordinate to get correct texture coordinates
441  blendDualPeelProg_[3]->setUniform("ViewportOffset", ACG::Vec2f(old_viewport[0], old_viewport[1]));
442 
443  ACG::GLState::activeTexture(GL_TEXTURE5); // back_blender: offset 6
444  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, pViewer->blendDualPeelTexID_[6]);
445 
446 
447  ACG::GLState::activeTexture(GL_TEXTURE4); // front_blender_tex base_offset: 2
448  ACG::GLState::bindTexture(GL_TEXTURE_RECTANGLE_EXT, pViewer->blendDualPeelTexID_[2 + currId]);
449 
450 
451  glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]);
452  drawQuadProj(-1.0f, 1.0f, 2.0f, 2.0f);
453 
454 
456 
457 
458 
460 
461 
462  // unlock states
463  ACG::GLState::unlockDepthFunc();
464  ACG::GLState::unlockState(GL_CULL_FACE);
465  ACG::GLState::unlockState(GL_LIGHTING);
466  ACG::GLState::unlockState(GL_NORMALIZE);
467 
468  ACG::GLState::unlockState(GL_DEPTH_TEST);
469  ACG::GLState::unlockState(GL_BLEND);
470 
471 
472  glPopAttrib();
473 }
GLSL::PtrVertexShader loadVertexShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.
Definition: GLSLShader.cc:969
static void lockProgram()
lock the program
Definition: GLState.hh:629
static void unlockShadeModel()
unlock shade model
Definition: GLState.hh:385
GLSL::Program * blendDualPeelProg_[4]
depth peeling programs
void destroyResources()
free all gl resources
GLuint blendQueryID_
fragment query
static void blendEquation(GLenum _mode)
replaces glBlendEquation, supports locking
Definition: GLState.cc:1672
void updatePeelingShaderSet()
regenerates peeling shaders based on light nodes in scenegraph
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
static void unlockBlendEquation()
unlock blend equation
Definition: GLState.hh:346
GLuint blendDualPeelFbo_
depth peeling fbo
unsigned int rtWidth_
render target width
GLuint blendDualPeelTexID_[7]
render target textures: {depth0, depth1, front_blend0, front_blend1, back_temp0, back_temp1, back_blend}
GLSL::Shader * blendShaders_[8]
shader resources
int viewport_width() const
get viewport width
Definition: GLState.hh:822
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
Definition: GLState.cc:2074
static void lockBlendEquation()
lock blend equation
Definition: GLState.hh:344
void drawScenePass(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, BaseNode *_sceneGraphRoot)
draw the current scene
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:921
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:355
static void lockState(GLenum _cap)
locks a specific cap state, such that enable() or disable() has no effect
Definition: GLState.cc:1547
static void drawBuffers(GLsizei _n, const GLenum *_bufs)
replaces glDrawBuffers, supports locking
Definition: GLState.cc:2048
void drawQuadProj(float _x0=-1.0f, float _y0=1.0f, float _w=2.0f, float _h=2.0f)
draw a quad in projection space (only positions)
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
Definition: GLState.cc:2089
ACG::GLState * glStateTmp_
current glState ptr for hiddenline rendering
GLSL program class.
Definition: GLSLShader.hh:211
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
Definition: GLState.hh:307
static void lockShadeModel()
lock shade model
Definition: GLState.hh:383
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
unsigned int rtHeight_
render target height
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
Definition: GLState.cc:2033
void attach(PtrConstShader _shader)
Attaches a shader object to the program object.
Definition: GLSLShader.cc:292
static void syncFromGL()
synchronize this class with the OpenGL state machine
Definition: GLState.cc:1244
void link()
Links the shader objects to the program.
Definition: GLSLShader.cc:326
int viewport_height() const
get viewport height
Definition: GLState.hh:824
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1729
static void unlockProgram()
unlock the program
Definition: GLState.hh:631
unsigned int glHeight_
viewer window height
GLSL::Shader * peelShaders_[PEEL_NUM_COMBINATIONS *3]
generated shader set
void reloadResources(int _viewerId)
reload gl resources
void glCheckErrors()
Definition: GLError.hh:96
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
Definition: GLState.cc:1857
GLSL::PtrFragmentShader loadFragmentShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.
Definition: GLSLShader.cc:983
GLSL::Program * peelProgs_[PEEL_NUM_COMBINATIONS]
generates shader programs
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
static void unlockState(GLenum _cap)
unlocks a specific cap state
Definition: GLState.cc:1552
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:385
void use()
Enables the program object for using.
Definition: GLSLShader.cc:345
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
unsigned int glWidth_
viewer window width
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition: GLState.cc:1868