//----------------------------------------------------------------------------- void ManualObject::copyTempVertexToBuffer(void) { mTempVertexPending = false; RenderOperation* rop = mCurrentSection->getRenderOperation(); if (rop->vertexData->vertexCount == 0 && !mCurrentUpdating) { // first vertex, autoorganise decl VertexDeclaration* oldDcl = rop->vertexData->vertexDeclaration; rop->vertexData->vertexDeclaration = oldDcl->getAutoOrganisedDeclaration(false, false); HardwareBufferManager::getSingleton().destroyVertexDeclaration(oldDcl); } resizeTempVertexBufferIfNeeded(++rop->vertexData->vertexCount); // get base pointer char* pBase = mTempVertexBuffer + (mDeclSize * (rop->vertexData->vertexCount-1)); const VertexDeclaration::VertexElementList& elemList = rop->vertexData->vertexDeclaration->getElements(); for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin(); i != elemList.end(); ++i) { float* pFloat = 0; RGBA* pRGBA = 0; const VertexElement& elem = *i; switch(elem.getType()) { case VET_FLOAT1: case VET_FLOAT2: case VET_FLOAT3: case VET_FLOAT4: elem.baseVertexPointerToElement(pBase, &pFloat); break; case VET_COLOUR: case VET_COLOUR_ABGR: case VET_COLOUR_ARGB: elem.baseVertexPointerToElement(pBase, &pRGBA); break; default: // nop ? break; }; RenderSystem* rs; unsigned short dims; switch(elem.getSemantic()) { case VES_POSITION: *pFloat++ = mTempVertex.position.x; *pFloat++ = mTempVertex.position.y; *pFloat++ = mTempVertex.position.z; break; case VES_NORMAL: *pFloat++ = mTempVertex.normal.x; *pFloat++ = mTempVertex.normal.y; *pFloat++ = mTempVertex.normal.z; break; case VES_TANGENT: *pFloat++ = mTempVertex.tangent.x; *pFloat++ = mTempVertex.tangent.y; *pFloat++ = mTempVertex.tangent.z; break; case VES_TEXTURE_COORDINATES: dims = VertexElement::getTypeCount(elem.getType()); for (ushort t = 0; t < dims; ++t) *pFloat++ = mTempVertex.texCoord[elem.getIndex()][t]; break; case VES_DIFFUSE: rs = Root::getSingleton().getRenderSystem(); if (rs) rs->convertColourValue(mTempVertex.colour, pRGBA++); else *pRGBA++ = mTempVertex.colour.getAsRGBA(); // pick one! break; default: // nop ? break; }; } }
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; }
// 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); } */ }
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(); }
// 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); }