void RenderDataManager::InitializeNode(TQuad* q) { assert(!q->renderData); QuadRenderData* rd = q->renderData = Allocate(); // Allocate vertex data space const size_t vertexSize = q->GetVertexSize(); if (static_cast<int>(vertexSize) != rd->vertexSize) { const size_t size = NUM_VERTICES * vertexSize; if (rd->vertexBuffer.GetSize() != size) { rd->vertexBuffer.Init(size); } rd->vertexSize = vertexSize; } // build the vertex buffer Vector3* v = (Vector3*)rd->vertexBuffer.LockData(); uint vda = q->textureSetup->vertexDataReq; // vertex data requirements const Heightmap* hm = roothm->GetLevel(q->depth); // get the right heightmap level for (int y = q->hmPos.y; y <= (q->hmPos.y + QUAD_W); y++) for (int x = q->hmPos.x; x <= (q->hmPos.x + QUAD_W); x++) { *(v++) = Vector3(x * hm->squareSize, hm->atSynced(x, y), y * hm->squareSize); Vector3 tangent, binormal; CalculateTangents(hm, x,y, tangent, binormal); Vector3 normal = binormal.cross(tangent); normal.ANormalize(); if (vda & VRT_Normal) *(v++) = normal; if (vda & VRT_TangentSpaceMatrix) { tangent.ANormalize(); binormal.ANormalize(); // orthonormal matrix, so inverse=transpose // Take the inverse of the tangent space -> world space transformation Vector3* tgs2ws = v; tgs2ws[0] = Vector3(tangent.x, binormal.x, normal.x); tgs2ws[1] = Vector3(tangent.y, binormal.y, normal.y); tgs2ws[2] = Vector3(tangent.z, binormal.z, normal.z); v += 3; } } rd->vertexBuffer.UnlockData(); rd->SetQuad(q); }
void RenderDataManager::UpdateRect(int sx, int sy,int w,int h) { for (size_t a = 0; a < qrd.size(); a++) { QuadRenderData* rd = qrd[a]; TQuad* q = rd->GetQuad(); // rect vs rect collision: if (q->sqPos.x + q->width >= sx && q->sqPos.y + q->width >= sy && q->sqPos.x <= sx + w && q->sqPos.y <= sy + h) { assert(q->renderData==qrd[a]); Free(q->renderData); } } }
// delete all renderdata that is not used this frame and has maxlod < VBufMinDetail void RenderDataManager::FreeUnused() { for (int a = 0; a < qrd.size(); a++) { QuadRenderData* rd = qrd[a]; if (rd->used) { rd->used = false; continue; } if (rd->GetQuad()->maxLodValue < VBufMinDetail) { Free(rd); a--; } } }