[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    playground/libs/kgllib/core/kgllib
From:       Rivo Laks <rivolaks () hot ! ee>
Date:       2008-08-14 19:22:47
Message-ID: 1218741767.542627.29266.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 847111 by rivol:

Add GeometryBuffer class, containing some of the functionality previously in Batch.
GeometryBuffer basically encapsulates a vertex array or VBO. The most important \
change is  that multiple Batch objects can now use a shared GeometryBuffer (and thus \
a shared VBO).  When multiple Batches (models) use a shared GeometryBuffer then that \
buffer needs to be  bound and unbound just once per frame instead of once per model, \
resulting in big performance  improvements.

 M  +2 -0      CMakeLists.txt  
 M  +69 -193   batch.cpp  
 M  +15 -34    batch.h  
 A             geometrybuffer.cpp   [License: LGPL (v2.1+)]
 A             geometrybuffer.h   [License: LGPL (v2.1+)]


--- trunk/playground/libs/kgllib/core/kgllib/CMakeLists.txt #847110:847111
@@ -21,6 +21,7 @@
         glwidget.cpp
         mesh.cpp
         textrenderer.cpp
+        geometrybuffer.cpp
         )
 qt4_automoc(${kgllib_SRCS})
 add_library(kgllib SHARED ${kgllib_SRCS})
@@ -44,6 +45,7 @@
         glwidget.h
         mesh.h
         textrenderer.h
+        geometrybuffer.h
         DESTINATION ${INCLUDE_INSTALL_DIR}/kgllib
         )
 install(TARGETS kgllib ${INSTALL_TARGETS_DEFAULT_ARGS})
--- trunk/playground/libs/kgllib/core/kgllib/batch.cpp #847110:847111
@@ -17,38 +17,32 @@
 
 #include "batch.h"
 
+#include "geometrybuffer.h"
+
 #include <QtDebug>
 
 using namespace Eigen;
 
-namespace
+
+namespace KGLLib
 {
-// Helper class to temporarily modify indices
-class BatchIndexChanger
+
+Batch::Batch()
 {
-public:
-    BatchIndexChanger(void** index, GLintptr newvalue)
-    {
-        pointer = index;
-        oldvalue = *index;
-        // Change current index, but only if it's not null
-        if (*index) {
-            *index = (char*)newvalue;
-        }
-    }
-    ~BatchIndexChanger()
-    {
-        *pointer = oldvalue;
-    }
-    void* oldvalue;
-    void** pointer;
-};
+    init();
 }
 
-namespace KGLLib
+Batch::Batch(GeometryBuffer* buffer, int offset, int indexoffset)
 {
+    init();
 
-Batch::Batch()
+    mBuffer = buffer;
+    mOwnBuffer = false;
+    mBufferOffset = offset;
+    mBufferIndexOffset = indexoffset;
+}
+
+void Batch::init()
 {
     mDirty = true;
     mVertices = mColors = mNormals = mTexcoords = 0;
@@ -56,19 +50,18 @@
 
     mIndices = 0;
     mIndexCount = 0;
-    mType = Auto;
-    mVBOId = mIndexVBOId = 0;
     mPrimitiveType = GL_TRIANGLES;
+    mBuffer = 0;
+    mBufferOffset = 0;
+    mBufferIndexOffset = 0;
+    mOwnBuffer = true;
 }
 
 Batch::~Batch()
 {
-    if (mVBOId) {
-        glDeleteBuffers(1, &mVBOId);
+    if (mOwnBuffer) {
+        delete mBuffer;
     }
-    if (mIndexVBOId) {
-        glDeleteBuffers(1, &mIndexVBOId);
-    }
 }
 
 void Batch::setVertexCount(int count)
@@ -112,20 +105,6 @@
     mDirty = true;
 }
 
