///////////////////////////////////////////////////////////////////////////////////////////////////////////// // InitModel: setup model from given geometry bool CModel::InitModel(const CModelDefPtr& modeldef) { // clean up any existing data first ReleaseData(); m_pModelDef = modeldef; size_t numBones = modeldef->GetNumBones(); if (numBones != 0) { size_t numBlends = modeldef->GetNumBlends(); // allocate matrices for bone transformations // (one extra matrix is used for the special case of bind-shape relative weighting) m_BoneMatrices = (CMatrix3D*)rtl_AllocateAligned(sizeof(CMatrix3D) * (numBones + 1 + numBlends), 16); for (size_t i = 0; i < numBones + 1 + numBlends; ++i) { m_BoneMatrices[i].SetIdentity(); } } m_PositionValid = true; return true; }
UniqueRange Allocate(size_t size, size_t alignment) { ENSURE(is_pow2(alignment)); if(alignment <= (size_t)idxDeleterBits) alignment = idxDeleterBits+1; const size_t alignedSize = round_up(size, alignment); const UniqueRange::pointer p = rtl_AllocateAligned(alignedSize, alignment); return RVALUE(UniqueRange(p, size, idxDeleterAligned)); }
UnalignedWriter::UnalignedWriter(const PFile& file, off_t ofs) : m_file(file), m_alignedBuf((u8*)rtl_AllocateAligned(BLOCK_SIZE, maxSectorSize), AlignedDeleter()) { m_alignedOfs = round_down(ofs, (off_t)BLOCK_SIZE); const size_t misalignment = (size_t)(ofs - m_alignedOfs); if(misalignment) { io::Operation op(*m_file.get(), m_alignedBuf.get(), BLOCK_SIZE, m_alignedOfs); THROW_STATUS_IF_ERR(io::Run(op)); } m_bytesUsed = misalignment; }
// Re-layout by assigning offsets on a first-come first-serve basis, // then round up to a reasonable stride. // Backing store is also created here, VBOs are created on upload. void VertexArray::Layout() { Free(); m_Stride = 0; //debug_printf(L"Layouting VertexArray\n"); for (ssize_t idx = m_Attributes.size()-1; idx >= 0; --idx) { Attribute* attr = m_Attributes[idx]; if (!attr->type || !attr->elems) continue; size_t attrSize = 0; switch(attr->type) { case GL_UNSIGNED_BYTE: attrSize = sizeof(GLubyte); break; case GL_UNSIGNED_SHORT: attrSize = sizeof(GLushort); break; case GL_FLOAT: attrSize = sizeof(GLfloat); break; default: attrSize = 0; debug_warn(L"Bad Attribute::type"); break; } attrSize *= attr->elems; attr->offset = m_Stride; m_Stride += attrSize; if (m_Target == GL_ARRAY_BUFFER) m_Stride = Align<4>(m_Stride); //debug_printf(L"%i: offset: %u\n", idx, attr->offset); } if (m_Target == GL_ARRAY_BUFFER) m_Stride = RoundStride(m_Stride); //debug_printf(L"Stride: %u\n", m_Stride); if (m_Stride) m_BackingStore = (char*)rtl_AllocateAligned(m_Stride * m_NumVertices, 16); }
UniqueRange AllocateAligned(size_t size, size_t alignment) { ENSURE(is_pow2(alignment)); alignment = std::max(alignment, allocationAlignment); const size_t alignedSize = round_up(size, alignment); const UniqueRange::pointer p = rtl_AllocateAligned(alignedSize, alignment); static volatile IdxDeleter idxDeleterAligned; if(idxDeleterAligned == 0) // (optional optimization) RegisterUniqueRangeDeleter(FreeAligned, &idxDeleterAligned); return RVALUE(UniqueRange(p, size, idxDeleterAligned)); }
// Updated transforms void PolygonSortModelRenderer::UpdateModelData(CModel* model, void* data, int updateflags) { PSModel* psmdl = (PSModel*)data; if (updateflags & (RENDERDATA_UPDATE_VERTICES|RENDERDATA_UPDATE_COLOR)) { CModelDefPtr mdef = model->GetModelDef(); size_t numVertices = mdef->GetNumVertices(); // build vertices // allocate working space for computing normals if (numVertices > m->normalsNumVertices) { rtl_FreeAligned(m->normals); size_t newSize = round_up_to_pow2(numVertices); m->normals = (char*)rtl_AllocateAligned(newSize*16, 16); m->normalsNumVertices = newSize; } VertexArrayIterator<CVector3D> Position = psmdl->m_Position.GetIterator<CVector3D>(); VertexArrayIterator<CVector3D> Normal = VertexArrayIterator<CVector3D>(m->normals, 16); ModelRenderer::BuildPositionAndNormals(model, Position, Normal); VertexArrayIterator<SColor4ub> Color = psmdl->m_Color.GetIterator<SColor4ub>(); ModelRenderer::BuildColor4ub(model, Normal, Color); // upload everything to vertex buffer psmdl->m_Array.Upload(); } // resort model indices from back to front, according to the view camera position - and store // the returned sqrd distance to the centre of the nearest triangle // Use the view camera instead of the cull camera because: // a) polygon sorting implicitly uses the view camera (and changing that would be costly) // b) using the cull camera is likely not interesting from a debugging POV PROFILE_START( "sorting transparent" ); CMatrix3D worldToCam; g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam); psmdl->BackToFrontIndexSort(worldToCam); PROFILE_END( "sorting transparent" ); }
WriteBuffer::WriteBuffer() : m_capacity(pageSize), m_data((u8*)rtl_AllocateAligned(m_capacity, maxSectorSize), AlignedDeleter()), m_size(0) { }