void CGrassDrawer::DrawBillboard(const int x, const int y, const float dist, VA_TYPE_TN* va_tn) { UnsyncedRNG rng; // need our own, cause this function may run threaded rng.Seed(y * mapDims.mapx / grassSquareSize + x); const float rdist = 1.0f + rng.RandFloat() * 0.5f; float alpha = 1.0f - linearstep(maxGrassDist, maxGrassDist + 127.f, dist + 128.f); alpha = std::min(alpha, linearstep(maxDetailedDist, maxDetailedDist + 128.f * rdist, dist)); for (int a = 0; a < numTurfs; a++) { const STurfParams p = GetTurfParams(rng, x, y); float3 pos(p.x, CGround::GetHeightReal(p.x, p.y, false), p.y); pos.y -= CGround::GetSlope(p.x, p.y, false) * 30.0f; va_tn[a * 4 + 0] = { pos, 0.0f, 1.0f, float3(-partTurfSize, -partTurfSize, alpha) }; va_tn[a * 4 + 1] = { pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize, -partTurfSize, alpha) }; va_tn[a * 4 + 2] = { pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, partTurfSize, alpha) }; va_tn[a * 4 + 3] = { pos, 0.0f, 0.0f, float3(-partTurfSize, partTurfSize, alpha) }; } }
void CGrassDrawer::DrawBillboard(const int x, const int y, const float dist, VA_TYPE_TN* va_tn) { GrassRNG trng; // need our own, this function may run threaded trng.Seed(y * mapDims.mapx / grassSquareSize + x); const float rDist = 1.0f + trng.NextFloat() * 0.5f; const float gStep = linearstep(maxGrassDist, maxGrassDist + 127.0f, dist + 128.0f); const float dStep = linearstep(maxDetailedDist, maxDetailedDist + 128.0f * rDist, dist); const float alpha = std::min(1.0f - gStep, dStep); for (int a = 0; a < numTurfs; a++) { const float3& p = GetTurfParams(trng, x, y); const float3 pos(p.x, CGround::GetHeightReal(p.x, p.y, false) - CGround::GetSlope(p.x, p.y, false) * 30.0f, p.y); va_tn[a * 4 + 0] = { pos, 0.0f, 1.0f, float3(-partTurfSize, -partTurfSize, alpha) }; va_tn[a * 4 + 1] = { pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize, -partTurfSize, alpha) }; va_tn[a * 4 + 2] = { pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, partTurfSize, alpha) }; va_tn[a * 4 + 3] = { pos, 0.0f, 0.0f, float3(-partTurfSize, partTurfSize, alpha) }; } }
void CGrassDrawer::DrawNear(const std::vector<InviewNearGrass>& inviewGrass) { for (const InviewNearGrass& g: inviewGrass) { rng.Seed(g.y * mapDims.mapx / grassSquareSize + g.x); // const float distSq = GetCamDistOfGrassBlock(g.x, g.y, true); const float rdist = 1.0f + rng.RandFloat() * 0.5f; const float alpha = linearstep(maxDetailedDist, maxDetailedDist + 128.f * rdist, g.dist); for (int a = 0; a < numTurfs; a++) { const STurfParams& p = GetTurfParams(rng, g.x, g.y); float3 pos(p.x, CGround::GetHeightReal(p.x, p.y, false), p.y); pos.y -= CGround::GetSlope(p.x, p.y, false) * 30.0f; pos.y -= 2.0f * mapInfo->grass.bladeHeight * alpha; glPushMatrix(); glTranslatef3(pos); glRotatef(p.rotation, 0.0f, 1.0f, 0.0f); glCallList(grassDL); glPopMatrix(); } } }