void DiFoliageLayerBatch::GenerateGrassSprite( const float *grassPositions, unsigned int grassCount ) { ReleaseVertexDeclaration(); ReleaseSourceData(); ReleaseIndexBuffer(); // TODO }
DiInstanceBatch::~DiInstanceBatch() { DeleteAllInstancedModels(); DiCullNode *sceneNode = GetParentCullNode(); if( sceneNode ) { sceneNode->DetachAllObjects(); sceneNode->GetParent()->RemoveChild( sceneNode->GetName() ); } if( mRemoveOwnVertexData ) ReleaseSourceData(); if( mRemoveOwnIndexData ) ReleaseIndexBuffer(); ReleaseVertexDeclaration(); }
DiWaterChunk::~DiWaterChunk() { ReleaseSourceData(); }
DiLineList::~DiLineList(void) { ReleaseSourceData(); ReleaseVertexDeclaration(); }
DiSprite::~DiSprite() { ReleaseSourceData(); ReleaseVertexDeclaration(); }
void DiSprite::UpdateGeometry(DiRenderTarget* rt) { if (mQuads.empty()) { mPrimitiveCount = 0; return; } if (!rt) return; ReleaseSourceData(); auto vb = Driver->CreateVertexBuffer(); if (!vb) return; mSourceData.push_back(vb); mVerticesNum = 6 * mQuads.size(); mPrimitiveCount = 2 * mQuads.size(); uint32 vertSize = (3 + 2) * sizeof(float) + sizeof(ARGB); mSourceData[0]->Create(mVerticesNum*vertSize); uint8* lockedData = DI_NEW uint8[mVerticesNum*vertSize]; uint32 w = (uint32)(rt->GetWidth() * rt->GetViewport().mWidth); uint32 h = (uint32)(rt->GetHeight() * rt->GetViewport().mHeight); DiVec2 invScreenSize; invScreenSize = DiVec2(1.0f / (float)w, 1.0f / (float)h); DiVec2 posAdjust(1, -1); float* dest = (float*)lockedData; if (!mMaterial || mMaterial->HasTexture()) { for (auto it = mQuads.begin(); it != mQuads.end(); ++it) { DiQuadElement quad = *it; DiVec2 topLeft, bottomRight, topLeftUv, bottomRightUv; quad.top *= -1; quad.bottom *= -1; if (!quad.absCoord) { quad.left *= (float)w; quad.right *= (float)w; quad.top *= (float)h; quad.bottom *= (float)h; } topLeft = (DiVec2((float)quad.left, (float)quad.top)/*+DiVec2(0.5f,0.5f)*/) * invScreenSize*2; bottomRight = (DiVec2((float)quad.right, (float)quad.bottom)/*+DiVec2(0.5f,0.5f)*/) * invScreenSize*2; topLeft -= posAdjust; bottomRight -= posAdjust; topLeftUv = DiVec2((float)quad.leftUv, (float)quad.topUv); bottomRightUv = DiVec2((float)quad.rightUv, (float)quad.bottomUv); *dest++ = topLeft.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topLeftColor; dest++; *dest++ = topLeftUv.x; *dest++ = topLeftUv.y; *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomLeftColor; dest++; *dest++ = topLeftUv.x; *dest++ = bottomRightUv.y; *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topRightColor; dest++; *dest++ = bottomRightUv.x; *dest++ = topLeftUv.y; *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topRightColor; dest++; *dest++ = bottomRightUv.x; *dest++ = topLeftUv.y; *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomLeftColor; dest++; *dest++ = topLeftUv.x; *dest++ = bottomRightUv.y; *dest++ = bottomRight.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomRightColor; dest++; *dest++ = bottomRightUv.x; *dest++ = bottomRightUv.y; } } else { for (auto it = mQuads.begin(); it != mQuads.end(); ++it) { DiQuadElement quad = *it; quad.top *= -1; quad.bottom *= -1; if (!quad.absCoord) { quad.left *= (float)w; quad.right *= (float)w; quad.top *= (float)h; quad.bottom *= (float)h; } DiVec2 topLeft, bottomRight, topLeftUV, bottomRightUV; topLeft = (DiVec2((float)quad.left, (float)quad.top)) * invScreenSize*2; bottomRight = (DiVec2((float)quad.right, (float)quad.bottom)) * invScreenSize*2; topLeft -= posAdjust; bottomRight -= posAdjust; *dest++ = topLeft.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topLeftColor; dest++; dest += 2; *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomLeftColor; dest++; dest += 2; *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topRightColor; dest++; dest += 2; *dest++ = bottomRight.x; *dest++ = topLeft.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.topRightColor; dest++; dest += 2; *dest++ = topLeft.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomLeftColor; dest++; dest += 2; *dest++ = bottomRight.x; *dest++ = bottomRight.y; *dest++ = 0.0f; *((ARGB*)dest) = quad.bottomRightColor; dest++; dest += 2; } } mSourceData[0]->WriteData(0, mVerticesNum*vertSize, lockedData); DI_DELETE[] lockedData; mSourceData[0]->SetStride(vertSize); }
void DiFoliageLayerBatch::GenerateGrassQuad( const float *grassPositions, unsigned int grassCount ) { ReleaseVertexDeclaration(); ReleaseSourceData(); ReleaseIndexBuffer(); unsigned int quadCount; quadCount = grassCount; unsigned int maxUInt16 = std::numeric_limits<uint16>::max(); if(grassCount > maxUInt16) { return; } if(quadCount > maxUInt16) { return; } if (quadCount <= 0) { mVerticesNum = 0; mPrimitiveCount = 0; return; } mVerticesNum = 4 * quadCount; mPrimitiveCount = 2 * quadCount; mVertexDecl = Driver->CreateVertexDeclaration(); mVertexDecl->AddElement(0,VERT_TYPE_FLOAT3, VERT_USAGE_POSITION); mVertexDecl->AddElement(0,VERT_TYPE_FLOAT2, VERT_USAGE_TEXCOORD); mVertexDecl->Create(); uint32 vertSize = mVertexDecl->GetElements().GetStreamElementsSize(0); uint32 size = vertSize * mVerticesNum; DiVertexBuffer* vb = Driver->CreateVertexBuffer(); vb->Create(size); vb->SetStride(vertSize); mSourceData.push_back(vb); DiVec2 chunkPos = mParent->mParent->GetTerrainMap()->GetChunkCenterPos(mParent->mChunkID.x,mParent->mChunkID.y); float* pReal = static_cast<float*>(vb->Lock(0,size)); float rndWidth = mLayer->mDesc->mMaxWidth - mLayer->mDesc->mMinWidth; float rndHeight = mLayer->mDesc->mMaxHeight - mLayer->mDesc->mMinHeight; float minY = DiMath::POS_INFINITY, maxY = DiMath::NEG_INFINITY; const float *posPtr = grassPositions; for (uint16 i = 0; i < grassCount; ++i) { float x = *posPtr++; float z = *posPtr++; float rnd = *posPtr++; float halfScaleX = (mLayer->mDesc->mMinWidth + rndWidth * rnd) * 0.5f; float scaleY = (mLayer->mDesc->mMinHeight + rndHeight * rnd); float angle = *posPtr++; float xTrans = DiMath::Cos(angle) * halfScaleX; float zTrans = DiMath::Sin(angle) * halfScaleX; float x1 = x - xTrans, z1 = z - zTrans; float x2 = x + xTrans, z2 = z + zTrans; float height = 0; mParent->mParent->GetTerrainMap()->GetHeight(chunkPos.x+x,chunkPos.y+z,height); float y1 = height; float y2 = height; *pReal++ = float(x1); *pReal++ = float(y1 + scaleY); *pReal++ = float(z1); //pos *pReal++ = 0.f; *pReal++ = 0.f; //uv *pReal++ = float(x2); *pReal++ = float(y2 + scaleY); *pReal++ = float(z2); //pos *pReal++ = 1.f; *pReal++ = 0.f; //uv *pReal++ = float(x1); *pReal++ = float(y1); *pReal++ = float(z1); //pos *pReal++ = 0.f; *pReal++ = 1.f; //uv *pReal++ = float(x2); *pReal++ = float(y2); *pReal++ = float(z2); //pos *pReal++ = 1.f; *pReal++ = 1.f; //uv if (y1 < minY) { minY = y1; } if (y2 < minY) { minY = y2; } if (y1 + scaleY > maxY) { maxY = y1 + scaleY; } if (y2 + scaleY > maxY) { maxY = y2 + scaleY; } } vb->Unlock(); uint32 ibsize = 6 * quadCount * sizeof(uint16); mIndexBuffer = Driver->CreateIndexBuffer(); mIndexBuffer->Create(ibsize); uint16* pI = static_cast<uint16*>(mIndexBuffer->Lock(0,ibsize)); for (uint16 i = 0; i < quadCount; ++i) { uint16 offset = i * 4; *pI++ = 0 + offset; *pI++ = 2 + offset; *pI++ = 1 + offset; *pI++ = 1 + offset; *pI++ = 2 + offset; *pI++ = 3 + offset; } mIndexBuffer->Unlock(); }
DiFoliageLayerBatch::~DiFoliageLayerBatch() { ReleaseVertexDeclaration(); ReleaseSourceData(); ReleaseIndexBuffer(); }