示例#1
0
void CGrassDrawer::CreateGrassDispList(int listNum)
{
	CVertexArray* va = GetVertexArray();
	va->Initialize();
	rng.Seed(15);

	for (int a = 0; a < strawPerTurf; ++a) {
		// draw a single blade
		const float lngRnd = rng.RandFloat();
		const float length = mapInfo->grass.bladeHeight * (1.0f + lngRnd);
		const float maxAng = mapInfo->grass.bladeAngle * std::max(rng.RandFloat(), 1.f - smoothstep(0.f,1.f,lngRnd));

		float3 sideVect(rng.RandFloat() - 0.5f, 0.0f, rng.RandFloat() - 0.5f);
		sideVect.ANormalize();
		float3 bendVect = sideVect.cross(UpVector); // direction to bend into
		sideVect *= mapInfo->grass.bladeWidth * (-0.15f * lngRnd + 1.0f);
		const float3 basePos = rng.RandVector2D() * (turfSize - (bendVect * std::sin(maxAng) * length).Length2D());

		// select one of the 16 color shadings
		const float xtexCoord = (rng.RandInt() % 16) / 16.0f;
		const int numSections = 2 + int(maxAng * 1.2f + length * 0.2f);

		float3 normalBend = -bendVect;

		// start btm
		va->AddVertexTN(basePos + sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord              , 0.f, normalBend);
		va->AddVertexTN(basePos - sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord + (1.0f / 16), 0.f, normalBend);

		for (float h = 0.0f; h < 1.0f; h += (1.0f / numSections)) {
			const float ang = maxAng * h;
			const float3 n = (normalBend * std::cos(ang) + UpVector * std::sin(ang)).ANormalize();
			const float3 edgePos  = (UpVector * std::cos(ang) + bendVect * std::sin(ang)) * length * h;
			const float3 edgePosL = edgePos - sideVect * (1.0f - h);
			const float3 edgePosR = edgePos + sideVect * (1.0f - h);

			va->AddVertexTN(basePos + edgePosR, xtexCoord + (1.0f / 32) * h              , h, (n + sideVect * 0.04f).ANormalize());
			va->AddVertexTN(basePos + edgePosL, xtexCoord - (1.0f / 32) * h + (1.0f / 16), h, (n - sideVect * 0.04f).ANormalize());
		}

		// end top tip (single triangle)
		const float3 edgePos = (UpVector * std::cos(maxAng) + bendVect * std::sin(maxAng)) * length;
		const float3 n = (normalBend * std::cos(maxAng) + UpVector * std::sin(maxAng)).ANormalize();
		va->AddVertexTN(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f, n);

		// next blade
		va->EndStrip();
	}

	glNewList(listNum, GL_COMPILE);
	va->DrawArrayTN(GL_TRIANGLE_STRIP);
	glEndList();
}
示例#2
0
void CGrassDrawer::CreateGrassDispList(int listNum)
{
	CVertexArray* va = GetVertexArray();
	va->Initialize();

	for (int a = 0; a < strawPerTurf; ++a) {
		const float maxAng = mapInfo->grass.bladeAngle * rng.RandFloat();
		const float length = mapInfo->grass.bladeHeight + mapInfo->grass.bladeHeight * rng.RandFloat();

		float3 sideVect(rng.RandFloat() - 0.5f, 0.0f, rng.RandFloat() - 0.5f);
		sideVect.ANormalize();
		float3 forwardVect = sideVect.cross(UpVector);
		sideVect *= mapInfo->grass.bladeWidth;

		float3 basePos(30.0f, 0.0f, 30.0f);
		while (basePos.SqLength2D() > (turfSize * turfSize / 4)) {
			basePos  = float3(rng.RandFloat() - 0.5f, 0.f, rng.RandFloat() - 0.5f) * turfSize;
		}

		const float xtexCoord = int(14.9999f * rng.RandFloat()) / 16.0f;
		const int numSections = 1 + int(maxAng * 5.0f);

		// draw single blade
		for (float h = 0; h <= 1.0f; h += (1.0f / numSections)) {
			const float ang = maxAng * h;

			const float3 edgePos  = (UpVector * std::cos(ang) + forwardVect * std::sin(ang)) * length * h;
			const float3 edgePosL = edgePos - sideVect * (1.0f - h);
			const float3 edgePosR = edgePos + sideVect * (1.0f - h);

			if (h == 0.0f) {
				// start with a degenerated triangle
				va->AddVertexT(basePos + edgePosR - float3(0.0f, 0.1f, 0.0f), xtexCoord, h);
				va->AddVertexT(basePos + edgePosR - float3(0.0f, 0.1f, 0.0f), xtexCoord, h);
			} else {
				va->AddVertexT(basePos + edgePosR, xtexCoord, h);
			}

			va->AddVertexT(basePos + edgePosL, xtexCoord + (1.0f / 16), h);
		}

		// end with a degenerated triangle
		// -> this way we can render multiple blades in a single GL_TRIANGLE_STRIP
		const float3 edgePos = (UpVector * std::cos(maxAng) + forwardVect * std::sin(maxAng)) * length;
		va->AddVertexT(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f);
		va->AddVertexT(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f);
	}

	glNewList(listNum, GL_COMPILE);
	va->DrawArrayT(GL_TRIANGLE_STRIP);
	glEndList();
}