void CAdvWater::UpdateWater(CGame* game) { if (!mapInfo->water.forceRendering && !readMap->HasVisibleWater()) 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(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->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->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, 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->SetPos().y *= -1.0f; camera->Update(); 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(DrawPass::WaterReflection); 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(*(reinterpret_cast<CCamera*>(realCam))); reinterpret_cast<CCamera*>(realCam)->~CCamera(); camera->Update(); glPopAttrib(); glPopAttrib(); }
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 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 unitDrawer->DrawUnitMiniMapIcons(); } 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) { glPointSize(1.0f); WorkaroundATIPointSizeBug(); 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, double(height)}; const double plane1[4] = {0, 1, 0, 0}; const double plane2[4] = {-1, 0, 0, double(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 CPieceProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points) { points.AddVertexQC(pos, color4::red); }
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; } 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); }
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 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); }
static void DrawFrameBarcode() { const float maxHist_f = 0.5f; const spring_time curTime = spring_now(); const spring_time maxHist = spring_secs(maxHist_f); float drawArea[4] = {0.01f, 0.2f, start_x - 0.05f, 0.25f}; // background CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(drawArea[0] - 10 * globalRendering->pixelX, drawArea[1] - 10 * globalRendering->pixelY, 0.0f); va->AddVertex0(drawArea[0] - 10 * globalRendering->pixelX, drawArea[3] + 20 * globalRendering->pixelY, 0.0f); va->AddVertex0(drawArea[2] + 10 * globalRendering->pixelX, drawArea[3] + 20 * globalRendering->pixelY, 0.0f); va->AddVertex0(drawArea[2] + 10 * globalRendering->pixelX, drawArea[1] - 10 * globalRendering->pixelY, 0.0f); glColor4f(0.0f,0.0f,0.0f, 0.5f); va->DrawArray0(GL_QUADS); // title and legend font->glFormat(drawArea[0], drawArea[3] + 10 * globalRendering->pixelY, 0.7f, FONT_TOP | DBG_FONT_FLAGS, "Frame Grapher (%.2fsec)" "\xff\xff\x80\xff GC" "\xff\xff\xff\x01 Unsynced" "\xff\x01\x01\xff Swap" "\xff\x01\xff\x01 Video" "\xff\xff\x01\x01 Sim" , maxHist_f); // gc frames glColor4f(1.0f,0.5f,1.0f, 0.55f); DrawTimeSlice(lgcFrames, curTime, maxHist, drawArea); // updateunsynced frames glColor4f(1.0f,1.0f,0.0f, 0.9f); DrawTimeSlice(uusFrames, curTime, maxHist, drawArea); // video swap frames glColor4f(0.0f,0.0f,1.0f, 0.55f); DrawTimeSlice(swpFrames, curTime, maxHist, drawArea); // video frames glColor4f(0.0f,1.0f,0.0f, 0.55f); DrawTimeSlice(vidFrames, curTime, maxHist, drawArea); // sim frames glColor4f(1.0f,0.0f,0.0f, 0.55f); DrawTimeSlice(simFrames, curTime, maxHist, drawArea); // draw `feeder` indicating current time pos //CVertexArray* va = GetVertexArray(); va->Initialize(); // draw feeder const float r = (curTime % maxHist).toSecsf() / maxHist_f; const float xf = drawArea[0] + r * (drawArea[2] - drawArea[0]); va->AddVertex0(xf, drawArea[1], 0.0f); va->AddVertex0(xf, drawArea[3], 0.0f); va->AddVertex0(xf + 10 * globalRendering->pixelX, drawArea[3], 0.0f); va->AddVertex0(xf + 10 * globalRendering->pixelX, drawArea[1], 0.0f); // draw scale (horizontal bar that indicates 30FPS timing length) const float xs1 = drawArea[2] - 1.f/(30.f*maxHist_f) * (drawArea[2] - drawArea[0]); const float xs2 = drawArea[2] + 0.0f * (drawArea[2] - drawArea[0]); va->AddVertex0(xs1, drawArea[3] + 2 * globalRendering->pixelY, 0.0f); va->AddVertex0(xs1, drawArea[3] + 10 * globalRendering->pixelY, 0.0f); va->AddVertex0(xs2, drawArea[3] + 10 * globalRendering->pixelY, 0.0f); va->AddVertex0(xs2, drawArea[3] + 2 * globalRendering->pixelY, 0.0f); glColor4f(1.0f,0.0f,0.0f, 1.0f); va->DrawArray0(GL_QUADS); }
static void DrawProfiler() { font->SetTextColor(1,1,1,1); CVertexArray* va = GetVertexArray(); CVertexArray* va2 = GetVertexArray(); // draw the background of the window if(!profiler.profile.empty()){ va->Initialize(); va->AddVertex0(start_x, end_y, 0); va->AddVertex0(end_x, end_y, 0); va->AddVertex0(start_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); va->AddVertex0(end_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); glColor4f(0.0f, 0.0f, 0.5f, 0.5f); va->DrawArray0(GL_TRIANGLE_STRIP); } std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; // draw the textual info (total-time, short-time percentual time, timer-name) int y = 0; for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { const float fStartY = start_y - y * 0.024f; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.04f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", pi->second.total.toSecsf()); // print percent of CPU time used within the last 500ms fStartX += 0.04f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", pi->second.percent * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.2f%%", pi->second.newPeak?1:255, pi->second.newPeak?1:255, pi->second.peak * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.0fms", pi->second.newLagPeak?1:255, pi->second.newLagPeak?1:255, pi->second.maxLag); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM, pi->first); } // draw the Timer selection boxes glPushMatrix(); glTranslatef(start_x + 0.005f, start_y, 0); glScalef(0.015f, 0.02f, 0.02f); va->Initialize(); va2->Initialize(); int i = 0; for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++i){ auto& fc = pi->second.color; SColor c(fc[0], fc[1], fc[2]); va->AddVertexC(float3(0, 0 - i * 1.2f, 0), c); va->AddVertexC(float3(1, 0 - i * 1.2f, 0), c); va->AddVertexC(float3(1, 1 - i * 1.2f, 0), c); va->AddVertexC(float3(0, 1 - i * 1.2f, 0), c); if (!pi->second.showGraph) { va2->AddVertex0(0, 0 - i * 1.2f, 0); va2->AddVertex0(1, 1 - i * 1.2f, 0); va2->AddVertex0(1, 0 - i * 1.2f, 0); va2->AddVertex0(0, 1 - i * 1.2f, 0); } } // draw the boxes va->DrawArrayC(GL_QUADS); // draw the 'graph view disabled' cross glColor3f(1,0,0); va2->DrawArray0(GL_LINES); glPopMatrix(); // draw the graph glLineWidth(3.0f); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) { if (!pi->second.showGraph) { continue; } va->Initialize(); const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size; for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) { // profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame) // This may be more then 1.0f, in case an operation // which ran over many frames, ended in this one. const float p = pi->second.frames[a].toSecsf() * GAME_SPEED; const float x = start_x + (a * steps_x); const float y = 0.02f + (p * 0.96f); va->AddVertex0(x, y, 0.0f); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glLineWidth(1.0f); }
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 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 CProjectileDrawer::UpdatePerlin() { perlinFB.Bind(); glViewport(perlintex->xstart * textureAtlas->xsize, perlintex->ystart * textureAtlas->ysize, 128, 128); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); glDisable(GL_FOG); unsigned char col[4]; float time = globalRendering->lastFrameTime * gs->speedFactor * 3; float speed = 1.0f; float size = 1.0f; for (int a = 0; a < 4; ++a) { perlinBlend[a] += time * speed; if (perlinBlend[a] > 1) { unsigned int temp = perlinTex[a * 2]; perlinTex[a * 2 ] = perlinTex[a * 2 + 1]; perlinTex[a * 2 + 1] = temp; GenerateNoiseTex(perlinTex[a * 2 + 1], 16); perlinBlend[a] -= 1; } float tsize = 8.0f / size; if (a == 0) glDisable(GL_BLEND); CVertexArray* va = GetVertexArray(); va->Initialize(); va->CheckInitSize(4 * VA_SIZE_TC, 0); for (int b = 0; b < 4; ++b) col[b] = int((1.0f - perlinBlend[a]) * 16 * size); glBindTexture(GL_TEXTURE_2D, perlinTex[a * 2]); va->AddVertexQTC(float3(0, 0, 0), 0, 0, col); va->AddVertexQTC(float3(0, 1, 0), 0, tsize, col); va->AddVertexQTC(float3(1, 1, 0), tsize, tsize, col); va->AddVertexQTC(float3(1, 0, 0), tsize, 0, col); va->DrawArrayTC(GL_QUADS); if (a == 0) glEnable(GL_BLEND); va = GetVertexArray(); va->Initialize(); va->CheckInitSize(4 * VA_SIZE_TC, 0); for (int b = 0; b < 4; ++b) col[b] = int(perlinBlend[a] * 16 * size); glBindTexture(GL_TEXTURE_2D, perlinTex[a * 2 + 1]); va->AddVertexQTC(float3(0, 0, 0), 0, 0, col); va->AddVertexQTC(float3(0, 1, 0), 0, tsize, col); va->AddVertexQTC(float3(1, 1, 0), tsize, tsize, col); va->AddVertexQTC(float3(1, 0, 0), tsize, 0, col); va->DrawArrayTC(GL_QUADS); speed *= 0.6f; size *= 2; } perlinFB.Unbind(); glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); }
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); } }
static void DrawProfiler() { font->SetTextColor(1,1,1,1); // draw the background of the window { CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(start_x, start_y + lineHeight + 0.005f, 0); va->AddVertex0(end_x, start_y + lineHeight + 0.005f, 0); va->AddVertex0(start_x, start_y - profiler.profile.size() * lineHeight - 0.01f, 0); va->AddVertex0(end_x, start_y - profiler.profile.size() * lineHeight - 0.01f, 0); glColor4f(0.0f, 0.0f, 0.5f, 0.5f); va->DrawArray0(GL_TRIANGLE_STRIP); } const float textSize = 0.5f; // table header { const float fStartY = start_y + 0.005f; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "totaltime"); // print percent of CPU time used within the last 500ms fStartX += 0.06f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "cur-%%usage"); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "max-%%usage"); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "lag"); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM, "title"); } // draw the textual info (total-time, short-time percentual time, timer-name) int y = 1; for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { const auto& profileData = pi->second; const float fStartY = start_y - y * lineHeight; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", profileData.total.toSecsf()); // print percent of CPU time used within the last 500ms fStartX += 0.06f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", profileData.percent * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.2f%%", profileData.newPeak?1:255, profileData.newPeak?1:255, profileData.peak * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.0fms", profileData.newLagPeak?1:255, profileData.newLagPeak?1:255, profileData.maxLag); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM, pi->first); } // draw the Timer selection boxes const float boxSize = lineHeight*0.9; const float selOffset = boxSize*0.2; glPushMatrix(); glTranslatef(start_x + 0.005f, start_y + boxSize, 0); // we are now at upper left of first box CVertexArray* va = GetVertexArray(); CVertexArray* va2 = GetVertexArray(); va->Initialize(); va2->Initialize(); int i = 1; for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++i){ auto& fc = pi->second.color; SColor c(fc[0], fc[1], fc[2]); va->AddVertexC(float3(0, -i*lineHeight, 0), c); // upper left va->AddVertexC(float3(0, -i*lineHeight-boxSize, 0), c); // lower left va->AddVertexC(float3(boxSize, -i*lineHeight-boxSize, 0), c); // lower right va->AddVertexC(float3(boxSize, -i*lineHeight, 0), c); // upper right if (pi->second.showGraph) { va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-selOffset, 0); // upper left va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower left va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower right va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-selOffset, 0); // upper right } } // draw the boxes va->DrawArrayC(GL_QUADS); // draw the 'graph view disabled' cross glColor3f(1,0,0); va2->DrawArray0(GL_QUADS); glPopMatrix(); // draw the graph glLineWidth(3.0f); for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) { if (!pi->second.showGraph) { continue; } CVertexArray* va = GetVertexArray(); va->Initialize(); const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size; for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) { // profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame) // This may be more then 1.0f, in case an operation // which ran over many frames, ended in this one. const float p = pi->second.frames[a].toSecsf() * GAME_SPEED; const float x = start_x + (a * steps_x); const float y = 0.02f + (p * 0.96f); va->AddVertex0(x, y, 0.0f); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glLineWidth(1.0f); }
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 CDecalsDrawerGL4::GenerateAtlasTexture() { std::unordered_map<std::string, STex> textures; GetBuildingDecals(textures); GetGroundScars(textures); GetFallbacks(textures); CQuadtreeAtlasAlloc atlas; atlas.SetNonPowerOfTwo(globalRendering->supportNPOTs); atlas.SetMaxSize(globalRendering->maxTextureSize, globalRendering->maxTextureSize); for (auto it = textures.begin(); it != textures.end(); ++it) { if (it->second.id == 0) continue; const float maxSize = 1024; //512; int2 size = it->second.size; if (size.x > maxSize) { size.y = size.y * (maxSize / size.x); size.x = maxSize; } if (size.y > maxSize) { size.x = size.x * (maxSize / size.y); size.y = maxSize; } atlas.AddEntry(it->first, size); } /*bool success =*/ atlas.Allocate(); glGenTextures(1, &atlasTex); glBindTexture(GL_TEXTURE_2D, atlasTex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f); glSpringTexStorage2D(GL_TEXTURE_2D, atlas.GetMaxMipMaps(), GL_RGBA8, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); FBO fb; if (!fb.IsValid()) { LOG_L(L_ERROR, "[%s] framebuffer not valid", __FUNCTION__); return; } fb.Bind(); fb.AttachTexture(atlasTex); if (!fb.CheckStatus(LOG_SECTION_DECALS_GL4)) { LOG_L(L_ERROR, "[%s] Couldn't render to FBO!", __FUNCTION__); return; } glViewport(0, 0, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); glSpringMatrix2dProj(atlas.GetAtlasSize().x, atlas.GetAtlasSize().y); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // transparent black glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_DEPTH_TEST); CVertexArray va; for (auto& p: textures) { if (p.second.id == 0) continue; const float4 texCoords = atlas.GetTexCoords(p.first); const float4 absCoords = atlas.GetEntry(p.first); atlasTexs[p.first] = SAtlasTex(texCoords); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBindTexture(GL_TEXTURE_2D, p.second.id); va.Initialize(); va.AddVertex2dT(absCoords.x, absCoords.y, 0.0f, 0.0f); va.AddVertex2dT(absCoords.z+1, absCoords.y, 1.0f, 0.0f); //FIXME why +1? va.AddVertex2dT(absCoords.x, absCoords.w+1, 0.0f, 1.0f); va.AddVertex2dT(absCoords.z+1, absCoords.w+1, 1.0f, 1.0f); //FIXME why +1? va.DrawArray2dT(GL_TRIANGLE_STRIP); glDeleteTextures(1, &p.second.id); } fb.Unbind(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, atlasTex); glGenerateMipmap(GL_TEXTURE_2D); #ifdef DEBUG_SAVE_ATLAS glSaveTexture(atlasTex, "x_decal_atlas.png"); #endif }
void DebugDrawerAI::Graph::Draw() { static unsigned char color[4] = {0.75f * 255, 0.75f * 255, 0.75f * 255, 0.5f * 255}; CVertexArray* va = GetVertexArray(); { color[0] = 0.25f * 255; color[1] = 0.25f * 255; color[2] = 0.25f * 255; color[3] = 1.00f * 255; // label-box va->Initialize(); va->AddVertexC(pos, color); va->AddVertexC(pos + float3(-(((maxLabelWidth * 1.33f) / globalRendering->viewSizeX) * size.x), 0.0f, 0.0f), color); va->AddVertexC(pos + float3(-(((maxLabelWidth * 1.33f) / globalRendering->viewSizeX) * size.x), size.y, 0.0f), color); va->AddVertexC(pos + float3( 0.0f, size.y, 0.0f), color); va->DrawArrayC(GL_LINE_STRIP); if (scale.y > 0.0f && scale.x > 0.0f) { font->Begin(); font->SetTextColor(0.25f, 0.25f, 0.25f, 1.0f); // horizontal grid lines for (float s = 0.0f; s <= (scale.y + 0.01f); s += (scale.y * 0.1f)) { va->Initialize(); va->AddVertexC(pos + float3( 0.0f, (s / scale.y) * size.y, 0.0f), color); va->AddVertexC(pos + float3(size.x, (s / scale.y) * size.y, 0.0f), color); va->DrawArrayC(GL_LINES); const float tx = (pos.x + size.x) + (size.x * 0.025f); const float ty = pos.y + (s / scale.y) * size.y; font->glFormat(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, "%2.1e", s + minScale.y); } // vertical grid lines for (float s = 0.0f; s <= (scale.x + 0.01f); s += (scale.x * 0.1f)) { va->Initialize(); va->AddVertexC(pos + float3((s / scale.x) * size.x, 0.0f, 0.0f), color); va->AddVertexC(pos + float3((s / scale.x) * size.x, size.y, 0.0f), color); va->DrawArrayC(GL_LINES); const float tx = (pos.x + (s / scale.x) * size.x) - (size.x * 0.05f); const float ty = pos.y - size.y * 0.1f; font->glFormat(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, "%2.1e", s + minScale.x); } font->End(); } } { typedef std::map<int, Graph::GraphLine>::const_iterator LineIt; typedef std::list<float3>::const_iterator ListIt; if (!lines.empty()) { font->Begin(); int lineNum = 0; float linePad = (1.0f / lines.size()) * 0.5f; for (LineIt lit = lines.begin(); lit != lines.end(); ++lit) { const Graph::GraphLine& line = lit->second; const std::list<float3>& data = line.lineData; if (data.empty()) { continue; } // right-outline the labels const float sx = (maxLabelWidth / globalRendering->viewSizeX) * size.x; const float tx = pos.x - ((line.lineLabelWidth / maxLabelWidth) * 1.33f) * sx; const float ty = pos.y + ((lineNum * linePad * 2.0f) + linePad) * size.y; font->SetTextColor(line.lineColor.x, line.lineColor.y, line.lineColor.z, 1.0f); font->glPrint(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, line.lineLabel); color[0] = line.lineColor.x * 255; color[1] = line.lineColor.y * 255; color[2] = line.lineColor.z * 255; color[3] = 255; glLineWidth(line.lineWidth); va->Initialize(); for (ListIt pit = data.begin(); pit != data.end(); ++pit) { ListIt npit = pit; ++npit; const float px1 = ((pit->x - minScale.x) / scale.x) * size.x; const float py1 = ((pit->y - minScale.y) / scale.y) * size.y; const float px2 = (npit == data.end()) ? px1 : ((npit->x - minScale.x) / scale.x) * size.x; const float py2 = (npit == data.end()) ? py1 : ((npit->y - minScale.y) / scale.y) * size.y; va->AddVertexC(pos + float3(px1, py1, 0.0f), color); va->AddVertexC(pos + float3(px2, py2, 0.0f), color); } va->DrawArrayC(GL_LINE_STRIP); glLineWidth(1.0f); lineNum += 1; } font->End(); } } glColor4f(1.0f, 1.0f, 1.0f, 1.0f); }
void ProfileDrawer::Draw() { GML_STDMUTEX_LOCK_NOPROF(time); // Draw // draw the background of the window glDisable(GL_TEXTURE_2D); glColor4f(0.0f, 0.0f, 0.5f, 0.5f); if(!profiler.profile.empty()){ glBegin(GL_TRIANGLE_STRIP); glVertex3f(start_x, end_y, 0); glVertex3f(end_x, end_y, 0); glVertex3f(start_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); glVertex3f(end_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); glEnd(); } std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; // draw the textual info (total-time, short-time percentual time, timer-name) int y = 0; font->Begin(); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { #if GML_MUTEX_PROFILER if (pi->first.size()<5 || pi->first.substr(pi->first.size()-5,5).compare("Mutex")!=0) { --y; continue; } const float fStartY = start_y - y * 0.020f; #else const float fStartY = start_y - y * 0.024f; #endif const float s = ((float)pi->second.total) / 1000.0f; const float p = pi->second.percent * 100; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.09f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", s); // print percent of CPU time used within the last 500ms fStartX += 0.08f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", p); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM, "%s", pi->first.c_str()); } font->End(); // draw the Timer selection boxes glPushMatrix(); glTranslatef(start_x + 0.005f, start_y, 0); glScalef(0.015f, 0.02f, 0.02f); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi){ glColorf3((float3)pi->second.color); glBegin(GL_QUADS); glVertex3f(0,0,0); glVertex3f(1,0,0); glVertex3f(1,1,0); glVertex3f(0,1,0); glEnd(); // draw the 'graph view disabled' cross if (!pi->second.showGraph) { glColor3f(1,0,0); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(1,1,0); glVertex3f(1,0,0); glVertex3f(0,1,0); glEnd(); } glTranslatef(0,-1.2f,0); } glPopMatrix(); // draw the graph for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) { if (!pi->second.showGraph) { continue; } CVertexArray* va = GetVertexArray(); va->Initialize(); const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size; for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) { // profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame) // This may be more then 1.0f, in case an operation // which ran over many frames, ended in this one. const float p = ((float)pi->second.frames[a]) / 1000.0f * GAME_SPEED; const float x = start_x + (a * steps_x); const float y = 0.02f + (p * 0.4f); va->AddVertex0(float3(x, y, 0.0f)); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glEnable(GL_TEXTURE_2D); }
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::Draw(bool useBlending) { if (!waterRendering->forceRendering && !readMap->HasVisibleWater()) 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; float3 forward = camera->GetDir(); float3 dir; float3 zpos; const int numDivs = 20; base *= numDivs; float maxY = -0.1f; float yInc = 1.0f / numDivs; float screenY = 1.0f; 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); glActiveTexture(GL_TEXTURE1); 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); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, reflectTexture); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, waterFP); glEnable(GL_FRAGMENT_PROGRAM_ARB); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE * wireFrameMode + GL_FILL * (1 - wireFrameMode)); forward.ANormalize2D(); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, forward.z, forward.x, 0.0f, 0.0f); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, -forward.x, forward.z, 0.0f, 0.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(5 * numDivs * (numDivs + 1) * 2, 5 * numDivs, VA_SIZE_TC); //! alloc room for all vertexes and strips 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->GetPos() + dir * (camera->GetPos().y / -dir.y); zpos.y = fastmath::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->GetPos() + dir * (camera->GetPos().y / -dir.y); zpos.y = fastmath::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->EndStrip(); base += dv; screenY -= yInc; } if (!maxReached) break; dv *= 0.5f; maxY *= 0.5f; yInc *= 0.5f; } va->DrawArrayTC(GL_TRIANGLE_STRIP); glDepthMask(1); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_FRAGMENT_PROGRAM_ARB); glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTexture(GL_TEXTURE0); // for translucent stuff like water, the default mode is blending and alpha testing enabled if (!useBlending) glEnable(GL_BLEND); }
CBumpWater::CBumpWater() : CEventClient("[CBumpWater]", 271923, false) { eventHandler.AddClient(this); // LOAD USER CONFIGS reflTexSize = next_power_of_2(configHandler->GetInt("BumpWaterTexSizeReflection")); reflection = configHandler->GetInt("BumpWaterReflection"); refraction = configHandler->GetInt("BumpWaterRefraction"); anisotropy = configHandler->GetFloat("BumpWaterAnisotropy"); depthCopy = configHandler->GetBool("BumpWaterUseDepthTexture"); depthBits = configHandler->GetInt("BumpWaterDepthBits"); if ((depthBits == 24) && !globalRendering->support24bitDepthBuffers) depthBits = 16; blurRefl = configHandler->GetBool("BumpWaterBlurReflection"); shoreWaves = (configHandler->GetBool("BumpWaterShoreWaves")) && mapInfo->water.shoreWaves; endlessOcean = (configHandler->GetBool("BumpWaterEndlessOcean")) && mapInfo->water.hasWaterPlane && ((readmap->initMinHeight <= 0.0f) || (mapInfo->water.forceRendering)); dynWaves = (configHandler->GetBool("BumpWaterDynamicWaves")) && (mapInfo->water.numTiles>1); useUniforms = (configHandler->GetBool("BumpWaterUseUniforms")); refractTexture = 0; reflectTexture = 0; // CHECK HARDWARE if (!globalRendering->haveGLSL) { throw content_error("["LOG_SECTION_BUMP_WATER"] your hardware/driver setup does not support GLSL"); } shoreWaves = shoreWaves && (GLEW_EXT_framebuffer_object); dynWaves = dynWaves && (GLEW_EXT_framebuffer_object && GLEW_ARB_imaging); // LOAD TEXTURES foamTexture = LoadTexture(mapInfo->water.foamTexture); normalTexture = LoadTexture(mapInfo->water.normalTexture , anisotropy , &normalTextureX, &normalTextureY); //! caustic textures const vector<string>& causticNames = mapInfo->water.causticTextures; if (causticNames.size() <= 0) { throw content_error("["LOG_SECTION_BUMP_WATER"] no caustic textures"); } for (int i = 0; i < (int)causticNames.size(); ++i) { caustTextures.push_back(LoadTexture(causticNames[i])); } // CHECK SHOREWAVES TEXTURE SIZE if (shoreWaves) { GLint maxw, maxh; glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA16F_ARB, 4096, 4096, 0, GL_RGBA, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &maxw); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &maxh); if (gs->mapx>maxw || gs->mapy>maxh) { shoreWaves = false; LOG_L(L_WARNING, "Can not display shorewaves (map too large)!"); } } // SHOREWAVES if (shoreWaves) { waveRandTexture = LoadTexture( "bitmaps/shorewaverand.png" ); glGenTextures(1, &coastTexture); glBindTexture(GL_TEXTURE_2D, coastTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, gs->mapx, gs->mapy, 0, GL_RGBA, GL_FLOAT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, gs->mapx, gs->mapy, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); //glGenerateMipmapEXT(GL_TEXTURE_2D); { blurShader = shaderHandler->CreateProgramObject("[BumpWater]", "CoastBlurShader", false); blurShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterCoastBlurFS.glsl", "", GL_FRAGMENT_SHADER)); blurShader->Link(); if (!blurShader->IsValid()) { const char* fmt = "shorewaves-shader compilation error: %s"; const char* log = (blurShader->GetLog()).c_str(); LOG_L(L_ERROR, fmt, log); //! string size is limited with content_error() throw content_error(string("["LOG_SECTION_BUMP_WATER"] shorewaves-shader compilation error!")); } blurShader->SetUniformLocation("tex0"); // idx 0 blurShader->SetUniformLocation("tex1"); // idx 1 blurShader->Enable(); blurShader->SetUniform1i(0, 0); blurShader->SetUniform1i(1, 1); blurShader->Disable(); blurShader->Validate(); if (!blurShader->IsValid()) { const char* fmt = "shorewaves-shader validation error: %s"; const char* log = (blurShader->GetLog()).c_str(); LOG_L(L_ERROR, fmt, log); throw content_error(string("["LOG_SECTION_BUMP_WATER"] shorewaves-shader validation error!")); } } coastFBO.reloadOnAltTab = true; coastFBO.Bind(); coastFBO.AttachTexture(coastTexture, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT); if (coastFBO.CheckStatus("BUMPWATER(Coastmap)")) { //! initialize texture glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); //! fill with current heightmap/coastmap UnsyncedHeightMapUpdate(SRectangle(0, 0, gs->mapx, gs->mapy)); UploadCoastline(true); UpdateCoastmap(); } else shoreWaves = false; if (shoreWaves) eventHandler.InsertEvent(this, "UnsyncedHeightMapUpdate"); //coastFBO.Unbind(); // gets done below } // CREATE TEXTURES if ((refraction > 0) || depthCopy) { //! ATIs do not have GLSL support for texrects screenTextureX = globalRendering->viewSizeX; screenTextureY = globalRendering->viewSizeY; if (GLEW_ARB_texture_rectangle && !globalRendering->atiHacks) { target = GL_TEXTURE_RECTANGLE_ARB; } else { target = GL_TEXTURE_2D; if (!globalRendering->supportNPOTs) { screenTextureX = next_power_of_2(globalRendering->viewSizeX); screenTextureY = next_power_of_2(globalRendering->viewSizeY); } } } if (refraction > 0) { //! CREATE REFRACTION TEXTURE glGenTextures(1, &refractTexture); glBindTexture(target, refractTexture); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (GLEW_EXT_texture_edge_clamp) { glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP); } glTexImage2D(target, 0, GL_RGBA8, screenTextureX, screenTextureY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } if (reflection > 0) { //! CREATE REFLECTION TEXTURE glGenTextures(1, &reflectTexture); glBindTexture(GL_TEXTURE_2D, reflectTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (GLEW_EXT_texture_edge_clamp) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } if (depthCopy) { //! CREATE DEPTH TEXTURE glGenTextures(1, &depthTexture); glBindTexture(target, depthTexture); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); GLuint depthFormat = GL_DEPTH_COMPONENT; switch (globalRendering->depthBufferBits) { // use same depth as screen framebuffer case 16: depthFormat = GL_DEPTH_COMPONENT16; break; case 24: if (!globalRendering->atiHacks) { depthFormat = GL_DEPTH_COMPONENT24; break; } // ATIs fall through and use 32bit! default: depthFormat = GL_DEPTH_COMPONENT32; break; } glTexImage2D(target, 0, depthFormat, screenTextureX, screenTextureY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } if (dynWaves) { //! SETUP DYNAMIC WAVES tileOffsets = new unsigned char[mapInfo->water.numTiles * mapInfo->water.numTiles]; normalTexture2 = normalTexture; glBindTexture(GL_TEXTURE_2D, normalTexture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0); glGenTextures(1, &normalTexture); glBindTexture(GL_TEXTURE_2D, normalTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); if (anisotropy > 0.0f) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, normalTextureX, normalTextureY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glGenerateMipmapEXT(GL_TEXTURE_2D); } // CREATE FBOs if (GLEW_EXT_framebuffer_object) { GLuint depthRBOFormat = GL_DEPTH_COMPONENT; switch (depthBits) { case 16: depthRBOFormat = GL_DEPTH_COMPONENT16; break; case 24: depthRBOFormat = GL_DEPTH_COMPONENT24; break; case 32: depthRBOFormat = GL_DEPTH_COMPONENT32; break; } if (reflection>0) { reflectFBO.Bind(); reflectFBO.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, depthRBOFormat, reflTexSize, reflTexSize); reflectFBO.AttachTexture(reflectTexture); } if (refraction>0) { refractFBO.Bind(); refractFBO.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, depthRBOFormat, screenTextureX, screenTextureY); refractFBO.AttachTexture(refractTexture,target); } if (!reflectFBO.CheckStatus("BUMPWATER(reflection)")) { reflection = 0; } if (!refractFBO.CheckStatus("BUMPWATER(refraction)")) { refraction = 0; } if (dynWaves) { dynWavesFBO.reloadOnAltTab = true; dynWavesFBO.Bind(); dynWavesFBO.AttachTexture(normalTexture); if (dynWavesFBO.CheckStatus("BUMPWATER(DynWaves)")) { UpdateDynWaves(true); //! initialize } } FBO::Unbind(); } /* * DEFINE SOME SHADER RUNTIME CONSTANTS * (I do not use Uniforms for that, because the GLSL compiler can not * optimize those!) */ string definitions; if (reflection>0) definitions += "#define opt_reflection\n"; if (refraction>0) definitions += "#define opt_refraction\n"; if (shoreWaves) definitions += "#define opt_shorewaves\n"; if (depthCopy) definitions += "#define opt_depth\n"; if (blurRefl) definitions += "#define opt_blurreflection\n"; if (endlessOcean) definitions += "#define opt_endlessocean\n"; if (target == GL_TEXTURE_RECTANGLE_ARB) definitions += "#define opt_texrect\n"; GLSLDefineConstf3(definitions, "MapMid", float3(readmap->width * SQUARE_SIZE * 0.5f, 0.0f, readmap->height * SQUARE_SIZE * 0.5f) ); GLSLDefineConstf2(definitions, "ScreenInverse", 1.0f / globalRendering->viewSizeX, 1.0f / globalRendering->viewSizeY ); GLSLDefineConstf2(definitions, "ScreenTextureSizeInverse", 1.0f / screenTextureX, 1.0f / screenTextureY ); GLSLDefineConstf2(definitions, "ViewPos", globalRendering->viewPosX, globalRendering->viewPosY ); if (useUniforms) { SetupUniforms(definitions); } else { GLSLDefineConstf4(definitions, "SurfaceColor", mapInfo->water.surfaceColor*0.4, mapInfo->water.surfaceAlpha ); GLSLDefineConstf4(definitions, "PlaneColor", mapInfo->water.planeColor*0.4, mapInfo->water.surfaceAlpha ); GLSLDefineConstf3(definitions, "DiffuseColor", mapInfo->water.diffuseColor); GLSLDefineConstf3(definitions, "SpecularColor", mapInfo->water.specularColor); GLSLDefineConstf1(definitions, "SpecularPower", mapInfo->water.specularPower); GLSLDefineConstf1(definitions, "SpecularFactor", mapInfo->water.specularFactor); GLSLDefineConstf1(definitions, "AmbientFactor", mapInfo->water.ambientFactor); GLSLDefineConstf1(definitions, "DiffuseFactor", mapInfo->water.diffuseFactor * 15.0f); GLSLDefineConstf3(definitions, "SunDir", sky->GetLight()->GetLightDir()); // FIXME: not a constant GLSLDefineConstf1(definitions, "FresnelMin", mapInfo->water.fresnelMin); GLSLDefineConstf1(definitions, "FresnelMax", mapInfo->water.fresnelMax); GLSLDefineConstf1(definitions, "FresnelPower", mapInfo->water.fresnelPower); GLSLDefineConstf1(definitions, "ReflDistortion", mapInfo->water.reflDistortion); GLSLDefineConstf2(definitions, "BlurBase", 0.0f, mapInfo->water.blurBase / globalRendering->viewSizeY); GLSLDefineConstf1(definitions, "BlurExponent", mapInfo->water.blurExponent); GLSLDefineConstf1(definitions, "PerlinStartFreq", mapInfo->water.perlinStartFreq); GLSLDefineConstf1(definitions, "PerlinLacunarity", mapInfo->water.perlinLacunarity); GLSLDefineConstf1(definitions, "PerlinAmp", mapInfo->water.perlinAmplitude); GLSLDefineConstf1(definitions, "WindSpeed", mapInfo->water.windSpeed); } { const int mapX = readmap->width * SQUARE_SIZE; const int mapZ = readmap->height * SQUARE_SIZE; const float shadingX = (float)gs->mapx / gs->pwr2mapx; const float shadingZ = (float)gs->mapy / gs->pwr2mapy; const float scaleX = (mapX > mapZ) ? (readmap->height/64)/16.0f * (float)mapX/mapZ : (readmap->width/64)/16.0f; const float scaleZ = (mapX > mapZ) ? (readmap->height/64)/16.0f : (readmap->width/64)/16.0f * (float)mapZ/mapX; GLSLDefineConst4f(definitions, "TexGenPlane", 1.0f/mapX, 1.0f/mapZ, scaleX/mapX, scaleZ/mapZ); GLSLDefineConst4f(definitions, "ShadingPlane", shadingX/mapX, shadingZ/mapZ, shadingX, shadingZ); } // LOAD SHADERS { waterShader = shaderHandler->CreateProgramObject("[BumpWater]", "WaterShader", false); waterShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterVS.glsl", definitions, GL_VERTEX_SHADER)); waterShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterFS.glsl", definitions, GL_FRAGMENT_SHADER)); waterShader->Link(); waterShader->SetUniformLocation("eyePos"); // idx 0 waterShader->SetUniformLocation("frame"); // idx 1 waterShader->SetUniformLocation("normalmap"); // idx 2 waterShader->SetUniformLocation("heightmap"); // idx 3 waterShader->SetUniformLocation("caustic"); // idx 4 waterShader->SetUniformLocation("foam"); // idx 5 waterShader->SetUniformLocation("reflection"); // idx 6 waterShader->SetUniformLocation("refraction"); // idx 7 waterShader->SetUniformLocation("depthmap"); // idx 8 waterShader->SetUniformLocation("coastmap"); // idx 9 waterShader->SetUniformLocation("waverand"); // idx 10 if (!waterShader->IsValid()) { const char* fmt = "water-shader compilation error: %s"; const char* log = (waterShader->GetLog()).c_str(); LOG_L(L_ERROR, fmt, log); throw content_error(string("["LOG_SECTION_BUMP_WATER"] water-shader compilation error!")); } if (useUniforms) { GetUniformLocations(waterShader); } // BIND TEXTURE UNIFORMS // NOTE: ATI shader validation code is stricter wrt. state, // so postpone the call until all texture uniforms are set waterShader->Enable(); waterShader->SetUniform1i( 2, 0); waterShader->SetUniform1i( 3, 1); waterShader->SetUniform1i( 4, 2); waterShader->SetUniform1i( 5, 3); waterShader->SetUniform1i( 6, 4); waterShader->SetUniform1i( 7, 5); waterShader->SetUniform1i( 8, 7); waterShader->SetUniform1i( 9, 6); waterShader->SetUniform1i(10, 8); waterShader->Disable(); waterShader->Validate(); if (!waterShader->IsValid()) { const char* fmt = "water-shader validation error: %s"; const char* log = (waterShader->GetLog()).c_str(); LOG_L(L_ERROR, fmt, log); throw content_error(string("["LOG_SECTION_BUMP_WATER"] water-shader validation error!")); } } // CREATE DISPLAYLIST displayList = glGenLists(1); glNewList(displayList, GL_COMPILE); if (endlessOcean) { DrawRadialDisc(); } else { const int mapX = readmap->width * SQUARE_SIZE; const int mapZ = readmap->height * SQUARE_SIZE; CVertexArray* va = GetVertexArray(); va->Initialize(); for (int z = 0; z < 9; z++) { for (int x = 0; x < 10; x++) { for (int zs = 0; zs <= 1; zs++) { va->AddVertex0(float3(x*(mapX/9.0f), 0.0f, (z + zs)*(mapZ/9.0f))); } } va->EndStrip(); } va->DrawArray0(GL_TRIANGLE_STRIP); } glEndList(); /* windndir = wind.GetCurrentDirection(); windStrength = (smoothstep(0.0f, 12.0f, wind.GetCurrentStrength()) * 0.5f + 4.0f); windVec = windndir * windStrength; */ windVec = float3(20.0, 0.0, 20.0); occlusionQuery = 0; occlusionQueryResult = GL_TRUE; wasLastFrameVisible = true; bool useOcclQuery = (configHandler->GetBool("BumpWaterOcclusionQuery")); if (useOcclQuery && GLEW_ARB_occlusion_query && (refraction < 2)) { //! in the case of a separate refraction pass, there isn't enough time for a occlusion query GLint bitsSupported; glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &bitsSupported); if (bitsSupported > 0) { glGenQueries(1, &occlusionQuery); } } if (refraction > 1) { drawSolid = true; } }
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 CLargeBeamLaserProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points) { unsigned char color[4] = { kocolstart[0], kocolstart[1], kocolstart[2], 255 }; lines.AddVertexQC(startPos, color); lines.AddVertexQC(endPos, color); }
void CEndGameBox::Draw() { if (!graphTex) { graphTex = bm.CreateTexture(); } if (!enabled) { return; } float mx = MouseX(mouse->lastx); float my = MouseY(mouse->lasty); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); // Large Box glColor4f(0.2f, 0.2f, 0.2f, guiAlpha); DrawBox(box); glColor4f(0.2f, 0.2f, 0.7f, guiAlpha); if (dispMode == 0) { DrawBox(box + playerBox); } else if (dispMode == 1) { DrawBox(box + sumBox); } else { DrawBox(box + difBox); } if (InBox(mx, my, box+exitBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); DrawBox(box + exitBox); } if (InBox(mx,my,box+playerBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); DrawBox(box + playerBox); } if (InBox(mx,my,box+sumBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); DrawBox(box + sumBox); } if (InBox(mx,my,box+difBox)) { glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); DrawBox(box + difBox); } glEnable(GL_TEXTURE_2D); glColor4f(1, 1, 1, 0.8f); font->glPrint(box.x1 + exitBox.x1 + 0.025f, box.y1 + exitBox.y1 + 0.005f, 1.0f, FONT_SCALE | FONT_NORM, "Exit"); font->glPrint(box.x1 + playerBox.x1 + 0.015f, box.y1 + playerBox.y1 + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Player stats"); font->glPrint(box.x1 + sumBox.x1 + 0.015f, box.y1 + sumBox.y1 + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Team stats"); font->glPrint(box.x1 + difBox.x1 + 0.015f, box.y1 + difBox.y1 + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Team delta stats"); if (winners.empty()) { font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, "Game result was undecided"); } else { std::stringstream winnersText; std::stringstream winnersList; // myPlayingAllyTeam is >= 0 iff we ever joined a team const bool neverPlayed = (gu->myPlayingAllyTeam < 0); bool playedAndWon = false; for (unsigned int i = 0; i < winners.size(); i++) { const int winnerAllyTeam = winners[i]; if (!neverPlayed && winnerAllyTeam == gu->myPlayingAllyTeam) { // we actually played and won! playedAndWon = true; break; } winnersList << (((i > 0)? ((i < (winners.size() - 1))? ", ": " and "): "")); winnersList << winnerAllyTeam; } if (neverPlayed) { winnersText << "Game Over! Ally-team(s) "; winnersText << winnersList.str() << " won!"; font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, (winnersText.str()).c_str()); } else { winnersText.str(""); winnersText << "Game Over! Your ally-team "; winnersText << (playedAndWon? "won!": "lost!"); font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, (winnersText.str()).c_str()); } } if (gs->frameNum <= 0) { return; } if (dispMode == 0) { float xpos = 0.01f; std::string headers[] = {"Name", "MC/m", "MP/m", "KP/m", "Cmds/m", "ACS"}; for (int a = 0; a < 6; ++a) { font->glPrint(box.x1 + xpos, box.y1 + 0.55f, 0.8f, FONT_SCALE | FONT_NORM,headers[a].c_str()); xpos += 0.1f; } float ypos = 0.5f; for (int a = 0; a < playerHandler->ActivePlayers(); ++a) { const CPlayer* p = playerHandler->Player(a); const PlayerStatistics& pStats = p->currentStats; char values[6][100]; SNPRINTF(values[0], 100, "%s", p->name.c_str()); if (game->totalGameTime>0){ //prevent div zero SNPRINTF(values[1], 100, "%i", int(pStats.mouseClicks * 60 / game->totalGameTime)); SNPRINTF(values[2], 100, "%i", int(pStats.mousePixels * 60 / game->totalGameTime)); SNPRINTF(values[3], 100, "%i", int(pStats.keyPresses * 60 / game->totalGameTime)); SNPRINTF(values[4], 100, "%i", int(pStats.numCommands * 60 / game->totalGameTime)); }else{ for(int i=1; i<5; i++) SNPRINTF(values[i], 100, "%i", 0); } SNPRINTF(values[5], 100, "%i", (pStats.numCommands != 0)? (pStats.unitCommands / pStats.numCommands): (0)); float xpos = 0.01f; for (int a = 0; a < 6; ++a) { font->glPrint(box.x1 + xpos, box.y1 + ypos, 0.8f, FONT_SCALE | FONT_NORM, values[a]); xpos += 0.1f; } ypos -= 0.02f; } } else { if (stats.empty()) { FillTeamStats(); } glBindTexture(GL_TEXTURE_2D, graphTex); CVertexArray* va=GetVertexArray(); va->Initialize(); va->AddVertexT(float3(box.x1+0.15f, box.y1+0.08f, 0), 0, 0); va->AddVertexT(float3(box.x1+0.69f, box.y1+0.08f, 0), 4, 0); va->AddVertexT(float3(box.x1+0.69f, box.y1+0.62f, 0), 4, 4); va->AddVertexT(float3(box.x1+0.15f, box.y1+0.62f, 0), 0, 4); va->DrawArrayT(GL_QUADS); if ((mx > box.x1 + 0.01f) && (mx < box.x1 + 0.12f) && (my < box.y1 + 0.57f) && (my > box.y1 + 0.571f - (stats.size() * 0.02f))) { const int sel = (int) math::floor(50 * -(my - box.y1 - 0.57f)); glColor4f(0.7f, 0.2f, 0.2f, guiAlpha); glDisable(GL_TEXTURE_2D); CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(float3(box.x1 + 0.01f, box.y1 + 0.55f - (sel * 0.02f) , 0)); va->AddVertex0(float3(box.x1 + 0.01f, box.y1 + 0.55f - (sel * 0.02f) + 0.02f , 0)); va->AddVertex0(float3(box.x1 + 0.12f, box.y1 + 0.55f - (sel * 0.02f) + 0.02f , 0)); va->AddVertex0(float3(box.x1 + 0.12f, box.y1 + 0.55f - (sel * 0.02f) , 0)); va->DrawArray0(GL_QUADS); glEnable(GL_TEXTURE_2D); glColor4f(1, 1, 1, 0.8f); } float ypos = 0.55f; for (size_t a = 0; a < stats.size(); ++a) { font->glPrint(box.x1 + 0.01f, box.y1 + ypos, 0.8f, FONT_SCALE | FONT_NORM, stats[a].name); ypos -= 0.02f; } float maxy = 1; if (dispMode == 1) { maxy = std::max(stats[stat1].max, (stat2 != -1) ? stats[stat2].max : 0); } else { maxy = std::max(stats[stat1].maxdif, (stat2 != -1) ? stats[stat2].maxdif : 0) / TeamStatistics::statsPeriod; } int numPoints = stats[0].values[0].size(); for (int a = 0; a < 5; ++a) { font->glPrint(box.x1 + 0.12f, box.y1 + 0.07f + (a * 0.135f), 0.8f, FONT_SCALE | FONT_NORM, FloatToSmallString(maxy * 0.25f * a)); font->glFormat(box.x1 + 0.135f + (a * 0.135f), box.y1 + 0.057f, 0.8f, FONT_SCALE | FONT_NORM, "%02i:%02i", (int) (a * 0.25f * numPoints * TeamStatistics::statsPeriod / 60), (int) (a * 0.25f * (numPoints - 1) * TeamStatistics::statsPeriod) % 60); } font->glPrint(box.x1 + 0.55f, box.y1 + 0.65f, 0.8f, FONT_SCALE | FONT_NORM, stats[stat1].name); font->glPrint(box.x1 + 0.55f, box.y1 + 0.63f, 0.8f, FONT_SCALE | FONT_NORM, (stat2 != -1) ? stats[stat2].name : ""); glDisable(GL_TEXTURE_2D); glBegin(GL_LINES); glVertex3f(box.x1+0.50f, box.y1+0.66f, 0); glVertex3f(box.x1+0.55f, box.y1+0.66f, 0); glEnd(); glLineStipple(3, 0x5555); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINES); glVertex3f(box.x1 + 0.50f, box.y1 + 0.64f, 0.0f); glVertex3f(box.x1 + 0.55f, box.y1 + 0.64f, 0.0f); glEnd(); glDisable(GL_LINE_STIPPLE); const float scalex = 0.54f / std::max(1.0f, numPoints - 1.0f); const float scaley = 0.54f / maxy; for (int team = 0; team < teamHandler->ActiveTeams(); team++) { const CTeam* pteam = teamHandler->Team(team); if (pteam->gaia) { continue; } glColor4ubv(pteam->color); glBegin(GL_LINE_STRIP); for (int a = 0; a < numPoints; ++a) { float value = 0.0f; if (dispMode == 1) { value = stats[stat1].values[team][a]; } else if (a > 0) { value = (stats[stat1].values[team][a] - stats[stat1].values[team][a - 1]) / TeamStatistics::statsPeriod; } glVertex3f(box.x1 + 0.15f + a * scalex, box.y1 + 0.08f + value * scaley, 0.0f); } glEnd(); if (stat2 != -1) { glLineStipple(3, 0x5555); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINE_STRIP); for (int a = 0; a < numPoints; ++a) { float value = 0; if (dispMode == 1) { value = stats[stat2].values[team][a]; } else if (a > 0) { value = (stats[stat2].values[team][a]-stats[stat2].values[team][a-1]) / TeamStatistics::statsPeriod; } glVertex3f(box.x1+0.15f+a*scalex, box.y1+0.08f+value*scaley, 0); } glEnd(); glDisable(GL_LINE_STIPPLE); } } } }
void CWeaponProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points) { points.AddVertexQC(pos, color4::yellow); }
void CLightningProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points) { unsigned char lcolor[4] = {(unsigned char)color[0]*255,(unsigned char)color[1]*255,(unsigned char)color[2]*255,255}; lines.AddVertexQC(pos, lcolor); lines.AddVertexQC(endPos, lcolor); }
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 CGrassDrawer::CreateFarTex() { //TODO create normalmap, too? const int sizeMod = 2; const int billboardSize = 256; const int numAngles = 16; const int texSizeX = billboardSize * numAngles; const int texSizeY = billboardSize; if (farTex == 0) { glGenTextures(1, &farTex); glBindTexture(GL_TEXTURE_2D, farTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGBA8, texSizeX, texSizeY); } FBO fboTex; fboTex.Bind(); fboTex.AttachTexture(farTex); fboTex.CheckStatus("GRASSDRAWER1"); FBO fbo; fbo.Bind(); fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, texSizeX * sizeMod, texSizeY * sizeMod); fbo.CheckStatus("GRASSDRAWER2"); if (!fboTex.IsValid() || !fbo.IsValid()) { grassOff = true; return; } glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glDisable(GL_FOG); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, grassBladeTex); glEnable(GL_TEXTURE_2D); glEnable(GL_CLIP_PLANE0); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glColor4f(1,1,1,1); glViewport(0,0,texSizeX*sizeMod, texSizeY*sizeMod); glClearColor(mapInfo->grass.color.r,mapInfo->grass.color.g,mapInfo->grass.color.b,0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f,0.f,0.f,0.f); static const GLdouble eq[4] = {0.f, 1.f, 0.f, 0.f}; // render turf from different vertical angles for (int a=0;a<numAngles;++a) { glViewport(a*billboardSize*sizeMod, 0, billboardSize*sizeMod, billboardSize*sizeMod); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(a*90.f/(numAngles-1),1,0,0); //glTranslatef(0,-0.5f,0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-partTurfSize, partTurfSize, partTurfSize, -partTurfSize, -turfSize, turfSize); // has to be applied after the matrix transformations, // cause it uses those an `compiles` them into the clip plane glClipPlane(GL_CLIP_PLANE0, &eq[0]); glCallList(grassDL); } glDisable(GL_CLIP_PLANE0); // scale down the rendered fartextures (MSAA) and write to the final texture glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo.fboId); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, fboTex.fboId); glBlitFramebufferEXT(0, 0, texSizeX*sizeMod, texSizeY*sizeMod, 0, 0, texSizeX, texSizeY, GL_COLOR_BUFFER_BIT, GL_LINEAR); // compute mipmaps glBindTexture(GL_TEXTURE_2D, farTex); glGenerateMipmap(GL_TEXTURE_2D); // blur non-rendered areas, so in mipmaps color data isn't blurred with background color { const int mipLevels = std::ceil(std::log(std::max(texSizeX, texSizeY) + 1)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_DST_ALPHA); // copy each mipmap to its predecessor background // -> fill background with blurred color data fboTex.Bind(); for (int mipLevel = mipLevels - 2; mipLevel >= 0; --mipLevel) { fboTex.AttachTexture(farTex, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT, mipLevel); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, mipLevel + 1.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, mipLevel + 1.f); glViewport(0, 0, texSizeX>>mipLevel, texSizeY>>mipLevel); CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertexT(float3(-1.0f, 1.0f, 0.0f), 0.0f, 1.0f); va->AddVertexT(float3( 1.0f, 1.0f, 0.0f), 1.0f, 1.0f); va->AddVertexT(float3( 1.0f, -1.0f, 0.0f), 1.0f, 0.0f); va->AddVertexT(float3(-1.0f, -1.0f, 0.0f), 0.0f, 0.0f); va->DrawArrayT(GL_QUADS); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // recreate mipmaps from now blurred base level glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.f); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000.f); glGenerateMipmap(GL_TEXTURE_2D); } glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); FBO::Unbind(); //glSaveTexture(farTex, "grassfar.png"); }
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 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); } } }