GhoulPrimitivesOgre.cpp
Go to the documentation of this file.00001 #include "lugre_prefix.h"
00002 #include <Ogre.h>
00003 #include "GhoulPrimitives.h"
00004
00005 using namespace GhoulPrimitive;
00006 using namespace Ogre;
00007 using namespace Lugre;
00008
00009
00010 #define MY_VERTEX_BINDING_SOURCE 0
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027 OgreRenderableDrawer::OgreRenderableDrawer () { PROFILE
00028 setMaterial("BaseWhiteNoLighting");
00029 mReady = false;
00030 mRenderOp.vertexData = new VertexData;
00031 mIndexBufferInitialized = false;
00032 mVertexDecInitialized = false;
00033 mVertexBufferCapacity = 0;
00034 mIndexBufferCapacity = 0;
00035 }
00036
00037 OgreRenderableDrawer::~OgreRenderableDrawer() { PROFILE
00038 delete mRenderOp.vertexData;
00039 if (mIndexBufferInitialized)
00040 delete mRenderOp.indexData;
00041 }
00042
00043
00044 void OgreRenderableDrawer::Prepare (eOpType opType,eGeometryChange gcHint,size_t vertexCount,size_t indexCount,bool hasNormals,bool hasTexCoords) { PROFILE
00045 assert(!mReady && "Prepare called twice");
00046
00047
00048 if (!mVertexDecInitialized || hasNormals != mHasNormals || mHasTexCoords != hasTexCoords) {
00049 mHasNormals = hasNormals;
00050 mHasTexCoords = hasTexCoords;
00051 VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
00052 if (mVertexDecInitialized) {
00053 while (decl->getVertexSize(MY_VERTEX_BINDING_SOURCE) > 0) {
00054
00055 decl->removeElement(0);
00056 }
00057 }
00058
00059
00060 size_t offset = 0;
00061 offset += decl->addElement(MY_VERTEX_BINDING_SOURCE, 0, VET_FLOAT3, VES_POSITION).getSize();
00062 if (mHasNormals) offset += decl->addElement(MY_VERTEX_BINDING_SOURCE,offset,VET_FLOAT3,VES_NORMAL).getSize();
00063 if (mHasTexCoords) offset += decl->addElement(MY_VERTEX_BINDING_SOURCE,offset,VET_FLOAT2,VES_TEXTURE_COORDINATES).getSize();
00064
00065 mVertexDecInitialized = true;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 }
00082
00083
00084 mRenderOp.operationType = GetOgreOpType(opType);
00085 mRenderOp.useIndexes = indexCount > 0;
00086 if (mRenderOp.useIndexes && !mIndexBufferInitialized) {
00087 mRenderOp.indexData = new IndexData;
00088 mIndexBufferInitialized = true;
00089 }
00090 mRenderOp.vertexData->vertexCount = vertexCount;
00091 if (mRenderOp.useIndexes) mRenderOp.indexData->indexCount = indexCount;
00092
00093
00094 mReady = true;
00095 miVerticesLeft = vertexCount;
00096 miIndicesLeft = indexCount;
00097 mBoundingBoxEmpty = true;
00098 mvAABMin = Vector3::ZERO;
00099 mvAABMax = Vector3::ZERO;
00100
00101
00102 if (vertexCount <= 0) return;
00103
00104
00105 if (mVertexBufferCapacity != vertexCount) {
00106 mVertexBufferCapacity = vertexCount;
00107
00108 mHWVBuf = HardwareBufferManager::getSingleton().createVertexBuffer(
00109 mRenderOp.vertexData->vertexDeclaration->getVertexSize(MY_VERTEX_BINDING_SOURCE),
00110 vertexCount,
00111 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
00112
00113 mRenderOp.vertexData->vertexBufferBinding->setBinding(MY_VERTEX_BINDING_SOURCE, mHWVBuf);
00114
00115
00116 }
00117 mRenderOp.vertexData->vertexCount = vertexCount;
00118
00119
00120
00121
00122 if (mIndexBufferCapacity != indexCount && mRenderOp.useIndexes) {
00123 mIndexBufferCapacity = indexCount;
00124
00125 mHWIBuf = HardwareBufferManager::getSingleton().createIndexBuffer(
00126 HardwareIndexBuffer::IT_16BIT,
00127 indexCount,
00128 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
00129 mRenderOp.indexData->indexBuffer = mHWIBuf;
00130
00131
00132 }
00133 if (mRenderOp.useIndexes) mRenderOp.indexData->indexCount = indexCount;
00134
00135
00136 mWritePtr = (vertexCount > 0) ? (static_cast<Real*>(mHWVBuf->lock(HardwareBuffer::HBL_DISCARD))) : 0;
00137 mIndexWritePtr = (indexCount > 0) ? (static_cast<unsigned short*>(mHWIBuf->lock(HardwareBuffer::HBL_DISCARD))) : 0;
00138 }
00139
00140 void OgreRenderableDrawer::AddVertex (kReal x,kReal y,kReal z,kReal nx,kReal ny,kReal nz,kReal u,kReal v) { PROFILE
00141
00142 assert(mReady && "Prepare not called");
00143 assert(miVerticesLeft > 0 && "vertex buffer overflow");
00144 if (miVerticesLeft <= 0) return;
00145 --miVerticesLeft;
00146 *mWritePtr++ = x;
00147 *mWritePtr++ = y;
00148 *mWritePtr++ = z;
00149 if (mHasNormals) {
00150 *mWritePtr++ = nx;
00151 *mWritePtr++ = ny;
00152 *mWritePtr++ = nz;
00153 }
00154 if (mHasTexCoords) {
00155 *mWritePtr++ = u;
00156 *mWritePtr++ = v;
00157 }
00158 if (mBoundingBoxEmpty || mvAABMin.x > x) mvAABMin.x = x;
00159 if (mBoundingBoxEmpty || mvAABMin.y > y) mvAABMin.y = y;
00160 if (mBoundingBoxEmpty || mvAABMin.z > z) mvAABMin.z = z;
00161 if (mBoundingBoxEmpty || mvAABMax.x < x) mvAABMax.x = x;
00162 if (mBoundingBoxEmpty || mvAABMax.y < y) mvAABMax.y = y;
00163 if (mBoundingBoxEmpty || mvAABMax.z < z) mvAABMax.z = z;
00164 mBoundingBoxEmpty = false;
00165 }
00166
00167 void OgreRenderableDrawer::AddIndex (IndexInt i) { PROFILE
00168
00169 assert(mReady && "Prepare not called");
00170 assert(miIndicesLeft > 0 && "index buffer overflow");
00171 if (miIndicesLeft <= 0) return;
00172 --miIndicesLeft;
00173 *mIndexWritePtr++ = i;
00174 }
00175
00176 void OgreRenderableDrawer::Finish () { PROFILE
00177 assert(mReady && "Prepare not called");
00178 assert(miVerticesLeft == 0 && "not enough vertices written");
00179 assert(miIndicesLeft == 0 && "not enough indices written");
00180 mBox.setExtents(mvAABMin,mvAABMax);
00181 mReady = false;
00182 if (mVertexBufferCapacity > 0) mHWVBuf->unlock();
00183 if (mIndexBufferCapacity > 0) mHWIBuf->unlock();
00184 }
00185
00186 Ogre::Real OgreRenderableDrawer::getBoundingRadius(void) const { PROFILE
00187 return Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
00188 }
00189
00190 Ogre::Real OgreRenderableDrawer::getSquaredViewDepth(const Ogre::Camera* cam) const { PROFILE
00191 Vector3 vMin, vMax, vMid, vDist;
00192 vMin = mBox.getMinimum();
00193 vMax = mBox.getMaximum();
00194 vMid = ((vMin - vMax) * 0.5) + vMin;
00195 vDist = cam->getDerivedPosition() - vMid;
00196 return vDist.squaredLength();
00197 }
00198
00199
00201 Ogre::RenderOperation::OperationType OgreRenderableDrawer::GetOgreOpType (const eOpType opType) { PROFILE
00202 switch (opType) {
00203 default:
00204 case kOpType_POINT_LIST : return Ogre::RenderOperation::OT_POINT_LIST;
00205 case kOpType_LINE_LIST : return Ogre::RenderOperation::OT_LINE_LIST;
00206 case kOpType_LINE_STRIP : return Ogre::RenderOperation::OT_LINE_STRIP;
00207 case kOpType_TRIANGLE_LIST : return Ogre::RenderOperation::OT_TRIANGLE_LIST;
00208 case kOpType_TRIANGLE_STRIP : return Ogre::RenderOperation::OT_TRIANGLE_STRIP;
00209 case kOpType_TRIANGLE_FAN : return Ogre::RenderOperation::OT_TRIANGLE_FAN;
00210 }
00211 }
00212
00214 Ogre::HardwareBuffer::Usage OgreRenderableDrawer::GetOgreHWBUsage (const eGeometryChange geometryChangeHint) { PROFILE
00215 switch (geometryChangeHint) {
00216 default:
00217 case kGeometryChange_Seldom : return Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY;
00218 case kGeometryChange_Often : return Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
00219 case kGeometryChange_AlmostEveryFrame : return Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 }