DWORD CIndexBufferManager::OnAllocateIndices(DWORD size, void *params) { ALLOCATERENDERBUFFERMSG * pmsg; VERIFY_MESSAGE_SIZE( size, sizeof( ALLOCATERENDERBUFFERMSG ) ); pmsg = (ALLOCATERENDERBUFFERMSG*)params; //create the allocation //find out if we have a buffer to accomodate the vertex type //find the FVF in our array DWORD tempFVF = pmsg->SizeVertexFormat;//CRenderer::CreateVertexBuffer(); DWORD VBIndex = -1; INDEXBUFFER_MAP::iterator iterf = m_IndexBufferMap.find( tempFVF ); if( iterf == m_IndexBufferMap.end() ) { //format not found, create new entry IIndexBuffer * newIB = m_Renderer->CreateIndexBuffer(); newIB->Resize( m_DefaultIBSize ); IBAllocationDescriptor desc; desc.m_FreeSpace.insert( IBALLOCATIONDESCPAIR( m_DefaultIBSize, 0 ) ); desc.m_IB = newIB; m_IndexBufferMap[ tempFVF ].push_back( desc ); VBIndex = 0; } else { //check full, not done VBIndex = 0; } //now get an allocation block //find a size that fits VBALLOCATIONDESC_MAP::iterator iter = m_IndexBufferMap[ tempFVF ][ VBIndex ].m_FreeSpace.end(); do//kind of weird since we're iterating backward { iter--; DWORD AvailableSize = (*iter).first; if( AvailableSize > pmsg->ElementsToAllocate ) { //use this iterator DWORD curOffset = (*iter).second; //create an allocation block: m_IndexBufferAllocations[ m_LastCreatedHandle ].m_AllocationHandle = m_LastCreatedHandle; m_IndexBufferAllocations[ m_LastCreatedHandle ].m_Offset = curOffset; m_IndexBufferAllocations[ m_LastCreatedHandle ].m_Size = pmsg->SizeVertexFormat; m_IndexBufferAllocations[ m_LastCreatedHandle ].m_Stride = tempFVF; m_IndexBufferAllocations[ m_LastCreatedHandle ].m_InterfaceHandle = VBIndex; pmsg->m_ReturnHandle = m_LastCreatedHandle; pmsg->m_ReturnOffset = curOffset; pmsg->m_ReturnInterfaceHandle = VBIndex; m_LastCreatedHandle++; m_IndexBufferMap[ tempFVF ][ VBIndex ].m_FreeSpace.erase( iter ); m_IndexBufferMap[ tempFVF ][ VBIndex ].m_FreeSpace.insert( VBALLOCATIONDESCPAIR( AvailableSize - pmsg->ElementsToAllocate, curOffset + pmsg->ElementsToAllocate ) ); } } while( iter != m_IndexBufferMap[ tempFVF ][ VBIndex ].m_FreeSpace.begin() ); return MSG_HANDLED; }
//! read indices void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices) { indices.reallocate(indexCount); core::stringc data = reader->getNodeData(); const c8* p = &data[0]; for (int i=0; i<indexCount && *p; ++i) { findNextNoneWhiteSpace(&p); indices.push_back(readInt(&p)); } }
Mesh* LineBatcher::Render() { #if BUILD_RELEASE if (m_IsDebug) { return nullptr; } #endif if (0 == m_Positions.Size()) { return nullptr; } IVertexBuffer* VertexBuffer = m_Renderer->CreateVertexBuffer(); IVertexDeclaration* VertexDeclaration = m_Renderer->GetVertexDeclaration(VD_POSITIONS | VD_COLORS); IIndexBuffer* IndexBuffer = m_Renderer->CreateIndexBuffer(); IVertexBuffer::SInit InitStruct; InitStruct.NumVertices = m_Positions.Size(); InitStruct.Positions = m_Positions.GetData(); InitStruct.Colors = m_Colors.GetData(); VertexBuffer->Init(InitStruct); IndexBuffer->Init(m_Indices.Size(), m_Indices.GetData()); IndexBuffer->SetPrimitiveType(EPT_LINELIST); auto LinesMesh = new Mesh(VertexBuffer, VertexDeclaration, IndexBuffer); #if BUILD_DEBUG LinesMesh->m_Name = "LineBatch"; LinesMesh->m_IsDebugMesh = m_IsDebug; #endif LinesMesh->SetMaterialDefinition(DEFAULT_NEWMATERIAL, m_Renderer); LinesMesh->SetTexture(0, m_Renderer->GetTextureManager()->GetTexture( DEFAULT_TEXTURE, TextureManager::ETL_Permanent)); LinesMesh->SetMaterialFlags(m_MaterialFlags); m_Renderer->AddMesh(LinesMesh); // Reset everything to its starting state m_Positions.Clear(); m_Colors.Clear(); m_Indices.Clear(); return LinesMesh; }
//For each material grouped in each input layout create batch vertex buffer xst_stl_foreach( Itr, m_vSubGroups ) { IVertexBuffer* pVB; IIndexBuffer* pIB; (*Itr).m_pVertexBuffer = pMeshMgr->GetRenderSystem()->CreateVertexBuffer(); (*Itr).m_pIndexBuffer = pMeshMgr->GetRenderSystem()->CreateIndexBuffer(); pVB = (*Itr).m_pVertexBuffer; pVB->SetInputLayout( (*Itr).m_pInputLayout ); pVB->SetTopologyType( TopologyTypes::TRIANGLE_LIST ); pVB->SetUsage( BufferUsages::DEFAULT ); pVB->SetVertexCount( (*Itr).m_ulVertexCount ); pIB = (*Itr).m_pIndexBuffer; pIB->SetUsage( BufferUsages::DEFAULT ); pIB->SetIndexCount( (*Itr).m_ulIndexCount ); pVB->Lock(); pIB->Lock(); CVertexData& VData = pVB->GetVertexData(); CIndexData& IData = pIB->GetIndexData(); const IInputLayout* pIL = (*Itr).m_pInputLayout; ul32 ulCurrVertex = 0; ul32 ulCurrIndexCount = 0; ul32 ulCurrVertexCount = 0; ul32 ulCurrIndex = 0; ul32 ulStartVertex = 0; u16 usStartIndex = 0; for(u32 i = 0; i < (*Itr).m_vObjects.size(); ++i) { CVertexData& TmpVData = (*Itr).m_vObjects[ i ].m_pMesh->GetVertexBuffer()->GetVertexData(); CIndexData& TmpIData = (*Itr).m_vObjects[ i ].m_pMesh->GetIndexBuffer()->GetIndexData(); ulStartVertex = ulCurrVertex; //Set vertices for(u32 v = 0; v < TmpVData.GetVertexCount(); ++v) { if( pIL->IsPosition() ) { TmpVData.GetPosition( v, &vecTmp3 ); VData.SetPosition( ulCurrVertex, vecTmp3 + (*Itr).m_vObjects[ i ].m_vecPosition ); } if( pIL->IsColor() ) { TmpVData.GetColor( v, &vecTmp4 ); VData.SetColor( ulCurrVertex, vecTmp4 ); } //Increment current vertex ++ulCurrVertex; } if( pCurrMat != (*Itr).m_vObjects[ i ].m_pMaterial ) { pCurrMat = (*Itr).m_vObjects[ i ].m_pMaterial; //Create batch CDynamicGeometryBatch Batch; Batch.m_usBeginIndex = (u16)ulCurrIndex; Batch.m_ulIndexCount = TmpIData.GetIndexCount(); Batch.m_pMaterial = pCurrMat; (*Itr).m_vBatches.push_back( Batch ); pCurrBatch = &(*Itr).m_vBatches.back(); } usStartIndex = (u16)ulCurrIndex; //Set indices for(u32 id = 0; id < TmpIData.GetIndexCount(); ++id) { u16 usIndex = TmpIData.GetIndex( id ) + ulCurrVertexCount; IData.SetIndex( ulCurrIndex++, TmpIData.GetIndex( id ) + ulCurrVertexCount ); } pCurrBatch->m_ulIndexCount = ulCurrIndex; ulCurrVertexCount = ulCurrVertex; (*Itr).m_vObjects[ i ].m_ulBeginVertex = ulStartVertex; (*Itr).m_vObjects[ i ].m_ulVertexCount = TmpVData.GetVertexCount(); (*Itr).m_vObjects[ i ].m_usBeginIndex = usStartIndex; (*Itr).m_vObjects[ i ].m_ulIndexCount = TmpIData.GetIndexCount(); (*Itr).m_vObjects[ i ].m_ulGroupId = this->m_ulID; (*Itr).m_vObjects[ i ].m_ulSubGroupId = ulCurrSubGroupId; xst_assert2( m_OnObjectBuild != xst_null ); CDynamicGeometryObject* pObj = &(*Itr).m_vObjects[ i ]; m_OnObjectBuild( (*Itr).m_vUserDatas[ i ], pObj ); //GUI::CComponent* pCmp = (GUI::CComponent*)(*Itr).m_vUserDatas[ i ]; } pVB->Unlock(); pVB->Create(); pIB->Unlock(); pIB->Create(); ++ulCurrSubGroupId; //Clear object buffer (*Itr).m_vObjects.clear(); }
void MeshParameterization::AddVertexSoup( RENDERBUFFERALLOCATION * renderbuffer, bool onlyIndices ) { if( renderbuffer) { // calculate the bbox HRESULT hr; Vec3 current; int numVerts = renderbuffer->m_VertexAllocation.m_Size; int stride = renderbuffer->m_VertexAllocation.m_Stride; int numIndices = renderbuffer->m_IndexAllocation.m_Size; m_CollapsedMesh->reserve( numVerts ); m_Faces->reserve( numIndices/3 ); BYTE* pVertex = NULL; static CHashString vp3(_T("MESH_STREAM_VERTEX_POSITION3")); int positionoffset = 0; int uvoffset = 0; int normalOffset = 0; int vertexFormatSize = renderbuffer->m_VertexAllocation.VertexFormat.size(); for( int i = 0; i < vertexFormatSize; i++ ) { ChannelDesc desc = renderbuffer->m_VertexAllocation.VertexFormat[i]; if( desc.ChannelHash == vp3.GetUniqueID() ) { break; } positionoffset += renderbuffer->m_VertexAllocation.VertexFormat[ i ].Stride; } static CHashString tc1(_T("MESH_STREAM_VERTEX_TEXTURECOORD1")); for( int i = 0; i < vertexFormatSize; i++ ) { ChannelDesc desc = renderbuffer->m_VertexAllocation.VertexFormat[i]; if( desc.ChannelHash == tc1.GetUniqueID() ) { break; } uvoffset += renderbuffer->m_VertexAllocation.VertexFormat[ i ].Stride; } static CHashString nrm(_T("MESH_STREAM_VERTEX_NORMAL")); for( int i = 0; i < vertexFormatSize; i++ ) { ChannelDesc desc = renderbuffer->m_VertexAllocation.VertexFormat[i]; if( desc.ChannelHash == nrm.GetUniqueID() ) { break; } normalOffset += renderbuffer->m_VertexAllocation.VertexFormat[ i ].Stride; } if( !onlyIndices ) { IVertexBufferObject * vb = renderbuffer->m_VertexBufferInterface; if( !vb )return; ParameterizationVertex curVert; hr = vb->Lock( renderbuffer->m_VertexAllocation.m_Offset, renderbuffer->m_VertexAllocation.m_Size, (void**)&pVertex ); if( pVertex != NULL ) { for( int i=0; i < numVerts; i++ ) { BYTE* posbyte = pVertex; BYTE* uvByte = pVertex; BYTE* normalByte = pVertex; normalByte += normalOffset; posbyte += positionoffset; uvByte += uvoffset; float* curpos = (float *)posbyte; float * curUv = (float*)uvByte; float * normal = (float*)normalByte; curVert.originalPosition.x = curpos[0]; curVert.originalPosition.y = curpos[1]; curVert.originalPosition.z = curpos[2]; tmin.x = min( curVert.originalPosition.x, tmin.x ); tmin.y = min( curVert.originalPosition.y, tmin.y ); tmin.z = min( curVert.originalPosition.z, tmin.z ); tmax.x = max( curVert.originalPosition.x, tmax.x ); tmax.y = max( curVert.originalPosition.y, tmax.y ); tmax.z = max( curVert.originalPosition.z, tmax.z ); curVert.generatedU = curUv[ 0 ]; curVert.generatedV = curUv[ 1 ]; curVert.originalU = curUv[ 0 ]; curVert.originalV = curUv[ 1 ]; curVert.normal.x = normal[0]; curVert.normal.y = normal[1]; curVert.normal.z = normal[2]; m_CollapsedMesh->push_back( curVert ); pVertex += renderbuffer->m_VertexBufferInterface->GetStride(); } } vb->Unlock(); } //do index buffers IIndexBuffer * ib = renderbuffer->m_IndexBufferInterface; if( !ib )return; TriangleFace curTri; IMaterial * mat = renderbuffer->m_Material; DWORD textureID = 0; if( mat ) { IBaseTextureObject * basetexture = mat->GetTexture(0,0); textureID = (DWORD)basetexture; } hr = ib->Lock( renderbuffer->m_IndexAllocation.m_Offset, renderbuffer->m_IndexAllocation.m_Size, (void**)&pVertex ); if( pVertex != NULL ) { for( int i=0; i < numIndices/3; i++ ) { BYTE* posbyte = pVertex; short * pShort = (short*)pVertex; curTri.index[ 0 ] = pShort[0]; curTri.index[ 1 ] = pShort[1]; curTri.index[ 2 ] = pShort[2]; curTri.m_Texture = textureID; pVertex += sizeof( short )*3; m_Faces->push_back( curTri ); } } ib->Unlock(); //Add texture if not already there ITextureObject * texture = NULL; IMaterial * curMat = renderbuffer->m_Material; if( curMat ) { IBaseTextureObject * baseTexture = curMat->GetTexture(0,0); texture = dynamic_cast< ITextureObject* >( baseTexture ); if( texture ) { m_MaterialTextures.insert( texture ); } } } }