-Batch::BatchType Batch::batchType() const
-{
-    if (mType == Auto) {
-        return VBO;
-    } else {
-        return mType;
-    }
-}
-
-void Batch::setBatchType(Batch::BatchType type)
-{
-    mType = type;
-}
-
 GLenum Batch::primitiveType() const
 {
     return mPrimitiveType;
@@ -134,186 +113,83 @@
 void Batch::setPrimitiveType(GLenum type)
 {
     mPrimitiveType = type;
+    if (mBuffer) {
+        mBuffer->setPrimitiveType(type);
+    }
 }
 
 void Batch::render()
 {
+    bind();
+    renderOnce();
+    unbind();
+}
+
+void Batch::bind()
+{
     if (mDirty) {
         update();
     }
 
-    BatchType t = batchType();
+    mBuffer->bind();
+}
 
-    if (t == Plain) {
-        renderPlain();
-    } else if (t == Array) {
-        renderArray();
-    } else if (t == VBO) {
-        renderVBO();
+void Batch::renderOnce()
+{
+    if (mBuffer->format().isIndexed()) {
+        mBuffer->renderIndexed(mIndexCount, mBufferIndexOffset);
     } else {
-        qCritical() << "Batch::render(): Unknown batch type" << t;
+        mBuffer->render(mVertexCount, mBufferOffset);
     }
 }
 
-void Batch::renderPlain()
+void Batch::unbind()
 {
-    glBegin(mPrimitiveType);
-    for (int i = 0; i < mVertexCount; i++) {
-        if (mNormals) {
-            glNormal3fv((float*)mNormals + 3*i);
-        }
-        if (mTexcoords) {
-            if (mTexcoordSize == 1) {
-                glTexCoord1fv((float*)mTexcoords + 1*i);
-            } else if (mTexcoordSize == 2) {
-                glTexCoord2fv((float*)mTexcoords + 2*i);
-            } else if (mTexcoordSize == 3) {
-                glTexCoord3fv((float*)mTexcoords + 3*i);
-            } else if (mTexcoordSize == 4) {
-                glTexCoord4fv((float*)mTexcoords + 4*i);
-            }
-        }
-        if (mColors) {
-            if (mColorSize == 3) {
-                glColor3fv((float*)mColors + 3*i);
-            } else if (mColorSize == 4) {
-                glColor4fv((float*)mColors + 4*i);
-            }
-        }
-        if (mVertexSize == 2) {
-            glVertex2fv((float*)mVertices + 2*i);
-        } else if (mVertexSize == 3) {
-            glVertex3fv((float*)mVertices + 3*i);
-        } else if (mVertexSize == 4) {
-            glVertex4fv((float*)mVertices + 4*i);
-        }
-    }
-    glEnd();
+    mBuffer->unbind();
 }
 
-void Batch::renderArray()
+void Batch::update()
 {
-    // Enable client states
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glVertexPointer(mVertexSize, GL_FLOAT, 0, mVertices);
-    if (mColors) {
-        glEnableClientState(GL_COLOR_ARRAY);
-        glColorPointer(mColorSize, GL_FLOAT, 0, mColors);
+    if (!mDirty) {
+        return;
     }
+
+    mDirty = false;
+
+    //qDebug() << "Batch::update(): create GeometryBufferFormat";
+    GeometryBufferFormat bufferformat(mVertexCount, mIndices ? mIndexCount : 0);
+    bufferformat.addVertices(mVertexSize);
+    bufferformat.addColors(mColorSize);
     if (mNormals) {
-        glEnableClientState(GL_NORMAL_ARRAY);
-        glNormalPointer(GL_FLOAT, 0, mNormals);
+        bufferformat.addNormals();
     }
-    if (mTexcoords) {
-        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        glTexCoordPointer(mTexcoordSize, GL_FLOAT, 0, mTexcoords);
-    }
+    bufferformat.addTexCoords(mTexcoordSize);
 
-    // Render
-    if (mIndexCount) {
-        glDrawElements(mPrimitiveType, mIndexCount, GL_UNSIGNED_INT, mIndices);
-    } else {
-        glDrawArrays(mPrimitiveType, 0, mVertexCount);
+    if (mOwnBuffer) {
+        //qDebug() << "Batch::update(): deleting old buffer";
+        delete mBuffer;
+        //qDebug() << "Batch::update(): create GeometryBuffer";
+        mBuffer = GeometryBuffer::createBuffer(bufferformat);
+        mBuffer->setPrimitiveType(mPrimitiveType);
     }
-
-    // Disable client states
-    glDisableClientState(GL_VERTEX_ARRAY);
+    //qDebug() << "Batch::update(): add data";
+    mBuffer->bind();
+    mBuffer->addVertices(mVertices, mVertexCount, mBufferOffset);
     if (mColors) {
-        glDisableClientState(GL_COLOR_ARRAY);
+        mBuffer->addColors(mColors, mVertexCount, mBufferOffset);
     }
     if (mNormals) {
-        glDisableClientState(GL_NORMAL_ARRAY);
+        mBuffer->addNormals(mNormals, mVertexCount, mBufferOffset);
     }
     if (mTexcoords) {
-        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        mBuffer->addTexCoords(mTexcoords, mVertexCount, mBufferOffset);
     }
-}
-
-void Batch::renderVBO()
-{
-    glBindBuffer(GL_ARRAY_BUFFER, mVBOId);
-    if (mIndexVBOId) {
-        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexVBOId);
+    if (mIndices) {
+        mBuffer->addIndices(reinterpret_cast<unsigned int*>(mIndices), mIndexCount, \
mBufferIndexOffset);  }
-
-    // Change vertices and normals pointers to be offsets
-#define CHANGE_POINTER(array)  BatchIndexChanger array##IndexChanger(&array, \
                array##VBOOffset);
-    CHANGE_POINTER(mVertices);
-    CHANGE_POINTER(mColors);
-    CHANGE_POINTER(mNormals);
-    CHANGE_POINTER(mTexcoords);
-#undef CHANGE_POINTER
-    void* origi = mIndices;
-    mIndices = 0;
-
-    // Render
-    renderArray();
-
-    mIndices = origi;
-
-    // Disable VBO
-    glBindBuffer(GL_ARRAY_BUFFER, 0);
-    if (mIndexVBOId) {
-        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
-    }
+    mBuffer->unbind();
+    //qDebug() << "Batch::update(): all done";
 }
 
-void Batch::update()
-{
-    if (!mDirty) {
-        return;
-    }
-
-    mDirty = false;
-
-    if (batchType() == VBO) {
-        // Create VBOs if they do not exist already
-        if (!mVBOId) {
-            glGenBuffers(1, &mVBOId);
-        }
-        if (mIndices && !mIndexVBOId) {
-            glGenBuffers(1, &mIndexVBOId);
-        }
-        // Calculate offsets for different data arrays
-        int totalsize = 0;
-#define CALC_VBO_OFFSET(array, elementsize)  { \
-            int arraysize = mVertexCount * elementsize * sizeof(float); \
-            array##VBOOffset = totalsize; \
-            totalsize += arraysize; \
-        }
-        CALC_VBO_OFFSET(mVertices, mVertexSize);
-        CALC_VBO_OFFSET(mColors, mColorSize);
-        CALC_VBO_OFFSET(mNormals, mNormalSize);
-        CALC_VBO_OFFSET(mTexcoords, mTexcoordSize);
-        qDebug() << "Total VBO size is" << totalsize;
-#undef CALC_VBO_OFFSET
-
-        // Bind and init array buffer
-        glBindBuffer(GL_ARRAY_BUFFER, mVBOId);
-        glBufferData(GL_ARRAY_BUFFER, totalsize, 0, GL_STATIC_DRAW);
-        // Add data
-#define ADD_VBO_DATA(array, elementsize)  { \
-            if (array) { \
-                int arraysize = mVertexCount * elementsize * sizeof(float); \
-                qDebug() << "VBO buffer for array" << #array << "is at offset" << \
                array##VBOOffset << "with size" << arraysize;\
-                glBufferSubData(GL_ARRAY_BUFFER, array##VBOOffset, arraysize, \
                array); \
-            } \
-        }
-        ADD_VBO_DATA(mVertices, mVertexSize);
-        ADD_VBO_DATA(mColors, mColorSize);
-        ADD_VBO_DATA(mNormals, mNormalSize);
-        ADD_VBO_DATA(mTexcoords, mTexcoordSize);
-#undef ADD_VBO_DATA
-        glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-        if (mIndices) {
-            // Same with indices
-            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexVBOId);
-            glBufferData(GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexCount*sizeof(unsigned \
                int), mIndices, GL_STATIC_DRAW);
-            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
-        }
-    }
 }
 
-}
-
--- trunk/playground/libs/kgllib/core/kgllib/batch.h #847110:847111
@@ -25,6 +25,7 @@
 
 namespace KGLLib
 {
+class GeometryBuffer;
 
 /**
  * @brief A set of geometry.
@@ -57,21 +58,12 @@
 {
 public:
     /**
-     * Specifies which method is used to render the geometry.
-     **/
-    enum BatchType {
-        Auto,  /**< Mode is chosen automatically, depending on the rendered \
                geomentry */
-        Plain,  /**< Immediate mode (i.e. glVertex(), glNormal() etc calls) */
-        Array,  /**< Vertex arrays */
-        VBO  /**< VBOs (vertex buffer objects) */
-    };
-
-    /**
      * Constructs new Batch object.
      * You will need to set at least vertices array and vertex count before the
      *  batch can be rendered.
      **/
     Batch();
+    Batch(GeometryBuffer* buffer, int offset, int indexOffset);
     virtual ~Batch();
 
     /**
@@ -79,6 +71,10 @@
      **/
     virtual void render();
 
+    virtual void bind();
+    virtual void renderOnce();
+    virtual void unbind();
+
     /**
      * Set the number of vertices in the batch to @p count.
      * Each specified array must contain at least @p count entries (if they
@@ -123,16 +119,6 @@
     int indicesCount() const  { return mIndexCount; }
 
     /**
-     * @return current rendering method of this Batch.
-     **/
-    BatchType batchType() const;
-    /**
-     * Sets the rendering method to @p type.
-     * The default method is @ref Auto.
-     **/
-    void setBatchType(BatchType type);
-
-    /**
      * Sets the primitive type used to render this batch (e.g. GL_QUADS).
      *
      * Default value is GL_TRIANGLES.
@@ -152,15 +138,15 @@
      **/
     virtual void update();
 
-protected:
-    void renderPlain();
-    void renderArray();
-    void renderVBO();
+    GeometryBuffer* buffer() const  { return mBuffer; }
 
+protected:
     void setVertices(void* vertices, int size);
     void setColors(void* colors, int size);
     void setTexcoords(void* texcoords, int size);
 
+    void init();
+
 private:
     // Pointers to corresponding arrays
     void* mVertices;
@@ -174,22 +160,17 @@
     int mTexcoordSize;
     // Indices array
     void* mIndices;
-    // GL_UNSIGNED_INT, GL_UNSIGNED_SHORT or GL_UNSIGNED_CHAR
-    GLenum mIndicesType;
 
-    // VBO offsets
-    GLintptr mVerticesVBOOffset;
-    GLintptr mColorsVBOOffset;
-    GLintptr mNormalsVBOOffset;
-    GLintptr mTexcoordsVBOOffset;
-
     int mVertexCount;
     int mIndexCount;
-    GLuint mVBOId, mIndexVBOId;
 
     bool mDirty;
-    BatchType mType;
     GLenum mPrimitiveType;
+
+    GeometryBuffer* mBuffer;
+    int mBufferOffset;
+    int mBufferIndexOffset;
+    bool mOwnBuffer;
 };
 
 }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic