53#define ACG_POLYLINENODET_C
57#include "PolyLineNodeT.hh"
58#include <ACG/GL/gl.hh>
59#include <ACG/GL/ShaderCache.hh>
60#include <ACG/Utils/VSToolsT.hh>
71template <
class PolyLine>
97template <
class PolyLine>
105template <
class PolyLine>
110 for (
unsigned int i=0; i< polyline_.n_vertices(); ++i)
112 _bbMin.
minimize(polyline_.point(i));
113 _bbMax.
maximize(polyline_.point(i));
121template <
class PolyLine>
133template <
class PolyLine>
139 if ( polyline_.n_vertices() == 0 )
157 vertexDecl_.activateFixedFunction();
160 if( polyline_.vertex_selections_available() && !selectedVertexIndexBuffer_.empty())
167 glDrawElements(GL_POINTS, selectedVertexIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedVertexIndexBuffer_[0]));
177 vertexDecl_.deactivateFixedFunction();
178 vertexDeclVCol_.activateFixedFunction();
182 glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
185 vertexDeclVCol_.deactivateFixedFunction();
187 vertexDecl_.deactivateFixedFunction();
192 vertexDecl_.activateFixedFunction();
195 if (polyline_.edge_selections_available() && !selectedEdgeIndexBuffer_.empty()) {
201 glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
208 if ( polyline_.is_closed() )
209 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
211 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
213 vertexDecl_.deactivateFixedFunction();
218 vertexDecl_.activateFixedFunction();
221 if (polyline_.edge_selections_available() && !selectedEdgeIndexBuffer_.empty()) {
227 glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
232 vertexDecl_.deactivateFixedFunction();
237 vertexDeclECol_.activateFixedFunction();
238 if (polyline_.is_closed())
239 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
241 glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
243 vertexDeclECol_.deactivateFixedFunction();
248 if (polyline_.vertex_normals_available()) {
249 double avg_len = polyline_.n_edges() > 0 ? (polyline_.length() / polyline_.n_edges() * 0.75) : 0;
250 std::vector<Point> ps;
251 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
252 ps.push_back(polyline_.point(i));
253 ps.push_back(polyline_.point(i) + polyline_.vertex_normal(i) * avg_len);
254 if (polyline_.vertex_binormals_available())
255 ps.push_back(polyline_.point(i) + polyline_.vertex_binormal(i) * avg_len);
266 int stride = polyline_.vertex_binormals_available() ? 3 : 2;
268 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
269 glArrayElement(stride * i);
270 glArrayElement(stride * i + 1);
274 if (polyline_.vertex_binormals_available()) {
277 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
278 glArrayElement(stride * i);
279 glArrayElement(stride * i + 2);
293 if (_drawMode & POINTS_SPHERES)
297 sphere_ =
new GLSphere(10,10);
299 if( polyline_.vertex_selections_available())
301 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
303 if(polyline_.vertex_selected(i))
314 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
319 if (_drawMode & POINTS_SPHERES_SCREEN)
323 sphere_ =
new GLSphere(10,10);
328 if( polyline_.vertex_selections_available())
330 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
332 if(polyline_.vertex_selected(i))
340 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
346 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
351 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
361template <
class PolyLine>
366 if ( polyline_.n_vertices() == 0 )
374 unsigned int n_end = polyline_.n_edges()+1;
375 if( !polyline_.is_closed()) --n_end;
388 pick_vertices( _state);
390 if (drawMode() & POINTS_SPHERES)
391 pick_spheres( _state);
393 if (drawMode() & POINTS_SPHERES_SCREEN)
394 pick_spheres_screen( _state);
402 pick_edges(_state, 0);
411 pick_vertices( _state);
413 if (drawMode() & POINTS_SPHERES)
414 pick_spheres( _state);
416 if (drawMode() & POINTS_SPHERES_SCREEN)
417 pick_spheres_screen( _state);
419 pick_edges( _state, polyline_.n_vertices());
439template <
class PolyLine>
444 if (!polyline_.n_vertices())
450 glDepthRange(0.0, 0.999999);
453 desc.vertexTemplateFile =
"Picking/pick_vertices_vs.glsl";
454 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs.glsl";
457 if (pickShader && pickShader->
isLinked())
468 vertexDecl_.activateShaderPipeline(pickShader);
475 pickShader->
setUniform(
"pickVertexOffset", pickOffsetIndex);
477 glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
479 vertexDecl_.deactivateShaderPipeline(pickShader);
487 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i) {
495 glDepthRange(0.0, 1.0);
499 glPointSize(point_size_old);
506template <
class PolyLine>
508PolyLineNodeT<PolyLine>::
509pick_spheres( GLState& _state )
512 sphere_ =
new GLSphere(10,10);
514 _state.pick_set_name(0);
516 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
518 _state.pick_set_name (i);
519 sphere_->draw(_state, _state.point_size(), (
Vec3f)polyline_.point(i));
526template <
class PolyLine>
528PolyLineNodeT<PolyLine>::
529pick_spheres_screen( GLState& _state )
532 sphere_ =
new GLSphere(10,10);
534 _state.pick_set_name(0);
537 double r = 0.5*_state.point_size()/double(_state.viewport_height())*2.0*tan(0.5*_state.fovy());
539 for(
unsigned int i=0; i<polyline_.n_vertices(); ++i)
541 _state.pick_set_name (i);
543 const Vec3d p = (
Vec3d)polyline_.point(i) - _state.eye();
544 double l = (p|_state.viewing_direction());
545 sphere_->draw(_state, r*l, (
Vec3f)polyline_.point(i));
556template <
class PolyLine>
558PolyLineNodeT<PolyLine>::
559pick_edges( GLState& _state,
unsigned int _offset)
562 if ( polyline_.n_edges() == 0 )
565 glDepthRange(0.0, 0.999999);
567 static ShaderGenDesc desc;
570 desc.vertexTemplateFile =
"Picking/vertex.glsl";
571 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs2.glsl";
575 desc.vertexTemplateFile =
"Picking/pick_vertices_vs.glsl";
576 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs.glsl";
580 if (pickShader && pickShader->
isLinked())
589 int pickOffsetIndex = int(_state.pick_current_index());
591 vertexDecl_.activateShaderPipeline(pickShader);
595 ACG::GLMatrixf transform = _state.projection() * _state.modelview();
598 pickShader->
setUniform(
"pickVertexOffset", pickOffsetIndex);
600 int numIndices = polyline_.n_vertices() + (polyline_.is_closed() ? 1 : 0);
601 glDrawArrays(GL_LINE_STRIP, 0, numIndices);
603 vertexDecl_.deactivateShaderPipeline(pickShader);
611 float line_width_old = _state.line_width();
613 _state.set_line_width(14);
615 unsigned int n_end = polyline_.n_edges() + 1;
616 if (!polyline_.is_closed()) --n_end;
618 for (
unsigned int i = 0; i < n_end; ++i) {
619 _state.pick_set_name(i + _offset);
621 glArrayElement(i % polyline_.n_vertices());
622 glArrayElement((i + 1) % polyline_.n_vertices());
626 _state.set_line_width(line_width_old);
629 glDepthRange(0.0, 1.0);
635template <
class PolyLine>
647 size_t curOffset = 12;
650 if (polyline_.vertex_normals_available())
657 if (polyline_.vertex_colors_available())
659 if (_colorSource == 1)
664 if (polyline_.edge_colors_available())
666 if (_colorSource == 2)
673 for (
size_t i = 0; i < customBuffers_.size(); ++i) {
688template <
class PolyLine>
695 for (
unsigned int i = 0; i < polyline_.get_num_custom_properties(); ++i) {
697 typename PolyLine::CustomPropertyHandle proph = polyline_.enumerate_custom_property_handles(i);
701 const void* propDataBuf = polyline_.get_custom_property_buffer(proph);
703 typename std::map< typename PolyLine::CustomPropertyHandle, int >::iterator mapEntry = polylinePropMap_.find(proph);
706 if (mapEntry == polylinePropMap_.end()) {
711 unsigned int propSize = 0;
712 if (polyline_.get_custom_property_shader_binding(proph, &propSize, &desc.
shaderInputName_, &desc.
type_)) {
717 polylinePropMap_[proph] = addCustomBuffer(desc, propDataBuf);
721 setCustomBuffer(mapEntry->second, propDataBuf);
726 setupVertexDeclaration(&vertexDecl_, 0);
727 setupVertexDeclaration(&vertexDeclVCol_, 1);
728 setupVertexDeclaration(&vertexDeclECol_, 2);
733 const unsigned int stride = vertexDecl_.getVertexStride();
735 char* data =
static_cast<char*
>(_buf);
736 size_t bytesWritten = 0;
738 for (
unsigned int i = 0 ; i < polyline_.n_vertices() && bytesWritten + stride <= _bufSize; ++i) {
739 writeVertex(i, data + i * stride);
740 bytesWritten += stride;
743 if (_addLineStripEndVertex && bytesWritten + stride <= _bufSize) {
745 writeVertex(0, data + polyline_.n_vertices() * stride);
746 bytesWritten += stride;
754template <
class PolyLine>
759 setupVertexDeclaration(&vertexDecl_, 0);
761 const unsigned int stride = vertexDecl_.getVertexStride();
764 size_t bufferSize = stride * (polyline_.n_vertices() + 1);
767 std::vector<char> vboData(bufferSize);
769 if (bufferSize > 0) {
770 size_t bytesWritten = fillVertexBuffer(&vboData[0], bufferSize,
true);
772 if (bytesWritten != bufferSize)
773 std::cerr <<
"PolyLineNode: fill vertex buffer only wrote " << bytesWritten <<
" bytes instead of expected " << bufferSize <<
" bytes" << std::endl;
776 vbo_.upload(bufferSize, &vboData[0], GL_STATIC_DRAW);
781 selectedVertexIndexBuffer_.clear();
784 selectedEdgeIndexBuffer_.clear();
786 for (
unsigned int i = 0 ; i < polyline_.n_vertices(); ++i) {
789 if ( polyline_.vertex_selections_available() && polyline_.vertex_selected(i) )
790 selectedVertexIndexBuffer_.push_back(i);
793 if ( polyline_.edge_selections_available() && polyline_.edge_selected(i) ) {
794 selectedEdgeIndexBuffer_.push_back(i);
795 selectedEdgeIndexBuffer_.push_back( (i + 1) % polyline_.n_vertices() );
806template <
class PolyLine>
809writeVertexColor(
unsigned int _vertex,
bool _colorSourceVertex,
void* _dst)
const
811 const VertexDeclaration* declToUse = _colorSourceVertex ? &vertexDeclVCol_ : &vertexDeclECol_;
814 unsigned char* ucdata = ((
unsigned char*)_dst) + byteOffset;
817 if (_colorSourceVertex)
818 col = polyline_.vertex_color(_vertex);
823 int edgeID = (_vertex + polyline_.n_edges() - 1) % polyline_.n_edges();
824 col = polyline_.edge_color(edgeID);
828 for (
int i = 0; i < 3; ++i)
831 int ival = int(col[i] * 255.0);
832 ival = std::min(std::max(ival, 0), 255);
840template <
class PolyLine>
846 float* fdata = (
float*)_dst;
849 for (
unsigned int j = 0 ; j < 3 ; ++j)
850 *(fdata++) = polyline_.point(_vertex)[j];
853 if ( polyline_.vertex_normals_available() )
854 for (
unsigned int j = 0 ; j < 3 ; ++j)
855 *(fdata++) = polyline_.vertex_normal(_vertex)[j];
857 if (polyline_.vertex_colors_available())
858 writeVertexColor(_vertex,
true, _dst);
860 if (polyline_.edge_colors_available())
861 writeVertexColor(_vertex,
false, _dst);
865 if (customElementOffset >= 0)
868 for (
unsigned int i = 0; i < customBuffers_.size(); ++i) {
875 if (!elementInputStride)
876 elementInputStride = elementSize;
879 const ACG::VertexElement* ve = vertexDeclVCol_.getElement(i +
static_cast<unsigned int>(customElementOffset));
881 const char* src = (
const char*)customBuffers_[i].second;
883 memcpy((
char*)_dst + ve->
getByteOffset(), src + elementInputStride * _vertex, elementSize);
890template <
class PolyLine>
896 if ( polyline_.n_vertices() == 0 )
903 _state.
enable(GL_COLOR_MATERIAL);
904 _state.
enable(GL_LIGHTING);
908 ro.setMaterial(_mat);
921 ro.debugName =
"PolyLine";
932 for (
unsigned int i = 0; i < _drawMode.
getNumLayers(); ++i) {
946 ro.setMaterial(&localMaterial);
949 switch (props->primitive()) {
951 case ACG::SceneGraph::DrawModes::PRIMITIVE_POINT:
954 ro.debugName =
"polyline.Points.selected";
956 ro.setMaterial(&localMaterial);
964 if (!selectedVertexIndexBuffer_.empty())
966 ro.glDrawElements(GL_POINTS, selectedVertexIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedVertexIndexBuffer_[0]));
968 applyRenderObjectSettings(props->primitive(), &ro);
974 ro.debugName =
"polyline.Points";
976 ro.setMaterial(&localMaterial);
977 ro.glDrawArrays(GL_POINTS, 0, polyline_.n_vertices());
979 if (props->
colored() && polyline_.vertex_colors_available())
990 applyRenderObjectSettings(props->primitive(), &ro);
996 case ACG::SceneGraph::DrawModes::PRIMITIVE_WIREFRAME:
997 case ACG::SceneGraph::DrawModes::PRIMITIVE_EDGE:
1000 ro.debugName =
"polyline.Wireframe.selected";
1001 localMaterial.
baseColor(selectionColor);
1002 ro.setMaterial(&localMaterial);
1010 if (!selectedEdgeIndexBuffer_.empty())
1012 ro.glDrawElements(GL_LINES, selectedEdgeIndexBuffer_.size(), GL_UNSIGNED_INT, &(selectedEdgeIndexBuffer_[0]));
1015 applyRenderObjectSettings(props->primitive(), &ro);
1020 ro.debugName =
"polyline.Wireframe";
1022 ro.setMaterial(&localMaterial);
1025 if ( polyline_.is_closed() )
1026 ro.glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices() + 1);
1028 ro.glDrawArrays(GL_LINE_STRIP, 0, polyline_.n_vertices());
1030 if (props->
colored() && polyline_.edge_colors_available())
1040 applyRenderObjectSettings(props->primitive(), &ro);
1047 case ACG::SceneGraph::DrawModes::PRIMITIVE_POLYGON:
1053 bool screenScale = _drawMode & POINTS_SPHERES_SCREEN;
1074 if (polyline_.vertex_selections_available())
1076 ro.debugName =
"polyline.Sphere.selected";
1077 localMaterial.
baseColor(selectionColor);
1078 ro.setMaterial(&localMaterial);
1080 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i)
1082 if (polyline_.vertex_selected(i))
1088 const Vec3d p = (
Vec3d)polyline_.point(i) - eyePos;
1089 radius = (p | viewDir) * r;
1092 sphere_->addToRenderer(_renderer, &ro, radius, (
Vec3f)polyline_.point(i));
1098 ro.debugName =
"polyline.Sphere";
1100 ro.setMaterial(&localMaterial);
1102 for (
unsigned int i = 0; i < polyline_.n_vertices(); ++i)
1104 if (!polyline_.vertex_selections_available() || !polyline_.vertex_selected(i))
1110 const Vec3d p = (
Vec3d)polyline_.point(i) - eyePos;
1111 radius = (p | viewDir) * r;
1114 sphere_->addToRenderer(_renderer, &ro, radius, (
Vec3f)polyline_.point(i));
1130template <
class PolyLine>
1136 customBuffers_.push_back( std::pair<ACG::VertexElement, const void*>(_desc, _buffer) );
1139 return int(customBuffers_.size()-1);
1143 std::cerr <<
"PolyLineNodeT::addCustomBuffer - null pointer buffer" << std::endl;
1150template <
class PolyLine>
1155 customBuffers_[_id].second = _buffer;
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Vec3d eye() const
get eye point
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
const GLMatrixd & modelview() const
get modelview matrix
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
int viewport_width() const
get viewport width
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Vec3d viewing_direction() const
get viewing ray
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
const GLMatrixd & projection() const
get projection matrix
void set_color(const Vec4f &_col)
set color
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
void set_line_width(float _f)
set line width
const Vec4f & ambient_color() const
get ambient color
void set_point_size(float _f)
set point size
double fovy() const
get field of view in y direction
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
int viewport_height() const
get viewport height
float line_width() const
get line width
const Vec4f & diffuse_color() const
get diffuse color
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
float point_size() const
get point size
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
DrawModeProperties stores a set of properties that defines, how to render an object.
bool colored() const
Are colors used?
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
size_t getNumLayers() const
returns the layer count
void baseColor(const Vec4f &_c)
set the base color (Sets the baseColor which is the same as the emission(const Vec4f& _c) )
void pointSize(float _sz)
set point size (default: 1.0)
void getRenderObjects(ACG::IRenderer *_renderer, ACG::GLState &_state, const ACG::SceneGraph::DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat) override
Add the objects to the given renderer.
DrawModes::DrawMode POINTS_SPHERES
This defines a local point spheres draw mode for all polyLine nodes.
void updateVBO()
Trigger an update of the vbo.
void writeVertexColor(unsigned int _vertex, bool _colorSourceVertex, void *_dst) const
Write color for rendering to a buffer.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
void setCustomBuffer(int _id, const void *_buffer)
void setupVertexDeclaration(VertexDeclaration *_dst, int _colorSource) const
Create the vertex declaration.
~PolyLineNodeT()
Destructor.
int addCustomBuffer(const ACG::VertexElement &_desc, const void *_buffer)
void draw(GLState &, const DrawModes::DrawMode &_drawMode) override
draw lines and normals
PolyLineNodeT(PolyLine &_pl, BaseNode *_parent=0, std::string _name="<PolyLineNode>")
Constructor.
size_t fillVertexBuffer(void *_buf, size_t _bufSize, bool _addLineStripEndVertex)
Fill a buffer with vertex data.
void writeVertex(unsigned int _vertex, void *_dst)
Write vertex data for rendering to a buffer.
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
DrawModes::DrawMode POINTS_SPHERES_SCREEN
This defines a local point spheres draw mode for all polyLine nodes with constant screen size.
void pick(GLState &_state, PickTarget _target) override
picking
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
Class to define the vertex input layout.
void addElement(const VertexElement *_pElement)
static size_t getGLTypeSize(unsigned int _type)
void setVertexStride(unsigned int _stride)
static size_t getElementSize(const VertexElement *_pElement)
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
bool isLinked()
Returns if the program object has been succesfully linked.
void disable()
Resets to standard rendering pipeline.
void use()
Enables the program object for using.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
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
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
DrawMode WIREFRAME
draw wireframe
DrawMode POINTS
draw unlighted points using the default base color
DrawMode EDGES_COLORED
draw edges with colors (without shading)
const DrawMode & addDrawMode(const std::string &_name, bool _propertyBased)
Add a custom DrawMode.
PickTarget
What target to use for picking.
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
@ 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, 4 > Vec4f
bool ACGDLLEXPORT openGLVersionTest(const int _major, const int _minor)
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_COLOR
"inColor"
@ VERTEX_USAGE_POSITION
"inPosition"
@ VERTEX_USAGE_SHADER_INPUT
defined by user via VertexElement::shaderInputName_
void compatibilityProfile(bool _enableCoreProfile)
Store opengl core profile setting.
VectorT< double, 3 > Vec3d
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
int priority
Priority to allow sorting of objects.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
Description of one vertex element.
void setByteOffset(unsigned int _offset)
unsigned int numElements_
how many elements of type_
const void * pointer_
Offset in bytes to the first occurrence of this element in vertex buffer; Or address to vertex data i...
VERTEX_USAGE usage_
position, normal, shader input ..
unsigned int getByteOffset() const
unsigned int type_
GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT, ...
const char * shaderInputName_
set shader input name, if usage_ = VERTEX_USAGE_USER_DEFINED otherwise this is set automatically,...