Example #1
0
void CGrassDrawer::DrawNearBillboards(const std::vector<InviewNearGrass>& inviewNearGrass)
{
	CVertexArray* va = GetVertexArray();
	va->Initialize();
	va->EnlargeArrays(inviewNearGrass.size() * numTurfs * 4, 0, VA_SIZE_TN);

	for (std::vector<InviewNearGrass>::const_iterator gi = inviewNearGrass.begin(); gi != inviewNearGrass.end(); ++gi) {
		const int x = (*gi).x;
		const int y = (*gi).y;

		rng.Seed(y * 1025 + x);

		for (int a = 0; a < numTurfs; a++) {
			const float dx = (x + rng.RandFloat()) * gSSsq;
			const float dy = (y + rng.RandFloat()) * gSSsq;
			const float col = 1.0f;

			float3 pos(dx, CGround::GetHeightReal(dx, dy, false) + 0.5f, dy);
				pos.y -= (CGround::GetSlope(dx, dy, false) * 10.0f + 0.03f);

			va->AddVertexQTN(pos,         0.0f, 0.0f, float3(-partTurfSize, -partTurfSize, col));
			va->AddVertexQTN(pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, -partTurfSize, col));
			va->AddVertexQTN(pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize,  partTurfSize, col));
			va->AddVertexQTN(pos,         0.0f, 1.0f, float3(-partTurfSize,  partTurfSize, col));
		}
	}

	va->DrawArrayTN(GL_QUADS);
}
void CProjectileHandler::Draw(bool drawReflection, bool drawRefraction) {
	glDisable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glDepthMask(1);

	if(gu->drawFog) {
		glEnable(GL_FOG);
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
	}

	CVertexArray* va = GetVertexArray();

	/* Putting in, say, viewport culling will deserve refactoring. */

	unitDrawer->SetupForUnitDrawing();

	{
		GML_STDMUTEX_LOCK(rpiece); // Draw

		flyingPieces.delete_delayed();
		flyingPieces.add_delayed();
	}

	size_t lasttex = 0xFFFFFFFF;
	size_t lastteam = 0xFFFFFFFF;
	va->Initialize();

	int numFlyingPieces = flyingPieces.render_size();
	int drawnPieces = numFlyingPieces;
	va->EnlargeArrays(numFlyingPieces * 4, 0, VA_SIZE_TN);

	FlyingPieceContainer::render_iterator fpi = flyingPieces.render_begin();

	// S3O flying pieces
	for( ; fpi != flyingPieces.render_end(); ++fpi) {
		FlyingPiece *fp = *fpi;
		if (fp->texture != lasttex) {
			lasttex = fp->texture;
			if (lasttex == 0)
				break;
			va->DrawArrayTN(GL_QUADS);
			va->Initialize();
			texturehandlerS3O->SetS3oTexture(lasttex);
		}
		if (fp->team != lastteam) {
			lastteam = fp->team;
			va->DrawArrayTN(GL_QUADS);
			va->Initialize();
			unitDrawer->SetTeamColour(lastteam);
		}
		CMatrix44f m;
		m.Rotate(fp->rot, fp->rotAxis);
		float3 interPos = fp->pos + fp->speed * gu->timeOffset;
		SS3OVertex* verts = fp->verts;
		float3 tp, tn;

		for (int i = 0; i < 4; i++){
			tp = m.Mul(verts[i].pos);
			tn = m.Mul(verts[i].normal);
			tp += interPos;
			va->AddVertexQTN(tp, verts[i].textureX, verts[i].textureY, tn);
		}
	}

	va->DrawArrayTN(GL_QUADS);
	va->Initialize();

	unitDrawer->SetupFor3DO();

	// 3DO flying pieces
	for ( ; fpi != flyingPieces.render_end(); ++fpi) {
		FlyingPiece* fp = *fpi;
		CMatrix44f m;
		m.Rotate(fp->rot, fp->rotAxis);
		float3 interPos = fp->pos + fp->speed * gu->timeOffset;
		C3DOTextureHandler::UnitTexture* tex = fp->prim->texture;

		const std::vector<S3DOVertex>& vertices    = fp->object->vertices;
		const std::vector<int>&        verticesIdx = fp->prim->vertices;

		const S3DOVertex* v = &vertices[verticesIdx[0]];
		float3 tp = m.Mul(v->pos);
		float3 tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xstart, tex->ystart, tn);

		v = &vertices[verticesIdx[1]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xend, tex->ystart, tn);

		v = &vertices[verticesIdx[2]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xend, tex->yend, tn);

		v = &vertices[verticesIdx[3]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xstart, tex->yend, tn);
	}

	va->DrawArrayTN(GL_QUADS);

	distset.clear();

	{
		GML_STDMUTEX_LOCK(rproj); // Draw

		//! batch-insert projectiles into render queue
		syncedProjectiles.add_delayed();

		unsyncedProjectiles.delete_delayed();
		unsyncedProjectiles.add_delayed();
	}

	{
		GML_STDMUTEX_LOCK(proj); // Draw

		//! 3DO projectiles get rendered immediately here, S3O's are queued
		DrawProjectiles(syncedProjectiles, drawReflection, drawRefraction);
		DrawProjectiles(unsyncedProjectiles, drawReflection, drawRefraction);

		unitDrawer->CleanUp3DO();
		unitDrawer->DrawQuedS3O(); //! draw qued S3O projectiles
		unitDrawer->CleanUpUnitDrawing();

		currentParticles = 0;
		CProjectile::inArray = false;
		CProjectile::va = GetVertexArray();
		CProjectile::va->Initialize();

		for (std::set<CProjectile*, distcmp>::iterator i = distset.begin(); i != distset.end(); ++i) {
			(*i)->Draw();
		}
	}

	glEnable(GL_BLEND);
	glDisable(GL_FOG);

	if (CProjectile::inArray) {
		// Alpha transculent particles
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_TEXTURE_2D);
		textureAtlas->BindTexture();
		glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
		glAlphaFunc(GL_GREATER, 0.0f);
		glEnable(GL_ALPHA_TEST);
		glDepthMask(0);

		// note: nano-particles (CGfxProjectile instances) also
		// contribute to the count, but have their own creation
		// cutoff
		currentParticles += CProjectile::DrawArray();
	}

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glDepthMask(1);

	currentParticles  = int(currentParticles * 0.2f);
	currentParticles += int((syncedProjectiles.render_size() + unsyncedProjectiles.render_size()) * 0.8f);
	currentParticles += (int) (0.2f * drawnPieces + 0.3f * numFlyingPieces);

	particleSaturation     = currentParticles     / float(maxParticles);
	nanoParticleSaturation = currentNanoParticles / float(maxNanoParticles);
}