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 CProjectileDrawer::DrawFlyingPieces(int modelType, int numFlyingPieces, int* drawnPieces) { static FlyingPieceContainer* containers[MODELTYPE_OTHER] = { &ph->flyingPieces3DO, &ph->flyingPiecesS3O, NULL }; FlyingPieceContainer* container = containers[modelType]; FlyingPieceContainer::render_iterator fpi; if (container != NULL) { CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(numFlyingPieces * 4, 0, VA_SIZE_TN); size_t lastTex = -1; size_t lastTeam = -1; for (fpi = container->render_begin(); fpi != container->render_end(); ++fpi) { (*fpi)->Draw(modelType, &lastTeam, &lastTex, va); } (*drawnPieces) += (va->drawIndex() / 32); va->DrawArrayTN(GL_QUADS); } }
void CGrassDrawer::CreateGrassDispList(int listNum) { CVertexArray* va = GetVertexArray(); va->Initialize(); grng.Seed(15); for (int a = 0; a < strawPerTurf; ++a) { // draw a single blade const float lngRnd = grng.NextFloat(); const float length = mapInfo->grass.bladeHeight * (1.0f + lngRnd); const float maxAng = mapInfo->grass.bladeAngle * std::max(grng.NextFloat(), 1.0f - smoothstep(0.0f, 1.0f, lngRnd)); float3 sideVect; sideVect.x = grng.NextFloat() - 0.5f; sideVect.z = grng.NextFloat() - 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 = grng.NextVector2D() * (turfSize - (bendVect * std::sin(maxAng) * length).Length2D()); // select one of the 16 color shadings const float xtexCoord = grng.NextInt(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(); }
void CFeatureHandler::Draw() { fadeFeatures.clear(); fadeFeaturesS3O.clear(); drawFar.clear(); GML_RECMUTEX_LOCK(feat); // Draw if(gu->drawFog) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); } unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); // S3O features can have transparent bits glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER,0.5f); unitDrawer->DrawQuedS3O(); glPopAttrib(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.8f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size()*4,0,VA_SIZE_TN); for (vector<CFeature*>::iterator usi = drawFar.begin(); usi != drawFar.end(); ++usi) { DrawFar(*usi, va); } va->DrawArrayTN(GL_QUADS); glDisable(GL_ALPHA_TEST); } glDisable(GL_FOG); }
void CFeatureHandler::Draw() { fadeFeatures.clear(); fadeFeaturesS3O.clear(); drawFar.clear(); GML_RECMUTEX_LOCK(feat); // Draw glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); unitDrawer->DrawQuedS3O(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.8f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size()*4,0,VA_SIZE_TN); for (vector<CFeature*>::iterator usi = drawFar.begin(); usi != drawFar.end(); usi++) { DrawFar(*usi, va); } va->DrawArrayTN(GL_QUADS); glDisable(GL_ALPHA_TEST); } glDisable(GL_FOG); }
void CFeatureHandler::Draw() { ASSERT_UNSYNCED_MODE; vector<CFeature*> drawFar; unitDrawer->SetupForUnitDrawing(); DrawRaw(0, &drawFar); unitDrawer->CleanUpUnitDrawing(); unitDrawer->DrawQuedS3O(); CVertexArray* va = GetVertexArray(); va->Initialize(); glAlphaFunc(GL_GREATER, 0.8f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_FOG); for (vector<CFeature*>::iterator usi = drawFar.begin(); usi != drawFar.end(); usi++) { DrawFar(*usi, va); } 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); }