Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TriangleMeshSplatRendering.cpp
1 #include <GLviewer/TriangleMeshSplatRendering.hh>
2 #include <Image/Camera.hh>
3 #include <Base/Image/ImageIO.hh>
4 #include <GLviewer/GLProjectionParametersBase.hh>
5 #include <algorithm>
6 
7 using namespace BIAS;
8 
9 const char* DEPTH_PASS_VS =
10  "uniform float depthTolerance;"
11  "uniform vec3 cameraCenter;"
12  "void main()"
13  "{"
14  " vec3 point = gl_Vertex.xyz;"
15  " vec3 diff = normalize(point - cameraCenter);"
16  " point += diff * depthTolerance;"
17  " gl_Position = gl_ModelViewProjectionMatrix * vec4(point, 1.0);"
18  "}";
19 
20 const char* DEPTH_PASS_FS =
21  "void main()"
22  "{"
23  " gl_FragColor = vec4(0, 0, 0, 0);"
24  "}";
25 
26 const char* NORMALIZATION_PASS_VS =
27  "void main()"
28  "{"
29  " gl_TexCoord[0] = gl_MultiTexCoord0;"
30  " gl_Position = gl_Vertex;" // no transformation
31  "}";
32 
33 const char* NORMALIZATION_PASS_FS =
34  "uniform sampler2D colorTexture;"
35  "uniform sampler2D depthTexture;"
36  "void main()"
37  "{"
38  " vec4 color = texture2D(colorTexture, gl_TexCoord[0].st);"
39  " float invAlpha = 1.0 / color.a;"
40  " color.r *= invAlpha;"
41  " color.g *= invAlpha;"
42  " color.b *= invAlpha;"
43  " gl_FragColor = color;"
44  " gl_FragDepth = texture2D(depthTexture, gl_TexCoord[0].st).r;"
45  "}";
46 
47 
49  : internalWidth_(1280)
50  , internalHeight_(960)
51  , depthTolerance_(0.1f)
52  , enableBlending_(true)
53  , mustCreateShaders_(true)
54  , mustCreateFrameBuffer_(true)
55 {
56  camera_ = NULL;
57 }
58 
61 {
62  // for (unsigned int i = 0; i < tdos_.size(); i++)
63 // {
64 // delete tdos_[i];
65 // }
66  tdos_.clear();
67 }
68 
70 SetInternalResolution(int width, int height)
71 {
72  internalWidth_ = width;
73  internalHeight_ = height;
74  mustCreateFrameBuffer_ = true;
75 }
76 
78 SetDepthTolerance(float depthTolerance)
79 {
80  depthTolerance_ = depthTolerance;
81 }
82 
85  camera_ = camera;
86 }
87 
89 ComputeDepthTolerance(float fraction)
90 {
91  Vector3<double> min, max;
92  GetBoundingBox(min, max);
93 
94  double width = max[0] - min[0];
95  double height = max[1] - min[1];
96  double depth = max[2] - min[2];
97 
98  double size = std::max(width, std::max(height, depth));
99  SetDepthTolerance((float)size * fraction);
100  // std::cout<<"Tolerance:"<<(float)size * fraction<<std::endl;
101 }
102 
105 {
106  tdos_.push_back(tdo);
107 }
108 
111  tdos_.clear();
112 }
113 
116 {
117  if (!enableBlending_)
118  {
119  for (unsigned int i = 0; i < tdos_.size(); i++)
120  {
121  tdos_[i]->OpenGLOutIndexedFaceSets();
122  }
123  return;
124  }
125 
126  if (mustCreateShaders_)
127  {
128  CreateShaders();
129  mustCreateShaders_ = false;
130  }
131 
132  if (mustCreateFrameBuffer_)
133  {
134  CreateFrameBuffer(internalWidth_, internalHeight_);
135  mustCreateFrameBuffer_ = false;
136  }
137 
138  // TODO: Sometimes it's not right to directly render to the
139  // screen, for example when distortion rendering is enabled.
140  // But where to get the current render target from?
141  glfRenderTarget& renderTarget = glfScreen::GetInstance();
142 
143  // store old viewport
144  GLint oldViewport[4];
145  glGetIntegerv(GL_VIEWPORT, oldViewport);
146 
147  // get camera center
148  Vector3<double> cameraCenter = camera_->GetMyselfAsProjectionParameterBase()->GetC();
149 
150  // ---------------------------------------------
151  // DEPTH PASS
152  // ---------------------------------------------
153 
154  // write to fbo
155  fbo_.Bind();
156  fbo_.ClearColorBuffer(0.0, 0.0, 0.0, 0.0);
157  fbo_.ClearDepthBuffer();
158  glViewport(0, 0, colorBuffer_.GetWidth(), colorBuffer_.GetHeight());
159 
160  // use depth buffer for reading and writing
161  glEnable(GL_DEPTH_TEST);
162  glDepthMask(GL_TRUE);
163  glDepthFunc(GL_LESS);
164 
165  // don't write to color buffer
166  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
167 
168  // use depth pass program
169  depthPassProgram_.SetUniform("cameraCenter", cameraCenter);
170  depthPassProgram_.SetUniform("depthTolerance", depthTolerance_);
171  depthPassProgram_.Bind();
172 
173  // render geometry
174  for (unsigned int i = 0; i < tdos_.size(); i++) {
175  tdos_[i]->OpenGLOutIndexedFaceSets();
176  }
177 
178  // ---------------------------------------------
179  // SPLATTING PASS
180  // ---------------------------------------------
181 
182  // use depth buffer read-only
183  glEnable(GL_DEPTH_TEST);
184  glDepthMask(GL_FALSE);
185  glDepthFunc(GL_LEQUAL);
186 
187  // write to color buffer
188  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
189 
190  // use additive blending
191  glEnable(GL_BLEND);
192  glBlendEquation(GL_FUNC_ADD);
193  glBlendFunc(GL_ONE, GL_ONE);
194 
195  // use fixed function
196  glUseProgram(0);
197 
198  // render geometry
199  for (unsigned int i = 0; i < tdos_.size(); i++) {
200  tdos_[i]->OpenGLOutIndexedFaceSets();
201  }
202 
203  // ---------------------------------------------
204  // NORMALIZATION PASS
205  // ---------------------------------------------
206 
207  // disable fbo and write to destination render target
208  renderTarget.Bind();
209  glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
210 
211  // use depth buffer
212  glEnable(GL_DEPTH_TEST);
213  glDepthMask(GL_TRUE);
214  glDepthFunc(GL_LEQUAL);
215 
216  // disable blending
217  glDisable(GL_BLEND);
218 
219  // use normalization pass program
220  normalizationPassProgram_.Bind();
221 
222  // use texture from fbo
223  glActiveTexture(GL_TEXTURE0);
224  colorBuffer_.Bind();
225  glActiveTexture(GL_TEXTURE1);
226  depthBuffer_.Bind();
227 
228  // render quad to screen
229  glBegin(GL_QUADS);
230  glTexCoord2f(0.0f, 0.0f);
231  glVertex2f(-1.0f, -1.0f);
232  glTexCoord2f(1.0f, 0.0f);
233  glVertex2f(1.0f, -1.0f);
234  glTexCoord2f(1.0f, 1.0f);
235  glVertex2f(1.0f, 1.0f);
236  glTexCoord2f(0.0f, 1.0f);
237  glVertex2f(-1.0f, 1.0f);
238  glEnd();
239 
240  // restore render states
241  glEnable(GL_DEPTH_TEST);
242  glDepthMask(GL_TRUE);
243  glDepthFunc(GL_LESS);
244  glUseProgram(0);
245  glActiveTexture(GL_TEXTURE0);
246 }
247 
248 void TriangleMeshSplatRendering::
249 CreateShaders()
250 {
251  // create shader program for depth pass
252  depthPassProgram_.Create();
253  depthPassProgram_.AttachShaderFromSource(GL_VERTEX_SHADER, DEPTH_PASS_VS);
254  depthPassProgram_.AttachShaderFromSource(GL_FRAGMENT_SHADER, DEPTH_PASS_FS);
255  depthPassProgram_.Link();
256 
257  // create shader program for normalization pass
258  normalizationPassProgram_.Create();
259  normalizationPassProgram_.AttachShaderFromSource(GL_VERTEX_SHADER, NORMALIZATION_PASS_VS);
260  normalizationPassProgram_.AttachShaderFromSource(GL_FRAGMENT_SHADER, NORMALIZATION_PASS_FS);
261  normalizationPassProgram_.Link();
262  normalizationPassProgram_.SetUniform("colorTexture", 0);
263  normalizationPassProgram_.SetUniform("depthTexture", 1);
264 }
265 
266 void TriangleMeshSplatRendering::
267 CreateFrameBuffer(int width, int height)
268 {
269  // create color buffer
270  colorBuffer_.Create();
271  colorBuffer_.SetMagFilter(GL_LINEAR);
272  colorBuffer_.SetMinFilter(GL_LINEAR);
273  colorBuffer_.SetWrapT(GL_CLAMP);
274  colorBuffer_.SetWrapS(GL_CLAMP);
275  colorBuffer_.Allocate(width, height, GL_RGBA16F_ARB);
276  colorBuffer_.GenerateMipMap();
277 
278  // create depth buffer
279  depthBuffer_.Create();
280  depthBuffer_.SetMagFilter(GL_NEAREST);
281  depthBuffer_.SetMinFilter(GL_NEAREST);
282  depthBuffer_.SetWrapT(GL_CLAMP);
283  depthBuffer_.SetWrapS(GL_CLAMP);
284  depthBuffer_.Allocate(width, height, GL_DEPTH_COMPONENT);
285 
286  // create framebuffer object
287  fbo_.Create();
288  fbo_.AttachTexture(colorBuffer_, GL_COLOR_ATTACHMENT0_EXT);
289  fbo_.AttachTexture(depthBuffer_, GL_DEPTH_ATTACHMENT_EXT);
290  fbo_.CheckComplete();
291 }
292 
295  Vector3<double>& max)
296 {
297  min[0] = DBL_MAX;
298  min[1] = DBL_MAX;
299  min[2] = DBL_MAX;
300  max[0] = -DBL_MAX;
301  max[1] = -DBL_MAX;
302  max[2] = -DBL_MAX;
303 
304  for (unsigned int i = 0; i < tdos_.size(); i++)
305  {
306  Vector3<double> localMin, localMax;
307  tdos_[i]->GetBoundingBox(localMin, localMax);
308 
309  min[0] = std::min(min[0], localMin[0]);
310  min[1] = std::min(min[1], localMin[1]);
311  min[2] = std::min(min[2], localMin[2]);
312 
313  max[0] = std::max(max[0], localMax[0]);
314  max[1] = std::max(max[1], localMax[1]);
315  max[2] = std::max(max[2], localMax[2]);
316  }
317 }
318 
void GetBoundingBox(BIAS::Vector3< double > &min, BIAS::Vector3< double > &max)
void AttachShaderFromSource(GLenum type, const std::string &sourceCode)
Attaches a shader to the program, without the need to create an instance of the glfShader class...
void Allocate(int width, int height, GLenum internalFormat, int mipmap=0)
Creates a texture with undefined content.
void AttachTexture(const glfTexture &texture, GLenum attachmentPoint, int attachedMipMapLevel=0, int zSlice=0, GLenum cubeMapSide=0)
Attaches a texture to an attachment point which can be.
void Create()
Creates the shader program.
void SetUniform(const std::string &varName, float value)
int GetWidth(int mipmap=0) const
Returns the width of a mipmap of the texture.
void Link()
Links the attached shaders.
void Create()
Creates the texture but does not upload any data yet.
Definition: glfTexture.cpp:80
void Bind() const
Binds the texture.
Definition: glfTexture.cpp:242
Unified output of 3D entities via OpenGL or VRML.
Definition: ThreeDOut.hh:349
void SetWrapS(GLenum wrapS)
Sets the wrapping mode for the 1st texture coordinate.
Definition: glfTexture.cpp:105
void SetMinFilter(GLenum minFilter)
Sets the minifying function.
Definition: glfTexture.cpp:89
void Bind() const
Binds the shader program.
Abstract interface class to handle changes in rendering parameters by controllers and in rendering co...
int GetHeight(int mipmap=0) const
Returns the height of a mipmap of the texture.
void CheckComplete() const
Checks whether the framebuffer object is supported in its current state.
static glfScreen & GetInstance()
Returns the global screen instance.
Definition: glfScreen.cpp:30
virtual void Bind() const =0
Makes this render target the currently used render target.
void AddThreeDOut(BIAS::ThreeDOut *tdo)
Adds an arbitrary triangle ThreeDOut object to the scene.
void SetWrapT(GLenum wrapT)
Sets the wrapping mode for the 2nd texture coordinate.
Definition: glfTexture.cpp:113
void SetInternalResolution(int width, int height)
Sets the resolution of the internal framebuffer object.
void ClearDepthBuffer(float depth=1.0f)
Clears the depth buffer of the render target with the given value.
void GenerateMipMap()
Explicitly generates the mipmaps of the texture in hardware.
Definition: glfTexture.cpp:194
virtual void Bind() const
Makes this render target the currently used render target.
void SetDepthTolerance(float depthTolerance)
Sets the maximum depth difference at which geometry is considered to represent the same surface and i...
void SetCamera(BIAS::GLProjectionParametersInterface *camera)
void ClearColorBuffer(float red=0.0f, float green=0.0f, float blue=0.0f, float alpha=0.0f)
Clears the color buffer of the render target with the given color.
void ComputeDepthTolerance(float fraction=0.01f)
Set depth tolerance based on fraction of bounding box of tdo objects.
Interface for render targets.
void Create()
Creates the framebuffer object.
void SetMagFilter(GLenum magFilter)
Sets the magnification function.
Definition: glfTexture.cpp:97