void InMapDraw_QuadDrawer::DrawQuad(int x, int y) { int drawQuadsX = imd->drawQuadsX; CInMapDraw::DrawQuad* dq = &imd->drawQuads[y * drawQuadsX + x]; va->EnlargeArrays(dq->points.size()*12,0,VA_SIZE_TC); //! draw point markers for (std::list<CInMapDraw::MapPoint>::iterator pi = dq->points.begin(); pi != dq->points.end(); ++pi) { if (pi->MaySee(imd)) { float3 pos = pi->pos; float3 dif(pos - camera->pos); dif.ANormalize(); float3 dir1(dif.cross(UpVector)); dir1.ANormalize(); float3 dir2(dif.cross(dir1)); unsigned char col[4]; col[0] = pi->color[0]; col[1] = pi->color[1]; col[2] = pi->color[2]; col[3] = 200; float size = 6; float3 pos1 = pos; pos1.y += 5.0f; float3 pos2 = pos1; pos2.y += 100.0f; va->AddVertexQTC(pos1 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos1 + dir1 * size + dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos1 - dir1 * size + dir2 * size, 0.00f, 0, col); va->AddVertexQTC(pos1 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos2 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos2 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos2 + dir1 * size - dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos2 - dir1 * size - dir2 * size, 0.00f, 0, col); if (pi->label.size() > 0) { font->SetTextColor(pi->color[0]/255.0f, pi->color[1]/255.0f, pi->color[2]/255.0f, 1.0f); //FIXME (overload!) font->glWorldPrint(pos2 + UpVector * 6, 26.0f, pi->label); } } } lineva->EnlargeArrays(dq->lines.size()*2,0,VA_SIZE_C); //! draw line markers for (std::list<CInMapDraw::MapLine>::iterator li = dq->lines.begin(); li != dq->lines.end(); ++li) { if (li->MaySee(imd)) { lineva->AddVertexQC(li->pos - (li->pos - camera->pos).ANormalize() * 26, li->color); lineva->AddVertexQC(li->pos2 - (li->pos2 - camera->pos).ANormalize() * 26, li->color); } } }
void InMapDraw_QuadDrawer::DrawQuad(int x, int y) { const int drawQuadsX = imd->drawQuadsX; CInMapDraw::DrawQuad* dq = &imd->drawQuads[y * drawQuadsX + x]; va->EnlargeArrays(dq->points.size()*12,0,VA_SIZE_TC); //! draw point markers for (std::list<CInMapDraw::MapPoint>::iterator pi = dq->points.begin(); pi != dq->points.end(); ++pi) { if (pi->MaySee(imd)) { const float3 pos = pi->pos; const float3 dif = (pos - camera->pos).ANormalize(); const float3 dir1 = (dif.cross(UpVector)).ANormalize(); const float3 dir2 = (dif.cross(dir1)); const unsigned char col[4] = { pi->color[0], pi->color[1], pi->color[2], 200 }; const float size = 6.0f; const float3 pos1(pos.x, pos.y + 5.0f, pos.z); const float3 pos2(pos1.x, pos1.y + 100.0f, pos1.z); va->AddVertexQTC(pos1 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos1 + dir1 * size + dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos1 - dir1 * size + dir2 * size, 0.00f, 0, col); va->AddVertexQTC(pos1 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos2 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos2 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos2 + dir1 * size - dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos2 - dir1 * size - dir2 * size, 0.00f, 0, col); if (!pi->label.empty()) { visLabels->push_back(&*pi); } } } lineva->EnlargeArrays(dq->lines.size() * 2, 0, VA_SIZE_C); //! draw line markers for (std::list<CInMapDraw::MapLine>::iterator li = dq->lines.begin(); li != dq->lines.end(); ++li) { if (li->MaySee(imd)) { lineva->AddVertexQC(li->pos - (li->pos - camera->pos).ANormalize() * 26, li->color); lineva->AddVertexQC(li->pos2 - (li->pos2 - camera->pos).ANormalize() * 26, li->color); } } }
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 InMapDraw_QuadDrawer::DrawQuad(int x, int y) { const CInMapDrawModel::DrawQuad* dq = inMapDrawerModel->GetDrawQuad(x, y); pointsVa->EnlargeArrays(dq->points.size() * 12, 0, VA_SIZE_TC); //! draw point markers for (std::list<CInMapDrawModel::MapPoint>::const_iterator pi = dq->points.begin(); pi != dq->points.end(); ++pi) { if (pi->IsLocalPlayerAllowedToSee(inMapDrawerModel)) { DrawPoint(&*pi); } } linesVa->EnlargeArrays(dq->lines.size() * 2, 0, VA_SIZE_C); //! draw line markers for (std::list<CInMapDrawModel::MapLine>::const_iterator li = dq->lines.begin(); li != dq->lines.end(); ++li) { if (li->IsLocalPlayerAllowedToSee(inMapDrawerModel)) { DrawLine(&*li); } } }
/* * Draws a trigonometric circle in 'resolution' steps, with a slope modifier */ void glBallisticCircle(const float3& center, const float radius, const CWeapon* weapon, unsigned int resolution, float slope) { int rdiv = 50; resolution *= 2; rdiv *= 1; CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(resolution, 0, VA_SIZE_0); float3* vertices = reinterpret_cast<float3*>(va->drawArray); va->drawArrayPos = va->drawArray + resolution * 3; for_mt(0, resolution, [&](const int i) { const float radians = (2.0f * PI) * (float)i / (float)resolution; float rad = radius; float sinR = fastmath::sin(radians); float cosR = fastmath::cos(radians); float3 pos; pos.x = center.x + (sinR * rad); pos.z = center.z + (cosR * rad); pos.y = CGround::GetHeightAboveWater(pos.x, pos.z, false); float heightDiff = (pos.y - center.y) * 0.5f; rad -= heightDiff * slope; float adjRadius = weapon ? weapon->GetRange2D(heightDiff * weapon->heightMod) : rad; float adjustment = rad * 0.5f; float ydiff = 0; for(int j = 0; j < rdiv && math::fabs(adjRadius - rad) + ydiff > .01 * rad; j++) { if (adjRadius > rad) { rad += adjustment; } else { rad -= adjustment; adjustment /= 2; } pos.x = center.x + (sinR * rad); pos.z = center.z + (cosR * rad); float newY = CGround::GetHeightAboveWater(pos.x, pos.z, false); ydiff = math::fabs(pos.y - newY); pos.y = newY; heightDiff = (pos.y - center.y); adjRadius = weapon ? weapon->GetRange2D(heightDiff * weapon->heightMod) : rad; } pos.x = center.x + (sinR * adjRadius); pos.z = center.z + (cosR * adjRadius); pos.y = CGround::GetHeightAboveWater(pos.x, pos.z, false) + 5.0f; vertices[i] = pos; }); va->DrawArray0(GL_LINE_LOOP); }
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 CProjectileHandler::DrawProjectilesMiniMap(const ProjectileContainer& pc) { if (pc.render_size() > 0) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays(pc.render_size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays(pc.render_size(), 0, VA_SIZE_C); for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) { CProjectile* p = *pci; if ((p->owner() && (p->owner()->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } if (!fbo.IsValid()) { queuedForRender.clear(); return; } // create new far-icons for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { const CSolidObject* obj = *it; if (!HaveFarIcon(obj)) { CreateFarTexture(obj); } } // render current queued far icons on the screen { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTextureID); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); ISky::SetupFog(); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); } queuedForRender.clear(); }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } //! create new faricons for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { const CSolidObject& obj = **it; if (cache.size()<=obj.team || cache[obj.team].size()<=obj.model->id || !cache[obj.team][obj.model->id]) { CreateFarTexture(*it); } } glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTexture); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); if (globalRendering->drawFog) { glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); glEnable(GL_FOG); } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); queuedForRender.clear(); }
void SmoothHeightMeshDrawer::Draw(float yoffset) { if (!drawEnabled) return; glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(1.0f); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_1D); glDisable(GL_CULL_FACE); const float quadSize = 4.0f * smoothGround->GetResolution(); const unsigned int numQuadsX = smoothGround->GetFMaxX() / quadSize; const unsigned int numQuadsZ = smoothGround->GetFMaxY() / quadSize; CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays((numQuadsX + 1) * (numQuadsZ + 1) * 4, 0, VA_SIZE_0); for (unsigned int zq = 0; zq <= numQuadsZ; zq++) { for (unsigned int xq = 0; xq <= numQuadsX; xq++) { const float x = xq * quadSize; const float z = zq * quadSize; const float h1 = smoothGround->GetHeightAboveWater(x, z ) + yoffset; const float h2 = smoothGround->GetHeightAboveWater(x + quadSize, z ) + yoffset; const float h3 = smoothGround->GetHeightAboveWater(x + quadSize, z + quadSize) + yoffset; const float h4 = smoothGround->GetHeightAboveWater(x, z + quadSize) + yoffset; va->AddVertexQ0(float3(x, h1, z )); va->AddVertexQ0(float3(x + quadSize, h2, z )); va->AddVertexQ0(float3(x + quadSize, h3, z + quadSize)); va->AddVertexQ0(float3(x, h4, z + quadSize)); } } glColor4ub(0, 255, 0, 255); va->DrawArray0(GL_QUADS); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); }
void QTPFSPathDrawer::DrawNodeTree(const MoveDef* md) const { QTPFS::QTNode* nt = pm->nodeTrees[md->pathType]; CVertexArray* va = GetVertexArray(); std::list<const QTPFS::QTNode*> nodes; std::list<const QTPFS::QTNode*>::const_iterator nodesIt; GetVisibleNodes(nt, nodes); va->Initialize(); va->EnlargeArrays(nodes.size() * 4, 0, VA_SIZE_C); for (nodesIt = nodes.begin(); nodesIt != nodes.end(); ++nodesIt) { DrawNode(*nodesIt, md, va, false, true, true); } glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); va->DrawArrayC(GL_QUADS); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1); }
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 CMiniMap::DrawForReal(bool use_geo) { SCOPED_TIMER("MiniMap::DrawForReal"); //glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPushAttrib(GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_FALSE); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_MODELVIEW); if (minimized) { if (!slaveDrawMode) { DrawMinimizedButton(); } glPopAttrib(); glEnable(GL_TEXTURE_2D); return; } // draw the frameborder if (!slaveDrawMode && !globalRendering->dualScreenMode && !maximized) { glEnable(GL_BLEND); DrawFrame(); glDisable(GL_BLEND); } bool resetTextureMatrix = false; if (use_geo) { glPushMatrix(); // switch to normalized minimap coords if (globalRendering->dualScreenMode) { glViewport(xpos, ypos, width, height); glScalef(width * globalRendering->pixelX, height * globalRendering->pixelY, 1.0f); } else { glTranslatef(xpos * globalRendering->pixelX, ypos * globalRendering->pixelY, 0.0f); glScalef(width * globalRendering->pixelX, height * globalRendering->pixelY, 1.0f); } /* FIXME: fix mouse handling too and make it fully customizable, so Lua can rotate the minimap to any angle CCameraController* camController = &camHandler->GetCurrentController(); COverheadController* taCam = dynamic_cast<COverheadController*>(camController); SmoothController* smCam = dynamic_cast<SmoothController*>(camController); if ((taCam && taCam->flipped) || (smCam && smCam->flipped)) { glTranslatef(1.0f, 1.0f, 0.0f); glScalef(-1.0f, -1.0f, 1.0f); glMatrixMode(GL_TEXTURE); glPushMatrix(); glTranslatef(1.0f, 1.0f, 0.0f); glScalef(-1.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); resetTextureMatrix = true; }*/ } setSurfaceCircleFunc(DrawSurfaceCircle); setSurfaceSquareFunc(DrawSurfaceSquare); cursorIcons.Enable(false); glColor4f(0.6f, 0.6f, 0.6f, 1.0f); // don't mirror the map texture with flipped cameras glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); // draw the map glDisable(GL_BLEND); readmap->DrawMinimap(); glEnable(GL_BLEND); glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); // clip everything outside of the minimap box { const double plane0[4] = {0,-1,0,1}; const double plane1[4] = {0,1,0,0}; const double plane2[4] = {-1,0,0,1}; const double plane3[4] = {1,0,0,0}; glClipPlane(GL_CLIP_PLANE0, plane0); // clip bottom glClipPlane(GL_CLIP_PLANE1, plane1); // clip top glClipPlane(GL_CLIP_PLANE2, plane2); // clip right glClipPlane(GL_CLIP_PLANE3, plane3); // clip left glEnable(GL_CLIP_PLANE0); glEnable(GL_CLIP_PLANE1); glEnable(GL_CLIP_PLANE2); glEnable(GL_CLIP_PLANE3); } // switch to top-down map/world coords (z is twisted with y compared to the real map/world coords) glPushMatrix(); glTranslatef(0.0f, +1.0f, 0.0f); glScalef(+1.0f / (gs->mapx * SQUARE_SIZE), -1.0f / (gs->mapy * SQUARE_SIZE), 1.0f); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f); { GML_RECMUTEX_LOCK(unit); // DrawForReal const std::set<CUnit*>& units = unitDrawer->GetUnsortedUnits(); for (std::set<CUnit*>::const_iterator it = units.begin(); it != units.end(); ++it) { DrawUnit(*it); } // highlight the selected unit CUnit* unit = GetSelectUnit(GetMapPosition(mouse->lastx, mouse->lasty)); if (unit != NULL) { DrawUnitHighlight(unit); } } glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); glPushMatrix(); glRotatef(-90.0f, +1.0f, 0.0f, 0.0f); // real 'world' coordinates glScalef(1.0f, 0.0f, 1.0f); // skip the y-coord (Lua's DrawScreen is perspective and so any z-coord in it influence the x&y, too) // draw the projectiles if (drawProjectiles) { projectileDrawer->DrawProjectilesMiniMap(); } // draw the queued commands // // NOTE: this needlessly adds to the CursorIcons list, but at least // they are not drawn (because the input receivers are drawn // after the command queues) LuaUnsyncedCtrl::DrawUnitCommandQueues(); if ((drawCommands > 0) && guihandler->GetQueueKeystate()) { selectedUnits.DrawCommands(); } lineDrawer.DrawAll(); // draw the selection shape, and some ranges if (drawCommands > 0) { guihandler->DrawMapStuff(!!drawCommands); } { GML_RECMUTEX_LOCK(sel); // DrawForReal // draw unit ranges const float radarSquare = radarhandler->radarDiv; CUnitSet& selUnits = selectedUnits.selectedUnits; for(CUnitSet::iterator si = selUnits.begin(); si != selUnits.end(); ++si) { CUnit* unit = *si; if (unit->radarRadius && !unit->beingBuilt && unit->activated) { glColor3fv(cmdColors.rangeRadar); DrawCircle(unit->pos, (unit->radarRadius * radarSquare)); } if (unit->sonarRadius && !unit->beingBuilt && unit->activated) { glColor3fv(cmdColors.rangeSonar); DrawCircle(unit->pos, (unit->sonarRadius * radarSquare)); } if (unit->jammerRadius && !unit->beingBuilt && unit->activated) { glColor3fv(cmdColors.rangeJammer); DrawCircle(unit->pos, (unit->jammerRadius * radarSquare)); } // change if someone someday create a non stockpiled interceptor const CWeapon* w = unit->stockpileWeapon; if((w != NULL) && w->weaponDef->interceptor) { if (w->numStockpiled) { glColor3fv(cmdColors.rangeInterceptorOn); } else { glColor3fv(cmdColors.rangeInterceptorOff); } DrawCircle(unit->pos, w->weaponDef->coverageRange); } } } glPopMatrix(); // revert to the 2d xform if (!minimap->maximized) { // draw the camera frustum lines cam2->GetFrustumSides(0.0f, 0.0f, 1.0f, true); cam2->ClipFrustumLines(true, -10000.0f, 400096.0f); const std::vector<CCamera::FrustumLine>& negSides = cam2->negFrustumSides; const std::vector<CCamera::FrustumLine>& posSides = cam2->posFrustumSides; std::vector<CCamera::FrustumLine>::const_iterator fli; CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(negSides.size() * 2, 0, VA_SIZE_2D0); for (fli = negSides.begin(); fli != negSides.end(); ++fli) { if (fli->minz < fli->maxz) { va->AddVertex2dQ0(fli->base + (fli->dir * fli->minz), fli->minz); va->AddVertex2dQ0(fli->base + (fli->dir * fli->maxz), fli->maxz); } } glLineWidth(2.5f); glColor4f(0, 0, 0, 0.5f); va->DrawArray2d0(GL_LINES); glLineWidth(1.5f); glColor4f(1, 1, 1, 0.75f); va->DrawArray2d0(GL_LINES); glLineWidth(1.0f); } // selection box glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CMouseHandler::ButtonPressEvt& bp = mouse->buttons[SDL_BUTTON_LEFT]; if (selecting && fullProxy && (bp.movement > 4)) { const float3 oldPos = GetMapPosition(bp.x, bp.y); const float3 newPos = GetMapPosition(mouse->lastx, mouse->lasty); glColor4fv(cmdColors.mouseBox); glBlendFunc((GLenum)cmdColors.MouseBoxBlendSrc(), (GLenum)cmdColors.MouseBoxBlendDst()); glLineWidth(cmdColors.MouseBoxLineWidth()); float verts[] = { oldPos.x, oldPos.z, newPos.x, oldPos.z, newPos.x, newPos.z, oldPos.x, newPos.z, }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, verts); glDrawArrays(GL_LINE_LOOP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glLineWidth(1.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } DrawNotes(); // reset 1 if (resetTextureMatrix) { glMatrixMode(GL_TEXTURE_MATRIX); glPopMatrix(); } glMatrixMode(GL_MODELVIEW); if (use_geo) { glPopMatrix(); } // reset 2 glPopMatrix(); glPopAttrib(); glEnable(GL_TEXTURE_2D); { //! prepare ClipPlanes for Lua's DrawInMinimap Modelview matrix //! quote from glClipPlane spec: //! "When glClipPlane is called, equation is transformed by the inverse of the modelview matrix and stored in the resulting eye coordinates. //! Subsequent changes to the modelview matrix have no effect on the stored plane-equation components." //! -> we have to use the same modelview matrix when calling glClipPlane and later draw calls //! set the modelview matrix to the same as used in Lua's DrawInMinimap glPushMatrix(); glLoadIdentity(); glScalef(1.0f / width, 1.0f / height, 1.0f); const double plane0[4] = {0,-1,0,height}; const double plane1[4] = {0,1,0,0}; const double plane2[4] = {-1,0,0,width}; const double plane3[4] = {1,0,0,0}; glClipPlane(GL_CLIP_PLANE0, plane0); // clip bottom glClipPlane(GL_CLIP_PLANE1, plane1); // clip top glClipPlane(GL_CLIP_PLANE2, plane2); // clip right glClipPlane(GL_CLIP_PLANE3, plane3); // clip left glPopMatrix(); } //! allow the LUA scripts to draw into the minimap eventHandler.DrawInMiniMap(); if (use_geo && globalRendering->dualScreenMode) glViewport(globalRendering->viewPosX,0,globalRendering->viewSizeX,globalRendering->viewSizeY); //FIXME: Lua modifies the matrices w/o reseting it! (quite complexe to fix because ClearMatrixStack() makes it impossible to use glPushMatrix) glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,1,0,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // disable ClipPlanes glDisable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE1); glDisable(GL_CLIP_PLANE2); glDisable(GL_CLIP_PLANE3); cursorIcons.Enable(true); setSurfaceCircleFunc(NULL); setSurfaceSquareFunc(NULL); }
void CProjectileDrawer::DrawProjectilesMiniMap() { GML_RECMUTEX_LOCK(proj); // DrawProjectilesMiniMap typedef std::set<CProjectile*> ProjectileSet; typedef std::set<CProjectile*>::const_iterator ProjectileSetIt; typedef std::map<int, ProjectileSet> ProjectileBin; typedef std::map<int, ProjectileSet>::const_iterator ProjectileBinIt; for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { const ProjectileBin& projectileBin = modelRenderers[modelType]->GetProjectileBin(); if (!projectileBin.empty()) { for (ProjectileBinIt binIt = projectileBin.begin(); binIt != projectileBin.end(); ++binIt) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays((binIt->second).size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays((binIt->second).size(), 0, VA_SIZE_C); for (ProjectileSetIt setIt = (binIt->second).begin(); setIt != (binIt->second).end(); ++setIt) { CProjectile* p = *setIt; CUnit *owner = p->owner(); if ((owner && (owner->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } } } if (!renderProjectiles.empty()) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays(renderProjectiles.size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays(renderProjectiles.size(), 0, VA_SIZE_C); for (std::set<CProjectile*>::iterator it = renderProjectiles.begin(); it != renderProjectiles.end(); ++it) { CProjectile* p = *it; const CUnit* owner = p->owner(); if ((owner && (owner->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } { // check if there is enough free space in the atlas, if not try resizing // it (as many times as the number of models queued for iconification) unsigned int maxNewIcons = 0; for (unsigned int n = 0; n < queuedForRender.size(); n++) { if (!CheckResizeAtlas(n + 1)) { break; } maxNewIcons++; } // now create the new far-icons // NOTE: // the icons are RTT'ed using a snapshot of the // current state (advModelShading, sunDir, etc) // and will not track later state-changes unitDrawer->SetupForUnitDrawing(); GML_VECTOR<const CSolidObject*>::iterator it; for (it = queuedForRender.begin(); it != queuedForRender.end() && maxNewIcons > 0; ++it) { maxNewIcons--; const CSolidObject* obj = *it; const S3DModel* mdl = obj->model; unitDrawer->GetOpaqueModelRenderer(mdl->type)->PushRenderState(); unitDrawer->SetTeamColour(obj->team); if (mdl->type != MODELTYPE_3DO) { texturehandlerS3O->SetS3oTexture(mdl->textureType); } if ((int)cache.size() <= obj->team || (int)cache[obj->team].size() <= mdl->id || !cache[obj->team][mdl->id]) { CreateFarTexture(obj); } unitDrawer->GetOpaqueModelRenderer(mdl->type)->PopRenderState(); } unitDrawer->CleanUpUnitDrawing(); } glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTextureID); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); ISky::SetupFog(); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); queuedForRender.clear(); }
void InMapDraw_QuadDrawer::DrawQuad(int x, int y) { int drawQuadsX = imd->drawQuadsX; CInMapDraw::DrawQuad* dq = &imd->drawQuads[y * drawQuadsX + x]; va->EnlargeArrays(dq->points.size()*12,0,VA_SIZE_TC); // draw point markers for (std::list<CInMapDraw::MapPoint>::iterator pi = dq->points.begin(); pi != dq->points.end(); ++pi) { const int allyteam = pi->senderAllyTeam; const bool spec = pi->senderSpectator; const bool allied = (gs->Ally(gu->myAllyTeam, allyteam) && gs->Ally(allyteam, gu->myAllyTeam)); const bool maySee = (gu->spectating || (!spec && allied) || imd->drawAll); if (maySee) { float3 pos = pi->pos; float3 dif(pos - camera->pos); float camDist = dif.Length(); dif /= camDist; float3 dir1(dif.cross(UpVector)); dir1.Normalize(); float3 dir2(dif.cross(dir1)); unsigned char col[4]; col[0] = pi->color[0]; col[1] = pi->color[1]; col[2] = pi->color[2]; col[3] = 200; float size = 6; float3 pos1 = pos; float3 pos2 = pos1; pos2.y += 100; va->AddVertexQTC(pos1 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos1 + dir1 * size + dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos1 - dir1 * size + dir2 * size, 0.00f, 0, col); va->AddVertexQTC(pos1 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos1 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 + dir1 * size, 0.75f, 1, col); va->AddVertexQTC(pos2 - dir1 * size, 0.75f, 0, col); va->AddVertexQTC(pos2 - dir1 * size, 0.25f, 0, col); va->AddVertexQTC(pos2 + dir1 * size, 0.25f, 1, col); va->AddVertexQTC(pos2 + dir1 * size - dir2 * size, 0.00f, 1, col); va->AddVertexQTC(pos2 - dir1 * size - dir2 * size, 0.00f, 0, col); if (pi->label.size() > 0) { glPushMatrix(); glTranslatef3(pi->pos + UpVector * 105); glScalef(1200, 1200, 1200); glColor4ub(pi->color[0], pi->color[1], pi->color[2], 250); font->glWorldPrint(pi->label.c_str()); glPopMatrix(); } } } va->EnlargeArrays(dq->lines.size()*2,0,VA_SIZE_C); // draw line markers for (std::list<CInMapDraw::MapLine>::iterator li = dq->lines.begin(); li != dq->lines.end(); ++li) { const int allyteam = li->senderAllyTeam; const bool spec = li->senderSpectator; const bool allied = (gs->Ally(gu->myAllyTeam, allyteam) && gs->Ally(allyteam, gu->myAllyTeam)); const bool maySee = (gu->spectating || (!spec && allied) || imd->drawAll); if (maySee) { lineva->AddVertexQC(li->pos - (li->pos - camera->pos).ANormalize() * 26, li->color); lineva->AddVertexQC(li->pos2 - (li->pos2 - camera->pos).ANormalize() * 26, li->color); } } }
void CFeatureDrawer::Draw() { drawFar.clear(); if(gu->drawFog) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); } GML_RECMUTEX_LOCK(feat); // Draw fadeFeatures.clear(); fadeFeaturesS3O.clear(); CBaseGroundDrawer *gd = readmap->GetGroundDrawer(); if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB); SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0); glBindTexture(GL_TEXTURE_2D, gd->infoTex); glActiveTextureARB(GL_TEXTURE0_ARB); } unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); unitDrawer->DrawQuedS3O(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.5f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size() * 4, 0, VA_SIZE_T); for (vector<CFeature*>::iterator it = drawFar.begin(); it != drawFar.end(); ++it) { fartextureHandler->DrawFarTexture(camera, (*it)->model, (*it)->pos, (*it)->radius, (*it)->heading, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); } if (gd->DrawExtraTex()) { glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); if(drawStat.size() > 0) { if(!water->drawReflection) { for (vector<CFeature *>::iterator fi = drawStat.begin(); fi != drawStat.end(); ++fi) DrawFeatureStats(*fi); } drawStat.clear(); } }
void CSelectedUnits::Draw() { glDisable(GL_TEXTURE_2D); glDepthMask(false); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); // for line smoothing glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(cmdColors.UnitBoxLineWidth()); GML_RECMUTEX_LOCK(grpsel); // Draw if (cmdColors.unitBox[3] > 0.05f) { const CUnitSet* unitSet; if (selectedGroup != -1) { unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units; } else { unitSet = &selectedUnits; } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(unitSet->size() * 8, 0, VA_SIZE_C); for (CUnitSet::const_iterator ui = unitSet->begin(); ui != unitSet->end(); ++ui) { const CUnit* unit = *ui; if (unit->isIcon) { continue; } const int uhxsize = (unit->xsize * SQUARE_SIZE) >> 1, uhzsize = (unit->zsize * SQUARE_SIZE) >> 1, mhxsize = (unit->mobility == NULL)? uhxsize: ((unit->mobility->xsize * SQUARE_SIZE) >> 1), mhzsize = (unit->mobility == NULL)? uhzsize: ((unit->mobility->zsize * SQUARE_SIZE) >> 1); const float3 verts[8] = { // UnitDef footprint corners float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize), float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize), float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize), float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize), // MoveDef footprint corners float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize), float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize), float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize), float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize), }; const unsigned char colors[2][4] = { {(0.0f + cmdColors.unitBox[0]) * 255, (0.0f + cmdColors.unitBox[1]) * 255, (0.0f + cmdColors.unitBox[2] * 255), cmdColors.unitBox[3] * 255}, {(1.0f - cmdColors.unitBox[0]) * 255, (1.0f - cmdColors.unitBox[1]) * 255, (1.0f - cmdColors.unitBox[2] * 255), cmdColors.unitBox[3] * 255}, }; va->AddVertexQC(verts[0], colors[0]); va->AddVertexQC(verts[1], colors[0]); va->AddVertexQC(verts[2], colors[0]); va->AddVertexQC(verts[3], colors[0]); if (globalRendering->drawdebug && (mhxsize != uhxsize || mhzsize != uhzsize)) { va->AddVertexQC(verts[4], colors[1]); va->AddVertexQC(verts[5], colors[1]); va->AddVertexQC(verts[6], colors[1]); va->AddVertexQC(verts[7], colors[1]); } } va->DrawArrayC(GL_QUADS); } // highlight queued build sites if we are about to build something // (or old-style, whenever the shift key is being held down) if (cmdColors.buildBox[3] > 0.0f) { if (!selectedUnits.empty() && ((cmdColors.BuildBoxesOnShift() && keyInput->IsKeyPressed(SDLK_LSHIFT)) || ((guihandler->inCommand >= 0) && (guihandler->inCommand < int(guihandler->commands.size())) && (guihandler->commands[guihandler->inCommand].id < 0)))) { GML_STDMUTEX_LOCK(cai); // Draw bool myColor = true; glColor4fv(cmdColors.buildBox); std::list<CBuilderCAI*>::const_iterator bi; for (bi = uh->builderCAIs.begin(); bi != uh->builderCAIs.end(); ++bi) { CBuilderCAI* builder = *bi; if (builder->owner->team == gu->myTeam) { if (!myColor) { glColor4fv(cmdColors.buildBox); myColor = true; } commandDrawer->DrawQuedBuildingSquares(builder); } else if (teamHandler->AlliedTeams(builder->owner->team, gu->myTeam)) { if (myColor) { glColor4fv(cmdColors.allyBuildBox); myColor = false; } commandDrawer->DrawQuedBuildingSquares(builder); } } } } glLineWidth(1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(true); glEnable(GL_TEXTURE_2D); }
void CSelectedUnitsHandler::Draw() { glDisable(GL_TEXTURE_2D); glDepthMask(false); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); // for line smoothing glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(cmdColors.UnitBoxLineWidth()); SColor color1(cmdColors.unitBox); SColor color2(cmdColors.unitBox); color2.r = 255 - color2.r; color2.g = 255 - color2.g; color2.b = 255 - color2.b; if (color1.a > 0) { const CUnitSet* unitSet; if (selectedGroup != -1) { // note: units in this set are not necessarily all selected themselves, eg. // if autoAddBuiltUnitsToSelectedGroup is true, so we check IsUnitSelected // for each unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units; } else { unitSet = &selectedUnits; } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(unitSet->size() * 8, 0, VA_SIZE_C); for (CUnitSet::const_iterator ui = unitSet->begin(); ui != unitSet->end(); ++ui) { const CUnit* unit = *ui; const MoveDef* moveDef = unit->moveDef; if (unit->isIcon) continue; if (!IsUnitSelected(unit)) continue; const int uhxsize = (unit->xsize * SQUARE_SIZE) >> 1, uhzsize = (unit->zsize * SQUARE_SIZE) >> 1, mhxsize = (moveDef == NULL)? uhxsize: ((moveDef->xsize * SQUARE_SIZE) >> 1), mhzsize = (moveDef == NULL)? uhzsize: ((moveDef->zsize * SQUARE_SIZE) >> 1); const float3 verts[8] = { // UnitDef footprint corners float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize), float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize), float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize), float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize), // MoveDef footprint corners float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize), float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize), float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize), float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize), }; va->AddVertexQC(verts[0], color1); va->AddVertexQC(verts[1], color1); va->AddVertexQC(verts[2], color1); va->AddVertexQC(verts[3], color1); if (globalRendering->drawdebug && (mhxsize != uhxsize || mhzsize != uhzsize)) { va->AddVertexQC(verts[4], color2); va->AddVertexQC(verts[5], color2); va->AddVertexQC(verts[6], color2); va->AddVertexQC(verts[7], color2); } } va->DrawArrayC(GL_QUADS); } // highlight queued build sites if we are about to build something // (or old-style, whenever the shift key is being held down) if (cmdColors.buildBox[3] > 0.0f) { if (!selectedUnits.empty() && ((cmdColors.BuildBoxesOnShift() && KeyInput::GetKeyModState(KMOD_SHIFT)) || ((guihandler->inCommand >= 0) && (guihandler->inCommand < int(guihandler->commands.size())) && (guihandler->commands[guihandler->inCommand].id < 0)))) { bool myColor = true; glColor4fv(cmdColors.buildBox); for (const auto bi: unitHandler->GetBuilderCAIs()) { const CBuilderCAI* builderCAI = bi.second; const CUnit* builder = builderCAI->owner; if (builder->team == gu->myTeam) { if (!myColor) { glColor4fv(cmdColors.buildBox); myColor = true; } commandDrawer->DrawQuedBuildingSquares(builderCAI); } else if (teamHandler->AlliedTeams(builder->team, gu->myTeam)) { if (myColor) { glColor4fv(cmdColors.allyBuildBox); myColor = false; } commandDrawer->DrawQuedBuildingSquares(builderCAI); } } } } glLineWidth(1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(true); glEnable(GL_TEXTURE_2D); }
void CAdvWater::UpdateWater(CGame* game) { if (!waterRendering->forceRendering && !readMap->HasVisibleWater()) return; glPushAttrib(GL_FOG_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); { bumpFBO.Bind(); glViewport(0, 0, 128, 128); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glSpringMatrix2dSetupPV(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); glColor3f(0.2f, 0.2f, 0.2f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(12, 0, VA_SIZE_T); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[0]); va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0046f); va->AddVertexQT( UpVector, 0, 2 + gs->frameNum*0.0046f); va->AddVertexQT( XYVector, 2, 2 + gs->frameNum*0.0046f); va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0046f); va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0026f); va->AddVertexQT( UpVector, 0, 4 + gs->frameNum*0.0026f); va->AddVertexQT( XYVector, 2, 4 + gs->frameNum*0.0026f); va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0026f); va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0012f); va->AddVertexQT( UpVector, 0, 8 + gs->frameNum*0.0012f); va->AddVertexQT( XYVector, 2, 8 + gs->frameNum*0.0012f); va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0012f); va->DrawArrayT(GL_QUADS); va = GetVertexArray(); va->Initialize(); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[1]); va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0036f); va->AddVertexQT( UpVector, 0, 1 + gs->frameNum*0.0036f); va->AddVertexQT( XYVector, 1, 1 + gs->frameNum*0.0036f); va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0036f); va->DrawArrayT(GL_QUADS); va = GetVertexArray(); va->Initialize(); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[2]); va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0082f); va->AddVertexQT( UpVector, 0, 1 + gs->frameNum*0.0082f); va->AddVertexQT( XYVector, 1, 1 + gs->frameNum*0.0082f); va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0082f); va->DrawArrayT(GL_QUADS); // this fixes a memory leak on ATI cards glBindTexture(GL_TEXTURE_2D, 0); glColor3f(1.0f, 1.0f, 1.0f); } reflectFBO.Bind(); glClearColor(sky->fogColor[0], sky->fogColor[1], sky->fogColor[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const double clipPlaneEqs[2 * 4] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, }; CCamera* prvCam = CCamera::GetSetActiveCamera(CCamera::CAMTYPE_UWREFL); CCamera* curCam = CCamera::GetActiveCamera(); { curCam->CopyStateReflect(prvCam); curCam->UpdateLoadViewPort(0, 0, 512, 512); DrawReflections(&clipPlaneEqs[0], true, true); } CCamera::SetActiveCamera(prvCam->GetCamType()); prvCam->Update(); prvCam->LoadViewPort(); FBO::Unbind(); glPopAttrib(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
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); }
void CAdvTreeDrawer::Draw(float treeDistance, bool drawReflection) { const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0]: treeGen->farTex[1]; const bool drawDetailed = ((treeDistance >= 4.0f) || drawReflection); CBaseGroundDrawer* gd = readmap->GetGroundDrawer(); Shader::IProgramObject* treeShader = NULL; const CMapInfo::light_t& light = mapInfo->light; glEnable(GL_ALPHA_TEST); glEnable(GL_TEXTURE_2D); ISky::SetupFog(); if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, shadowHandler->shadowTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW]; treeShader->Enable(); if (globalRendering->haveGLSL) { treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]); treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x)); } else { treeShader->SetUniformTarget(GL_FRAGMENT_PROGRAM_ARB); treeShader->SetUniform4f(10, light.groundAmbientColor.x, light.groundAmbientColor.y, light.groundAmbientColor.z, 1.0f); treeShader->SetUniform4f(11, 0.0f, 0.0f, 0.0f, 1.0f - (sky->GetLight()->GetGroundShadowDensity() * 0.5f)); treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); glMatrixMode(GL_MATRIX0_ARB); glLoadMatrixf(shadowHandler->shadowMatrix.m); glMatrixMode(GL_MODELVIEW); } } else { glBindTexture(GL_TEXTURE_2D, activeFarTex); } const int cx = int(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE)); const int cy = int(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE)); CAdvTreeSquareDrawer drawer(this, cx, cy, treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE, drawDetailed); GML_STDMUTEX_LOCK(tree); // Draw oldTreeDistance = treeDistance; // draw far-trees using map-dependent grid-visibility readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer); if (drawDetailed) { // draw near-trees const int xstart = std::max( 0, cx - 2); const int xend = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2); const int ystart = std::max( 0, cy - 2); const int yend = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2); if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); treeShader = treeShaders[TREE_PROGRAM_NEAR_SHADOW]; treeShader->Enable(); if (globalRendering->haveGLSL) { treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]); treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x)); } glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glActiveTexture(GL_TEXTURE0); } else { glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); treeShader = treeShaders[TREE_PROGRAM_NEAR_BASIC]; treeShader->Enable(); if (!globalRendering->haveGLSL) { const int mx = gs->pwr2mapx * SQUARE_SIZE; const int my = gs->pwr2mapy * SQUARE_SIZE; treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); treeShader->SetUniform4f(15, 1.0f / mx, 1.0f / my, 1.0f / mx, 1.0f); } } if (globalRendering->haveGLSL) { treeShader->SetUniform3fv(0, &camera->right[0]); treeShader->SetUniform3fv(1, &camera->up[0]); treeShader->SetUniform2f(5, 0.20f * (1.0f / MAX_TREE_HEIGHT), 0.85f); } else { treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); treeShader->SetUniform3f(13, camera->right.x, camera->right.y, camera->right.z); treeShader->SetUniform3f( 9, camera->up.x, camera->up.y, camera->up.z ); treeShader->SetUniform4f(11, light.groundSunColor.x, light.groundSunColor.y, light.groundSunColor.z, 0.85f); treeShader->SetUniform4f(14, light.groundAmbientColor.x, light.groundAmbientColor.y, light.groundAmbientColor.z, 0.85f); treeShader->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT)); // w = alpha/height modifier } glAlphaFunc(GL_GREATER, 0.5f); glDisable(GL_BLEND); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); static FadeTree fadeTrees[3000]; FadeTree* pFT = fadeTrees; for (TreeSquareStruct* pTSS = trees + (ystart * treesX); pTSS <= trees + (yend * treesX); pTSS += treesX) { for (TreeSquareStruct* tss = pTSS + xstart; tss <= (pTSS + xend); ++tss) { tss->lastSeen = gs->frameNum; va->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { const TreeStruct* ts = &ti->second; const float3 pos(ts->pos); if (!camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2.0f, 0.0f), MAX_TREE_HEIGHT / 2.0f)) { continue; } const float camDist = (pos - camera->pos).SqLength(); int type = ts->type; float dy = 0.0f; unsigned int dispList; if (type < 8) { dy = 0.5f; dispList = treeGen->pineDL + type; } else { type -= 8; dy = 0.0f; dispList = treeGen->leafDL + type; } if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 110 * 110)) { // draw detailed near-distance tree (same as mid-distance trees without alpha) treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z); glCallList(dispList); } else if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 125 * 125)) { // draw mid-distance tree const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15); treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z); glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f); glCallList(dispList); glAlphaFunc(GL_GREATER, 0.5f); // save for second pass pFT->pos = pos; pFT->deltaY = dy; pFT->type = type; pFT->relDist = relDist; ++pFT; } else { // draw far-distance tree CAdvTreeDrawer::DrawTreeVertex(va, pos, type * 0.125f, dy, false); } } } } // reset the world-offset treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), 0.0f, 0.0f, 0.0f); // draw trees that have been marked as falling for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) { const float3 pos = fti->pos - UpVector * (fti->fallPos * 20); if (camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2, 0.0f), MAX_TREE_HEIGHT / 2.0f)) { const float ang = fti->fallPos * PI; const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang)); const float3 zvec((yvec.cross(float3(-1.0f, 0.0f, 0.0f))).ANormalize()); const float3 xvec(yvec.cross(zvec)); CMatrix44f transMatrix(pos, xvec, yvec, zvec); glPushMatrix(); glMultMatrixf(&transMatrix[0]); int type = fti->type; int dispList = 0; if (type < 8) { dispList = treeGen->pineDL + type; } else { type -= 8; dispList = treeGen->leafDL + type; } glCallList(dispList); glPopMatrix(); } } if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW]; treeShader->Enable(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTexture(GL_TEXTURE0); } else { treeShader->Disable(); glBindTexture(GL_TEXTURE_2D, activeFarTex); } // draw far-distance trees va->DrawArrayT(GL_QUADS); // draw faded mid-distance trees for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) { va = GetVertexArray(); va->Initialize(); va->CheckInitSize(12 * VA_SIZE_T); CAdvTreeDrawer::DrawTreeVertex(va, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f)); va->DrawArrayT(GL_QUADS); } } if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) { treeShader->Disable(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); } else { glBindTexture(GL_TEXTURE_2D, 0); } glDisable(GL_TEXTURE_2D); glDisable(GL_FOG); glDisable(GL_ALPHA_TEST); // clean out squares from memory that are no longer visible const int startClean = lastListClean * 20 % (nTrees); const int endClean = gs->frameNum * 20 % (nTrees); lastListClean = gs->frameNum; if (startClean > endClean) { for (TreeSquareStruct* pTSS = trees + startClean; pTSS < (trees + nTrees); ++pTSS) { if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->dispList) { glDeleteLists(pTSS->dispList, 1); pTSS->dispList = 0; } if ((pTSS->lastSeenFar < (gs->frameNum - 50)) && pTSS->farDispList) { glDeleteLists(pTSS->farDispList, 1); pTSS->farDispList = 0; } } for (TreeSquareStruct* pTSS = trees; pTSS < (trees + endClean); ++pTSS) { if ((pTSS->lastSeen < (gs->frameNum - 50)) && pTSS->dispList) { glDeleteLists(pTSS->dispList, 1); pTSS->dispList = 0; } if ((pTSS->lastSeenFar < (gs->frameNum - 50)) && pTSS->farDispList) { glDeleteLists(pTSS->farDispList, 1); pTSS->farDispList = 0; } } } else { for (TreeSquareStruct* pTSS = trees + startClean; pTSS < (trees + endClean); ++pTSS) { if ((pTSS->lastSeen < (gs->frameNum - 50)) && pTSS->dispList) { glDeleteLists(pTSS->dispList, 1); pTSS->dispList = 0; } if ((pTSS->lastSeenFar < (gs->frameNum - 50)) && pTSS->farDispList) { glDeleteLists(pTSS->farDispList, 1); pTSS->farDispList = 0; } } } }
void CAdvTreeSquareDrawer_SP::DrawQuad(int x, int y) { const int treesX = td->treesX; CAdvTreeDrawer::TreeSquareStruct* tss = &td->trees[(y * treesX) + x]; if ((abs(cy - y) <= 2) && (abs(cx - x) <= 2) && drawDetailed) { // skip the closest squares return; } float3 dif; dif.x = camera->pos.x - ((x * SQUARE_SIZE * TREE_SQUARE_SIZE) + (SQUARE_SIZE * TREE_SQUARE_SIZE / 2)); dif.y = 0.0f; dif.z = camera->pos.z - ((y * SQUARE_SIZE * TREE_SQUARE_SIZE) + (SQUARE_SIZE * TREE_SQUARE_SIZE / 2)); const float dist = dif.Length(); const float distFactor = dist / treeDistance; dif.Normalize(); if (distFactor < MID_TREE_DIST_FACTOR) { // midle distance trees tss->lastSeen = gs->frameNum; if (!tss->dispList) { CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes tss->dispList = glGenLists(1); for (std::map<int, CAdvTreeDrawer::TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { CAdvTreeDrawer::TreeStruct* ts = &ti->second; if (ts->type < 8) { CAdvTreeDrawer::DrawTreeVertexMid(va, ts->pos, (ts->type ) * 0.125f, 0.5f, false); } else { CAdvTreeDrawer::DrawTreeVertexMid(va, ts->pos, (ts->type - 8) * 0.125f, 0.0f, false); } } glNewList(tss->dispList, GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glAlphaFunc(GL_GREATER, 0.5f); glCallList(tss->dispList); } else if (distFactor < FAR_TREE_DIST_FACTOR) { // far trees tss->lastSeenFar = gs->frameNum; if (!tss->farDispList || dif.dot(tss->viewVector) < 0.97f) { CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(4 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes tss->viewVector = dif; if (!tss->farDispList) tss->farDispList = glGenLists(1); const float3 side = UpVector.cross(dif); for (std::map<int, CAdvTreeDrawer::TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { CAdvTreeDrawer::TreeStruct* ts = &ti->second; if (ts->type < 8) { CAdvTreeDrawer::DrawTreeVertexFar(va, ts->pos, side * HALF_MAX_TREE_HEIGHT, (ts->type ) * 0.125f, 0.5f, false); } else { CAdvTreeDrawer::DrawTreeVertexFar(va, ts->pos, side * HALF_MAX_TREE_HEIGHT, (ts->type - 8) * 0.125f, 0.0f, false); } } glNewList(tss->farDispList, GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } if (distFactor > FADE_TREE_DIST_FACTOR) { // faded far trees const float alpha = 1.0f - (distFactor - FADE_TREE_DIST_FACTOR) / (FAR_TREE_DIST_FACTOR - FADE_TREE_DIST_FACTOR); glColor4f(1.0f, 1.0f, 1.0f, alpha); glAlphaFunc(GL_GREATER, alpha * 0.5f); } else { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glAlphaFunc(GL_GREATER, 0.5f); } glCallList(tss->farDispList); } }
void CAdvWater::UpdateWater(CGame* game) { if ((!mapInfo->water.forceRendering && (readmap->currMinHeight > 1.0f)) || mapInfo->map.voidWater) { return; } glPushAttrib(GL_FOG_BIT); glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); bumpFBO.Bind(); glViewport(0, 0, 128, 128); glClearColor(0.0f, 0.0f, 0.0f, 1); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 1, 0, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f(0.2f, 0.2f, 0.2f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(12, 0, VA_SIZE_T); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[0]); va->AddVertexQT(float3(0, 0, 0), 0, 0 + gs->frameNum*0.0046f); va->AddVertexQT(float3(0, 1, 0), 0, 2 + gs->frameNum*0.0046f); va->AddVertexQT(float3(1, 1, 0), 2, 2 + gs->frameNum*0.0046f); va->AddVertexQT(float3(1, 0, 0), 2, 0 + gs->frameNum*0.0046f); va->AddVertexQT(float3(0, 0, 0), 0, 0 + gs->frameNum*0.0026f); va->AddVertexQT(float3(0, 1, 0), 0, 4 + gs->frameNum*0.0026f); va->AddVertexQT(float3(1, 1, 0), 2, 4 + gs->frameNum*0.0026f); va->AddVertexQT(float3(1, 0, 0), 2, 0 + gs->frameNum*0.0026f); va->AddVertexQT(float3(0, 0, 0), 0, 0 + gs->frameNum*0.0012f); va->AddVertexQT(float3(0, 1, 0), 0, 8 + gs->frameNum*0.0012f); va->AddVertexQT(float3(1, 1, 0), 2, 8 + gs->frameNum*0.0012f); va->AddVertexQT(float3(1, 0, 0), 2, 0 + gs->frameNum*0.0012f); va->DrawArrayT(GL_QUADS); va->Initialize(); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[1]); va->AddVertexQT(float3(0, 0, 0), 0, 0 + gs->frameNum*0.0036f); va->AddVertexQT(float3(0, 1, 0), 0, 1 + gs->frameNum*0.0036f); va->AddVertexQT(float3(1, 1, 0), 1, 1 + gs->frameNum*0.0036f); va->AddVertexQT(float3(1, 0, 0), 1, 0 + gs->frameNum*0.0036f); va->DrawArrayT(GL_QUADS); va->Initialize(); glBindTexture(GL_TEXTURE_2D, rawBumpTexture[2]); va->AddVertexQT(float3(0, 0, 0), 0, 0 + gs->frameNum*0.0082f); va->AddVertexQT(float3(0, 1, 0), 0, 1 + gs->frameNum*0.0082f); va->AddVertexQT(float3(1, 1, 0), 1, 1 + gs->frameNum*0.0082f); va->AddVertexQT(float3(1, 0, 0), 1, 0 + gs->frameNum*0.0082f); va->DrawArrayT(GL_QUADS); // this fixes a memory leak on ATI cards glBindTexture(GL_TEXTURE_2D, 0); glColor3f(1, 1, 1); // CCamera* realCam = camera; // camera = new CCamera(*realCam); char realCam[sizeof(CCamera)]; new (realCam) CCamera(*camera); // anti-crash workaround for multithreading camera->forward.y *= -1.0f; camera->pos.y *= -1.0f; camera->Update(false); reflectFBO.Bind(); glViewport(0, 0, 512, 512); glClear(GL_DEPTH_BUFFER_BIT); game->SetDrawMode(CGame::gameReflectionDraw); sky->Draw(); glEnable(GL_CLIP_PLANE2); double plane[4] = {0, 1, 0, 0}; glClipPlane(GL_CLIP_PLANE2, plane); drawReflection = true; readmap->GetGroundDrawer()->Draw(true); unitDrawer->Draw(true); featureDrawer->Draw(); unitDrawer->DrawCloakedUnits(true); featureDrawer->DrawFadeFeatures(true); projectileDrawer->Draw(true); eventHandler.DrawWorldReflection(); game->SetDrawMode(CGame::gameNormalDraw); drawReflection = false; glDisable(GL_CLIP_PLANE2); FBO::Unbind(); glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glClearColor(mapInfo->atmosphere.fogColor[0], mapInfo->atmosphere.fogColor[1], mapInfo->atmosphere.fogColor[2], 1); // delete camera; // camera = realCam; camera->~CCamera(); new (camera) CCamera(*(CCamera*)realCam); camera->Update(false); glPopAttrib(); glPopAttrib(); }
void CAdvTreeDrawer::DrawShadowPass() { const float treeDistance = oldTreeDistance; const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0] : treeGen->farTex[1]; const bool drawDetailed = (treeDistance >= 4.0f); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, activeFarTex); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA_TEST); glDisable(GL_CULL_FACE); glPolygonOffset(1, 1); glEnable(GL_POLYGON_OFFSET_FILL); CAdvTreeSquareDrawer_SP drawer; const int cx = drawer.cx = (int)(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE)); const int cy = drawer.cy = (int)(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE)); drawer.drawDetailed = drawDetailed; drawer.td = this; drawer.treeDistance = treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE; Shader::IProgramObject* po = NULL; GML_STDMUTEX_LOCK(tree); // DrawShadowPass // draw with extraSize=1 readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer, 1); if (drawDetailed) { const int xstart = std::max( 0, cx - 2); const int xend = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2); const int ystart = std::max( 0, cy - 2); const int yend = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glEnable(GL_TEXTURE_2D); po = shadowHandler->GetShadowGenProg(CShadowHandler::SHADOWGEN_PROGRAM_TREE_NEAR); po->Enable(); if (globalRendering->haveGLSL) { po->SetUniform3fv(1, &camera->right[0]); po->SetUniform3fv(2, &camera->up[0]); } else { po->SetUniformTarget(GL_VERTEX_PROGRAM_ARB); po->SetUniform4f(13, camera->right.x, camera->right.y, camera->right.z, 0.0f); po->SetUniform4f(9, camera->up.x, camera->up.y, camera->up.z, 0.0f); po->SetUniform4f(11, 1.0f, 1.0f, 1.0f, 0.85f ); po->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT)); // w = alpha/height modifier } glAlphaFunc(GL_GREATER, 0.5f); glEnable(GL_ALPHA_TEST); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); static FadeTree fadeTrees[3000]; FadeTree* pFT = fadeTrees; for (TreeSquareStruct* pTSS = trees + (ystart * treesX); pTSS <= trees + (yend * treesX); pTSS += treesX) { for (TreeSquareStruct* tss = pTSS + xstart; tss <= pTSS + xend; ++tss) { tss->lastSeen = gs->frameNum; va->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { const TreeStruct* ts = &ti->second; const float3 pos(ts->pos); if (!camera->InView(pos + float3(0, MAX_TREE_HEIGHT / 2, 0), MAX_TREE_HEIGHT / 2 + 150)) { continue; } const float camDist = (pos - camera->pos).SqLength(); int type = ts->type; float dy = 0.0f; unsigned int dispList; if (type < 8) { dy = 0.5f; dispList = treeGen->pineDL + type; } else { type -= 8; dy = 0; dispList = treeGen->leafDL + type; } if (camDist < SQUARE_SIZE * SQUARE_SIZE * 110 * 110) { po->SetUniform3f((globalRendering->haveGLSL? 3: 10), pos.x, pos.y, pos.z); glCallList(dispList); } else if (camDist < SQUARE_SIZE * SQUARE_SIZE * 125 * 125) { const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15); glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f); po->SetUniform3f((globalRendering->haveGLSL? 3: 10), pos.x, pos.y, pos.z); glCallList(dispList); glAlphaFunc(GL_GREATER, 0.5f); pFT->pos = pos; pFT->deltaY = dy; pFT->type = type; pFT->relDist = relDist; ++pFT; } else { CAdvTreeDrawer::DrawTreeVertex(va, pos, type * 0.125f, dy, false); } } } } po->SetUniform3f((globalRendering->haveGLSL? 3: 10), 0.0f, 0.0f, 0.0f); for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) { const float3 pos = fti->pos - UpVector * (fti->fallPos * 20); if (camera->InView(pos + float3(0, MAX_TREE_HEIGHT / 2, 0), MAX_TREE_HEIGHT / 2)) { const float ang = fti->fallPos * PI; const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang)); const float3 zvec((yvec.cross(float3(1.0f, 0.0f, 0.0f))).ANormalize()); const float3 xvec(zvec.cross(yvec)); CMatrix44f transMatrix(pos, xvec, yvec, zvec); glPushMatrix(); glMultMatrixf(&transMatrix[0]); int type = fti->type; int dispList; if (type < 8) { dispList = treeGen->pineDL + type; } else { type -= 8; dispList = treeGen->leafDL + type; } glCallList(dispList); glPopMatrix(); } } po->Disable(); po = shadowHandler->GetShadowGenProg(CShadowHandler::SHADOWGEN_PROGRAM_TREE_FAR); po->Enable(); glBindTexture(GL_TEXTURE_2D, activeFarTex); va->DrawArrayT(GL_QUADS); for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) { // faded close trees va = GetVertexArray(); va->Initialize(); va->CheckInitSize(12 * VA_SIZE_T); CAdvTreeDrawer::DrawTreeVertex(va, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f)); va->DrawArrayT(GL_QUADS); } po->Disable(); } glEnable(GL_CULL_FACE); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); }
void CAdvWater::Draw(bool useBlending) { if (!mapInfo->water.forceRendering && (readmap->currMinHeight > 1.0f)) { return; } float3 base = camera->CalcPixelDir(globalRendering->viewPosX, globalRendering->viewSizeY); float3 dv = camera->CalcPixelDir(globalRendering->viewPosX, 0) - camera->CalcPixelDir(globalRendering->viewPosX, globalRendering->viewSizeY); float3 dh = camera->CalcPixelDir(globalRendering->viewPosX + globalRendering->viewSizeX, 0) - camera->CalcPixelDir(globalRendering->viewPosX, 0); float3 xbase; const int numDivs = 20; base *= numDivs; float maxY = -0.1f; float yInc = 1.0f / numDivs; float screenY = 1; unsigned char col[4]; col[0] = (unsigned char)(waterSurfaceColor.x * 255); col[1] = (unsigned char)(waterSurfaceColor.y * 255); col[2] = (unsigned char)(waterSurfaceColor.z * 255); glDisable(GL_ALPHA_TEST); if (useBlending) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } glDepthMask(0); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, bumpTexture); GLfloat plan[] = {0.02f, 0, 0, 0}; glTexGeni(GL_S,GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_S,GL_EYE_PLANE, plan); glEnable(GL_TEXTURE_GEN_S); GLfloat plan2[] = {0, 0, 0.02f, 0}; glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_T, GL_EYE_PLANE, plan2); glEnable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, reflectTexture); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, waterFP); glEnable(GL_FRAGMENT_PROGRAM_ARB); float3 forward = camera->forward; forward.y = 0; forward.ANormalize(); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, forward.z, forward.x, 0, 0); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, -forward.x, forward.z, 0, 0); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(5*numDivs*(numDivs + 1)*2, 5*numDivs, VA_SIZE_TC); //! alloc room for all vertexes and strips float3 dir, zpos; for (int a = 0; a < 5; ++a) { //! CAUTION: loop count must match EnlargeArrays above bool maxReached = false; for (int y = 0; y < numDivs; ++y) { dir = base; dir.ANormalize(); if (dir.y >= maxY) { maxReached = true; break; } xbase = base; for (int x = 0; x < numDivs + 1; ++x) { //! CAUTION: loop count must match EnlargeArrays above dir = xbase + dv; dir.ANormalize(); zpos = camera->pos + dir*(camera->pos.y / -dir.y); zpos.y = sin(zpos.z*0.1f + gs->frameNum*0.06f)*0.06f + 0.05f; col[3] = (unsigned char)((0.8f + 0.7f*dir.y)*255); va->AddVertexQTC(zpos, x*(1.0f/numDivs), screenY - yInc, col); dir = xbase; dir.ANormalize(); zpos = camera->pos + dir*(camera->pos.y / -dir.y); zpos.y = sin(zpos.z*0.1f + gs->frameNum*0.06f)*0.06f + 0.05f; col[3] = (unsigned char)((0.8f + 0.7f*dir.y)*255); va->AddVertexQTC(zpos, x*(1.0f/numDivs), screenY, col); xbase += dh; } va->EndStripQ(); base += dv; screenY -= yInc; } if (!maxReached) { break; } dv *= 0.5f; maxY *= 0.5f; yInc *= 0.5f; } va->DrawArrayTC(GL_TRIANGLE_STRIP); glDepthMask(1); glDisable(GL_FRAGMENT_PROGRAM_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); if (!useBlending) { // for translucent stuff like water, the default mode is blending and alpha testing enabled glEnable(GL_BLEND); } }
void CLegacyMeshDrawer::DoDrawGroundRow(const CCamera* cam, int bty) { if (!BigTexSquareRowVisible(cam, bty)) { //! skip this entire row of squares if we can't see it return; } CVertexArray* ma = GetVertexArray(); bool inStrip = false; float x0, x1; int x,y; int sx = 0; int ex = smfReadMap->numBigTexX; //! only process the necessary big squares in the x direction const int bigSquareSizeY = bty * smfReadMap->bigSquareSize; const std::vector<CCamera::FrustumLine> negSides = cam->GetNegFrustumSides(); const std::vector<CCamera::FrustumLine> posSides = cam->GetPosFrustumSides(); std::vector<CCamera::FrustumLine>::const_iterator fli; for (fli = negSides.begin(); fli != negSides.end(); ++fli) { x0 = fli->base + fli->dir * bigSquareSizeY; x1 = x0 + fli->dir * smfReadMap->bigSquareSize; if (x0 > x1) x0 = x1; x0 /= smfReadMap->bigSquareSize; if (x0 > sx) sx = (int) x0; } for (fli = posSides.begin(); fli != posSides.end(); ++fli) { x0 = fli->base + fli->dir * bigSquareSizeY + smfReadMap->bigSquareSize; x1 = x0 + fli->dir * smfReadMap->bigSquareSize; if (x0 < x1) x0 = x1; x0 /= smfReadMap->bigSquareSize; if (x0 < ex) ex = (int) x0; } if (sx > ex) return; const float cx2 = cam2->GetPos().x / SQUARE_SIZE; const float cy2 = cam2->GetPos().z / SQUARE_SIZE; for (int btx = sx; btx < ex; ++btx) { ma->Initialize(); for (int lod = 1; lod < neededLod; lod <<= 1) { float oldcamxpart = 0.0f; float oldcamypart = 0.0f; const int hlod = lod >> 1; const int dlod = lod << 1; int cx = cx2; int cy = cy2; if (lod > 1) { int cxo = (cx / hlod) * hlod; int cyo = (cy / hlod) * hlod; float cx2o = (cxo / lod) * lod; float cy2o = (cyo / lod) * lod; oldcamxpart = (cx2 - cx2o) / lod; oldcamypart = (cy2 - cy2o) / lod; } cx = (cx / lod) * lod; cy = (cy / lod) * lod; const int ysquaremod = (cy % dlod) / lod; const int xsquaremod = (cx % dlod) / lod; const float camxpart = (cx2 - ((cx / dlod) * dlod)) / dlod; const float camypart = (cy2 - ((cy / dlod) * dlod)) / dlod; const float mcxp = 1.0f - camxpart, mcyp = 1.0f - camypart; const float hcxp = 0.5f * camxpart, hcyp = 0.5f * camypart; const float hmcxp = 0.5f * mcxp, hmcyp = 0.5f * mcyp; const float mocxp = 1.0f - oldcamxpart, mocyp = 1.0f - oldcamypart; const float hocxp = 0.5f * oldcamxpart, hocyp = 0.5f * oldcamypart; const float hmocxp = 0.5f * mocxp, hmocyp = 0.5f * mocyp; const int minty = bty * smfReadMap->bigSquareSize, maxty = minty + smfReadMap->bigSquareSize; const int mintx = btx * smfReadMap->bigSquareSize, maxtx = mintx + smfReadMap->bigSquareSize; const int minly = cy + (-viewRadius + 3 - ysquaremod) * lod; const int maxly = cy + ( viewRadius - 1 - ysquaremod) * lod; const int minlx = cx + (-viewRadius + 3 - xsquaremod) * lod; const int maxlx = cx + ( viewRadius - 1 - xsquaremod) * lod; const int xstart = std::max(minlx, mintx), xend = std::min(maxlx, maxtx); const int ystart = std::max(minly, minty), yend = std::min(maxly, maxty); const int vrhlod = viewRadius * hlod; for (y = ystart; y < yend; y += lod) { int xs = xstart; int xe = xend; FindRange(cam2, /*inout*/ xs, /*inout*/ xe, y, lod); // If FindRange modifies (xs, xe) to a (less then) empty range, // continue to the next row. // If we'd continue, nloop (below) would become negative and we'd // allocate a vertex array with negative size. (mantis #1415) if (xe < xs) continue; int ylod = y + lod; int yhlod = y + hlod; int nloop = (xe - xs) / lod + 1; ma->EnlargeArrays(52 * nloop); int yhdx = y * smfReadMap->heightMapSizeX; int ylhdx = yhdx + lod * smfReadMap->heightMapSizeX; int yhhdx = yhdx + hlod * smfReadMap->heightMapSizeX; for (x = xs; x < xe; x += lod) { int xlod = x + lod; int xhlod = x + hlod; //! info: all triangle quads start in the top left corner if ((lod == 1) || (x > cx + vrhlod) || (x < cx - vrhlod) || (y > cy + vrhlod) || (y < cy - vrhlod)) { //! normal terrain (all vertices in one LOD) if (!inStrip) { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod); inStrip = true; } DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xlod, ylod); } else { //! border between 2 different LODs if ((x >= cx + vrhlod)) { //! lower LOD to the right int idx1 = CLAMP(yhdx + x), idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod); int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod); int idx3 = CLAMP(yhhdx + x), idx3HLOD = CLAMP(idx3 + hlod); float h1 = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx2)) * hmocxp + GetVisibleVertexHeight(idx3) * oldcamxpart; float h2 = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx1LOD)) * hmocxp + GetVisibleVertexHeight(idx1HLOD) * oldcamxpart; float h3 = (GetVisibleVertexHeight(idx2) + GetVisibleVertexHeight(idx1LOD)) * hmocxp + GetVisibleVertexHeight(idx3HLOD) * oldcamxpart; float h4 = (GetVisibleVertexHeight(idx2) + GetVisibleVertexHeight(idx2LOD)) * hmocxp + GetVisibleVertexHeight(idx2HLOD) * oldcamxpart; if (inStrip) { ma->EndStrip(); inStrip = false; } DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, yhlod, h1); DrawVertexAQ(ma, xhlod, y, h2); DrawVertexAQ(ma, xhlod, yhlod, h3); ma->EndStrip(); DrawVertexAQ(ma, x, yhlod, h1); DrawVertexAQ(ma, x, ylod); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xhlod, ylod, h4); ma->EndStrip(); DrawVertexAQ(ma, xhlod, ylod, h4); DrawVertexAQ(ma, xlod, ylod); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xhlod, y, h2); ma->EndStrip(); } else if ((x <= cx - vrhlod)) { //! lower LOD to the left int idx1 = CLAMP(yhdx + x), idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod); int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod); int idx3 = CLAMP(yhhdx + x), idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod); float h1 = (GetVisibleVertexHeight(idx1LOD) + GetVisibleVertexHeight(idx2LOD)) * hocxp + GetVisibleVertexHeight(idx3LOD ) * mocxp; float h2 = (GetVisibleVertexHeight(idx1 ) + GetVisibleVertexHeight(idx1LOD)) * hocxp + GetVisibleVertexHeight(idx1HLOD) * mocxp; float h3 = (GetVisibleVertexHeight(idx2 ) + GetVisibleVertexHeight(idx1LOD)) * hocxp + GetVisibleVertexHeight(idx3HLOD) * mocxp; float h4 = (GetVisibleVertexHeight(idx2 ) + GetVisibleVertexHeight(idx2LOD)) * hocxp + GetVisibleVertexHeight(idx2HLOD) * mocxp; if (inStrip) { ma->EndStrip(); inStrip = false; } DrawVertexAQ(ma, xlod, yhlod, h1); DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xhlod, y, h2); ma->EndStrip(); DrawVertexAQ(ma, xlod, ylod); DrawVertexAQ(ma, xlod, yhlod, h1); DrawVertexAQ(ma, xhlod, ylod, h4); DrawVertexAQ(ma, xhlod, yhlod, h3); ma->EndStrip(); DrawVertexAQ(ma, xhlod, y, h2); DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, x, ylod); DrawVertexAQ(ma, xhlod, ylod, h4); ma->EndStrip(); } if ((y >= cy + vrhlod)) { //! lower LOD above int idx1 = yhdx + x, idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod); int idx2 = ylhdx + x, idx2LOD = CLAMP(idx2 + lod); int idx3 = yhhdx + x, idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod); float h1 = (GetVisibleVertexHeight(idx1 ) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx1HLOD) * oldcamypart; float h2 = (GetVisibleVertexHeight(idx1 ) + GetVisibleVertexHeight(idx2 )) * hmocyp + GetVisibleVertexHeight(idx3 ) * oldcamypart; float h3 = (GetVisibleVertexHeight(idx2 ) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx3HLOD) * oldcamypart; float h4 = (GetVisibleVertexHeight(idx2LOD) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx3LOD ) * oldcamypart; if (inStrip) { ma->EndStrip(); inStrip = false; } DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, yhlod, h2); DrawVertexAQ(ma, xhlod, y, h1); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xlod, yhlod, h4); ma->EndStrip(); DrawVertexAQ(ma, x, yhlod, h2); DrawVertexAQ(ma, x, ylod); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xlod, ylod); DrawVertexAQ(ma, xlod, yhlod, h4); ma->EndStrip(); } else if ((y <= cy - vrhlod)) { //! lower LOD beneath int idx1 = CLAMP(yhdx + x), idx1LOD = CLAMP(idx1 + lod); int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod); int idx3 = CLAMP(yhhdx + x), idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod); float h1 = (GetVisibleVertexHeight(idx2 ) + GetVisibleVertexHeight(idx2LOD)) * hocyp + GetVisibleVertexHeight(idx2HLOD) * mocyp; float h2 = (GetVisibleVertexHeight(idx1 ) + GetVisibleVertexHeight(idx2 )) * hocyp + GetVisibleVertexHeight(idx3 ) * mocyp; float h3 = (GetVisibleVertexHeight(idx2 ) + GetVisibleVertexHeight(idx1LOD)) * hocyp + GetVisibleVertexHeight(idx3HLOD) * mocyp; float h4 = (GetVisibleVertexHeight(idx2LOD) + GetVisibleVertexHeight(idx1LOD)) * hocyp + GetVisibleVertexHeight(idx3LOD ) * mocyp; if (inStrip) { ma->EndStrip(); inStrip = false; } DrawVertexAQ(ma, x, yhlod, h2); DrawVertexAQ(ma, x, ylod); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, xhlod, ylod, h1); DrawVertexAQ(ma, xlod, yhlod, h4); DrawVertexAQ(ma, xlod, ylod); ma->EndStrip(); DrawVertexAQ(ma, xlod, yhlod, h4); DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xhlod, yhlod, h3); DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, yhlod, h2); ma->EndStrip(); } } } if (inStrip) { ma->EndStrip(); inStrip = false; } } //for (y = ystart; y < yend; y += lod) const int yst = std::max(ystart - lod, minty); const int yed = std::min(yend + lod, maxty); int nloop = (yed - yst) / lod + 1; if (nloop > 0) ma->EnlargeArrays(8 * nloop); //! rita yttre begr?snings yta mot n?ta lod if (maxlx < maxtx && maxlx >= mintx) { x = maxlx; int xlod = x + lod; for (y = yst; y < yed; y += lod) { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, y + lod); if (y % dlod) { const int idx1 = CLAMP((y ) * smfReadMap->heightMapSizeX + x), idx1LOD = CLAMP(idx1 + lod); const int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x), idx2LOD = CLAMP(idx2 + lod); const int idx3 = CLAMP((y - lod) * smfReadMap->heightMapSizeX + x), idx3LOD = CLAMP(idx3 + lod); const float h = (GetVisibleVertexHeight(idx3LOD) + GetVisibleVertexHeight(idx2LOD)) * hmcxp + GetVisibleVertexHeight(idx1LOD) * camxpart; DrawVertexAQ(ma, xlod, y, h); DrawVertexAQ(ma, xlod, y + lod); } else { const int idx1 = CLAMP((y ) * smfReadMap->heightMapSizeX + x), idx1LOD = CLAMP(idx1 + lod); const int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x), idx2LOD = CLAMP(idx2 + lod); const int idx3 = CLAMP((y + dlod) * smfReadMap->heightMapSizeX + x), idx3LOD = CLAMP(idx3 + lod); const float h = (GetVisibleVertexHeight(idx1LOD) + GetVisibleVertexHeight(idx3LOD)) * hmcxp + GetVisibleVertexHeight(idx2LOD) * camxpart; DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xlod, y + lod, h); } ma->EndStrip(); } } if (minlx > mintx && minlx < maxtx) { x = minlx - lod; int xlod = x + lod; for (y = yst; y < yed; y += lod) { if (y % dlod) { int idx1 = CLAMP((y ) * smfReadMap->heightMapSizeX + x); int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x); int idx3 = CLAMP((y - lod) * smfReadMap->heightMapSizeX + x); float h = (GetVisibleVertexHeight(idx3) + GetVisibleVertexHeight(idx2)) * hcxp + GetVisibleVertexHeight(idx1) * mcxp; DrawVertexAQ(ma, x, y, h); DrawVertexAQ(ma, x, y + lod); } else { int idx1 = CLAMP((y ) * smfReadMap->heightMapSizeX + x); int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x); int idx3 = CLAMP((y + dlod) * smfReadMap->heightMapSizeX + x); float h = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx3)) * hcxp + GetVisibleVertexHeight(idx2) * mcxp; DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, y + lod, h); } DrawVertexAQ(ma, xlod, y); DrawVertexAQ(ma, xlod, y + lod); ma->EndStrip(); } } if (maxly < maxty && maxly > minty) { y = maxly; int xs = std::max(xstart - lod, mintx); int xe = std::min(xend + lod, maxtx); FindRange(cam2, xs, xe, y, lod); if (xs < xe) { x = xs; int ylod = y + lod; int nloop = (xe - xs) / lod + 2; //! one extra for if statment int ylhdx = (y + lod) * smfReadMap->heightMapSizeX; ma->EnlargeArrays(2 * nloop); if (x % dlod) { int idx2 = CLAMP(ylhdx + x), idx2PLOD = CLAMP(idx2 + lod), idx2MLOD = CLAMP(idx2 - lod); float h = (GetVisibleVertexHeight(idx2MLOD) + GetVisibleVertexHeight(idx2PLOD)) * hmcyp + GetVisibleVertexHeight(idx2) * camypart; DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod, h); } else { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod); } for (x = xs; x < xe; x += lod) { if (x % dlod) { DrawVertexAQ(ma, x + lod, y); DrawVertexAQ(ma, x + lod, ylod); } else { int idx2 = CLAMP(ylhdx + x), idx2PLOD = CLAMP(idx2 + lod), idx2PLOD2 = CLAMP(idx2 + dlod); float h = (GetVisibleVertexHeight(idx2PLOD2) + GetVisibleVertexHeight(idx2)) * hmcyp + GetVisibleVertexHeight(idx2PLOD) * camypart; DrawVertexAQ(ma, x + lod, y); DrawVertexAQ(ma, x + lod, ylod, h); } } ma->EndStrip(); } } if (minly > minty && minly < maxty) { y = minly - lod; int xs = std::max(xstart - lod, mintx); int xe = std::min(xend + lod, maxtx); FindRange(cam2, xs, xe, y, lod); if (xs < xe) { x = xs; int ylod = y + lod; int yhdx = y * smfReadMap->heightMapSizeX; int nloop = (xe - xs) / lod + 2; //! one extra for if statment ma->EnlargeArrays(2 * nloop); if (x % dlod) { int idx1 = CLAMP(yhdx + x), idx1PLOD = CLAMP(idx1 + lod), idx1MLOD = CLAMP(idx1 - lod); float h = (GetVisibleVertexHeight(idx1MLOD) + GetVisibleVertexHeight(idx1PLOD)) * hcyp + GetVisibleVertexHeight(idx1) * mcyp; DrawVertexAQ(ma, x, y, h); DrawVertexAQ(ma, x, ylod); } else { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod); } for (x = xs; x < xe; x+= lod) { if (x % dlod) { DrawVertexAQ(ma, x + lod, y); DrawVertexAQ(ma, x + lod, ylod); } else { int idx1 = CLAMP(yhdx + x), idx1PLOD = CLAMP(idx1 + lod), idx1PLOD2 = CLAMP(idx1 + dlod); float h = (GetVisibleVertexHeight(idx1PLOD2) + GetVisibleVertexHeight(idx1)) * hcyp + GetVisibleVertexHeight(idx1PLOD) * mcyp; DrawVertexAQ(ma, x + lod, y, h); DrawVertexAQ(ma, x + lod, ylod); } } ma->EndStrip(); } } } //for (int lod = 1; lod < neededLod; lod <<= 1) smfGroundDrawer->SetupBigSquare(btx, bty); DrawGroundVertexArrayQ(ma); } }
void CLegacyMeshDrawer::DoDrawGroundShadowLOD(int nlod) { CVertexArray* ma = GetVertexArray(); ma->Initialize(); bool inStrip = false; int x,y; int lod = 1 << nlod; float cx2 = camera->GetPos().x / SQUARE_SIZE; float cy2 = camera->GetPos().z / SQUARE_SIZE; float oldcamxpart = 0.0f; float oldcamypart = 0.0f; int hlod = lod >> 1; int dlod = lod << 1; int cx = (int)cx2; int cy = (int)cy2; if (lod > 1) { int cxo = (cx / hlod) * hlod; int cyo = (cy / hlod) * hlod; float cx2o = (cxo / lod) * lod; float cy2o = (cyo / lod) * lod; oldcamxpart = (cx2 - cx2o) / lod; oldcamypart = (cy2 - cy2o) / lod; } cx = (cx / lod) * lod; cy = (cy / lod) * lod; const int ysquaremod = (cy % dlod) / lod; const int xsquaremod = (cx % dlod) / lod; const float camxpart = (cx2 - (cx / dlod) * dlod) / dlod; const float camypart = (cy2 - (cy / dlod) * dlod) / dlod; const int minty = 0, maxty = mapDims.mapy; const int mintx = 0, maxtx = mapDims.mapx; const int minly = cy + (-viewRadius + 3 - ysquaremod) * lod, maxly = cy + ( viewRadius - 1 - ysquaremod) * lod; const int minlx = cx + (-viewRadius + 3 - xsquaremod) * lod, maxlx = cx + ( viewRadius - 1 - xsquaremod) * lod; const int xstart = std::max(minlx, mintx), xend = std::min(maxlx, maxtx); const int ystart = std::max(minly, minty), yend = std::min(maxly, maxty); const int lhdx = lod * smfReadMap->heightMapSizeX; const int hhdx = hlod * smfReadMap->heightMapSizeX; const int dhdx = dlod * smfReadMap->heightMapSizeX; const float mcxp = 1.0f - camxpart, mcyp = 1.0f - camypart; const float hcxp = 0.5f * camxpart, hcyp = 0.5f * camypart; const float hmcxp = 0.5f * mcxp, hmcyp = 0.5f * mcyp; const float mocxp = 1.0f - oldcamxpart, mocyp = 1.0f - oldcamypart; const float hocxp = 0.5f * oldcamxpart, hocyp = 0.5f * oldcamypart; const float hmocxp = 0.5f * mocxp, hmocyp = 0.5f * mocyp; const int vrhlod = viewRadius * hlod; for (y = ystart; y < yend; y += lod) { int xs = xstart; int xe = xend; if (xe < xs) continue; int ylod = y + lod; int yhlod = y + hlod; int ydx = y * smfReadMap->heightMapSizeX; int nloop = (xe - xs) / lod + 1; ma->EnlargeArrays(52 * nloop); for (x = xs; x < xe; x += lod) { int xlod = x + lod; int xhlod = x + hlod; if ((lod == 1) || (x > cx + vrhlod) || (x < cx - vrhlod) || (y > cy + vrhlod) || (y < cy - vrhlod)) { if (!inStrip) { DrawVertexAQ(ma, x, y ); DrawVertexAQ(ma, x, ylod); inStrip = true; } DrawVertexAQ(ma, xlod, y ); DrawVertexAQ(ma, xlod, ylod); } else { //! inre begr?sning mot f?eg?nde lod int yhdx=ydx+x; int ylhdx=yhdx+lhdx; int yhhdx=yhdx+hhdx; if ( x>= cx + vrhlod) { const float h1 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(ylhdx )) * hmocxp + GetVisibleVertexHeight(yhhdx ) * oldcamxpart; const float h2 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(yhdx+lod )) * hmocxp + GetVisibleVertexHeight(yhdx+hlod ) * oldcamxpart; const float h3 = (GetVisibleVertexHeight(ylhdx) + GetVisibleVertexHeight(yhdx+lod )) * hmocxp + GetVisibleVertexHeight(yhhdx+hlod) * oldcamxpart; const float h4 = (GetVisibleVertexHeight(ylhdx) + GetVisibleVertexHeight(ylhdx+lod)) * hmocxp + GetVisibleVertexHeight(ylhdx+hlod) * oldcamxpart; if(inStrip){ ma->EndStrip(); inStrip=false; } DrawVertexAQ(ma, x,y); DrawVertexAQ(ma, x,yhlod,h1); DrawVertexAQ(ma, xhlod,y,h2); DrawVertexAQ(ma, xhlod,yhlod,h3); ma->EndStrip(); DrawVertexAQ(ma, x,yhlod,h1); DrawVertexAQ(ma, x,ylod); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xhlod,ylod,h4); ma->EndStrip(); DrawVertexAQ(ma, xhlod,ylod,h4); DrawVertexAQ(ma, xlod,ylod); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xhlod,y,h2); ma->EndStrip(); } if (x <= cx - vrhlod) { const float h1 = (GetVisibleVertexHeight(yhdx+lod) + GetVisibleVertexHeight(ylhdx+lod)) * hocxp + GetVisibleVertexHeight(yhhdx+lod ) * mocxp; const float h2 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(yhdx+lod )) * hocxp + GetVisibleVertexHeight(yhdx+hlod ) * mocxp; const float h3 = (GetVisibleVertexHeight(ylhdx ) + GetVisibleVertexHeight(yhdx+lod )) * hocxp + GetVisibleVertexHeight(yhhdx+hlod) * mocxp; const float h4 = (GetVisibleVertexHeight(ylhdx ) + GetVisibleVertexHeight(ylhdx+lod)) * hocxp + GetVisibleVertexHeight(ylhdx+hlod) * mocxp; if(inStrip){ ma->EndStrip(); inStrip=false; } DrawVertexAQ(ma, xlod,yhlod,h1); DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xhlod,y,h2); ma->EndStrip(); DrawVertexAQ(ma, xlod,ylod); DrawVertexAQ(ma, xlod,yhlod,h1); DrawVertexAQ(ma, xhlod,ylod,h4); DrawVertexAQ(ma, xhlod,yhlod,h3); ma->EndStrip(); DrawVertexAQ(ma, xhlod,y,h2); DrawVertexAQ(ma, x,y); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, x,ylod); DrawVertexAQ(ma, xhlod,ylod,h4); ma->EndStrip(); } if (y >= cy + vrhlod) { const float h1 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhdx+hlod ) * oldcamypart; const float h2 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(ylhdx )) * hmocyp + GetVisibleVertexHeight(yhhdx ) * oldcamypart; const float h3 = (GetVisibleVertexHeight(ylhdx ) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhhdx+hlod) * oldcamypart; const float h4 = (GetVisibleVertexHeight(ylhdx+lod) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhhdx+lod ) * oldcamypart; if(inStrip){ ma->EndStrip(); inStrip=false; } DrawVertexAQ(ma, x,y); DrawVertexAQ(ma, x,yhlod,h2); DrawVertexAQ(ma, xhlod,y,h1); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xlod,yhlod,h4); ma->EndStrip(); DrawVertexAQ(ma, x,yhlod,h2); DrawVertexAQ(ma, x,ylod); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xlod,ylod); DrawVertexAQ(ma, xlod,yhlod,h4); ma->EndStrip(); } if (y <= cy - vrhlod) { const float h1 = (GetVisibleVertexHeight(ylhdx ) + GetVisibleVertexHeight(ylhdx+lod)) * hocyp + GetVisibleVertexHeight(ylhdx+hlod) * mocyp; const float h2 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(ylhdx )) * hocyp + GetVisibleVertexHeight(yhhdx ) * mocyp; const float h3 = (GetVisibleVertexHeight(ylhdx ) + GetVisibleVertexHeight(yhdx+lod )) * hocyp + GetVisibleVertexHeight(yhhdx+hlod) * mocyp; const float h4 = (GetVisibleVertexHeight(ylhdx+lod) + GetVisibleVertexHeight(yhdx+lod )) * hocyp + GetVisibleVertexHeight(yhhdx+lod ) * mocyp; if (inStrip) { ma->EndStrip(); inStrip = false; } DrawVertexAQ(ma, x,yhlod,h2); DrawVertexAQ(ma, x,ylod); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, xhlod,ylod,h1); DrawVertexAQ(ma, xlod,yhlod,h4); DrawVertexAQ(ma, xlod,ylod); ma->EndStrip(); DrawVertexAQ(ma, xlod,yhlod,h4); DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xhlod,yhlod,h3); DrawVertexAQ(ma, x,y); DrawVertexAQ(ma, x,yhlod,h2); ma->EndStrip(); } } } if (inStrip) { ma->EndStrip(); inStrip=false; } } int yst = std::max(ystart - lod, minty); int yed = std::min(yend + lod, maxty); int nloop = (yed - yst) / lod + 1; ma->EnlargeArrays(8 * nloop); //!rita yttre begr?snings yta mot n?ta lod if (maxlx < maxtx && maxlx >= mintx) { x = maxlx; const int xlod = x + lod; for (y = yst; y < yed; y += lod) { DrawVertexAQ(ma, x, y ); DrawVertexAQ(ma, x, y + lod); const int yhdx = y * smfReadMap->heightMapSizeX + x; if (y % dlod) { const float h = (GetVisibleVertexHeight(yhdx - lhdx + lod) + GetVisibleVertexHeight(yhdx + lhdx + lod)) * hmcxp + GetVisibleVertexHeight(yhdx+lod) * camxpart; DrawVertexAQ(ma, xlod, y, h); DrawVertexAQ(ma, xlod, y + lod); } else { const float h = (GetVisibleVertexHeight(yhdx+lod) + GetVisibleVertexHeight(yhdx+dhdx+lod)) * hmcxp + GetVisibleVertexHeight(yhdx+lhdx+lod) * camxpart; DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xlod,y+lod,h); } ma->EndStrip(); } } if (minlx > mintx && minlx < maxtx) { x = minlx - lod; const int xlod = x + lod; for(y = yst; y < yed; y += lod) { int yhdx = y * smfReadMap->heightMapSizeX + x; if(y%dlod){ const float h = (GetVisibleVertexHeight(yhdx-lhdx) + GetVisibleVertexHeight(yhdx+lhdx)) * hcxp + GetVisibleVertexHeight(yhdx) * mcxp; DrawVertexAQ(ma, x,y,h); DrawVertexAQ(ma, x,y+lod); } else { const float h = (GetVisibleVertexHeight(yhdx) + GetVisibleVertexHeight(yhdx+dhdx)) * hcxp + GetVisibleVertexHeight(yhdx+lhdx) * mcxp; DrawVertexAQ(ma, x,y); DrawVertexAQ(ma, x,y+lod,h); } DrawVertexAQ(ma, xlod,y); DrawVertexAQ(ma, xlod,y+lod); ma->EndStrip(); } } if (maxly < maxty && maxly > minty) { y = maxly; const int xs = std::max(xstart -lod, mintx); const int xe = std::min(xend + lod, maxtx); if (xs < xe) { x = xs; const int ylod = y + lod; const int ydx = y * smfReadMap->heightMapSizeX; const int nloop = (xe - xs) / lod + 2; //! two extra for if statment ma->EnlargeArrays(2 * nloop); if (x % dlod) { const int ylhdx = ydx + x + lhdx; const float h = (GetVisibleVertexHeight(ylhdx-lod) + GetVisibleVertexHeight(ylhdx+lod)) * hmcyp + GetVisibleVertexHeight(ylhdx) * camypart; DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod, h); } else { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod); } for (x = xs; x < xe; x += lod) { if (x % dlod) { DrawVertexAQ(ma, x + lod, y); DrawVertexAQ(ma, x + lod, ylod); } else { DrawVertexAQ(ma, x+lod,y); const int ylhdx = ydx + x + lhdx; const float h = (GetVisibleVertexHeight(ylhdx+dlod) + GetVisibleVertexHeight(ylhdx)) * hmcyp + GetVisibleVertexHeight(ylhdx+lod) * camypart; DrawVertexAQ(ma, x+lod,ylod,h); } } ma->EndStrip(); } } if (minly > minty && minly < maxty) { y = minly - lod; const int xs = std::max(xstart - lod, mintx); const int xe = std::min(xend + lod, maxtx); if (xs < xe) { x = xs; const int ylod = y + lod; const int ydx = y * smfReadMap->heightMapSizeX; const int nloop = (xe - xs) / lod + 2; //! two extra for if statment ma->EnlargeArrays(2 * nloop); if (x % dlod) { const int yhdx = ydx + x; const float h = (GetVisibleVertexHeight(yhdx-lod) + GetVisibleVertexHeight(yhdx + lod)) * hcyp + GetVisibleVertexHeight(yhdx) * mcyp; DrawVertexAQ(ma, x, y, h); DrawVertexAQ(ma, x, ylod); } else { DrawVertexAQ(ma, x, y); DrawVertexAQ(ma, x, ylod); } for (x = xs; x < xe; x += lod) { if (x % dlod) { DrawVertexAQ(ma, x + lod, y); DrawVertexAQ(ma, x + lod, ylod); } else { const int yhdx = ydx + x; const float h = (GetVisibleVertexHeight(yhdx+dlod) + GetVisibleVertexHeight(yhdx)) * hcyp + GetVisibleVertexHeight(yhdx+lod) * mcyp; DrawVertexAQ(ma, x + lod, y, h); DrawVertexAQ(ma, x + lod, ylod); } } ma->EndStrip(); } } DrawGroundVertexArrayQ(ma); }
void CSelectedUnits::Draw() { glDisable(GL_TEXTURE_2D); glDepthMask(false); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); // for line smoothing glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(cmdColors.UnitBoxLineWidth()); GML_RECMUTEX_LOCK(grpsel); // Draw if (cmdColors.unitBox[3] > 0.0f) { glColor4fv(cmdColors.unitBox); const CUnitSet* unitSet; if (selectedGroup != -1) { unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units; } else { unitSet = &selectedUnits; } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(unitSet->size()*4, 0, VA_SIZE_0); CUnitSet::const_iterator ui; for (ui = unitSet->begin(); ui != unitSet->end(); ++ui) { const CUnit* unit = *ui; if (unit->isIcon) { continue; } va->AddVertexQ0(unit->drawPos.x + unit->xsize * 4, unit->drawPos.y, unit->drawPos.z + unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x - unit->xsize * 4, unit->drawPos.y, unit->drawPos.z + unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x - unit->xsize * 4, unit->drawPos.y, unit->drawPos.z - unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x + unit->xsize * 4, unit->drawPos.y, unit->drawPos.z - unit->zsize * 4); } va->DrawArray0(GL_QUADS); } // highlight queued build sites if we are about to build something // (or old-style, whenever the shift key is being held down) if (cmdColors.buildBox[3] > 0.0f) { if (!selectedUnits.empty() && ((cmdColors.BuildBoxesOnShift() && keys[SDLK_LSHIFT]) || ((guihandler->inCommand >= 0) && (guihandler->inCommand < int(guihandler->commands.size())) && (guihandler->commands[guihandler->inCommand].id < 0)))) { GML_STDMUTEX_LOCK(cai); // Draw bool myColor = true; glColor4fv(cmdColors.buildBox); std::list<CBuilderCAI*>::const_iterator bi; for (bi = uh->builderCAIs.begin(); bi != uh->builderCAIs.end(); ++bi) { CBuilderCAI* builder = *bi; if (builder->owner->team == gu->myTeam) { if (!myColor) { glColor4fv(cmdColors.buildBox); myColor = true; } builder->DrawQuedBuildingSquares(); } else if (teamHandler->AlliedTeams(builder->owner->team, gu->myTeam)) { if (myColor) { glColor4fv(cmdColors.allyBuildBox); myColor = false; } builder->DrawQuedBuildingSquares(); } } } } glLineWidth(1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(true); glEnable(GL_TEXTURE_2D); }