/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : include/ICLGeom/Primitive.h ** ** Module : ICLGeom ** ** Authors: Christof Elbrechter ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #ifndef ICL_PRIMITIVE_H #define ICL_PRIMITIVE_H #ifndef HAVE_OPENGL #warning "this header must not be included if HAVE_OPENGL is not defined" #else #include #include #include #include #include namespace icl{ /** \cond */ class SceneObject; /** \endcond */ /// Abastract base type for geoemtric primitives /** Primitives are atomar geometric entities, that are used to build SceneObjects. Primitives must only* define, how they are rendered in OpenGL. For rendering, the primitives can access the parent objects data such as vertices and normals. By these means, several primitives can share resources such as vertices, normals or even textures. Usually primitives will just define vertex indices that are then used to pick the correct vertices from the parent SceneObject's vertex list.\n *) only is not completely correct, they also have to implement a deep copy interface \see Primitive::copy */ struct Primitive{ /// primitive type for dynamic handling of different primitives enum Type{ vertex = 1<<0, // start and end position of the line) triangle = 1<<2, // &vertices; //!< list of shared vertices const std::vector &normals; //!< list of shared normals const std::vector &vertexColors; //!< list of vertex colors const std::vector > &sharedTextures; //!< list of shared textures bool lineColorsFromVertices; //!< line coloring bool triangleColorsFromVertices; //!< triangle coloring bool quadColorsFromVertices; //!< quad coloring bool polygonColorsFromVertices; //!< polygon coloring SceneObject *object; //!< the parent object }; /// Default constructor Primitive(Type type=nothing, const GeomColor &color=GeomColor(255,255,255,255)):type(type),color(color){} /// virtual, but empty destructor virtual ~Primitive() {} /// virtual render method, which is called by the parent scene object virtual void render(const Primitive::RenderContext &ctx) = 0; /// must be implemented in order to obtain a deep and independent copy virtual Primitive *copy() const = 0; }; /// line primitive (the line references 2 vertices) struct LinePrimitive : public FixedColVector, public Primitive{ /// super type typedef FixedColVector super; /// constructor LinePrimitive(int a, int b, const GeomColor &color): FixedColVector(a,b),Primitive(Primitive::line,color){} /// render virtual void render(const Primitive::RenderContext &ctx); /// direct access to the i-th vertex/normal index inline int i(int idx) const { return super::operator[](idx); } /// deep copy implementation (trivial) virtual Primitive *copy() const { return new LinePrimitive(*this); } }; /// triangle primitive struct TrianglePrimitive : public FixedColVector, public Primitive{ /// super type typedef FixedColVector super; /// constructor TrianglePrimitive(int a, int b, int c, const GeomColor &color, int na=-1, int nb=-1, int nc=-1): super(a,b,c,na,nb,nc),Primitive(Primitive::triangle,color){} /// render method virtual void render(const Primitive::RenderContext &ctx); /// direct access to the i-th vertex/normal index inline int i(int idx) const { return super::operator[](idx); } /// deep copy implementation (trivial) virtual Primitive *copy() const { return new TrianglePrimitive(*this); } }; /// quad primitive struct QuadPrimitive : public FixedColVector, public Primitive{ /// super type typedef FixedColVector super; /// constructor QuadPrimitive(int a, int b, int c, int d, const GeomColor &color, int na=-1, int nb=-1, int nc=-1, int nd=-1): super(a,b,c,d,na,nb,nc,nd),Primitive(Primitive::quad,color){} /// render method virtual void render(const Primitive::RenderContext &ctx); /// direct access to the i-th vertex/normal index inline int i(int idx) const { return super::operator[](idx); } /// deep copy implementation (trivial) virtual Primitive *copy() const { return new QuadPrimitive(*this); } }; /// polygon primitive /** The Array2D's first row contains the */ struct PolygonPrimitive : public Primitive{ /// vertex and texture primitives /** Layout: - first row: column i -> vertex index i - 2nd row: (optional) column i -> normal index i */ Array2D idx; /// constructor PolygonPrimitive(int n,const int *vidx, const GeomColor &color,const int *nidx=0): Primitive(Primitive::polygon,color),idx(n,nidx?2:1){ std::copy(vidx,vidx+n,idx.begin()); if(nidx) std::copy(nidx,nidx+n,idx.begin()+n); } /// render method virtual void render(const Primitive::RenderContext &ctx); /// deep copy method virtual Primitive *copy() const { PolygonPrimitive *p = new PolygonPrimitive(*this); p->idx.detach(); return p; } /// direct access to number of vertices inline int getNumPoints() const { return idx.getWidth(); } /// direct access to i-th vertex index inline int getVertexIndex(int i) const { return idx(i,0); } /// direct access to i-th normal index /** This will crash, if there are no normals */ inline int getNormalIndex(int i) const { return idx(i,1); } /// utility method to ask whether normal indices are available inline bool hasNormals() const { return idx.getHeight() == 2; } }; /// Texture Primitive /** Texture Primitives hare two modes: -# createTextureOnce=true: In this case, the texture data that is given to the constructor is only copied once. This will result in a static texture, that is only transferred to the graphics card-memory once. This is very efficient, but the texture cannot be updated lateron automatically -# createTextureOnce=false: in this case, the texture data will always be updated before the texture is drawn. In this way, one can easily create video textures. */ struct TexturePrimitive : public QuadPrimitive{ GLImg texture; //!<< internal texture const ImgBase *image; //!<< set if the texture shall be updated every time it is drawn /// create with given texture that is either copied once or everytime the primitive is rendered TexturePrimitive(int a, int b, int c, int d, const ImgBase *image=0, bool createTextureOnce=true, int na=-1, int nb=-1, int nc=-1, int nd=-1, scalemode sm=interpolateLIN): QuadPrimitive(a,b,c,d,na,nb,nc,nd), texture(image,sm), image(createTextureOnce ? 0 : image){ type = Primitive::texture; } /// create with given texture, that is copied once TexturePrimitive(int a, int b, int c, int d, const Img8u &image, int na=-1, int nb=-1, int nc=-1, int nd=-1, scalemode sm=interpolateLIN): QuadPrimitive(a,b,c,d,na,nb,nc,nd), texture(&image,sm), image(0){ type = Primitive::texture; } /// render method virtual void render(const Primitive::RenderContext &ctx); /// deep copy virtual Primitive *copy() const { return new TexturePrimitive(i(0),i(1),i(2),i(3), image ? image : texture.extractImage(), image ? true : false, i(4),i(5),i(6),i(7), texture.getScaleMode()); } }; /// The shared texture primitive references a texture from the parent SceneObject /** Therefore, shared textures can be reused in order to avoid that identical textures have to be hold several times in the graphics hardware memory */ struct SharedTexturePrimitive : public QuadPrimitive{ int sharedTextureIndex; /// create with given texture that is either copied once or everytime the primitive is rendered SharedTexturePrimitive(int a, int b, int c, int d, int sharedTextureIndex, int na=-1, int nb=-1, int nc=-1, int nd=-1): QuadPrimitive(a,b,c,d,na,nb,nc,nd), sharedTextureIndex(sharedTextureIndex){ type = Primitive::texture; } /// render method virtual void render(const Primitive::RenderContext &ctx); /// deep copy virtual Primitive *copy() const { return new SharedTexturePrimitive(*this); } }; /// Text Texture /** The text texture is implemented by a static common texture */ struct TextPrimitive : public TexturePrimitive{ /// internal memory for the text size int textSize; /// internal memory for the text color GeomColor textColor; /// utility method to creat a text texture static Img8u create_texture(const std::string &text, const GeomColor &color, int textSize); /// used for billboard text /** if the value is > 0, the text-texture will always be oriented towards the camera. the billboardHeight value is used as text-height (in scene units) */ int billboardHeight; /// constructor TextPrimitive(int a, int b, int c, int d, const std::string &text, int textSize=20, const GeomColor &textColor=GeomColor(255,255,255,255), int na=-1, int nb=-1, int nc=-1, int nd=-1, int billboardHeight=0, scalemode sm=interpolateLIN): TexturePrimitive(a,b,c,d,create_texture(text,textColor,textSize),na,nb,nc,nd, sm), textSize(textSize), textColor(textColor), billboardHeight(billboardHeight){ type = Primitive::text; } /// render method virtual void render(const Primitive::RenderContext &ctx); /// deep copy method virtual Primitive *copy() const { Primitive *p = TexturePrimitive::copy(); p->type = text; return p; } /// sets new text inline void updateText(const std::string &newText){ Img8u t = create_texture(newText,textColor,textSize); texture.update(&t); } }; } #endif #endif