KGLLib
core/kgllib/geometrybuffer.h
00001 /*
00002  * Copyright (C) 2008 Rivo Laks <rivolaks@hot.ee>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef KGLLIB_GEOMETRYBUFFER_H
00019 #define KGLLIB_GEOMETRYBUFFER_H
00020 
00021 #include "kgllib.h"
00022 
00023 #include <Eigen/Core>
00024 
00025 
00026 namespace KGLLib
00027 {
00028 
00037 class KGLLIB_EXPORT GeometryBufferFormat
00038 {
00039 public:
00040     enum Format
00041     {
00042         Vertex3   = 1 << 0,
00043         Vertex4   = 1 << 1,
00044         Color3    = 1 << 2,
00045         Color4    = 1 << 3,
00046         Normal3   = 1 << 4,
00047         Normal    = Normal3,
00048         TexCoord2 = 1 << 5
00049     };
00050 
00057     GeometryBufferFormat();
00058     GeometryBufferFormat(int vertexCount, int indexCount = 0);
00059     GeometryBufferFormat(Format fmt, int vertexCount, int indexCount = 0);
00060 
00066     void addVertices(int size)  { mVertexSize = size; }
00070     void addNormals()  { mNormalSize = 3; }
00074     void addColors(int size)  { mColorSize = size; }
00078     void addTexCoords(int size)  { mTexCoordSize = size; }
00079 
00083     int vertexSize() const  { return mVertexSize; }
00087     int colorSize() const  { return mColorSize; }
00091     int normalSize() const  { return mNormalSize; }
00095     int texCoordSize() const  { return mTexCoordSize; }
00096 
00102     int vertexCount() const  { return mVertexCount; }
00103     void setVertexCount(int count);
00113     int indexCount() const  { return mIndexCount; }
00114     void setIndexCount(int count);
00115 
00121     bool isIndexed() const  { return mIndexCount > 0; }
00122 
00123 protected:
00124     void init(int vertexCount, int indexCount);
00125 
00126 private:
00127     int mVertexCount;
00128     int mIndexCount;
00129 
00130     int mVertexSize;
00131     int mColorSize;
00132     int mNormalSize;
00133     int mTexCoordSize;  // TODO: support multiple texcoords
00134     // TODO: support vertex attributes
00135 };
00136 
00137 
00153 class KGLLIB_EXPORT GeometryBuffer
00154 {
00155 public:
00162     static GeometryBuffer* createBuffer(const GeometryBufferFormat& format);
00169     static GeometryBuffer* createBuffer(GeometryBufferFormat::Format format, int vertexCount, int indexCount = 0);
00170 
00171 
00175     virtual ~GeometryBuffer();
00176 
00184     virtual void render();
00195     virtual void renderIndexed(int indices, int offset) = 0;
00206     virtual void render(int vertices, int offset) = 0;
00207 
00214     virtual bool bind()  { return true; }
00220     virtual bool unbind()  { return true; }
00221 
00236     void addVertices(void* vertices, int count, int offset = 0);
00237     void addColors(void* colors, int count, int offset = 0);
00238     void addNormals(void* normals, int count, int offset = 0);
00239     void addTexCoords(void* texcoords, int count, int offset = 0);
00245     virtual void addIndices(unsigned int* indices, int count, int offset = 0) = 0;
00246 
00252     virtual void setPrimitiveType(GLenum type);
00256     GLenum primitiveType() const  { return mPrimitiveType; }
00257 
00261     const GeometryBufferFormat& format() const  { return mFormat; }
00262 
00263 protected:
00264     GeometryBuffer(const GeometryBufferFormat& format);
00265 
00266     virtual void init(const GeometryBufferFormat& format);
00267 
00271     int bufferSize() const;
00275     int indexBufferSize() const;
00276 
00283     virtual void addData(void* data, int size, int offset) = 0;
00284 
00285 protected:
00286     struct AttributeData
00287     {
00288         AttributeData(int _size, int _offset, int _stride)
00289         {
00290             size = _size;
00291             offset = _offset;
00292             stride = _stride;
00293         }
00294         AttributeData()
00295         {
00296             size = offset = stride = 0;
00297         }
00298 
00299         // Size of a single element, in bytes
00300         int size;
00301         // Offset of the first element in the buffer
00302         int offset;
00303         // Number of bytes between two consecutive elements
00304         int stride;
00305     };
00306 
00307     GLenum mPrimitiveType;
00308     GeometryBufferFormat mFormat;
00309 
00310     AttributeData mVertexData;
00311     AttributeData mColorData;
00312     AttributeData mNormalData;
00313     AttributeData mTexCoordData;
00314 };
00315 
00321 class GeometryBufferVertexArray : public GeometryBuffer
00322 {
00323 public:
00324     GeometryBufferVertexArray(const GeometryBufferFormat& format);
00325     virtual ~GeometryBufferVertexArray();
00326 
00327     virtual bool bind();
00328     virtual bool unbind();
00329 
00330     virtual void renderIndexed(int indices, int offset);
00331     virtual void render(int vertices, int offset);
00332 
00333     virtual void addIndices(unsigned int* indices, int count, int offset = 0);
00334 
00335 protected:
00336     // FIXME: ugly
00337     GeometryBufferVertexArray(const GeometryBufferFormat& format, bool createArrays);
00338 
00339     virtual void createArrays();
00340     virtual void addData(void* data, int size, int offset);
00341 
00342 private:
00343     char* mBuffer;
00344     char* mIndexBuffer;
00345 };
00346 
00353 class GeometryBufferVBO : public GeometryBufferVertexArray
00354 {
00355 public:
00356     GeometryBufferVBO(const GeometryBufferFormat& format);
00357     virtual ~GeometryBufferVBO();
00358 
00359     virtual bool bind();
00360     virtual bool unbind();
00361 
00362     virtual void addIndices(unsigned int* indices, int count, int offset = 0);
00363 
00364 protected:
00365     virtual void createArrays();
00366     virtual void addData(void* data, int size, int offset);
00367 
00368 private:
00369     GLuint mVBOId, mIndexVBOId;
00370 };
00371 
00372 }
00373 
00374 #endif