[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