59 #define ACG_POLYLINENODET_C
63 #include "PolyLineNodeT.hh"
64 #include <ACG/GL/gl.hh>
65 #include <ACG/GL/ShaderCache.hh>
66 #include <ACG/Utils/VSToolsT.hh>
72 namespace SceneGraph {
77 template <
class PolyLine>
104 template <
class PolyLine>
112 template <
class PolyLine>
117 for (
unsigned int i=0; i< polyline_.n_vertices(); ++i)
119 _bbMin.minimize(polyline_.point(i));
120 _bbMax.maximize(polyline_.point(i));
128 template <
class PolyLine>
140 template <
class PolyLine>
146 if ( polyline_.n_vertices() == 0 )
164 vertexDecl_.activateFixedFunction();
167 if( polyline_.vertex_selections_available() && !selectedVertexIndexBuffer_.empty())
174 glDrawElements(GL_POINTS, selectedVertexIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedVertexIndexBuffer_[0]));
182 if (_drawMode & DrawModes::POINTS_COLORED)
184 vertexDecl_.deactivateFixedFunction();
185 vertexDeclVCol_.activateFixedFunction();
189 glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
191 if (_drawMode & DrawModes::POINTS_COLORED)
192 vertexDeclVCol_.deactivateFixedFunction();
194 vertexDecl_.deactivateFixedFunction();
199 vertexDecl_.activateFixedFunction();
202 if (polyline_.edge_selections_available() && !selectedEdgeIndexBuffer_.empty()) {
208 glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
215 if ( polyline_.is_closed() )
216 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
218 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
220 vertexDecl_.deactivateFixedFunction();
225 vertexDecl_.activateFixedFunction();
228 if (polyline_.edge_selections_available() && !selectedEdgeIndexBuffer_.empty()) {
234 glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
239 vertexDecl_.deactivateFixedFunction();
244 vertexDeclECol_.activateFixedFunction();
245 if (polyline_.is_closed())
246 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
248 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
250 vertexDeclECol_.deactivateFixedFunction();
255 if (polyline_.vertex_normals_available()) {
256 double avg_len = polyline_.n_edges() > 0 ? (polyline_.length() / polyline_.n_edges() * 0.75) : 0;
257 std::vector<Point> ps;
258 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
259 ps.push_back(polyline_.point(i));
260 ps.push_back(polyline_.point(i) + polyline_.vertex_normal(i) * avg_len);
261 if (polyline_.vertex_binormals_available())
262 ps.push_back(polyline_.point(i) + polyline_.vertex_binormal(i) * avg_len);
273 int stride = polyline_.vertex_binormals_available() ? 3 : 2;
275 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
276 glArrayElement(stride * i);
277 glArrayElement(stride * i + 1);
281 if (polyline_.vertex_binormals_available()) {
284 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
285 glArrayElement(stride * i);
286 glArrayElement(stride * i + 2);
300 if (_drawMode & POINTS_SPHERES)
306 if( polyline_.vertex_selections_available())
308 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
310 if(polyline_.vertex_selected(i))
321 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
326 if (_drawMode & POINTS_SPHERES_SCREEN)
335 if( polyline_.vertex_selections_available())
337 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
339 if(polyline_.vertex_selected(i))
347 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
353 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
358 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
368 template <
class PolyLine>
373 if ( polyline_.n_vertices() == 0 )
381 unsigned int n_end = polyline_.n_edges()+1;
382 if( !polyline_.is_closed()) --n_end;
395 pick_vertices( _state);
397 if (drawMode() & POINTS_SPHERES)
398 pick_spheres( _state);
400 if (drawMode() & POINTS_SPHERES_SCREEN)
401 pick_spheres_screen( _state);
409 pick_edges(_state, 0);
418 pick_vertices( _state);
420 if (drawMode() & POINTS_SPHERES)
421 pick_spheres( _state);
423 if (drawMode() & POINTS_SPHERES_SCREEN)
424 pick_spheres_screen( _state);
426 pick_edges( _state, polyline_.n_vertices());
446 template <
class PolyLine>
451 if (!polyline_.n_vertices())
457 glDepthRange(0.0, 0.999999);
461 if (pickShader && pickShader->isLinked())
472 vertexDecl_.activateShaderPipeline(pickShader);
478 pickShader->setUniform(
"mWVP", transform);
479 pickShader->setUniform(
"pickVertexOffset", pickOffsetIndex);
481 glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
483 vertexDecl_.deactivateShaderPipeline(pickShader);
484 pickShader->disable();
491 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
499 glDepthRange(0.0, 1.0);
503 glPointSize(point_size_old);
510 template <
class PolyLine>
512 PolyLineNodeT<PolyLine>::
513 pick_spheres( GLState& _state )
516 sphere_ =
new GLSphere(10,10);
518 _state.pick_set_name(0);
520 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
522 _state.pick_set_name (i);
523 sphere_->draw(_state, _state.point_size(), (
Vec3f)polyline_.point(i));
530 template <
class PolyLine>
532 PolyLineNodeT<PolyLine>::
533 pick_spheres_screen( GLState& _state )
536 sphere_ =
new GLSphere(10,10);
538 _state.pick_set_name(0);
541 double r = 0.5*_state.point_size()/double(_state.viewport_height())*2.0*tan(0.5*_state.fovy());
543 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
545 _state.pick_set_name (i);
547 const Vec3d p = (
Vec3d)polyline_.point(i) - _state.eye();
548 double l = (p|_state.viewing_direction());
549 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
560 template <
class PolyLine>
562 PolyLineNodeT<PolyLine>::
563 pick_edges( GLState& _state,
unsigned int _offset)
566 if ( polyline_.n_edges() == 0 )
569 glDepthRange(0.0, 0.999999);
573 if (pickShader && pickShader->
isLinked())
582 int pickOffsetIndex = int(_state.pick_current_index());
584 vertexDecl_.activateShaderPipeline(pickShader);
588 ACG::GLMatrixf transform = _state.projection() * _state.modelview();
591 pickShader->
setUniform(
"pickVertexOffset", pickOffsetIndex);
593 int numIndices = polyline_.n_vertices() + (polyline_.is_closed() ? 1 : 0);
594 glDrawArrays(GL_LINE_STRIP, 0, numIndices);
596 vertexDecl_.deactivateShaderPipeline(pickShader);
604 float line_width_old = _state.line_width();
606 _state.set_line_width(14);
608 unsigned int n_end = polyline_.n_edges() + 1;
609 if (!polyline_.is_closed()) --n_end;
611 for (
unsigned int i = 0; i < n_end; ++i) {
612 _state.pick_set_name(i + _offset);
614 glArrayElement(i % polyline_.n_vertices());
615 glArrayElement((i + 1) % polyline_.n_vertices());
619 _state.set_line_width(line_width_old);
622 glDepthRange(0.0, 1.0);
628 template <
class PolyLine>
640 size_t curOffset = 12;
643 if (polyline_.vertex_normals_available())
650 if (polyline_.vertex_colors_available())
652 if (_colorSource == 1)
657 if (polyline_.edge_colors_available())
659 if (_colorSource == 2)
666 for (
size_t i = 0; i < customBuffers_.size(); ++i) {
681 template <
class PolyLine>
688 for (
unsigned int i = 0; i < polyline_.get_num_custom_properties(); ++i) {
690 typename PolyLine::CustomPropertyHandle proph = polyline_.enumerate_custom_property_handles(i);
694 const void* propDataBuf = polyline_.get_custom_property_buffer(proph);
696 typename std::map< typename PolyLine::CustomPropertyHandle, int >::iterator mapEntry = polylinePropMap_.find(proph);
699 if (mapEntry == polylinePropMap_.end()) {
704 unsigned int propSize = 0;
705 if (polyline_.get_custom_property_shader_binding(proph, &propSize, &desc.
shaderInputName_, &desc.
type_)) {
710 polylinePropMap_[proph] = addCustomBuffer(desc, propDataBuf);
714 setCustomBuffer(mapEntry->second, propDataBuf);
719 setupVertexDeclaration(&vertexDecl_, 0);
720 setupVertexDeclaration(&vertexDeclVCol_, 1);
721 setupVertexDeclaration(&vertexDeclECol_, 2);
723 const unsigned int stride = vertexDecl_.getVertexStride();
730 unsigned int bufferSize = stride * (polyline_.n_vertices() + 1);
733 char* vboData_ =
new char[bufferSize];
736 selectedVertexIndexBuffer_.clear();
739 selectedEdgeIndexBuffer_.clear();
741 for (
unsigned int i = 0 ; i < polyline_.n_vertices(); ++i) {
743 writeVertex(i, vboData_ + i * stride);
746 if ( polyline_.vertex_selections_available() && polyline_.vertex_selected(i) )
747 selectedVertexIndexBuffer_.push_back(i);
750 if ( polyline_.edge_selections_available() && polyline_.edge_selected(i) ) {
751 selectedEdgeIndexBuffer_.push_back(i);
752 selectedEdgeIndexBuffer_.push_back( (i + 1) % polyline_.n_vertices() );
758 writeVertex(0, vboData_ + polyline_.n_vertices() * stride);
773 template <
class PolyLine>
778 const VertexDeclaration* declToUse = _colorSourceVertex ? &vertexDeclVCol_ : &vertexDeclECol_;
781 unsigned char* ucdata = ((
unsigned char*)_dst) + byteOffset;
784 if (_colorSourceVertex)
785 col = polyline_.vertex_color(_vertex);
790 int edgeID = (_vertex + polyline_.n_edges() - 1) % polyline_.n_edges();
791 col = polyline_.edge_color(edgeID);
795 for (
int i = 0; i < 3; ++i)
798 int ival = int(col[i] * 255.0);
799 ival = std::min(std::max(ival, 0), 255);
807 template <
class PolyLine>
813 float* fdata = (
float*)_dst;
816 for (
unsigned int j = 0 ; j < 3 ; ++j)
817 *(fdata++) = polyline_.point(_vertex)[j];
820 if ( polyline_.vertex_normals_available() )
821 for (
unsigned int j = 0 ; j < 3 ; ++j)
822 *(fdata++) = polyline_.vertex_normal(_vertex)[j];
824 if (polyline_.vertex_colors_available())
825 writeVertexColor(_vertex,
true, _dst);
827 if (polyline_.edge_colors_available())
828 writeVertexColor(_vertex,
false, _dst);
832 if (customElementOffset >= 0)
835 for (
unsigned int i = 0; i < customBuffers_.size(); ++i) {
842 if (!elementInputStride)
843 elementInputStride = elementSize;
846 const ACG::VertexElement* ve = vertexDeclVCol_.getElement(i + static_cast<unsigned int>(customElementOffset));
848 const char* src = (
const char*)customBuffers_[i].second;
850 memcpy((
char*)_dst + ve->
getByteOffset(), src + elementInputStride * _vertex, elementSize);
857 template <
class PolyLine>
863 if ( polyline_.n_vertices() == 0 )
869 _state.
enable(GL_COLOR_MATERIAL);
870 _state.
enable(GL_LIGHTING);
873 ro.setMaterial(_mat);
886 ro.debugName =
"PolyLine";
897 for (
unsigned int i = 0; i < _drawMode.
getNumLayers(); ++i) {
911 ro.setMaterial(&localMaterial);
914 switch (props->primitive()) {
916 case ACG::SceneGraph::DrawModes::PRIMITIVE_POINT:
919 ro.debugName =
"polyline.Points.selected";
921 ro.setMaterial(&localMaterial);
929 if (!selectedVertexIndexBuffer_.empty())
931 ro.glDrawElements(GL_POINTS, selectedVertexIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedVertexIndexBuffer_[0]));
933 applyRenderObjectSettings(props->primitive(), &ro);
939 ro.debugName =
"polyline.Points";
941 ro.setMaterial(&localMaterial);
942 ro.glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
944 if (props->
colored() && polyline_.vertex_colors_available())
955 applyRenderObjectSettings(props->primitive(), &ro);
961 case ACG::SceneGraph::DrawModes::PRIMITIVE_WIREFRAME:
962 case ACG::SceneGraph::DrawModes::PRIMITIVE_EDGE:
965 ro.debugName =
"polyline.Wireframe.selected";
967 ro.setMaterial(&localMaterial);
975 if (!selectedEdgeIndexBuffer_.empty())
977 ro.glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
980 applyRenderObjectSettings(props->primitive(), &ro);
985 ro.debugName =
"polyline.Wireframe";
987 ro.setMaterial(&localMaterial);
990 if ( polyline_.is_closed() )
991 ro.glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
993 ro.glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
995 if (props->
colored() && polyline_.edge_colors_available())
1005 applyRenderObjectSettings(props->primitive(), &ro);
1012 case ACG::SceneGraph::DrawModes::PRIMITIVE_POLYGON:
1018 bool screenScale = _drawMode & POINTS_SPHERES_SCREEN;
1039 if (polyline_.vertex_selections_available())
1041 ro.debugName =
"polyline.Sphere.selected";
1042 localMaterial.
baseColor(selectionColor);
1043 ro.setMaterial(&localMaterial);
1045 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i)
1047 if (polyline_.vertex_selected(i))
1053 const Vec3d p = (
Vec3d)polyline_.point(i) - eyePos;
1054 radius = (p | viewDir) * r;
1057 sphere_->addToRenderer(_renderer, &ro, radius, (
Vec3f)polyline_.point(i));
1063 ro.debugName =
"polyline.Sphere";
1065 ro.setMaterial(&localMaterial);
1067 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i)
1069 if (!polyline_.vertex_selections_available() || !polyline_.vertex_selected(i))
1075 const Vec3d p = (
Vec3d)polyline_.point(i) - eyePos;
1076 radius = (p | viewDir) * r;
1079 sphere_->addToRenderer(_renderer, &ro, radius, (
Vec3f)polyline_.point(i));
1095 template <
class PolyLine>
1101 customBuffers_.push_back( std::pair<ACG::VertexElement, const void*>(_desc, _buffer) );
1104 return int(customBuffers_.size()-1);
1108 std::cerr <<
"PolyLineNodeT::addCustomBuffer - null pointer buffer" << std::endl;
1115 template <
class PolyLine>
1120 customBuffers_[_id].second = _buffer;
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
size_t getNumLayers() const
returns the layer count
DrawMode EDGES_COLORED
draw edges with colors (without shading)
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Namespace providing different geometric functions concerning angles.
static void enable(GLenum _cap)
replaces glEnable, but supports locking
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
void setByteOffset(unsigned int _offset)
int viewport_width() const
get viewport width
void pick_set_name(unsigned int _idx)
sets the current name/color (like glLoadName(_idx))
PickTarget
What target to use for picking.
DrawModes::DrawMode availableDrawModes() const
return available draw modes
static void disable(GLenum _cap)
replaces glDisable, but supports locking
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
static void bufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
pick any of the prior targets (should be implemented for all nodes)
static unsigned int getGLTypeSize(unsigned int _type)
static unsigned int getElementSize(const VertexElement *_pElement)
const void * pointer_
Offset in bytes to the first occurrence of this element in vertex buffer; Or address to vertex data i...
unsigned int type_
GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT, ...
void setCustomBuffer(int _id, const void *_buffer)
void updateVBO()
Trigger an update of the vbo.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
unsigned int getByteOffset() const
float line_width() const
get line width
int priority
Priority to allow sorting of objects.
float point_size() const
get point size
int viewport_height() const
get viewport height
const Vec4f & ambient_color() const
get ambient color
VectorT< float, 4 > Vec4f
double fovy() const
get field of view in y direction
int addCustomBuffer(const ACG::VertexElement &_desc, const void *_buffer)
VectorT< double, 3 > Vec3d
const GLMatrixd & modelview() const
get modelview matrix
const GLMatrixd & projection() const
get projection matrix
~PolyLineNodeT()
Destructor.
const Vec4f & diffuse_color() const
get diffuse color
VERTEX_USAGE usage_
position, normal, shader input ..
picks verices (may not be implemented for all nodes)
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
void writeVertex(unsigned int _vertex, void *_dst)
Write vertex data for rendering to a buffer.
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
void baseColor(const Vec4f &_c)
set the base color
PolyLineNodeT(PolyLine &_pl, BaseNode *_parent=0, std::string _name="<PolyLineNode>")
Constructor.
Vec3d viewing_direction() const
get viewing ray
picks edges (may not be implemented for all nodes)
static void genBuffersARB(GLsizei n, GLuint *buffers)
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
static unsigned int getElementSize(const VertexElement *_pElement)
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
void use()
Enables the program object for using.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
void writeVertexColor(unsigned int _vertex, bool _colorSourceVertex, void *_dst) const
Write color for rendering to a buffer.
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
unsigned int pick_current_index() const
Returns the current color picking index (can be used for caching)
void set_color(const Vec4f &_col)
set color
bool isLinked()
Returns if the program object has been succesfully linked.
void pick(GLState &_state, PickTarget _target)
picking
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
float line_width() const
get line width
VectorT< float, 3 > Vec3f
defined by user via VertexElement::shaderInputName_
float point_size() const
get point size
Interface class between scenegraph and renderer.
DrawMode POINTS
draw unlighted points using the default base color
Vec3d eye() const
get eye point
double fovy() const
get field of view in y direction
void pointSize(float _sz)
set point size (default: 1.0)
Vec3d viewing_direction() const
get viewing ray
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
4x4 matrix implementing OpenGL commands.
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Class to define the vertex input layout.
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.
DrawModeProperties stores a set of properties that defines, how to render an object.
DrawMode WIREFRAME
draw wireframe
void set_line_width(float _f)
set line width
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
bool colored() const
Are colors used?
DrawModes::DrawMode POINTS_SPHERES
This defines a local point spheres draw mode for all polyLine nodes.
Description of one vertex element.
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
unsigned int getByteOffset() const
void setupVertexDeclaration(VertexDeclaration *_dst, int _colorSource) const
Create the vertex declaration.
unsigned int numElements_
how many elements of type_
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const Vec4f & ambient_color() const
get ambient color
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
void disable()
Resets to standard rendering pipeline.
ACGDLLEXPORT const DrawMode & addDrawMode(const std::string &_name, bool _propertyBased=false)
Add a custom DrawMode.
void set_point_size(float _f)
set point size
Vec3d eye() const
get eye point
const char * shaderInputName_
set shader input name, if usage_ = VERTEX_USAGE_USER_DEFINED otherwise this is set automatically...
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
int viewport_height() const
get viewport height
DrawModes::DrawMode POINTS_SPHERES_SCREEN
This defines a local point spheres draw mode for all polyLine nodes with constant screen size...
void draw(GLState &, const DrawModes::DrawMode &_drawMode)
draw lines and normals
const Vec4f & diffuse_color() const
get diffuse color
void addElement(const VertexElement *_pElement)
void setVertexStride(unsigned int _stride)