KGLLib
batch.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "batch.h"
00019
00020 #include "geometrybuffer.h"
00021
00022 #include <QtDebug>
00023
00024 using namespace Eigen;
00025
00026
00027 namespace KGLLib
00028 {
00029
00030 Batch::Batch()
00031 {
00032 init();
00033 }
00034
00035 Batch::Batch(GeometryBuffer* buffer, int offset, int indexoffset)
00036 {
00037 init();
00038 setBuffer(buffer, offset, indexoffset);
00039 }
00040
00041 void Batch::init()
00042 {
00043 mDirty = true;
00044 mVertices = mColors = mNormals = mTexcoords = 0;
00045 mVertexSize = mColorSize = mNormalSize = mTexcoordSize = 0;
00046
00047 mIndices = 0;
00048 mIndexCount = 0;
00049 mPrimitiveType = GL_TRIANGLES;
00050 mBuffer = 0;
00051 mBufferOffset = 0;
00052 mBufferIndexOffset = 0;
00053 mOwnBuffer = true;
00054 }
00055
00056 Batch::~Batch()
00057 {
00058 if (mOwnBuffer) {
00059 delete mBuffer;
00060 }
00061 }
00062
00063 void Batch::setVertexCount(int count)
00064 {
00065 mVertexCount = count;
00066 mDirty = true;
00067 }
00068
00069 void Batch::setVertices(void* vertices, int size)
00070 {
00071 mVertices = vertices;
00072 mVertexSize = vertices ? size : 0;
00073 mDirty = true;
00074 }
00075
00076 void Batch::setColors(void* colors, int size)
00077 {
00078 mColors = colors;
00079 mColorSize = colors ? size : 0;
00080 mDirty = true;
00081 }
00082
00083 void Batch::setNormals(Eigen::Vector3f* normals)
00084 {
00085 mNormals = normals;
00086 mNormalSize = normals ? 3 : 0;
00087 mDirty = true;
00088 }
00089
00090 void Batch::setTexcoords(void* texcoords, int size)
00091 {
00092 mTexcoords = texcoords;
00093 mTexcoordSize = texcoords ? size : 0;
00094 mDirty = true;
00095 }
00096
00097 void Batch::setIndices(unsigned int* indices, int indexCount)
00098 {
00099 mIndices = indices;
00100 mIndexCount = indexCount;
00101 mDirty = true;
00102 }
00103
00104 GLenum Batch::primitiveType() const
00105 {
00106 return mPrimitiveType;
00107 }
00108
00109 void Batch::setPrimitiveType(GLenum type)
00110 {
00111 mPrimitiveType = type;
00112 if (mBuffer) {
00113 mBuffer->setPrimitiveType(type);
00114 }
00115 }
00116
00117 void Batch::render()
00118 {
00119 bind();
00120 renderOnce();
00121 unbind();
00122 }
00123
00124 void Batch::bind()
00125 {
00126 if (mDirty) {
00127 update();
00128 }
00129
00130 mBuffer->bind();
00131 }
00132
00133 void Batch::renderOnce()
00134 {
00135 if (mBuffer->format().isIndexed()) {
00136 mBuffer->renderIndexed(mIndexCount, mBufferIndexOffset);
00137 } else {
00138 mBuffer->render(mVertexCount, mBufferOffset);
00139 }
00140 }
00141
00142 void Batch::unbind()
00143 {
00144 mBuffer->unbind();
00145 }
00146
00147 void Batch::setBuffer(GeometryBuffer* buffer, int offset, int indexOffset)
00148 {
00149 if (mOwnBuffer) {
00150 delete mBuffer;
00151 }
00152
00153 mBuffer = buffer;
00154 mOwnBuffer = (!buffer) ? true : false;
00155 mBufferOffset = offset;
00156 mBufferIndexOffset = indexOffset;
00157
00158 mDirty = true;
00159 }
00160
00161 GeometryBufferFormat Batch::bestBufferFormat() const
00162 {
00163 GeometryBufferFormat bufferformat(mVertexCount, mIndices ? mIndexCount : 0);
00164 bufferformat.addVertices(mVertexSize);
00165 bufferformat.addColors(mColorSize);
00166 if (mNormals) {
00167 bufferformat.addNormals();
00168 }
00169 bufferformat.addTexCoords(mTexcoordSize);
00170
00171 return bufferformat;
00172 }
00173
00174 GeometryBuffer* Batch::createSharedBuffer(const QList<Batch*>& batches)
00175 {
00176 if (batches.isEmpty()) {
00177 return 0;
00178 }
00179
00180 int vertexcount = 0;
00181 int indexcount = 0;
00182 foreach (Batch* b, batches) {
00183 vertexcount += b->vertexCount();
00184 indexcount += b->indicesCount();
00185 }
00186
00187 GeometryBufferFormat format = batches.first()->bestBufferFormat();
00188 format.setVertexCount(vertexcount);
00189 format.setIndexCount(indexcount);
00190
00191 GeometryBuffer* buffer = GeometryBuffer::createBuffer(format);
00192
00193 int vertexoffset = 0;
00194 int indexoffset = 0;
00195 foreach (Batch* b, batches) {
00196 b->setBuffer(buffer, vertexoffset, indexoffset),
00197 vertexoffset += b->vertexCount();
00198 indexoffset += b->indicesCount();
00199 }
00200
00201 return buffer;
00202 }
00203
00204 void Batch::update()
00205 {
00206 if (!mDirty) {
00207 return;
00208 }
00209
00210 mDirty = false;
00211
00212 if (mOwnBuffer) {
00213
00214 delete mBuffer;
00215
00216
00217
00218
00219 mBuffer = GeometryBuffer::createBuffer(bestBufferFormat());
00220 mBuffer->setPrimitiveType(mPrimitiveType);
00221 }
00222
00223 mBuffer->bind();
00224 mBuffer->addVertices(mVertices, mVertexCount, mBufferOffset);
00225 if (mColors) {
00226 mBuffer->addColors(mColors, mVertexCount, mBufferOffset);
00227 }
00228 if (mNormals) {
00229 mBuffer->addNormals(mNormals, mVertexCount, mBufferOffset);
00230 }
00231 if (mTexcoords) {
00232 mBuffer->addTexCoords(mTexcoords, mVertexCount, mBufferOffset);
00233 }
00234 if (mIndices) {
00235 if (mBufferOffset) {
00236
00237
00238 unsigned int* offsetIndices = new unsigned int[mIndexCount];
00239 for (int i = 0; i < mIndexCount; i++) {
00240 offsetIndices[i] = reinterpret_cast<unsigned int*>(mIndices)[i] + mBufferOffset;
00241 }
00242 mBuffer->addIndices(offsetIndices, mIndexCount, mBufferIndexOffset);
00243 delete[] offsetIndices;
00244 } else {
00245 mBuffer->addIndices(reinterpret_cast<unsigned int*>(mIndices), mIndexCount, mBufferIndexOffset);
00246 }
00247 }
00248 mBuffer->unbind();
00249
00250 }
00251
00252 }
00253