53#include <ACG/GL/acg_glew.hh>
54#include <ACG/GL/IRenderer.hh>
56#include "SplatCloudNode.hh"
75const SplatCloudNode::Index SplatCloudNode::DEFAULT_INDEX ( -1);
76const SplatCloudNode::Viewlist SplatCloudNode::DEFAULT_VIEWLIST ( 0.0);
77const SplatCloudNode::Selection SplatCloudNode::DEFAULT_SELECTION(
false);
85 splatCloud_ ( _splatCloud ),
86 positionsModified_ ( false ),
87 colorsModified_ ( false ),
88 normalsModified_ ( false ),
89 pointsizesModified_ ( false ),
90 selectionsModified_ ( false ),
91 pickColorsModified_ ( false ),
92 defaultColor_ (
Color (0,0,0) ),
93 defaultNormal_ (
Normal (0,0,0) ),
94 defaultPointsize_ ( Pointsize( 0.0) ),
95 splatsDrawMode_ ( DrawModes::addDrawMode(
"Splats" ) ),
96 dotsDrawMode_ ( DrawModes::addDrawMode(
"Dots" ) ),
97 pointsDrawMode_ ( DrawModes::addDrawMode(
"Points" ) ),
98 pickingBaseIndex_ ( 0 ),
99 pickDrawMode_ ( DrawModes::NONE ),
104 vboPositionsOffset_ ( -1 ),
105 vboColorsOffset_ ( -1 ),
106 vboNormalsOffset_ ( -1 ),
107 vboPointsizesOffset_( -1 ),
108 vboSelectionsOffset_( -1 ),
109 vboPickColorsOffset_( -1 ),
110 pointsizeScale_ ( 1.0f ),
111 backfaceCulling_ ( false ),
112 geometryShaderQuads_( false )
133 ACG::Vec3f bbMin( FLT_MAX, FLT_MAX, FLT_MAX );
134 ACG::Vec3f bbMax(-FLT_MAX,-FLT_MAX,-FLT_MAX );
139 for( i=0; i<num; ++i )
161 static const int RENDERMODE_DOTS = 1;
162 static const int RENDERMODE_SPLATS = 2;
167 rendermode = RENDERMODE_SPLATS;
169 rendermode = RENDERMODE_DOTS;
171 static const int RENDERMODE_POINTS = 0;
172 rendermode = RENDERMODE_POINTS;
181 rebuildVBO( _state );
204 if( vboColorsOffset_ != -1 )
207 glSecondaryColorPointer( 3, GL_UNSIGNED_BYTE,
static_cast<GLsizei
>(vboStride_), (
unsigned char *) 0 + vboColorsOffset_ );
216 if( vboNormalsOffset_ != -1 )
224 glNormal3f( defaultNormal_[0], defaultNormal_[1], defaultNormal_[2] );
228 if( vboPointsizesOffset_ != -1 )
230 glClientActiveTexture( GL_TEXTURE0 );
236 glClientActiveTexture( GL_TEXTURE0 );
238 glMultiTexCoord1f( GL_TEXTURE0, defaultPointsize_ );
242 if( vboSelectionsOffset_ != -1 )
244 glClientActiveTexture( GL_TEXTURE1 );
250 glClientActiveTexture( GL_TEXTURE1 );
252 glMultiTexCoord1f( GL_TEXTURE1, 0.0f );
256 if( vboPickColorsOffset_ != -1 )
259 ACG::GLState::colorPointer( 4, GL_UNSIGNED_BYTE,
static_cast<GLsizei
>(vboStride_), (
unsigned char *) 0 + vboPickColorsOffset_ );
264 glColor4ub( 255, 255, 255, 255 );
271 if( rendermode == RENDERMODE_SPLATS || rendermode == RENDERMODE_DOTS )
277 glDrawArrays( GL_POINTS, 0, vboNumSplats_ );
292 glClientActiveTexture( GL_TEXTURE0 );
296 glClientActiveTexture( GL_TEXTURE1 );
309 glClientActiveTexture( GL_TEXTURE0 );
310 glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f );
311 glSecondaryColor3f( 1.0f, 1.0f, 1.0f );
322 static const int RENDERMODE_POINTS = 0;
323 static const int RENDERMODE_DOTS = 1;
324 static const int RENDERMODE_SPLATS = 2;
329 rendermode = RENDERMODE_SPLATS;
331 rendermode = RENDERMODE_DOTS;
333 rendermode = RENDERMODE_POINTS;
341 obj.setMaterial(_mat);
343 obj.depthTest =
true;
368 if (vboColorsOffset_ != -1)
373 obj.emissive /= 255.0f;
377 if (vboNormalsOffset_ != -1)
386 if (vboPointsizesOffset_ != -1)
395 if (vboSelectionsOffset_ != -1)
404 if (vboPickColorsOffset_ != -1)
424 obj.programPointSize =
false;
427 if (rendermode == RENDERMODE_DOTS)
435 case RENDERMODE_SPLATS:
437 if (geometryShaderQuads_)
439 obj.
shaderDesc.vertexTemplateFile =
"SplatCloud_ShaderGen/splats_quad_vs.glsl";
440 obj.
shaderDesc.geometryTemplateFile =
"SplatCloud_ShaderGen/splats_quad_gs.glsl";
441 obj.
shaderDesc.fragmentTemplateFile =
"SplatCloud_ShaderGen/splats_quad_fs.glsl";
442 obj.programPointSize =
false;
446 obj.
shaderDesc.vertexTemplateFile =
"SplatCloud_ShaderGen/splats_psize_vs.glsl";
447 obj.
shaderDesc.fragmentTemplateFile =
"SplatCloud_ShaderGen/splats_psize_fs.glsl";
448 obj.programPointSize =
true;
452 case RENDERMODE_DOTS:
454 if (geometryShaderQuads_)
456 obj.
shaderDesc.vertexTemplateFile =
"SplatCloud_ShaderGen/dots_quad_vs.glsl";
457 obj.
shaderDesc.geometryTemplateFile =
"SplatCloud_ShaderGen/splats_quad_gs.glsl";
458 obj.
shaderDesc.fragmentTemplateFile =
"SplatCloud_ShaderGen/splats_quad_fs.glsl";
459 obj.programPointSize =
false;
463 obj.
shaderDesc.vertexTemplateFile =
"SplatCloud_ShaderGen/dots_psize_vs.glsl";
464 obj.programPointSize =
true;
468 case RENDERMODE_POINTS:
470 obj.
shaderDesc.vertexTemplateFile =
"SplatCloud_ShaderGen/points_vs.glsl";
471 obj.programPointSize =
false;
493 int left, bottom, width, height;
496 float x = (float)left;
497 float y = (float)bottom;
498 float w = (float)width;
499 float h = (float)height;
503 GLfloat depthRange[2];
504 glGetFloatv(GL_DEPTH_RANGE, depthRange);
505 float z = (float)depthRange[0];
506 float d = (float)depthRange[1] - z;
509 if (w <= 0.0f || h <= 0.0f || d <= 0.0f)
514 invVPs[0] = 2.0f / w;
515 invVPs[1] = 2.0f / h;
516 invVPs[2] = 2.0f / d;
521 invVPt[0] = -(x * invVPs[0] + 1.0f);
522 invVPt[1] = -(y * invVPs[1] + 1.0f);
523 invVPt[2] = -(z * invVPs[2] + 1.0f);
527 GLfloat VPs_z = 0.5f * d;
528 GLfloat VPt_z = z + VPs_z;
531 static const double RCP_3 = 1.0 / 3.0;
533 double detMV = mv(0, 0) * (mv(1, 1)*mv(2, 2) - mv(1, 2)*mv(2, 1))
534 + mv(0, 1) * (mv(1, 2)*mv(2, 0) - mv(1, 0)*mv(2, 2))
535 + mv(0, 2) * (mv(1, 0)*mv(2, 1) - mv(1, 1)*mv(2, 0));
536 GLfloat MVs = (GLfloat)pow(fabs(detMV), RCP_3);
539 GLfloat VPsFov_y = _state.
projection()(1, 1) * (0.5f * h);
548 obj.
setUniform(
"viewportScaleFov_y", VPsFov_y);
550 obj.
setUniform(
"pointsizeScale", pointsizeScale_);
551 obj.
setUniform(
"backfaceCulling", backfaceCulling_);
552 obj.
setUniform(
"defaultPointsize", defaultPointsize_);
553 obj.
setUniform(
"defaultNormal", defaultNormal_);
555 if (vboColorsOffset_ != -1)
559 obj.glDrawArrays(GL_POINTS, 0, vboNumSplats_);
576 std::cerr <<
"SplatCloudNode::pick() : Color range too small, picking failed." << std::endl;
586 pickColorsModified_ =
true;
590 draw( _state, pickDrawMode_ );
599void SplatCloudNode::createVBO()
604 glGenBuffers( 1, &vboGlId_ );
616void SplatCloudNode::destroyVBO()
621 glDeleteBuffers( 1, &vboGlId_ );
632void SplatCloudNode::rebuildVBO( GLState &_state )
646 unsigned int stride = 0;
648 int positionsOffset = -1;
649 int colorsOffset = -1;
650 int normalsOffset = -1;
651 int pointsizesOffset = -1;
652 int selectionsOffset = -1;
653 int pickColorsOffset = -1;
660 { pickColorsOffset = stride; stride += 4; }
663 glBufferData( GL_ARRAY_BUFFER_ARB,
static_cast<GLsizei
>(stride * numSplats), 0, GL_STATIC_DRAW_ARB );
666 unsigned char *data = (
unsigned char *) glMapBuffer( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );
671 std::cout <<
"SplatCloudNode::rebuildVBO() : glMapBuffer() failed." << std::endl;
679 vboNumSplats_ = numSplats;
684 vboColorsOffset_ = colorsOffset;
685 vboNormalsOffset_ = normalsOffset;
686 vboPointsizesOffset_ = pointsizesOffset;
687 vboSelectionsOffset_ = selectionsOffset;
688 vboPickColorsOffset_ = pickColorsOffset;
695 if( _state.color_picking() )
698 pickingBaseIndex_ =
static_cast<unsigned int>(_state.pick_current_index());
703 if( colorsModified_ ) rebuildVBOColors();
704 if( normalsModified_ ) rebuildVBONormals();
705 if( pointsizesModified_ ) rebuildVBOPointsizes();
706 if( selectionsModified_ ) rebuildVBOSelections();
707 if( pickColorsModified_ ) rebuildVBOPickColors( _state );
709# ifdef REPORT_VBO_UPDATES
710 std::cout << std::endl;
715 colorsModified_ =
false;
716 normalsModified_ =
false;
717 pointsizesModified_ =
false;
718 selectionsModified_ =
false;
719 pickColorsModified_ =
false;
722 if( !glUnmapBuffer( GL_ARRAY_BUFFER_ARB ) )
724 std::cout <<
"SplatCloudNode::rebuildVBO() : glUnmapBuffer() failed." << std::endl;
737static void addFloatToBuffer(
float _value,
unsigned char *&_buffer )
740 unsigned char *v = (
unsigned char *) &_value;
753static void addIntToBuffer(
int _value,
unsigned char *&_buffer )
756 unsigned char *v = (
unsigned char *) &_value;
769static void addUCharToBuffer(
unsigned char _value,
unsigned char *&_buffer )
772 unsigned char *v = (
unsigned char *) &_value;
782void SplatCloudNode::rebuildVBOPositions()
787# ifdef REPORT_VBO_UPDATES
788 std::cout <<
"SplatCloudNode::rebuildVBOPositions()" << std::endl;
794 for(
unsigned int i=0; i<num; ++i )
801 addFloatToBuffer( p[0], buffer );
802 addFloatToBuffer( p[1], buffer );
803 addFloatToBuffer( p[2], buffer );
812void SplatCloudNode::rebuildVBOColors()
817# ifdef REPORT_VBO_UPDATES
818 std::cout <<
"SplatCloudNode::rebuildVBOColors()" << std::endl;
823 for(
unsigned int i=0; i<num; ++i )
826 const Color &c = getColor( i );
829 unsigned char *buffer = vboData_ + vboColorsOffset_ + i * vboStride_;
831 addUCharToBuffer( c[0], buffer );
832 addUCharToBuffer( c[1], buffer );
833 addUCharToBuffer( c[2], buffer );
841void SplatCloudNode::rebuildVBONormals()
846# ifdef REPORT_VBO_UPDATES
847 std::cout <<
"SplatCloudNode::rebuildVBONormals()" << std::endl;
852 for(
unsigned int i=0; i<num; ++i )
855 const Normal &n = getNormal( i );
858 unsigned char *buffer = vboData_ + vboNormalsOffset_ + i * vboStride_;
860 addFloatToBuffer( n[0], buffer );
861 addFloatToBuffer( n[1], buffer );
862 addFloatToBuffer( n[2], buffer );
870void SplatCloudNode::rebuildVBOPointsizes()
875# ifdef REPORT_VBO_UPDATES
876 std::cout <<
"SplatCloudNode::rebuildVBOPointsizes()" << std::endl;
881 for(
unsigned int i=0; i<num; ++i )
884 const Pointsize &ps = getPointsize( i );
887 unsigned char *buffer = vboData_ + vboPointsizesOffset_ + i * vboStride_;
889 addFloatToBuffer(ps, buffer);
897void SplatCloudNode::rebuildVBOSelections()
902# ifdef REPORT_VBO_UPDATES
903 std::cout <<
"SplatCloudNode::rebuildVBOSelections()" << std::endl;
908 for(
unsigned int i=0; i<num; ++i )
910 const bool &s = getSelection( i );
913 unsigned char *buffer = vboData_ + vboSelectionsOffset_ + i * vboStride_;
915 addFloatToBuffer((s ? 1.0f : 0.0f), buffer);
923void SplatCloudNode::rebuildVBOPickColors( GLState &_state )
928# ifdef REPORT_VBO_UPDATES
929 std::cout <<
"SplatCloudNode::rebuildVBOPickColors()" << std::endl;
934 for(
unsigned int i=0; i<num; ++i )
937 const Vec4uc &pc = _state.pick_get_name_color( i );
940 unsigned char *buffer = vboData_ + vboPickColorsOffset_ + i * vboStride_;
942 addUCharToBuffer( pc[0], buffer );
943 addUCharToBuffer( pc[1], buffer );
944 addUCharToBuffer( pc[2], buffer );
945 addUCharToBuffer( pc[3], buffer );
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
const GLMatrixd & modelview() const
get modelview matrix
bool color_picking() const
Is color picking active?
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
const GLMatrixd & projection() const
get projection matrix
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
const GLMatrixd & inverse_projection() const
get inverse projection matrix
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
~SplatCloudNode()
destructor
int vboPositionsOffset_
offsets relative to vboData_ or -1 if not present in VBO
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw the SplatCloud
bool positionsModified_
marks if parts of the data has been modified
void pick(GLState &_state, PickTarget _target) override
picking
const SplatCloud & splatCloud_
reference to class containing all the data
SplatCloudNode(const SplatCloud &_splatCloud, BaseNode *_parent=0, std::string _name="<SplatCloudNode>")
constructor
bool vboStructureModified() const
returns true iff the internal block structure of the VBO has to be changed
Color defaultColor_
the default values will be used when the specific array is not present
void boundingBox(ACG::Vec3d &_bbMin, ACG::Vec3d &_bbMax) override
update bounding box
const Position & getPosition(int _idx) const
if the data array exists, the entry with the given index is returned, otherwise the default value is ...
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat) override
create render objects
bool vboModified() const
return true iff any of the data values in the VBO has to be changed
void addElement(const VertexElement *_pElement)
void setVertexStride(unsigned int _stride)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
bool hasPointsizes() const
Return the availability of the predefined property.
unsigned int numSplats() const
Get the number of splats.
bool hasPositions() const
Return the availability of the predefined property.
Position & positions(int _idx)
Get a reference of the predefined property's value.
bool hasSelections() const
Return the availability of the predefined property.
bool hasNormals() const
Return the availability of the predefined property.
bool hasColors() const
Return the availability of the predefined property.
PickTarget
What target to use for picking.
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
Namespace providing different geometric functions concerning angles.
VectorT< float, 3 > Vec3f
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_COLOR
"inColor"
@ VERTEX_USAGE_POSITION
"inPosition"
@ VERTEX_USAGE_TEXCOORD
"inTexCoord"
@ VERTEX_USAGE_SHADER_INPUT
defined by user via VertexElement::shaderInputName_
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void setUniform(const char *_name, GLint _value)
set values for int uniforms
void initFromState(GLState *_glState)
Initializes a RenderObject instance.