void GeomUtils::createQuad(VertexData*& vertexData) { assert(vertexData); vertexData->vertexCount = 4; vertexData->vertexStart = 0; VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; VertexBufferBinding* bind = vertexData->vertexBufferBinding; vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(0, vbuf); // Upload data float data[]={ -1,1,-1, // corner 1 -1,-1,-1, // corner 2 1,1,-1, // corner 3 1,-1,-1}; // corner 4 vbuf->writeData(0, sizeof(data), data, true); }
void NxLine::fillHardwareBuffers() { int size = mPoints.size(); prepareHardwareBuffers(size,0, mUseVertexColour); if (!size) { mBox.setExtents(Vector3::ZERO,Vector3::ZERO); mDirty=false; return; } Nx::Vector3 vaabMin = mPoints[0]; Nx::Vector3 vaabMax = mPoints[0]; HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0); Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); { for(int i = 0; i < size; i++) { *prPos++ = mPoints[i].x; *prPos++ = mPoints[i].y; *prPos++ = mPoints[i].z; if(mPoints[i].x < vaabMin.x) vaabMin.x = mPoints[i].x; if(mPoints[i].y < vaabMin.y) vaabMin.y = mPoints[i].y; if(mPoints[i].z < vaabMin.z) vaabMin.z = mPoints[i].z; if(mPoints[i].x > vaabMax.x) vaabMax.x = mPoints[i].x; if(mPoints[i].y > vaabMax.y) vaabMax.y = mPoints[i].y; if(mPoints[i].z > vaabMax.z) vaabMax.z = mPoints[i].z; } } vbuf->unlock(); if( mUseVertexColour ) { HardwareVertexBufferSharedPtr cbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(1); cbuf->writeData(0, size * sizeof(unsigned int), &mPointsColor[0], true ); } mBox.setExtents( NxVec3ToOgre( vaabMin ), NxVec3ToOgre( vaabMax ) ); mDirty = false; }
void NxTriangles::SetTextureCoordinates( const float * Coordinates ) { HardwareVertexBufferSharedPtr cbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(2); cbuf->writeData(0, cbuf->getNumVertices() * sizeof(float) * (mUVW ? 3 : 2), Coordinates, true ); }
//--------------------------------------------------------------------- void PrefabFactory::createPlane(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); float vertices[32] = { -100, -100, 0, // pos 0,0,1, // normal 0,1, // texcoord 100, -100, 0, 0,0,1, 1,1, 100, 100, 0, 0,0,1, 1,0, -100, 100, 0 , 0,0,1, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = 4; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[6] = {0,1,2, 0,2,3 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = 6; sub->indexData->indexStart =0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); }
void MovableText::_updateColors(void) { assert(mpFont); assert(!mpMaterial.isNull()); // Convert to system-specific RGBA color; Root::getSingleton().convertColourValue(mColor, &color); HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING); //RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_NORMAL)); RGBA* pDest=(RGBA*)malloc(vbuf->getSizeInBytes()); RGBA* oDest=pDest; for (uint i = 0; i < mRenderOp.vertexData->vertexCount; ++i) *pDest++ = color; //vbuf->unlock(); vbuf->writeData(0, vbuf->getSizeInBytes(), oDest, true); free(oDest); mUpdateColors = false; }
void ColoredTextAreaOverlayElement::updateColours(void) { if(!mRenderOp.vertexData) return; // Convert to system-specific RGBA topColour, bottomColour; // Set default to white Root::getSingleton().convertColourValue(ColourValue::White, &topColour); Root::getSingleton().convertColourValue(ColourValue::White, &bottomColour); HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING); //RGBA* pDest = static_cast<RGBA*>( // vbuf->lock(HardwareBuffer::HBL_NORMAL) ); RGBA* pDest=(RGBA*)malloc(vbuf->getSizeInBytes()); RGBA* oDest=pDest; for (size_t i = 0; i < mAllocSize; ++i) { if (i < m_Colors.size()) { Root::getSingleton().convertColourValue(GetColor(m_Colors[i], m_ValueTop), &topColour); Root::getSingleton().convertColourValue(GetColor(m_Colors[i], m_ValueBottom), &bottomColour); } // First tri (top, bottom, top) *pDest++ = topColour; *pDest++ = bottomColour; *pDest++ = topColour; // Second tri (top, bottom, bottom) *pDest++ = topColour; *pDest++ = bottomColour; *pDest++ = bottomColour; } vbuf->writeData(0, vbuf->getSizeInBytes(), oDest, true); free(oDest); //vbuf->unlock(); }
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments) { // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); int nextBuf = 0; // This function is just one long stream of Ogre-barf, but it works // great. // Add vertices int numVerts = data->vertices.length / 3; sub->vertexData = new VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; VertexDeclaration *decl = sub->vertexData->vertexDeclaration; decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false); if(flip) { float *datamod = new float[data->vertices.length]; //std::cout << "Shape" << shape->name.toString() << "\n"; for(int i = 0; i < numVerts; i++) { int index = i * 3; const float *pos = data->vertices.ptr + index; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = mTransform * original; mBoundingBox.merge(original); datamod[index] = original.x; datamod[index+1] = original.y; datamod[index+2] = original.z; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else { vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false); } VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); if (data->normals.length) { decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); if(flip) { Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); float *datamod = new float[data->normals.length]; for(int i = 0; i < numVerts; i++) { int index = i * 3; const float *pos = data->normals.ptr + index; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = rotation * original; if (mNormaliseNormals) { original.normalise(); } datamod[index] = original.x; datamod[index+1] = original.y; datamod[index+2] = original.z; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else { vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false); } bind->setBinding(nextBuf++, vbuf); } // Vertex colors if (data->colors.length) { const float *colors = data->colors.ptr; RenderSystem* rs = Root::getSingleton().getRenderSystem(); std::vector<RGBA> colorsRGB(numVerts); RGBA *pColour = &colorsRGB.front(); for (int i=0; i<numVerts; i++) { rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], colors[3]),pColour++); colors += 4; } decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_COLOUR), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); bind->setBinding(nextBuf++, vbuf); } if (data->uvlist.length) { decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT2), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); if(flip) { float *datamod = new float[data->uvlist.length]; for(unsigned int i = 0; i < data->uvlist.length; i+=2){ float x = *(data->uvlist.ptr + i); float y = *(data->uvlist.ptr + i + 1); datamod[i] =x; datamod[i + 1] =y; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false); bind->setBinding(nextBuf++, vbuf); } // Triangle faces - The total number of triangle points int numFaces = data->triangles.length; if (numFaces) { sub->indexData->indexCount = numFaces; sub->indexData->indexStart = 0; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer(HardwareIndexBuffer::IT_16BIT, numFaces, HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){ sub->indexData->indexBuffer = ibuf; uint16 *datamod = new uint16[numFaces]; int index = 0; for (size_t i = 0; i < sub->indexData->indexCount; i+=3) { const short *pos = data->triangles.ptr + index; uint16 i0 = (uint16) *(pos+0); uint16 i1 = (uint16) *(pos+1); uint16 i2 = (uint16) *(pos+2); //std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n"; datamod[index] = i2; datamod[index+1] = i1; datamod[index+2] = i0; index += 3; } ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false); delete [] datamod; } else ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); sub->indexData->indexBuffer = ibuf; } // Set material if one was given if (!material.empty()) sub->setMaterialName(material); //add vertex bone assignments for (std::list<VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin(); it != vertexBoneAssignments.end(); it++) { sub->addBoneAssignment(*it); } if(mSkel.isNull()) needBoneAssignments.push_back(sub); }
void BasicTutorial2::createColourCube() { /// Create the mesh via the MeshManager Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General"); /// Create one submesh SubMesh* sub = msh->createSubMesh(); const float sqrt13 = 0.577350269f; /* sqrt(1/3) */ /// Define the vertices (8 vertices, each have 3 floats for position and 3 for normal) const size_t nVertices = 8; const size_t vbufCount = 3*2*nVertices; float vertices[vbufCount] = { -100.0,100.0,-100.0, //0 position -sqrt13,sqrt13,-sqrt13, //0 normal 100.0,100.0,-100.0, //1 position sqrt13,sqrt13,-sqrt13, //1 normal 100.0,-100.0,-100.0, //2 position sqrt13,-sqrt13,-sqrt13, //2 normal -100.0,-100.0,-100.0, //3 position -sqrt13,-sqrt13,-sqrt13, //3 normal -100.0,100.0,100.0, //4 position -sqrt13,sqrt13,sqrt13, //4 normal 100.0,100.0,100.0, //5 position sqrt13,sqrt13,sqrt13, //5 normal 100.0,-100.0,100.0, //6 position sqrt13,-sqrt13,sqrt13, //6 normal -100.0,-100.0,100.0, //7 position -sqrt13,-sqrt13,sqrt13, //7 normal }; RenderSystem* rs = Root::getSingleton().getRenderSystem(); RGBA colours[nVertices]; RGBA *pColour = colours; // Use render system to convert colour value since colour packing varies rs->convertColourValue(ColourValue(1.0,0.0,0.0), pColour++); //0 colour rs->convertColourValue(ColourValue(1.0,1.0,0.0), pColour++); //1 colour rs->convertColourValue(ColourValue(0.0,1.0,0.0), pColour++); //2 colour rs->convertColourValue(ColourValue(0.0,0.0,0.0), pColour++); //3 colour rs->convertColourValue(ColourValue(1.0,0.0,1.0), pColour++); //4 colour rs->convertColourValue(ColourValue(1.0,1.0,1.0), pColour++); //5 colour rs->convertColourValue(ColourValue(0.0,1.0,1.0), pColour++); //6 colour rs->convertColourValue(ColourValue(0.0,0.0,1.0), pColour++); //7 colour /// Define 12 triangles (two triangles per cube face) /// The values in this table refer to vertices in the above table const size_t ibufCount = 36; unsigned short faces[ibufCount] = { 0,2,3, 0,1,2, 1,6,2, 1,5,6, 4,6,5, 4,7,6, 0,7,4, 0,3,7, 0,5,1, 0,4,5, 2,7,3, 2,6,7 }; /// Create vertex data structure for 8 vertices shared between submeshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; // 1st buffer decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); // 2nd buffer offset = 0; decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), colours, true); /// Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding(1, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100)); msh->_setBoundingSphereRadius(Math::Sqrt(3*100*100)); /// Notify -Mesh object that it has been loaded msh->load(); }
//--------------------------------------------------------------------- void PrefabFactory::createCube(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides const int NUM_ENTRIES_PER_VERTEX = 8; const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides const Real CUBE_SIZE = 100.0f; const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; // Create 4 vertices per side instead of 6 that are shared for the whole cube. // The reason for this is with only 6 vertices the normals will look bad // since each vertex can "point" in a different direction depending on the face it is included in. float vertices[NUM_VERTEX_ENTRIES] = { // front side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos 0,0,1, // normal 0,1, // texcoord CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , 0,0,1, 0,0, // back side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,0, // left side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,0, // right side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,0, // up side -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 0,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 0,0, // down side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 1,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 1,0, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = NUM_VERTICES; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, NUM_INDICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[NUM_INDICES] = { // front 0,1,2, 0,2,3, // back 4,5,6, 4,6,7, // left 8,9,10, 8,10,11, // right 12,13,14, 12,14,15, // up 16,17,18, 16,18,19, // down 20,21,22, 20,22,23 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = NUM_INDICES; sub->indexData->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); }
//----------------------------------------------------------------------------- ManualObject::ManualObjectSection* ManualObject::end(void) { if (!mCurrentSection) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "You cannot call end() until after you call begin()", "ManualObject::end"); } if (mTempVertexPending) { // bake current vertex copyTempVertexToBuffer(); } // pointer that will be returned ManualObjectSection* result = NULL; RenderOperation* rop = mCurrentSection->getRenderOperation(); // Check for empty content if (rop->vertexData->vertexCount == 0 || (rop->useIndexes && rop->indexData->indexCount == 0)) { // You're wasting my time sonny if (mCurrentUpdating) { // Can't just undo / remove since may be in the middle // Just allow counts to be 0, will not be issued to renderer // return the finished section (though it has zero vertices) result = mCurrentSection; } else { // First creation, can really undo // Has already been added to section list end, so remove mSectionList.pop_back(); OGRE_DELETE mCurrentSection; } } else // not an empty section { // Bake the real buffers HardwareVertexBufferSharedPtr vbuf; // Check buffer sizes bool vbufNeedsCreating = true; bool ibufNeedsCreating = rop->useIndexes; // Work out if we require 16 or 32-bit index buffers HardwareIndexBuffer::IndexType indexType = mCurrentSection->get32BitIndices()? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT; if (mCurrentUpdating) { // May be able to reuse buffers, check sizes vbuf = rop->vertexData->vertexBufferBinding->getBuffer(0); if (vbuf->getNumVertices() >= rop->vertexData->vertexCount) vbufNeedsCreating = false; if (rop->useIndexes) { if ((rop->indexData->indexBuffer->getNumIndexes() >= rop->indexData->indexCount) && (indexType == rop->indexData->indexBuffer->getType())) ibufNeedsCreating = false; } } if (vbufNeedsCreating) { // Make the vertex buffer larger if estimated vertex count higher // to allow for user-configured growth area size_t vertexCount = std::max(rop->vertexData->vertexCount, mEstVertexCount); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( mDeclSize, vertexCount, mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : HardwareBuffer::HBU_STATIC_WRITE_ONLY); rop->vertexData->vertexBufferBinding->setBinding(0, vbuf); } if (ibufNeedsCreating) { // Make the index buffer larger if estimated index count higher // to allow for user-configured growth area size_t indexCount = std::max(rop->indexData->indexCount, mEstIndexCount); rop->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( indexType, indexCount, mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : HardwareBuffer::HBU_STATIC_WRITE_ONLY); } // Write vertex data vbuf->writeData( 0, rop->vertexData->vertexCount * vbuf->getVertexSize(), mTempVertexBuffer, true); // Write index data if(rop->useIndexes) { if (HardwareIndexBuffer::IT_32BIT == indexType) { // direct copy from the mTempIndexBuffer rop->indexData->indexBuffer->writeData( 0, rop->indexData->indexCount * rop->indexData->indexBuffer->getIndexSize(), mTempIndexBuffer, true); } else //(HardwareIndexBuffer::IT_16BIT == indexType) { uint16* pIdx = static_cast<uint16*>(rop->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); uint32* pSrc = mTempIndexBuffer; for (size_t i = 0; i < rop->indexData->indexCount; i++) { *pIdx++ = static_cast<uint16>(*pSrc++); } rop->indexData->indexBuffer->unlock(); } } // return the finished section result = mCurrentSection; } // empty section check mCurrentSection = 0; resetTempAreas(); // Tell parent if present if (mParentNode) { mParentNode->needUpdate(); } // will return the finished section or NULL if // the section was empty (i.e. zero vertices/indices) return result; }
void VolumeRenderable::initialise() { // Create geometry size_t nvertices = mSlices*4; // n+1 planes size_t elemsize = 3*3; size_t dsize = elemsize*nvertices; size_t x; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Create structures float *vertices = new float[dsize]; float coords[4][2] = { {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(x=0; x<mSlices; x++) { for(size_t y=0; y<4; y++) { float xcoord = coords[y][0]-0.5; float ycoord = coords[y][1]-0.5; float zcoord = -((float)x/(float)(mSlices-1) - 0.5f); // 1.0f .. a/(a+1) // coordinate vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f); // normal vertices[x*4*elemsize+y*elemsize+3] = 0.0f; vertices[x*4*elemsize+y*elemsize+4] = 0.0f; vertices[x*4*elemsize+y*elemsize+5] = 1.0f; // tex vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f); } } unsigned short *faces = new unsigned short[mSlices*6]; for(x=0; x<mSlices; x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+1; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT3); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mSlices*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mSlices*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] vertices; delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; // Create a brand new private material MaterialPtr material = MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", false, 0); // Manual, loader // Remove pre-created technique from defaults material->removeAllTechniques(); // Create a techinique and a pass and a texture unit Technique * technique = material->createTechnique(); Pass * pass = technique->createPass(); TextureUnitState * textureUnit = pass->createTextureUnitState(); // Set pass parameters pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setDepthWriteEnabled(false); pass->setCullingMode(CULL_NONE); pass->setLightingEnabled(false); // Set texture unit parameters textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); textureUnit->setTextureName(mTexture, TEX_TYPE_3D); textureUnit->setTextureFiltering(TFO_TRILINEAR); mUnit = textureUnit; m_pMaterial = material; }
//------------------------------------------------------------------------ void TerrainBatch::updateVertexData( const Ogre::Rect& vertexRectInTile ) { Vector3 center = mBoundingBox.getCenter(); Ogre::Rect dirtyRect = mVertexRectInTile.intersect( vertexRectInTile ); if ( mGpuVertexData && (dirtyRect.isNull() == false) ) { mOneVertexSize = mTileRender->getOneVertexSize(); //////////////////////////////////////////////////////////////////////////////// Ogre::VertexData* tileVertexData = mTileRender->getCpuVertexData(); uint16 srcPosRowSkip = 0; unsigned char * srcRootPosBuf = 0; unsigned char * srcRowPosBuf = 0; HardwareVertexBufferSharedPtr srcPosbuf = tileVertexData->vertexBufferBinding->getBuffer(TerrainTileRender::POSITION_BUFFER); long destOffsetX = dirtyRect.left <= mVertexRectInTile.left ? 0 : (dirtyRect.left - mVertexRectInTile.left) ; long destOffsetY = dirtyRect.top <= mVertexRectInTile.top ? 0 : (dirtyRect.top - mVertexRectInTile.top) ; uint16 destPosRowSkip = 0; size_t destRowPos = 0; HardwareVertexBufferSharedPtr destPosbuf = mGpuVertexData->vertexBufferBinding->getBuffer(TerrainTileRender::POSITION_BUFFER); if (!srcPosbuf.isNull() && !destPosbuf.isNull()) { srcPosRowSkip = mTileRender->getVertexSideSize() * mOneVertexSize; srcRootPosBuf = static_cast<unsigned char*>(srcPosbuf->lock(HardwareBuffer::HBL_READ_ONLY)); // skip src buffer in by left/top srcRowPosBuf = srcRootPosBuf; srcRowPosBuf += dirtyRect.top * srcPosRowSkip + dirtyRect.left * mOneVertexSize; destPosRowSkip = mVertexSideNum * mOneVertexSize; // skip dest pos in by left/top destRowPos = destOffsetY * destPosRowSkip + destOffsetX * mOneVertexSize; /////////////////////////////////////////////////////////////////////////////////////// { size_t destRowHeadPos = destRowPos; size_t rowCopyLen = (dirtyRect.width() + 1) * mOneVertexSize; for (uint16 y = dirtyRect.top; y <= dirtyRect.bottom; y ++) { destPosbuf->writeData( destRowHeadPos, rowCopyLen, srcRowPosBuf ); srcRowPosBuf += srcPosRowSkip; destRowHeadPos += destPosRowSkip; } } /////////////////////////////////////////////////////////////////////////////////////// //{ // unsigned char * pRootPosBuf = static_cast<unsigned char*>(destPosbuf->lock( HardwareBuffer::HBL_NORMAL )); // { // pRootPosBuf += destRowPos; // unsigned char * destRowHeadPos = pRootPosBuf; // unsigned char * destRowPixelPos = pRootPosBuf; // for (uint16 y = dirtyRect.top; y <= dirtyRect.bottom; y ++) // { // destRowPixelPos = destRowHeadPos; // for (uint16 x = dirtyRect.left; x <= dirtyRect.right; x ++) // { // float* pPosBuf = static_cast<float*>(static_cast<void*>(destRowPixelPos)); // if (pPosBuf) // { // //position // *pPosBuf++ = *pPosBuf - center.x; // *pPosBuf++; // *pPosBuf++ = *pPosBuf - center.z; // } // destRowPixelPos += mOneVertexSize; // } // destRowHeadPos += destPosRowSkip; // } // } // destPosbuf->unlock(); //} /////////////////////////////////////////////////////////////////////////////////////// srcPosbuf->unlock(); //destPosbuf->unlock(); } } }
Ogre::VertexData* MeshBuilder::createVertexData() { // Declarations std::map<unsigned short, std::vector<tElement> >::iterator iterSource, iterSourceEnd; std::vector<tVertex>::iterator iterVertex, iterVertexEnd; HardwareVertexBufferSharedPtr vbuffer; float fBuffer[4]; // Create the vertex data VertexData* pVertexData = new VertexData(); pVertexData->vertexStart = 0; pVertexData->vertexCount = m_currentSubMesh.vertices.size(); // Initializes the vertex declaration for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end(); iterSource != iterSourceEnd; ++iterSource) { size_t offset = 0; std::vector<tElement>::iterator iter, iterEnd; for (iter = iterSource->second.begin(), iterEnd = iterSource->second.end(); iter != iterEnd; ++iter) { pVertexData->vertexDeclaration->addElement(iterSource->first, offset, iter->type, iter->semantic, iter->usIndex); offset += VertexElement::getTypeSize(iter->type); } vbuffer = HardwareBufferManager::getSingleton().createVertexBuffer(offset, m_currentSubMesh.vertices.size(), m_currentSubMesh.vertexBufferInfos[iterSource->first].usage, m_currentSubMesh.vertexBufferInfos[iterSource->first].bUseShadowBuffer); pVertexData->vertexBufferBinding->setBinding(iterSource->first, vbuffer); } // Add the vertices into their buffers VertexBufferBinding::VertexBufferBindingMap bindings = pVertexData->vertexBufferBinding->getBindings(); for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end(); iterSource != iterSourceEnd; ++iterSource) { vbuffer = bindings[iterSource->first]; size_t offset = 0; unsigned int vertexIndex = 0; for (iterVertex = m_currentSubMesh.vertices.begin(), iterVertexEnd = m_currentSubMesh.vertices.end(); iterVertex != iterVertexEnd; ++iterVertex) { std::vector<tElement>::iterator iter, iterEnd; for (iter = iterSource->second.begin(), iterEnd = iterSource->second.end(); iter != iterEnd; ++iter) { switch (iter->semantic) { case Ogre::VES_POSITION: fBuffer[0] = iterVertex->position.x; fBuffer[1] = iterVertex->position.y; fBuffer[2] = iterVertex->position.z; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_NORMAL: fBuffer[0] = iterVertex->normal.x; fBuffer[1] = iterVertex->normal.y; fBuffer[2] = iterVertex->normal.z; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_BINORMAL: fBuffer[0] = iterVertex->binormal.x; fBuffer[1] = iterVertex->binormal.y; fBuffer[2] = iterVertex->binormal.z; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_TANGENT: fBuffer[0] = iterVertex->tangent.x; fBuffer[1] = iterVertex->tangent.y; fBuffer[2] = iterVertex->tangent.z; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_DIFFUSE: fBuffer[0] = iterVertex->diffuseColour.a; fBuffer[1] = iterVertex->diffuseColour.r; fBuffer[2] = iterVertex->diffuseColour.g; fBuffer[3] = iterVertex->diffuseColour.b; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_SPECULAR: fBuffer[0] = iterVertex->specularColour.a; fBuffer[1] = iterVertex->specularColour.r; fBuffer[2] = iterVertex->specularColour.g; fBuffer[3] = iterVertex->specularColour.b; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_TEXTURE_COORDINATES: fBuffer[0] = iterVertex->texCoord[iter->usIndex].x; fBuffer[1] = iterVertex->texCoord[iter->usIndex].y; fBuffer[2] = iterVertex->texCoord[iter->usIndex].z; vbuffer->writeData(offset, VertexElement::getTypeSize(iter->type), fBuffer); break; case Ogre::VES_BLEND_WEIGHTS: case Ogre::VES_BLEND_INDICES: // Nothing to do, but the compiler complains if not present break; } offset += VertexElement::getTypeSize(iter->type); } ++vertexIndex; } } return pVertexData; }
void Road2::createMesh() { AxisAlignedBox aab; union { float* vertices; CoVertice_t* covertices; }; /// Create the mesh via the MeshManager Ogre::String mesh_name = Ogre::String("RoadSystem-").append(Ogre::StringConverter::toString(mid)); msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mainsub = msh->createSubMesh(); mainsub->setMaterialName("road2"); /// Define the vertices size_t vbufCount = (2 * 3 + 2) * vertexcount; vertices = (float*)malloc(vbufCount * sizeof(float)); int i; //fill values for (i = 0; i < vertexcount; i++) { covertices[i].texcoord = tex[i]; covertices[i].vertex = vertex[i]; //normals are computed later covertices[i].normal = Vector3::ZERO; aab.merge(vertex[i]); } /// Define triangles size_t ibufCount = 3 * tricount; //compute normals for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++) { Vector3 v1, v2; v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex; v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex; v1 = v1.crossProduct(v2); v1.normalise(); covertices[tris[i * 3]].normal += v1; covertices[tris[i * 3 + 1]].normal += v1; covertices[tris[i * 3 + 2]].normal += v1; } //normalize for (i = 0; i < vertexcount; i++) { covertices[i].normal.normalise(); } /// Create vertex data structure for vertices shared between sub meshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = vertexcount; /// Create declaration (memory format) of vertex data VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); //for the face /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), tris, true); /// Set parameters of the submesh mainsub->useSharedVertices = true; mainsub->indexData->indexBuffer = ibuf; mainsub->indexData->indexCount = ibufCount; mainsub->indexData->indexStart = 0; msh->_setBounds(aab, true); /// Notify Mesh object that it has been loaded msh->load(); free(vertices); };
Airbrake::Airbrake(char* basename, int num, node_t *ndref, node_t *ndx, node_t *ndy, node_t *nda, Vector3 pos, float width, float length, float maxang, char* texname, float tx1, float ty1, float tx2, float ty2, float lift_coef) { snode=0; noderef=ndref; nodex=ndx; nodey=ndy; nodea=nda; offset=pos; maxangle=maxang; area=width*length*lift_coef; char meshname[256]; sprintf(meshname, "airbrakemesh-%s-%i", basename, num); /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(meshname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); union { float *vertices; CoVertice_t *covertices; }; /// Create submesh SubMesh* sub = msh->createSubMesh(); //materials sub->setMaterialName(texname); /// Define the vertices size_t nVertices = 4; size_t vbufCount = (2*3+2)*nVertices; vertices=(float*)malloc(vbufCount*sizeof(float)); //textures coordinates covertices[0].texcoord=Vector2(tx1, ty1); covertices[1].texcoord=Vector2(tx2, ty1); covertices[2].texcoord=Vector2(tx2, ty2); covertices[3].texcoord=Vector2(tx1, ty2); /// Define triangles /// The values in this table refer to vertices in the above table size_t ibufCount = 3*4; unsigned short *faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short)); faces[0]=0; faces[1]=1; faces[2]=2; faces[3]=0; faces[4]=2; faces[5]=3; faces[6]=0; faces[7]=2; faces[8]=1; faces[9]=0; faces[10]=3; faces[11]=2; //set coords covertices[0].vertex=Vector3(0,0,0); covertices[1].vertex=Vector3(width,0,0); covertices[2].vertex=Vector3(width,0,length); covertices[3].vertex=Vector3(0,0,length); covertices[0].normal=Vector3(0,1,0); covertices[1].normal=Vector3(0,1,0); covertices[2].normal=Vector3(0,1,0); covertices[3].normal=Vector3(0,1,0); /// Create vertex data structure for vertices shared between submeshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE); // offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card faceibuf->writeData(0, faceibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = faceibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true); //msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1)); /// Notify Mesh object that it has been loaded msh->load(); // create the entity and scene node char entname[256]; sprintf(entname, "airbrakenode-%s-%i", basename, num); ec = gEnv->sceneManager->createEntity(entname, meshname); snode = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); snode->attachObject(ec); updatePosition(0.0); free (vertices); free (faces); }
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. static void createOgreMesh(Mesh *mesh, NiTriShape *shape, const String &material) { NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); int nextBuf = 0; // This function is just one long stream of Ogre-barf, but it works // great. // Add vertices int numVerts = data->vertices.length / 3; sub->vertexData = new VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; VertexDeclaration *decl = sub->vertexData->vertexDeclaration; decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, true); VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); // Vertex normals if(data->normals.length) { decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, true); bind->setBinding(nextBuf++, vbuf); } // Vertex colors if(data->colors.length) { const float *colors = data->colors.ptr; RenderSystem* rs = Root::getSingleton().getRenderSystem(); std::vector<RGBA> colorsRGB(numVerts); RGBA *pColour = &colorsRGB.front(); for(int i=0; i<numVerts; i++) { rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], colors[3]),pColour++); colors += 4; } decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_COLOUR), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); bind->setBinding(nextBuf++, vbuf); } // Texture UV coordinates if(data->uvlist.length) { decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT2), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, true); bind->setBinding(nextBuf++, vbuf); } // Triangle faces int numFaces = data->triangles.length; if(numFaces) { HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer(HardwareIndexBuffer::IT_16BIT, numFaces, HardwareBuffer::HBU_STATIC_WRITE_ONLY); ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, true); sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = numFaces; sub->indexData->indexStart = 0; } // Set material if one was given if(!material.empty()) sub->setMaterialName(material); /* Old commented D code. Might be useful when reimplementing animation. // Assign this submesh to the given bone VertexBoneAssignment v; v.boneIndex = ((Bone*)bone)->getHandle(); v.weight = 1.0; std::cerr << "+ Assigning bone index " << v.boneIndex << "\n"; for(int i=0; i < numVerts; i++) { v.vertexIndex = i; sub->addBoneAssignment(v); } */ }
Ogre::MeshPtr LodOutsideMarker::createConvexHullMesh(const String& meshName, const String& resourceGroupName) { // Based on the wiki sample: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh // Resource with given name should not exist! assert(MeshManager::getSingleton().getByName(meshName).isNull()); generateHull(); // calculate mHull triangles. // Convex hull can't be empty! assert(!mHull.empty()); MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, resourceGroupName, NULL); SubMesh* subMesh = mesh->createSubMesh(); vector<Real>::type vertexBuffer; vector<unsigned short>::type indexBuffer; // 3 position/triangle * 3 Real/position vertexBuffer.reserve(mHull.size() * 9); // 3 index / triangle indexBuffer.reserve(mHull.size() * 3); int id=0; // min & max position Vector3 minBounds(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max()); Vector3 maxBounds(std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min()); for (size_t i = 0; i < mHull.size(); i++) { assert(!mHull[i].removed); for(size_t n = 0; n < 3; n++){ indexBuffer.push_back(id++); vertexBuffer.push_back(mHull[i].vertex[n]->position.x); vertexBuffer.push_back(mHull[i].vertex[n]->position.y); vertexBuffer.push_back(mHull[i].vertex[n]->position.z); minBounds.x = std::min<Real>(minBounds.x, mHull[i].vertex[n]->position.x); minBounds.y = std::min<Real>(minBounds.y, mHull[i].vertex[n]->position.y); minBounds.z = std::min<Real>(minBounds.z, mHull[i].vertex[n]->position.z); maxBounds.x = std::max<Real>(maxBounds.x, mHull[i].vertex[n]->position.x); maxBounds.y = std::max<Real>(maxBounds.y, mHull[i].vertex[n]->position.y); maxBounds.z = std::max<Real>(maxBounds.z, mHull[i].vertex[n]->position.z); } } /// Create vertex data structure for 8 vertices shared between submeshes mesh->sharedVertexData = new VertexData(); mesh->sharedVertexData->vertexCount = mHull.size() * 3; /// Create declaration (memory format) of vertex data VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; size_t offset = 0; // 1st buffer decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), &vertexBuffer[0], true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, indexBuffer.size(), HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), &indexBuffer[0], true); /// Set parameters of the submesh subMesh->useSharedVertices = true; subMesh->indexData->indexBuffer = ibuf; subMesh->indexData->indexCount = indexBuffer.size(); subMesh->indexData->indexStart = 0; /// Set bounding information (for culling) mesh->_setBounds(AxisAlignedBox(minBounds, maxBounds)); mesh->_setBoundingSphereRadius(maxBounds.distance(minBounds) / 2.0f); /// Set material to transparent blue subMesh->setMaterialName("Examples/TransparentBlue50"); /// Notify -Mesh object that it has been loaded mesh->load(); return mesh; }
Mesh* OgreSubsystem::createMesh(const MeshData& data,String name) { String nombre = name; if(name=="AUTO_NAME_ME") { nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex); ++mAutoNameIndex; } using namespace Ogre; bool hasVertexColor = data.getDiffuse(); bool hasNormals = data.getNormals(); int numFaces = data.indices.size()/3; int numVertices = data.vertices.size()/3; HardwareVertexBufferSharedPtr posVertexBuffer; HardwareVertexBufferSharedPtr normVertexBuffer; std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer; HardwareVertexBufferSharedPtr diffuseVertexBuffer; HardwareIndexBufferSharedPtr indexBuffer; Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual( nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get(); Ogre::SubMesh* sm = m->createSubMesh(); sm->useSharedVertices = false; sm->vertexData = new VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding; size_t bufferCount = 0; vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION); if(hasNormals) vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL); if(hasVertexColor) vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE); for(int i=0;i<data.texcoords.size();++i) vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i); bufferCount = 0; // Positions posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(bufferCount, posVertexBuffer); float* vertices = data.getVertices(); float* normals = data.getNormals(); float* diffuse = data.getDiffuse(); unsigned short* indices = data.getIndices(); posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true); // Normals if(hasNormals) { normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(++bufferCount, normVertexBuffer); normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true); } if(hasVertexColor) { diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbind->setBinding(++bufferCount, diffuseVertexBuffer); diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true); } // Texcoords for(int i=0;i<data.texcoords.size();++i) { texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY)); vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]); texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false); } if(!data.indices.empty()) { // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); //unsigned short *faceVertexIndices = (unsigned short*) //indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); // Set index buffer for this submesh sm->indexData->indexBuffer = indexBuffer; sm->indexData->indexStart = 0; sm->indexData->indexCount = 3*numFaces; indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true); } //vdecl->sort(); m->load(); m->touch(); m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2], data.bbox[3],data.bbox[4],data.bbox[5]), false); sm->setMaterialName("Terrain"); Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName()); Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre); node->attachObject(ent); ent->setCastShadows(false); Mesh* mm = new Mesh(nombre,node,ent); mSceneNodes.push_back(mm); return mm; }
void Tile::_generateSubMesh(MeshPtr& mesh) { // Create a submesh to the given mesh. SubMesh* tileMesh = mesh->createSubMesh(); // Define the vertices. size_t index = 0; size_t vertCount = this->mCorners.size() + 1; // corner count + center corner Real* vertices = new Real[vertCount*3*2]; // (number of verts)*(x, y, z)*(coord, normal) -or- vertCount*3*2 // Manually add center vertex. // -- Position (ord: x, y, z) vertices[index++] = this->mPosition.x; vertices[index++] = (Ogre::Real)(this->elevation); vertices[index++] = this->mPosition.y; // -- Normal (ord: x, y, z) Vector3 norm = Vector3::UNIT_Y; vertices[index++] = norm.x; vertices[index++] = norm.y; vertices[index++] = norm.z; // Add the rest of the vertices to data buffer. for(std::vector<Corner*>::iterator it = this->mCorners.begin(); it != this->mCorners.end(); ++it) { // Add to the next point to the array. // -- Position Vector3 vector = (*it)->vec3(); vertices[index++] = vector.x; vertices[index++] = vector.y; vertices[index++] = vector.z; // -- Normal Vector3 normal = Vector3::UNIT_Y; vertices[index++] = normal.x; vertices[index++] = normal.y; vertices[index++] = normal.z; } // Define vertices color. RenderSystem* rs = Root::getSingleton().getRenderSystem(); RGBA* colors = new RGBA[vertCount]; for(size_t i = 0; i < vertCount; ++i) rs->convertColourValue(ColourValue(0.0f + 0.175f*i, 0.2f, 1.0f - 0.175f*i), colors + i); // Define the triangles. size_t faceCount = vertCount - 1; // Face count = vertCount - cent size_t center = 0; size_t last = 1; //collin was here size_t curr = 2; unsigned short* faces = new unsigned short[faceCount*3]; index = 0; for(size_t i = 0; i < faceCount; ++i) { assert(last < vertCount && curr < vertCount); // Panic check faces[index++] = center; faces[index++] = curr; faces[index++] = last; last = curr++; if(curr >= vertCount) curr = 1; } // All information has been generated, move into mesh structures. // Note: Currently does not implement or used any sort of shared // vertices. This is intentional and should be changed at the // soonest conveienence. IE -- Never. ;P tileMesh->useSharedVertices = false; tileMesh->vertexData = new VertexData(); tileMesh->vertexData->vertexCount = vertCount; // Create memory footprint for vertex data. size_t offset = 0; VertexDeclaration* decl = tileMesh->vertexData->vertexDeclaration; // Position and normal buffer. // -- Position decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); // -- Normal decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // Allocate a vertex buffer for a number of vertices and vertex size. HardwareVertexBufferSharedPtr vertBuff = HardwareBufferManager::getSingleton().createVertexBuffer( offset, // Size of a vertex, in bytes. tileMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write our data to vertex buffer. vertBuff->writeData(0, vertBuff->getSizeInBytes(), vertices, true); // Set the buffer's bind location. VertexBufferBinding* vertBind = tileMesh->vertexData->vertexBufferBinding; vertBind->setBinding(0, vertBuff); // Color buffer for vertices offset = 0; decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); // Allocate a new buffer for colors. vertBuff = HardwareBufferManager::getSingleton().createVertexBuffer( offset, // Size of a vertex, in bytes. tileMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write color data to buffer. vertBuff->writeData(0, vertBuff->getSizeInBytes(), colors, true); // Set the color buffer's bind location vertBind->setBinding(1, vertBuff); // Allocate a buffer for the index information HardwareIndexBufferSharedPtr indexBuff = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, faceCount*3, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write data to the buffer. indexBuff->writeData(0, indexBuff->getSizeInBytes(), faces, true); // Finalize submesh. tileMesh->indexData->indexBuffer = indexBuff; tileMesh->indexData->indexCount = faceCount*3; tileMesh->indexData->indexStart = 0; // Deallocate the vertex and face arrays. if(vertices) delete[] vertices; if(faces) delete[] faces; }
void MovableText::_setupGeometry() { assert(mpFont); assert(!mpMaterial.isNull()); uint vertexCount = static_cast<uint>(mCaption.size() * 6); if (mRenderOp.vertexData) { // Removed this test as it causes problems when replacing a caption // of the same size: replacing "Hello" with "hello" // as well as when changing the text alignment //if (mRenderOp.vertexData->vertexCount != vertexCount) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; mUpdateColors = true; } } if (!mRenderOp.vertexData) mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vertexCount; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; size_t offset = 0; // create/bind positions/tex.ccord. buffer if (!decl->findElementBySemantic(VES_POSITION)) decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES)) decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, ptbuf); // Colours - store these in a separate buffer because they change less often if (!decl->findElementBySemantic(VES_DIFFUSE)) decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, cbuf); size_t charlen = mCaption.size(); //Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_NORMAL)); Real *pPCBuff=(Real*)malloc(ptbuf->getSizeInBytes()); Real *oPCBuff=pPCBuff; float largestWidth = 0; float left = 0 * 2.0 - 1.0; float top = -((0 * 2.0) - 1.0); // Derive space width from a capital A if (fabs(mSpaceWidth) < 0.00001f) mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0; // for calculation of AABB Ogre::Vector3 min=Ogre::Vector3::ZERO, max=Ogre::Vector3::ZERO, currPos=Ogre::Vector3::ZERO; Ogre::Real maxSquaredRadius = 0.0f; bool first = true; // Use iterator UTFString::iterator i, iend; iend = mCaption.end(); bool newLine = true; Real len = 0.0f; if(mVerticalAlignment == MovableText::V_ABOVE) { // Raise the first line of the caption top += mCharHeight; for (i = mCaption.begin(); i != iend; ++i) { if (*i == '\n') top += mCharHeight * 2.0; } } for (i = mCaption.begin(); i != iend; ++i) { if (newLine) { len = 0.0f; for (UTFString::iterator j = i; j != iend && *j != '\n'; j++) { if (*j == ' ') len += mSpaceWidth; else len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0; } newLine = false; } if (*i == '\n') { left = 0 * 2.0 - 1.0; top -= mCharHeight * 2.0; newLine = true; continue; } if (*i == ' ') { // Just leave a gap, no tris left += mSpaceWidth; // Also reduce tri count mRenderOp.vertexData->vertexCount -= 6; continue; } Real horiz_height = mpFont->getGlyphAspectRatio(*i); Real u1, u2, v1, v2; Ogre::Font::UVRect utmp; utmp = mpFont->getGlyphTexCoords(*i); u1 = utmp.left; u2 = utmp.right; v1 = utmp.top; v2 = utmp.bottom; // each vert is (x, y, z, u, v) //------------------------------------------------------------------------------------- // First tri // // Upper left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v1; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); if (first) { min = max = currPos; maxSquaredRadius = currPos.squaredLength(); first = false; } else { min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); } top -= mCharHeight * 2.0; // Bottom left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top += mCharHeight * 2.0; left += horiz_height * mCharHeight * 2.0; // Top right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; //------------------------------------------------------------------------------------- // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); //------------------------------------------------------------------------------------- // Second tri // // Top right (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; left -= horiz_height * mCharHeight * 2.0; // Bottom left (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); left += horiz_height * mCharHeight * 2.0; // Bottom right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v2; //------------------------------------------------------------------------------------- currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); // Go back up with top top += mCharHeight * 2.0; float currentWidth = (left + 1)/2 - 0; if (currentWidth > largestWidth) largestWidth = currentWidth; } // Unlock vertex buffer //ptbuf->unlock(); ptbuf->writeData(0, ptbuf->getSizeInBytes(), oPCBuff, true); free(oPCBuff); // update AABB/Sphere radius mAABB = Ogre::AxisAlignedBox(min, max); mRadius = Ogre::Math::Sqrt(maxSquaredRadius); if (mUpdateColors) this->_updateColors(); mNeedUpdate = false; }