//-------------------------------------------------------------------------- Helper::Ptr HelperManager::CreateTangentSpace( VertexBuffer3F& _pvbo, VertexBuffer3F& _nvbo, VertexBuffer4F& _tvbo, IndexBuffer& _ibo, int _startIndex, int _countIndex, float _vectorSize) { Helper::Ptr ref = Helper::Create(); ref->vbuffer.Allocate(6*_countIndex,GL_STATIC_DRAW); ref->cbuffer.Allocate(6*_countIndex,GL_STATIC_DRAW); ref->type = GL_LINES; ref->transform = glm::mat4(1.f); glm::vec3* hvertices = ref->vbuffer.Lock(); glm::vec3* hcolors = ref->cbuffer.Lock(); glm::vec3* vertices = _pvbo.Lock(); glm::vec4* tangents = _tvbo.Lock(); glm::vec3* normals = _nvbo.Lock(); unsigned int* indices= _ibo.Lock(); int current = 0; for(int i=_startIndex; i<_startIndex+_countIndex; ++i) { int index = indices[i]; // Tangent hvertices[current+0] = vertices[index]; hvertices[current+1] = vertices[index] + glm::vec3(tangents[index]) * _vectorSize; // Bitangent glm::vec3 bitangent = glm::cross(glm::vec3(tangents[index]),normals[index]) * glm::sign(tangents[index].w); hvertices[current+2] = vertices[index]; hvertices[current+3] = vertices[index] + bitangent * _vectorSize; // Normal hvertices[current+4] = vertices[index]; hvertices[current+5] = vertices[index] + normals[index] * _vectorSize; hcolors[current+0] = glm::vec3(1.f,0.f,0.f); hcolors[current+1] = glm::vec3(1.f,0.f,0.f); hcolors[current+2] = glm::vec3(0.f,1.f,0.f); hcolors[current+3] = glm::vec3(0.f,1.f,0.f); hcolors[current+4] = glm::vec3(0.f,0.f,1.f); hcolors[current+5] = glm::vec3(0.f,0.f,1.f); current += 6; } _ibo.Unlock(); _nvbo.Unlock(); _tvbo.Unlock(); _pvbo.Unlock(); ref->cbuffer.Unlock(); ref->vbuffer.Unlock(); helpers.push_back(ref); return ref; }
void InitIndexBuffer(IndexBuffer & pIB, LPVOID indices, UINT idxCnt, UINT stride) { D3DFORMAT format; if (stride == sizeof(WORD)) format = D3DFMT_INDEX16; else if (stride == sizeof(DWORD)) format = D3DFMT_INDEX32; GetD3D9Device()->CreateIndexBuffer(idxCnt * stride, NULL, format, D3DPOOL_MANAGED, &pIB, NULL); LPVOID pIndex; pIB->Lock(0, 0, (LPVOID*)&pIndex, 0); memcpy(pIndex, indices, idxCnt * stride); pIB->Unlock(); }
SharedPtr<Model> Model::Clone(const String& cloneName) const { SharedPtr<Model> ret(new Model(context_)); ret->SetName(cloneName); ret->boundingBox_ = boundingBox_; ret->skeleton_ = skeleton_; ret->geometryBoneMappings_ = geometryBoneMappings_; ret->geometryCenters_ = geometryCenters_; ret->morphs_ = morphs_; ret->morphRangeStarts_ = morphRangeStarts_; ret->morphRangeCounts_ = morphRangeCounts_; // Deep copy vertex/index buffers HashMap<VertexBuffer*, VertexBuffer*> vbMapping; for (Vector<SharedPtr<VertexBuffer> >::ConstIterator i = vertexBuffers_.Begin(); i != vertexBuffers_.End(); ++i) { VertexBuffer* origBuffer = *i; SharedPtr<VertexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new VertexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetVertexCount(), origBuffer->GetElementMask(), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetVertexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original vertex buffer for copying"); } vbMapping[origBuffer] = cloneBuffer; } ret->vertexBuffers_.Push(cloneBuffer); } HashMap<IndexBuffer*, IndexBuffer*> ibMapping; for (Vector<SharedPtr<IndexBuffer> >::ConstIterator i = indexBuffers_.Begin(); i != indexBuffers_.End(); ++i) { IndexBuffer* origBuffer = *i; SharedPtr<IndexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new IndexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetIndexCount(), origBuffer->GetIndexSize() == sizeof(unsigned), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetIndexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original index buffer for copying"); } ibMapping[origBuffer] = cloneBuffer; } ret->indexBuffers_.Push(cloneBuffer); } // Deep copy all the geometry LOD levels and refer to the copied vertex/index buffers ret->geometries_.Resize(geometries_.Size()); for (unsigned i = 0; i < geometries_.Size(); ++i) { ret->geometries_[i].Resize(geometries_[i].Size()); for (unsigned j = 0; j < geometries_[i].Size(); ++j) { SharedPtr<Geometry> cloneGeometry; Geometry* origGeometry = geometries_[i][j]; if (origGeometry) { cloneGeometry = new Geometry(context_); cloneGeometry->SetIndexBuffer(ibMapping[origGeometry->GetIndexBuffer()]); unsigned numVbs = origGeometry->GetNumVertexBuffers(); for (unsigned k = 0; k < numVbs; ++k) { cloneGeometry->SetVertexBuffer(k, vbMapping[origGeometry->GetVertexBuffer(k)]); } cloneGeometry->SetDrawRange(origGeometry->GetPrimitiveType(), origGeometry->GetIndexStart(), origGeometry->GetIndexCount(), origGeometry->GetVertexStart(), origGeometry->GetVertexCount(), false); cloneGeometry->SetLodDistance(origGeometry->GetLodDistance()); } ret->geometries_[i][j] = cloneGeometry; } } // Deep copy the morph data (if any) to allow modifying it for (Vector<ModelMorph>::Iterator i = ret->morphs_.Begin(); i != ret->morphs_.End(); ++i) { ModelMorph& morph = *i; for (HashMap<unsigned, VertexBufferMorph>::Iterator j = morph.buffers_.Begin(); j != morph.buffers_.End(); ++j) { VertexBufferMorph& vbMorph = j->second_; if (vbMorph.dataSize_) { SharedArrayPtr<unsigned char> cloneData(new unsigned char[vbMorph.dataSize_]); memcpy(cloneData.Get(), vbMorph.morphData_.Get(), vbMorph.dataSize_); vbMorph.morphData_ = cloneData; } } } ret->SetMemoryUse(GetMemoryUse()); return ret; }
//============================================================================= //============================================================================= void StaticModelPoolMgr::AddStaticModelData(Node *pNode, StaticModel *pStaticModel) { NvMeshData nvMeshData; StaticModelData staticModelData; Model *pModel = pStaticModel->GetModel(); // only one geom currently supprted assert( pModel && pModel->GetNumGeometries() == 1 && "multiple gemoetries currently NOT supported" ); Matrix3x4 objMatrix = pNode->GetTransform(); Quaternion objRotation = pNode->GetRotation(); Geometry *pGeometry = pModel->GetGeometry(0, 0); VertexBuffer *pVbuffer = pGeometry->GetVertexBuffer(0); unsigned uElementMask = pVbuffer->GetElementMask(); unsigned vertexSize = pVbuffer->GetVertexSize(); const unsigned char *pVertexData = (const unsigned char*)pVbuffer->Lock(0, pVbuffer->GetVertexCount()); // get verts, normals, uv, etc. if ( pVertexData ) { unsigned numVertices = pVbuffer->GetVertexCount(); for ( unsigned i = 0; i < numVertices; ++i ) { unsigned char *pDataAlign = (unsigned char *)(pVertexData + i * vertexSize); if ( uElementMask & MASK_POSITION ) { const Vector3 vPos = *reinterpret_cast<Vector3*>( pDataAlign ); pDataAlign += sizeof( Vector3 ); Vector3 vxformPos = objMatrix * vPos; // xform // verts list staticModelData.listVerts.Push( vxformPos ); nvMeshData.listVerts.push_back( Vec3f( vxformPos.x_, vxformPos.y_, vxformPos.z_ ) ); } if ( uElementMask & MASK_NORMAL ) { const Vector3 vNorm = *reinterpret_cast<Vector3*>( pDataAlign ); pDataAlign += sizeof( Vector3 ); // normal list Vector3 vxformNorm = objRotation * vNorm; // xform staticModelData.listNormals.Push( vxformNorm ); nvMeshData.listNormals.push_back( Vec3f( vxformNorm.x_, vxformNorm.y_, vxformNorm.z_ ) ); } if ( uElementMask & MASK_COLOR ) { const unsigned uColor = *reinterpret_cast<unsigned*>( pDataAlign ); pDataAlign += sizeof( unsigned ); } if ( uElementMask & MASK_TEXCOORD1 ) { const Vector2 vUV = *reinterpret_cast<Vector2*>( pDataAlign ); pDataAlign += sizeof( Vector2 ); // uv list staticModelData.listUVs.Push( vUV ); } // skip other mask elements - we got what we wanted } //unlock pVbuffer->Unlock(); } else { // error assert( false && "failed to unlock vertex buffer" ); } // get indeces IndexBuffer *pIbuffer = pGeometry->GetIndexBuffer(); const unsigned *pIndexData = (const unsigned *)pIbuffer->Lock( 0, pIbuffer->GetIndexCount() ); const unsigned short *pUShortData = (const unsigned short *)pIndexData; if ( pUShortData ) { unsigned numIndeces = pIbuffer->GetIndexCount(); unsigned indexSize = pIbuffer->GetIndexSize(); assert( indexSize == sizeof(unsigned short) ); for( unsigned i = 0; i < numIndeces; i += 3 ) { int idx0 = (int)pUShortData[i ]; int idx1 = (int)pUShortData[i+1]; int idx2 = (int)pUShortData[i+2]; staticModelData.listTris.Push( IntVector3( idx0, idx1, idx2 ) ); nvMeshData.listTris.push_back( Vec3i( idx0, idx1, idx2 ) ); } //unlock pIbuffer->Unlock(); } else { // error assert( false && "failed to unlock index buffer" ); } // rest of the static model data staticModelData.node = pNode; staticModelData.drawable = pStaticModel; staticModelData.begVertex = m_pNvScene->getNumVertices(); staticModelData.begTriList = m_pNvScene->getNumTriangles(); // resize coeff lists staticModelData.listVertexUnshadoweCoeff.Resize( staticModelData.listVerts.Size() ); staticModelData.listVertexShadowCoeff.Resize( staticModelData.listVerts.Size() ); staticModelData.listVertexDiffuseColor.Resize( staticModelData.listVerts.Size() ); staticModelData.listVertexSampleOcclude.resize( staticModelData.listVerts.Size() ); // find material matcolor VertexUtil *pVertexUtil = GetScene()->GetComponent<VertexUtil>(); staticModelData.materialColor = pVertexUtil->GetModelMaterialColor( pStaticModel ); // save model m_vStaticModelPool.Push( staticModelData ); // push it to nv Scene m_pNvScene->AddTriangleMesh( nvMeshData ); }
/** * @brief * Builds the octree */ bool MeshOctree::Build(MeshLODLevel &cMeshLODLevel, uint32 nNumOfGeometries, const uint32 nGeometries[], Array<Array<uint32>*> *plstOctreeIDList) { // Check parameters if (!cMeshLODLevel.GetMesh() || !cMeshLODLevel.GetMesh()->GetMorphTarget() || !cMeshLODLevel.GetMesh()->GetMorphTarget()->GetVertexBuffer() || !cMeshLODLevel.GetIndexBuffer()) return false; // Error! // Store geometries m_pOwnerMeshLODLevel = &cMeshLODLevel; m_bBuild = true; m_nNumOfGeometries = nNumOfGeometries; m_pnGeometries = new uint32[m_nNumOfGeometries]; MemoryManager::Copy(m_pnGeometries, nGeometries, sizeof(uint32)*m_nNumOfGeometries); // Get vertex and index buffer pointers // [TODO] Get right morph target and LOD level! VertexBuffer *pVertexBuffer = cMeshLODLevel.GetMesh()->GetMorphTarget()->GetVertexBuffer(); IndexBuffer *pIndexBuffer = cMeshLODLevel.GetIndexBuffer(); // Lock buffers if (!m_pParent) { if (!pIndexBuffer->Lock(Lock::ReadOnly)) return false; // Error! if (!pVertexBuffer->Lock(Lock::ReadOnly)) { // Unlock the index buffer pIndexBuffer->Unlock(); // Error! return false; } } // Init bounding box with the first vertex of the geometry Vector3 vBoundingBox[2]; { const Geometry &cGeometry = cMeshLODLevel.GetGeometries()->Get(m_pnGeometries[0]); for (int i=0; i<3; i++) { vBoundingBox[0][i] = vBoundingBox[1][i] = static_cast<float*>(pVertexBuffer->GetData(pIndexBuffer->GetData(cGeometry.GetStartIndex()), VertexBuffer::Position))[i]; } } // Get octree bounding box for (uint32 nGeometry=0; nGeometry<m_nNumOfGeometries; nGeometry++) { // Get geometry const Geometry &cGeometry = cMeshLODLevel.GetGeometries()->Get(m_pnGeometries[nGeometry]); // Add octree ID to the geometry octree list if (plstOctreeIDList) plstOctreeIDList->Get(m_pnGeometries[nGeometry])->Add(m_nID); // Loop through geometry vertices uint32 nIndex = cGeometry.GetStartIndex(); for (uint32 i=0; i<cGeometry.GetIndexSize(); i++) { const float *pfVertex = static_cast<const float*>(pVertexBuffer->GetData(pIndexBuffer->GetData(nIndex++), VertexBuffer::Position)); if (vBoundingBox[0].x > pfVertex[Vector3::X]) vBoundingBox[0].x = pfVertex[Vector3::X]; if (vBoundingBox[1].x < pfVertex[Vector3::X]) vBoundingBox[1].x = pfVertex[Vector3::X]; if (vBoundingBox[0].y > pfVertex[Vector3::Y]) vBoundingBox[0].y = pfVertex[Vector3::Y]; if (vBoundingBox[1].y < pfVertex[Vector3::Y]) vBoundingBox[1].y = pfVertex[Vector3::Y]; if (vBoundingBox[0].z > pfVertex[Vector3::Z]) vBoundingBox[0].z = pfVertex[Vector3::Z]; if (vBoundingBox[1].z < pfVertex[Vector3::Z]) vBoundingBox[1].z = pfVertex[Vector3::Z]; } } if (m_pParent) { // Adjust bounding box // Get parent center position const Vector3 &vPCenter = static_cast<MeshOctree*>(m_pParent)->m_vBBCenter; const Vector3 vPBBMin = static_cast<MeshOctree*>(m_pParent)->m_cBoundingBox.GetCorner1(); const Vector3 vPBBMax = static_cast<MeshOctree*>(m_pParent)->m_cBoundingBox.GetCorner2(); // Check octree sector switch (m_nIDOffset) { // 0. left top back case 0: if (vBoundingBox[0].x < vPBBMin.x) vBoundingBox[0].x = vPBBMin.x; if (vBoundingBox[1].x > vPCenter.x) vBoundingBox[1].x = vPCenter.x; if (vBoundingBox[0].y < vPCenter.y) vBoundingBox[0].y = vPCenter.y; if (vBoundingBox[1].y > vPBBMax.y) vBoundingBox[1].y = vPBBMax.y; if (vBoundingBox[0].z < vPBBMin.z) vBoundingBox[0].z = vPBBMin.z; if (vBoundingBox[1].z > vPCenter.z) vBoundingBox[1].z = vPCenter.z; break; // 1. right top back case 1: if (vBoundingBox[0].x < vPCenter.x) vBoundingBox[0].x = vPCenter.x; if (vBoundingBox[1].x > vPBBMax.x) vBoundingBox[1].x = vPBBMax.x; if (vBoundingBox[0].y < vPCenter.y) vBoundingBox[0].y = vPCenter.y; if (vBoundingBox[1].y > vPBBMax.y) vBoundingBox[1].y = vPBBMax.y; if (vBoundingBox[0].z < vPBBMin.z) vBoundingBox[0].z = vPBBMin.z; if (vBoundingBox[1].z > vPCenter.z) vBoundingBox[1].z = vPCenter.z; break; // 2. right top front case 2: if (vBoundingBox[0].x < vPCenter.x) vBoundingBox[0].x = vPCenter.x; if (vBoundingBox[1].x > vPBBMax.x) vBoundingBox[1].x = vPBBMax.x; if (vBoundingBox[0].y < vPCenter.y) vBoundingBox[0].y = vPCenter.y; if (vBoundingBox[1].y > vPBBMax.y) vBoundingBox[1].y = vPBBMax.y; if (vBoundingBox[0].z < vPCenter.z) vBoundingBox[0].z = vPCenter.z; if (vBoundingBox[1].z > vPBBMax.z) vBoundingBox[1].z = vPBBMax.z; break; // 3. left top front case 3: if (vBoundingBox[0].x < vPBBMin.x) vBoundingBox[0].x = vPBBMin.x; if (vBoundingBox[1].x > vPCenter.x) vBoundingBox[1].x = vPCenter.x; if (vBoundingBox[0].y < vPCenter.y) vBoundingBox[0].y = vPCenter.y; if (vBoundingBox[1].y > vPBBMax.y) vBoundingBox[1].y = vPBBMax.y; if (vBoundingBox[0].z < vPCenter.z) vBoundingBox[0].z = vPCenter.z; if (vBoundingBox[1].z > vPBBMax.z) vBoundingBox[1].z = vPBBMax.z; break; // 4. left bottom back case 4: if (vBoundingBox[0].x < vPBBMin.x) vBoundingBox[0].x = vPBBMin.x; if (vBoundingBox[1].x > vPCenter.x) vBoundingBox[1].x = vPCenter.x; if (vBoundingBox[0].y < vPBBMin.y) vBoundingBox[0].y = vPBBMin.y; if (vBoundingBox[1].y > vPCenter.y) vBoundingBox[1].y = vPCenter.y; if (vBoundingBox[0].z < vPBBMin.z) vBoundingBox[0].z = vPBBMin.z; if (vBoundingBox[1].z > vPCenter.z) vBoundingBox[1].z = vPCenter.z; break; // 5. right bottom back case 5: if (vBoundingBox[0].x < vPCenter.x) vBoundingBox[0].x = vPCenter.x; if (vBoundingBox[1].x > vPBBMax.x) vBoundingBox[1].x = vPBBMax.x; if (vBoundingBox[0].y < vPBBMin.y) vBoundingBox[0].y = vPBBMin.y; if (vBoundingBox[1].y > vPCenter.y) vBoundingBox[1].y = vPCenter.y; if (vBoundingBox[0].z < vPBBMin.z) vBoundingBox[0].z = vPBBMin.z; if (vBoundingBox[1].z > vPCenter.z) vBoundingBox[1].z = vPCenter.z; break; // 6. right bottom front case 6: if (vBoundingBox[0].x < vPCenter.x) vBoundingBox[0].x = vPCenter.x; if (vBoundingBox[1].x > vPBBMax.x) vBoundingBox[1].x = vPBBMax.x; if (vBoundingBox[0].y < vPBBMin.y) vBoundingBox[0].y = vPBBMin.y; if (vBoundingBox[1].y > vPCenter.y) vBoundingBox[1].y = vPCenter.y; if (vBoundingBox[0].z < vPCenter.z) vBoundingBox[0].z = vPCenter.z; if (vBoundingBox[1].z > vPBBMax.z) vBoundingBox[1].z = vPBBMax.z; break; // 7. left bottom front case 7: if (vBoundingBox[0].x < vPBBMin.x) vBoundingBox[0].x = vPBBMin.x; if (vBoundingBox[1].x > vPCenter.x) vBoundingBox[1].x = vPCenter.x; if (vBoundingBox[0].y < vPBBMin.y) vBoundingBox[0].y = vPBBMin.y; if (vBoundingBox[1].y > vPCenter.y) vBoundingBox[1].y = vPCenter.y; if (vBoundingBox[0].z < vPCenter.z) vBoundingBox[0].z = vPCenter.z; if (vBoundingBox[1].z > vPBBMax.z) vBoundingBox[1].z = vPBBMax.z; break; } } // Get octree center m_vBBCenter = (vBoundingBox[0]+vBoundingBox[1])/2; vBoundingBox[0] -= m_vBBCenter; vBoundingBox[1] -= m_vBBCenter; // Set octree bounding box m_cBoundingBox.SetPos(m_vBBCenter.x, m_vBBCenter.y, m_vBBCenter.z); m_cBoundingBox.SetSize(vBoundingBox[0].x, vBoundingBox[0].y, vBoundingBox[0].z, vBoundingBox[1].x, vBoundingBox[1].y, vBoundingBox[1].z); // [TODO] Clean this up // Check if the octree should be divided if (static_cast<signed>(m_nLevel) >= m_nSubdivide) { // if (m_nLevel >= m_nSubdivide || m_nNumOfGeometries < m_nMinGeometries) { // Unlock the buffers if (!m_pParent) { pIndexBuffer->Unlock(); pVertexBuffer->Unlock(); } // Done return true; } // Children uint32 nGeometriesT[8]; uint32 *pGeometriesT[8]; // Get the geometries in which are in the children for (int i=0; i<8; i++) { pGeometriesT[i] = new uint32[m_nNumOfGeometries]; MemoryManager::Set(pGeometriesT[i], -1, sizeof(uint32)*m_nNumOfGeometries); nGeometriesT[i] = 0; } for (uint32 nGeometry=0; nGeometry<m_nNumOfGeometries; nGeometry++) { // Get data uint32 nGeoID = m_pnGeometries[nGeometry]; const Geometry &cGeometry = cMeshLODLevel.GetGeometries()->Get(nGeoID); if (&cGeometry != &Array<Geometry>::Null) { // Loop through geometry vertices uint32 nIndex = cGeometry.GetStartIndex(); for (uint32 i=0; i<cGeometry.GetIndexSize(); i++) { // Get vertex float *pfVertex = static_cast<float*>(pVertexBuffer->GetData(pIndexBuffer->GetData(nIndex++), VertexBuffer::Position)); // Check in which octree sector the vertex is in // 0. left top back if ((!nGeometriesT[0] || pGeometriesT[0][nGeometriesT[0]-1] != nGeoID) && pfVertex[Vector3::X] <= m_vBBCenter.x && pfVertex[Vector3::Y] >= m_vBBCenter.y && pfVertex[Vector3::Z] <= m_vBBCenter.z) { pGeometriesT[0][nGeometriesT[0]] = nGeoID; nGeometriesT[0]++; } // 1. right top back if ((!nGeometriesT[1] || pGeometriesT[1][nGeometriesT[1]-1] != nGeoID) && pfVertex[Vector3::X] >= m_vBBCenter.x && pfVertex[Vector3::Y] >= m_vBBCenter.y && pfVertex[Vector3::Z] <= m_vBBCenter.z) { pGeometriesT[1][nGeometriesT[1]] = nGeoID; nGeometriesT[1]++; } // 2. right top front if ((!nGeometriesT[2] || pGeometriesT[2][nGeometriesT[2]-1] != nGeoID) && pfVertex[Vector3::X] >= m_vBBCenter.x && pfVertex[Vector3::Y] >= m_vBBCenter.y && pfVertex[Vector3::Z] >= m_vBBCenter.z) { pGeometriesT[2][nGeometriesT[2]] = nGeoID; nGeometriesT[2]++; } // 3. left top front if ((!nGeometriesT[3] || pGeometriesT[3][nGeometriesT[3]-1] != nGeoID) && pfVertex[Vector3::X] <= m_vBBCenter.x && pfVertex[Vector3::Y] >= m_vBBCenter.y && pfVertex[Vector3::Z] >= m_vBBCenter.z) { pGeometriesT[3][nGeometriesT[3]] = nGeoID; nGeometriesT[3]++; } // 4. left bottom back if ((!nGeometriesT[4] || pGeometriesT[4][nGeometriesT[4]-1] != nGeoID) && pfVertex[Vector3::X] <= m_vBBCenter.x && pfVertex[Vector3::Y] <= m_vBBCenter.y && pfVertex[Vector3::Z] <= m_vBBCenter.z) { pGeometriesT[4][nGeometriesT[4]] = nGeoID; nGeometriesT[4]++; } // 5. right bottom back if ((!nGeometriesT[5] || pGeometriesT[5][nGeometriesT[5]-1] != nGeoID) && pfVertex[Vector3::X] >= m_vBBCenter.x && pfVertex[Vector3::Y] <= m_vBBCenter.y && pfVertex[Vector3::Z] <= m_vBBCenter.z) { pGeometriesT[5][nGeometriesT[5]] = nGeoID; nGeometriesT[5]++; } // 6. right bottom front if ((!nGeometriesT[6] || pGeometriesT[6][nGeometriesT[6]-1] != nGeoID) && pfVertex[Vector3::X] >= m_vBBCenter.x && pfVertex[Vector3::Y] <= m_vBBCenter.y && pfVertex[Vector3::Z] >= m_vBBCenter.z) { pGeometriesT[6][nGeometriesT[6]] = nGeoID; nGeometriesT[6]++; } // 7. left bottom front if ((!nGeometriesT[7] || pGeometriesT[7][nGeometriesT[7]-1] != nGeoID) && pfVertex[Vector3::X] <= m_vBBCenter.x && pfVertex[Vector3::Y] <= m_vBBCenter.y && pfVertex[Vector3::Z] >= m_vBBCenter.z) { pGeometriesT[7][nGeometriesT[7]] = nGeoID; nGeometriesT[7]++; } } } } // Get number of children m_nNumOfChildren = 0; for (int i=0; i<8; i++) { if (nGeometriesT[i]) // if (nGeometriesT[i] >= m_nMinGeometries) m_nNumOfChildren++; } if (m_nNumOfChildren) { // Create children uint32 nChild = 0; m_ppChild = new Octree*[m_nNumOfChildren]; for (int i=0; i<8; i++) { if (nGeometriesT[i]) { // if (nGeometriesT[i] >= m_nMinGeometries) { // Build child m_ppChild[nChild] = new MeshOctree(); m_ppChild[nChild]->Init(this, m_nSubdivide, m_nMinGeometries, i); static_cast<MeshOctree*>(m_ppChild[nChild])->Build(cMeshLODLevel, nGeometriesT[i], pGeometriesT[i], plstOctreeIDList); nChild++; } } } // Delete temp child data for (int i=0; i<8; i++) delete [] pGeometriesT[i]; // Unlock the buffers if (!m_pParent) { pIndexBuffer->Unlock(); pVertexBuffer->Unlock(); } // Done return true; }
//[-------------------------------------------------------] //[ Public virtual SPK::BufferHandler functions ] //[-------------------------------------------------------] void SPK_PLQuadRenderer::createBuffers(const SPK::Group &group) { // Create the SPK_PLBuffer instance m_pSPK_PLBuffer = static_cast<SPK_PLBuffer*>(group.createBuffer(PLBufferName, PLBufferCreator(GetPLRenderer(), NumOfVerticesPerParticle, NumOfIndicesPerParticle, texturingMode), 0U, false)); // Is there a valid m_pSPK_PLBuffer instance? if (m_pSPK_PLBuffer && m_pSPK_PLBuffer->GetVertexBuffer()) { switch (texturingMode) { case SPK::TEXTURE_2D: if (!group.getModel()->isEnabled(SPK::PARAM_TEXTURE_INDEX)) { // Get the vertex buffer instance from m_pSPK_PLBuffer and lock it VertexBuffer *pVertexBuffer = m_pSPK_PLBuffer->GetVertexBuffer(); if (pVertexBuffer->Lock(Lock::WriteOnly)) { // Set correct data const uint32 nVertexSize = pVertexBuffer->GetVertexSize(); float *pfTexCoord = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::TexCoord)); for (size_t i=0; i<group.getParticles().getNbReserved(); i++) { // Top right vertex pfTexCoord[0] = 1.0f; pfTexCoord[1] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Top left vertex pfTexCoord[0] = 0.0f; pfTexCoord[1] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Bottom left pfTexCoord[0] = 0.0f; pfTexCoord[1] = 1.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Bottom right pfTexCoord[0] = 1.0f; pfTexCoord[1] = 1.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! } // Unlock the vertex buffer pVertexBuffer->Unlock(); } } break; case SPK::TEXTURE_3D: { // Get the vertex buffer instance from m_pSPK_PLBuffer and lock it VertexBuffer *pVertexBuffer = m_pSPK_PLBuffer->GetVertexBuffer(); if (pVertexBuffer->Lock(Lock::WriteOnly)) { // Set correct data const uint32 nVertexSize = pVertexBuffer->GetVertexSize(); float *pfTexCoord = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::TexCoord)); for (size_t i=0; i<group.getParticles().getNbReserved(); i++) { // Top right vertex pfTexCoord[0] = 1.0f; pfTexCoord[1] = 0.0f; pfTexCoord[2] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Top left vertex pfTexCoord[0] = 0.0f; pfTexCoord[1] = 0.0f; pfTexCoord[2] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Bottom left pfTexCoord[0] = 0.0f; pfTexCoord[1] = 1.0f; pfTexCoord[2] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! // Bottom right pfTexCoord[0] = 1.0f; pfTexCoord[1] = 1.0f; pfTexCoord[2] = 0.0f; pfTexCoord = reinterpret_cast<float*>(reinterpret_cast<char*>(pfTexCoord) + nVertexSize); // Next, please! } // Unlock the vertex buffer pVertexBuffer->Unlock(); } break; } } } // Is there a valid m_pSPK_PLBuffer instance? if (m_pSPK_PLBuffer && m_pSPK_PLBuffer->GetIndexBuffer()) { // Get the index buffer instance from m_pSPK_PLBuffer and lock it IndexBuffer *pIndexBuffer = m_pSPK_PLBuffer->GetIndexBuffer(); if (pIndexBuffer && pIndexBuffer->Lock(Lock::WriteOnly)) { // Fill the index buffer with valid data for (uint32 i=0, nVertices=4, nIndex=0; i<group.getParticles().getNbReserved(); i++, nVertices+=4) { // Triangle 1 pIndexBuffer->SetData(nIndex++, nVertices-4); pIndexBuffer->SetData(nIndex++, nVertices-3); pIndexBuffer->SetData(nIndex++, nVertices-2); // Triangle 2 pIndexBuffer->SetData(nIndex++, nVertices-4); pIndexBuffer->SetData(nIndex++, nVertices-2); pIndexBuffer->SetData(nIndex++, nVertices-1); } // Unlock the index buffer pIndexBuffer->Unlock(); } } }
void RenderManager::DrawTextPrivate() { if(enqueuedTextData.size() == 0) return; gRenderAPI->BeginPerfEvent("RenderText"); for(int fnt=0; fnt<FONT_MaxSupported; fnt++) { // Calculate number of quads to render int numQuads = 0; for(vector<TextRenderData>::const_iterator it=enqueuedTextData.begin(); it != enqueuedTextData.end(); it++) { if(it->useFont == fnt) numQuads += it->text.length(); } if(numQuads == 0) continue; // Create vertex buffer VertexBuffer* textVB = gRenderAPI->CreateVertexBuffer(VFMT_P3C3U2, numQuads*4, NULL, true); VertexContainer_P3C3U2* pData = (VertexContainer_P3C3U2*)textVB->Lock(); float fontHeightNDC, fontWidthNDC; for(vector<TextRenderData>::const_iterator it=enqueuedTextData.begin(); it != enqueuedTextData.end(); it++) { const TextRenderData& data = *it; if(data.useFont == fnt) { // Convert font height from pixel units to NDC units fontHeightNDC = 2*data.size/fullScreenBufferSizeY; // The current position of the render cursor float renderCursorX = data.posX; // Font used BitmapFont* font = engineFonts[data.useFont]; // Font color ColorVector color = data.color; // Text to render const string& renderText = data.text; for(unsigned int i=0; i<renderText.length(); i++) { BitmapFont::CharDescriptor charData = font->GetData(renderText.at(i), data.bBold); fontWidthNDC = charData.aspectRatio * fontHeightNDC; pData->px = renderCursorX; pData->py = data.posY; pData->pz = 0.f; pData->cx = color.r; pData->cy = color.g; pData->cz = color.b; pData->u = charData.u1; pData->v = charData.v1; pData++; pData->px = renderCursorX + fontWidthNDC; pData->py = data.posY; pData->pz = 0.f; pData->cx = color.r; pData->cy = color.g; pData->cz = color.b; pData->u = charData.u2; pData->v = charData.v1; pData++; pData->px = renderCursorX + fontWidthNDC; pData->py = data.posY - fontHeightNDC; pData->pz = 0.f; pData->cx = color.r; pData->cy = color.g; pData->cz = color.b; pData->u = charData.u2; pData->v = charData.v2; pData++; pData->px = renderCursorX; pData->py = data.posY - fontHeightNDC; pData->pz = 0.f; pData->cx = color.r; pData->cy = color.g; pData->cz = color.b; pData->u = charData.u1; pData->v = charData.v2; pData++; renderCursorX += fontWidthNDC; } } } textVB->Unlock(); // Create index buffer IndexBuffer* textIB = gRenderAPI->CreateIndexBuffer(IFMT_16Bit, numQuads*6, NULL, true); short* iData = (short*)textIB->Lock(); int offset = 0; for(unsigned int i=0; i<enqueuedTextData.size(); i++) { if(enqueuedTextData.at(i).useFont == fnt) { for(unsigned int j=0; j<enqueuedTextData.at(i).text.length(); j++) { *iData = offset + 4*j + 0; iData++; *iData = offset + 4*j + 1; iData++; *iData = offset + 4*j + 3; iData++; *iData = offset + 4*j + 2; iData++; *iData = offset + 4*j + 3; iData++; *iData = offset + 4*j + 1; iData++; } offset += 4*enqueuedTextData.at(i).text.length(); } } textIB->Unlock(); // Vertex shader VertexShader* vShader = gRenderManager.GetPassthroughShader(VFMT_P3C3U2, INTERPOLANT_MeshUV | INTERPOLANT_MeshColor); vShader->Bind(); // Pixel shader simpleFontPixelShader->SetValues(engineFonts[fnt]->GetTexture(), SamplerState::TrilinearWrap); simpleFontPixelShader->Bind(); gRenderAPI->SetVertexBuffer(0, textVB); gRenderAPI->SetIndexBuffer(textIB); gRenderAPI->DrawIndexed(TOPOLOGY_TriangleList, numQuads*2); // Clean up the buffers gRenderAPI->DestroyVertexBuffer(textVB); gRenderAPI->DestroyIndexBuffer(textIB); } gRenderAPI->EndPerfEvent(); }
//[-------------------------------------------------------] //[ Private virtual MeshCreator functions ] //[-------------------------------------------------------] Mesh *MeshCreatorCube::Create(Mesh &cMesh, uint32 nLODLevel, bool bStatic) const { // Call base implementation MeshCreator::Create(cMesh, nLODLevel, bStatic); // Get dimension and offset const Vector3 &vDimension = Dimension.Get(); const Vector3 &vOffset = Offset.Get(); // Get morph target MeshMorphTarget *pMorphTarget = cMesh.GetMorphTarget(0); if (pMorphTarget && pMorphTarget->GetVertexBuffer()) { VertexBuffer *pVertexBuffer = pMorphTarget->GetVertexBuffer(); if (TexCoords || Normals) { // Allocate data pVertexBuffer->AddVertexAttribute(VertexBuffer::Position, 0, VertexBuffer::Float3); if (TexCoords) pVertexBuffer->AddVertexAttribute(VertexBuffer::TexCoord, 0, VertexBuffer::Float2); if (Normals) pVertexBuffer->AddVertexAttribute(VertexBuffer::Normal, 0, VertexBuffer::Float3); pVertexBuffer->Allocate(24, bStatic ? Usage::Static : Usage::Dynamic); if (pVertexBuffer->Lock(Lock::WriteOnly)) { // Setup vertices // x-positive (0) // 0 float *pfVertices = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 1 pfVertices = static_cast<float*>(pVertexBuffer->GetData(1, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 2 pfVertices = static_cast<float*>(pVertexBuffer->GetData(2, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 3 pfVertices = static_cast<float*>(pVertexBuffer->GetData(3, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // x-negative (1) // 4 pfVertices = static_cast<float*>(pVertexBuffer->GetData(4, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 5 pfVertices = static_cast<float*>(pVertexBuffer->GetData(5, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 6 pfVertices = static_cast<float*>(pVertexBuffer->GetData(6, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 7 pfVertices = static_cast<float*>(pVertexBuffer->GetData(7, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // y-positive (2) // 8 pfVertices = static_cast<float*>(pVertexBuffer->GetData(8, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 9 pfVertices = static_cast<float*>(pVertexBuffer->GetData(9, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 10 pfVertices = static_cast<float*>(pVertexBuffer->GetData(10, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 11 pfVertices = static_cast<float*>(pVertexBuffer->GetData(11, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // y-negative (3) // 12 pfVertices = static_cast<float*>(pVertexBuffer->GetData(12, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 13 pfVertices = static_cast<float*>(pVertexBuffer->GetData(13, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 14 pfVertices = static_cast<float*>(pVertexBuffer->GetData(14, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 15 pfVertices = static_cast<float*>(pVertexBuffer->GetData(15, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // z-positive (4) // 16 pfVertices = static_cast<float*>(pVertexBuffer->GetData(16, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 17 pfVertices = static_cast<float*>(pVertexBuffer->GetData(17, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 18 pfVertices = static_cast<float*>(pVertexBuffer->GetData(18, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 19 pfVertices = static_cast<float*>(pVertexBuffer->GetData(19, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // z-negative (5) // 20 pfVertices = static_cast<float*>(pVertexBuffer->GetData(20, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 21 pfVertices = static_cast<float*>(pVertexBuffer->GetData(21, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 22 pfVertices = static_cast<float*>(pVertexBuffer->GetData(22, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 23 pfVertices = static_cast<float*>(pVertexBuffer->GetData(23, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // Setup texture coordinates if (TexCoords) { for (int nSide=0; nSide<6; nSide++) { // 0 pfVertices = static_cast<float*>(pVertexBuffer->GetData(0+nSide*4, VertexBuffer::TexCoord)); pfVertices[Vector2::X] = 1.0f; pfVertices[Vector2::Y] = 0.0f; // 1 pfVertices = static_cast<float*>(pVertexBuffer->GetData(1+nSide*4, VertexBuffer::TexCoord)); pfVertices[Vector2::X] = 0.0f; pfVertices[Vector2::Y] = 0.0f; // 2 pfVertices = static_cast<float*>(pVertexBuffer->GetData(2+nSide*4, VertexBuffer::TexCoord)); pfVertices[Vector2::X] = 0.0f; pfVertices[Vector2::Y] = 1.0f; // 3 pfVertices = static_cast<float*>(pVertexBuffer->GetData(3+nSide*4, VertexBuffer::TexCoord)); pfVertices[Vector2::X] = 1.0f; pfVertices[Vector2::Y] = 1.0f; } } // Setup normal vectors if (Normals) { // x-positive (0) SetNormals(*pVertexBuffer, 0, 1.0f, 0.0f, 0.0f); // x-negative (1) SetNormals(*pVertexBuffer, 1, -1.0f, 0.0f, 0.0f); // y-positive (2) SetNormals(*pVertexBuffer, 2, 0.0f, 1.0f, 0.0f); // y-negative (3) SetNormals(*pVertexBuffer, 3, 0.0f, -1.0f, 0.0f); // z-positive (4) SetNormals(*pVertexBuffer, 4, 0.0f, 0.0f, 1.0f); // z-negative (5) SetNormals(*pVertexBuffer, 5, 0.0f, 0.0f, -1.0f); } // Unlock the vertex buffer pVertexBuffer->Unlock(); } // Get LOD level MeshLODLevel *pLODLevel = cMesh.GetLODLevel(nLODLevel); if (pLODLevel && pLODLevel->GetIndexBuffer()) { // Allocate and setup index buffer IndexBuffer *pIndexBuffer = pLODLevel->GetIndexBuffer(); pIndexBuffer->SetElementTypeByMaximumIndex(pVertexBuffer->GetNumOfElements()-1); pIndexBuffer->Allocate(24, bStatic ? Usage::Static : Usage::Dynamic); if (pIndexBuffer->Lock(Lock::WriteOnly)) { for (int nSide=0; nSide<6; nSide++) { if (Order) { pIndexBuffer->SetData(nSide*4+0, nSide*4+3-2); pIndexBuffer->SetData(nSide*4+1, nSide*4+3-3); pIndexBuffer->SetData(nSide*4+2, nSide*4+3-1); pIndexBuffer->SetData(nSide*4+3, nSide*4+3-0); } else { pIndexBuffer->SetData(nSide*4+0, nSide*4+3-1); pIndexBuffer->SetData(nSide*4+1, nSide*4+3-0); pIndexBuffer->SetData(nSide*4+2, nSide*4+3-2); pIndexBuffer->SetData(nSide*4+3, nSide*4+3-3); } } // Unlock the index buffer pIndexBuffer->Unlock(); } // Create the geometries Array<Geometry> &lstGeometries = *pLODLevel->GetGeometries(); for (int i=0; i<6; i++) { Geometry &cGeometry = lstGeometries.Add(); cGeometry.SetPrimitiveType(Primitive::TriangleStrip); cGeometry.SetStartIndex(i*4); cGeometry.SetIndexSize(4); if (MultiMaterials && i) { cMesh.AddMaterial(cMesh.GetRenderer()->GetRendererContext().GetMaterialManager().Create()); cGeometry.SetMaterial(i); } } } } else { // No texture coordinates // Allocate and setup data pVertexBuffer->AddVertexAttribute(VertexBuffer::Position, 0, VertexBuffer::Float3); pVertexBuffer->Allocate(8, bStatic ? Usage::Static : Usage::Dynamic); if (pVertexBuffer->Lock(Lock::WriteOnly)) { // Setup vertices // 0 float *pfVertices = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 1 pfVertices = static_cast<float*>(pVertexBuffer->GetData(1, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 2 pfVertices = static_cast<float*>(pVertexBuffer->GetData(2, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 3 pfVertices = static_cast<float*>(pVertexBuffer->GetData(3, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 4 pfVertices = static_cast<float*>(pVertexBuffer->GetData(4, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 5 pfVertices = static_cast<float*>(pVertexBuffer->GetData(5, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = -vDimension.z + vOffset.z; // 6 pfVertices = static_cast<float*>(pVertexBuffer->GetData(6, VertexBuffer::Position)); pfVertices[Vector3::X] = vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // 7 pfVertices = static_cast<float*>(pVertexBuffer->GetData(7, VertexBuffer::Position)); pfVertices[Vector3::X] = -vDimension.x + vOffset.x; pfVertices[Vector3::Y] = -vDimension.y + vOffset.y; pfVertices[Vector3::Z] = vDimension.z + vOffset.z; // Unlock the vertex buffer pVertexBuffer->Unlock(); } // Get LOD level MeshLODLevel *pLODLevel = cMesh.GetLODLevel(nLODLevel); if (pLODLevel) { // Allocate and setup index buffer IndexBuffer *pIndexBuffer = pLODLevel->GetIndexBuffer(); pIndexBuffer->SetElementTypeByMaximumIndex(pVertexBuffer->GetNumOfElements()-1); pIndexBuffer->Allocate(24, bStatic ? Usage::Static : Usage::Dynamic); if (pIndexBuffer->Lock(Lock::WriteOnly)) { if (Order) { // Left pIndexBuffer->SetData(0, 7); pIndexBuffer->SetData(1, 4); pIndexBuffer->SetData(2, 3); pIndexBuffer->SetData(3, 0); // Front pIndexBuffer->SetData(4, 1); pIndexBuffer->SetData(5, 0); pIndexBuffer->SetData(6, 5); pIndexBuffer->SetData(7, 4); // Right pIndexBuffer->SetData(8, 5); pIndexBuffer->SetData(9, 6); pIndexBuffer->SetData(10, 1); pIndexBuffer->SetData(11, 2); // Back pIndexBuffer->SetData(12, 6); pIndexBuffer->SetData(13, 7); pIndexBuffer->SetData(14, 2); pIndexBuffer->SetData(15, 3); // Top pIndexBuffer->SetData(16, 2); pIndexBuffer->SetData(17, 3); pIndexBuffer->SetData(18, 1); pIndexBuffer->SetData(19, 0); // Bottom pIndexBuffer->SetData(20, 5); pIndexBuffer->SetData(21, 4); pIndexBuffer->SetData(22, 6); pIndexBuffer->SetData(23, 7); } else { // Left pIndexBuffer->SetData(0, 3); pIndexBuffer->SetData(1, 0); pIndexBuffer->SetData(2, 7); pIndexBuffer->SetData(3, 4); // Front pIndexBuffer->SetData(4, 5); pIndexBuffer->SetData(5, 4); pIndexBuffer->SetData(6, 1); pIndexBuffer->SetData(7, 0); // Right pIndexBuffer->SetData(8, 1); pIndexBuffer->SetData(9, 2); pIndexBuffer->SetData(10, 5); pIndexBuffer->SetData(11, 6); // Back pIndexBuffer->SetData(12, 2); pIndexBuffer->SetData(13, 3); pIndexBuffer->SetData(14, 6); pIndexBuffer->SetData(15, 7); // Top pIndexBuffer->SetData(16, 1); pIndexBuffer->SetData(17, 0); pIndexBuffer->SetData(18, 2); pIndexBuffer->SetData(19, 3); // Bottom pIndexBuffer->SetData(20, 6); pIndexBuffer->SetData(21, 7); pIndexBuffer->SetData(22, 5); pIndexBuffer->SetData(23, 4); } // Unlock the index buffer pIndexBuffer->Unlock(); } // Create the geometries Array<Geometry> &lstGeometries = *pLODLevel->GetGeometries(); for (int i=0; i<6; i++) { Geometry &cGeometry = lstGeometries.Add(); cGeometry.SetPrimitiveType(Primitive::TriangleStrip); cGeometry.SetStartIndex(i*4); cGeometry.SetIndexSize(4); } } } } // Return the created mesh return &cMesh; }