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); }