Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
RaycastVolume.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
33 #include <vlGraphics/GLSL.hpp>
34 #include <vlGraphics/Light.hpp>
35 #include <vlGraphics/Camera.hpp>
36 
37 using namespace vl;
38 
66 {
67  VL_DEBUG_SET_OBJECT_NAME()
68  // box geometry
69  mGeometry = new Geometry;
70 
71  // install vertex coords array
72  mVertCoord = new ArrayFloat3;
73  mVertCoord->resize( 8 );
74  mGeometry->setVertexArray( mVertCoord.get() );
75 
76  // install texture coords array
77  mTexCoord = new ArrayFloat3;
78  mTexCoord->resize( 8 );
79  mGeometry->setTexCoordArray( 0, mTexCoord.get() );
80 
81  // install index array
83  mGeometry->drawCalls().push_back( de.get() );
84  unsigned int de_indices[] =
85  {
86  0,1,2, 0,2,3, 1,5,6, 1,6,2, 5,4,7, 5,7,6, 4,0,3, 4,3,7, 3,2,6, 3,6,7, 4,5,1, 4,1,0
87  };
88  de->indexBuffer()->resize( 6 * 6 );
89  memcpy( de->indexBuffer()->ptr(), de_indices, sizeof( de_indices ) );
90 
91  // generate default texture coordinates
92  fvec3 texc[] =
93  {
94  fvec3( 0,0,0 ), fvec3( 1,0,0 ), fvec3( 1,1,0 ), fvec3( 0,1,0 ),
95  fvec3( 0,0,1 ), fvec3( 1,0,1 ), fvec3( 1,1,1 ), fvec3( 0,1,1 )
96  };
97  memcpy( mTexCoord->ptr(), texc, sizeof( texc ) );
98 
99  // default box dimensions and geometry
100  setBox( AABB( vec3( 0,0,0 ), vec3( 1,1,1 ) ) );
101 }
102 //-----------------------------------------------------------------------------
109 void RaycastVolume::updateUniforms( vl::Actor*actor, vl::real, const vl::Camera* camera, vl::Renderable*, const vl::Shader* shader )
110 {
111  const GLSLProgram* glsl = shader->getGLSLProgram();
112  VL_CHECK( glsl );
113 
114  // used later
115  fmat4 inv_mat;
116  if (actor->transform())
117  inv_mat = ( fmat4 )actor->transform()->worldMatrix().getInverse();
118 
119  if ( glsl->getUniformLocation( "lights[0].position" ) != -1 && glsl->getUniformLocation( "lights[0].enabled" ) != -1 )
120  {
121  // computes up to 4 light positions ( in object space ) and enables
122  fvec4 light_position;
123 
124  int ilight = 0;
125  for( ; ilight < 4 && ilight < (int)mLights.size(); ++ilight )
126  {
127  const vl::Light* light = mLights[ilight].get();
128  VL_CHECK( light );
129  actor->gocUniform( String::printf("lights[%d].enabled", ilight).toStdString().c_str() )->setUniformI( true );
130  if ( light )
131  {
132  // light position following transform
133  if ( light->boundTransform() )
134  light_position = ( fmat4 )light->boundTransform()->worldMatrix() * light->position();
135  // light position following camera
136  else
137  light_position = ( ( fmat4 )camera->modelingMatrix() * light->position() );
138 
139  // light position in object space
140  if ( actor->transform() )
141  light_position = inv_mat * light_position;
142 
143  actor->gocUniform( String::printf("lights[%d].position", ilight).toStdString().c_str() )->setUniform( light_position );
144  actor->gocUniform( String::printf("lights[%d].diffuse", ilight).toStdString().c_str() )->setUniform( light->diffuse() );
145  actor->gocUniform( String::printf("lights[%d].specular", ilight).toStdString().c_str() )->setUniform( light->specular() );
146  actor->gocUniform( String::printf("lights[%d].ambient", ilight).toStdString().c_str() )->setUniform( light->ambient() );
147  }
148  }
149 
150  // Disable remaining lights
151  for( ; ilight < 4; ++ilight ) {
152  actor->gocUniform( String::printf("lights[%d].enabled", ilight).toStdString().c_str() )->setUniformI( false );
153  }
154  }
155 
156  if ( glsl->getUniformLocation( "eye_position" ) != -1 )
157  {
158  // pass the eye position in object space
159 
160  // eye postion
161  fvec3 eye = ( fvec3 )camera->modelingMatrix().getT();
162  // world to object space
163  if ( actor->transform() )
164  eye = inv_mat * eye;
165  actor->gocUniform( "eye_position" )->setUniform( eye );
166  }
167 
168  if ( glsl->getUniformLocation( "eye_look" ) != -1 )
169  {
170  // pass the eye look direction in object space
171 
172  // eye postion
173  fvec3 look = -( fvec3 )camera->modelingMatrix().getZ();
174  // world to object space
175  if ( actor->transform() )
176  {
177  // look = inv_mat * look;
178  look = ( fmat4 )actor->transform()->worldMatrix().getInverse().getTransposed() * look;
179  }
180  actor->gocUniform( "eye_look" )->setUniform( look );
181  }
182 
183  // Normalized x/y/z offeset required to center on a texel
184  const Texture* tex = shader->getTextureSampler( 0 )->texture();
185  fvec3 centering = fvec3(
186  0.5f / tex->width(),
187  0.5f / tex->height(),
188  0.5f / tex->depth()
189  );
190  actor->gocUniform( "texel_centering" )->setUniform( centering );
191 
192  // Compute gradient delta: 0.25 seems to produce better results than 0.5.
193  actor->gocUniform( "gradient_delta" )->setUniform( fvec3( 0.25f / tex->width(), 0.25f / tex->height(), 0.25f / tex->depth() ) );
194 }
195 //-----------------------------------------------------------------------------
197 {
198  actor->actorEventCallbacks()->erase( this );
199  actor->actorEventCallbacks()->push_back( this );
200  actor->setLod( 0, mGeometry.get() );
201 }
202 //-----------------------------------------------------------------------------
203 void RaycastVolume::onActorRenderStarted( Actor* actor, real clock, const Camera* camera, Renderable* rend, const Shader* shader, int pass )
204 {
205  if ( pass>0 )
206  return;
207 
208  // setup uniform variables
209 
210  if ( shader->getGLSLProgram() ) {
211  updateUniforms( actor, clock, camera, rend, shader );
212  }
213 }
214 //-----------------------------------------------------------------------------
216 {
217  if ( ! img_size.x() || ! img_size.y() || ! img_size.z() )
218  {
219  Log::error( "RaycastVolume::generateTextureCoordinates(): failed! The size passed does not represent a 3D image.\n" );
220  return;
221  }
222 
223  float dx = 0.5f / img_size.x();
224  float dy = 0.5f / img_size.y();
225  float dz = 0.5f / img_size.z();
226 
227  float x0 = 0.0f + dx;
228  float x1 = 1.0f - dx;
229  float y0 = 0.0f + dy;
230  float y1 = 1.0f - dy;
231  float z0 = 0.0f + dz;
232  float z1 = 1.0f - dz;
233 
234  fvec3 texc[] =
235  {
236  fvec3( x0,y0,z1 ), fvec3( x1,y0,z1 ), fvec3( x1,y1,z1 ), fvec3( x0,y1,z1 ),
237  fvec3( x0,y0,z0 ), fvec3( x1,y0,z0 ), fvec3( x1,y1,z0 ), fvec3( x0,y1,z0 ),
238  };
239  memcpy( mTexCoord->ptr(), texc, sizeof( texc ) );
240 }
241 //-----------------------------------------------------------------------------
243 {
244  mBox = box;
245  // generate the box geometry
246  float x0 = box.minCorner().x();
247  float y0 = box.minCorner().y();
248  float z0 = box.minCorner().z();
249  float x1 = box.maxCorner().x();
250  float y1 = box.maxCorner().y();
251  float z1 = box.maxCorner().z();
252  fvec3 box_verts[] =
253  {
254  fvec3( x0,y0,z1 ), fvec3( x1,y0,z1 ), fvec3( x1,y1,z1 ), fvec3( x0,y1,z1 ),
255  fvec3( x0,y0,z0 ), fvec3( x1,y0,z0 ), fvec3( x1,y1,z0 ), fvec3( x0,y1,z0 ),
256  };
257  memcpy( mVertCoord->ptr(), box_verts, sizeof( box_verts ) );
258  mGeometry->setBoundsDirty( true );
259 }
260 //-----------------------------------------------------------------------------
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
int height() const
The vertical dimension of the texture in texels.
Definition: Texture.hpp:705
virtual void updateUniforms(Actor *actor, real clock, const Camera *camera, Renderable *rend, const Shader *shader)
Updates the uniforms used by the GLSLProgram to render the volume each time the onActorRenderStarted(...
Vector3< float > fvec3
A 3 components vector with float precision.
Definition: Vector3.hpp:252
Transform * transform()
Returns the Transform bound tho an Actor.
Definition: Actor.hpp:190
Vector3< T_Scalar > getZ() const
Definition: Matrix4.hpp:126
const T * get() const
Definition: Object.hpp:128
int getUniformLocation(const char *name) const
Returns the binding index of the given uniform.
Definition: GLSL.hpp:405
const T_Scalar & z() const
Definition: Vector3.hpp:91
ref< Geometry > mGeometry
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
Wraps a GLSL program to which you can bind vertex, fragment and geometry shaders. ...
Definition: GLSL.hpp:233
Wraps an OpenGL texture object representing and managing all the supported texture types...
Definition: Texture.hpp:143
const Collection< ActorEventCallback > * actorEventCallbacks() const
Returns the list of ActorEventCallback bound to an Actor.
Definition: Actor.hpp:370
void resize(size_t dim)
Definition: Array.hpp:233
Texture * texture()
The texture sampler by a texture unit.
Definition: Shader.hpp:1768
void generateTextureCoordinates(const ivec3 &img_size)
Generates a default set of texture coordinates for the 8 box corners of the volume based on the given...
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Definition: Geometry.hpp:66
Visualization Library main namespace.
const fvec4 & diffuse() const
Definition: Light.hpp:66
void setBox(const AABB &box)
Defines the dimensions of the box in model coordinates enclosing the volume and generates the actual ...
std::vector< ref< Light > > mLights
const unsigned char * ptr() const
Returns the pointer to the first element of the local buffer. Equivalent to bufferObject()->ptr() ...
Definition: Array.hpp:103
T_Scalar getInverse(Matrix4 &dest) const
Definition: Matrix4.hpp:1009
The AABB class implements an axis-aligned bounding box using vl::real precision.
Definition: AABB.hpp:44
const vec3 & maxCorner() const
Returns the corner of the AABB with the maximum x y z coordinates.
Definition: AABB.hpp:193
See DrawElements.
An abstract class that represents all the objects that can be rendered.
Definition: Renderable.hpp:58
const mat4 & modelingMatrix() const
Returns the Camera&#39;s modelingMatrix() (inverse of the view matrix).
Definition: Camera.hpp:169
void onActorRenderStarted(Actor *actor, real frame_clock, const Camera *cam, Renderable *renderable, const Shader *shader, int pass)
Event generated just before an Actor is rendered but after the render states are ready and setup...
ref< ArrayFloat3 > mVertCoord
Transform * boundTransform()
Definition: Light.cpp:119
const T_Scalar & y() const
Definition: Vector3.hpp:90
const AABB & box() const
The dimensions of the box enclosing the volume.
const mat4 & worldMatrix() const
Returns the world matrix used for rendering.
Definition: Transform.hpp:168
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
Definition: Shader.hpp:1830
void setUniformI(const int &value)
Definition: Uniform.hpp:176
arr_type * indexBuffer()
The BufferObject containing the indices used to render.
Uniform * gocUniform(const char *name)
Equivalent to getUniformSet()->getUniform(name, get_mode)
Definition: Actor.cpp:131
const vec3 & minCorner() const
Returns the corner of the AABB with the minimum x y z coordinates.
Definition: AABB.hpp:190
const GLSLProgram * getGLSLProgram() const
Returns a GLSLProgram if it exists or NULL otherwise.
Definition: Shader.cpp:59
Vector3< T_Scalar > getT() const
Definition: Matrix4.hpp:131
const fvec4 & specular() const
Definition: Light.hpp:69
fvec3 vec3
Defined as: &#39;typedef fvec3 vec3&#39;. See also VL_PIPELINE_PRECISION.
Definition: Vector3.hpp:269
void bindActor(Actor *)
Binds a RaycastVolume to an Actor.
const fvec4 & position() const
The position or direction of a light.
Definition: Light.hpp:79
void setLod(int lod_index, Renderable *renderable)
Sets the Renderable object representing the LOD level specifed by lod_index.
Definition: Actor.hpp:159
void setUniform(int count, const int *value)
Definition: Uniform.hpp:145
Wraps the OpenGL function glLight().
Definition: Light.hpp:51
const T_Scalar & x() const
Definition: Vector3.hpp:89
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
Matrix4< float > fmat4
A 4x4 matrix using float precision.
Definition: Matrix4.hpp:1229
ref< ArrayFloat3 > mTexCoord
An array of vl::fvec3.
Definition: Array.hpp:414
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
static String printf(const char *fmt,...)
Returns a formatted string using the legacy printf syntax. The resulting string can be maximum 1024 +...
Definition: String.cpp:1510
int depth() const
The z dimension of the texture in texels.
Definition: Texture.hpp:710
#define VL_CHECK(expr)
Definition: checks.hpp:73
const fvec4 & ambient() const
Definition: Light.hpp:63
int width() const
The horizontal dimension of the texture in texels.
Definition: Texture.hpp:700
const TextureSampler * getTextureSampler(int unit_index) const
Definition: Shader.hpp:2128