void CInMapDraw::Draw(void) { glDepthMask(0); CVertexArray* va = GetVertexArray(); va->Initialize(); CVertexArray* lineva = GetVertexArray(); lineva->Initialize(); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); InMapDraw_QuadDrawer drawer; drawer.imd = this; drawer.lineva = lineva; drawer.va = va; drawer.texture = texture; readmap->GridVisibility(camera, DRAW_QUAD_SIZE, 3000.0f, &drawer); glDisable(GL_TEXTURE_2D); glLineWidth(3); lineva->DrawArrayC(GL_LINES); glLineWidth(1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); va->DrawArrayTC(GL_QUADS); glDepthMask(1); }
void CInMapDraw::Draw(void) { GML_STDMUTEX_LOCK(inmap); //! Draw CVertexArray* va = GetVertexArray(); va->Initialize(); CVertexArray* lineva = GetVertexArray(); lineva->Initialize(); InMapDraw_QuadDrawer drawer; drawer.imd = this; drawer.lineva = lineva; drawer.va = va; drawer.visLabels = &visibleLabels; glDepthMask(0); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, texture); readmap->GridVisibility(camera, DRAW_QUAD_SIZE, 3000.0f, &drawer); glDisable(GL_TEXTURE_2D); glLineWidth(3.f); lineva->DrawArrayC(GL_LINES); //! draw lines // XXX hopeless drivers, retest in a year or so... // width greater than 2 causes GUI flicker on ATI hardware as of driver version 9.3 // so redraw lines with width 1 if (globalRendering->atiHacks) { glLineWidth(1.f); lineva->DrawArrayC(GL_LINES); } // draw points glLineWidth(1); glEnable(GL_TEXTURE_2D); va->DrawArrayTC(GL_QUADS); //! draw point markers if (!visibleLabels.empty()) { font->SetColors(); //! default //! draw point labels for (std::vector<MapPoint*>::iterator pi = visibleLabels.begin(); pi != visibleLabels.end(); ++pi) { float3 pos = (*pi)->pos; pos.y += 111.0f; font->SetTextColor((*pi)->color[0]/255.0f, (*pi)->color[1]/255.0f, (*pi)->color[2]/255.0f, 1.0f); //FIXME (overload!) font->glWorldPrint(pos, 26.0f, (*pi)->label); } visibleLabels.clear(); } glDepthMask(1); }
void CInMapDrawView::Draw() { CVertexArray* pointsVa = GetVertexArray(); pointsVa->Initialize(); CVertexArray* linesVa = GetVertexArray(); linesVa->Initialize(); InMapDraw_QuadDrawer drawer; drawer.linesVa = linesVa; drawer.pointsVa = pointsVa; drawer.visibleLabels = &visibleLabels; glDepthMask(0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, texture); readMap->GridVisibility(camera, CInMapDrawModel::DRAW_QUAD_SIZE, 1e9, &drawer); glDisable(GL_TEXTURE_2D); glLineWidth(3.f); linesVa->DrawArrayC(GL_LINES); //! draw lines // XXX hopeless drivers, retest in a year or so... // width greater than 2 causes GUI flicker on ATI hardware as of driver version 9.3 // so redraw lines with width 1 if (globalRendering->atiHacks) { glLineWidth(1.f); linesVa->DrawArrayC(GL_LINES); } // draw points glLineWidth(1); glEnable(GL_TEXTURE_2D); pointsVa->DrawArrayTC(GL_QUADS); //! draw point markers if (!visibleLabels.empty()) { font->SetColors(); //! default //! draw point labels for (std::vector<const CInMapDrawModel::MapPoint*>::const_iterator pi = visibleLabels.begin(); pi != visibleLabels.end(); ++pi) { float3 pos = (*pi)->GetPos(); pos.y += 111.0f; const unsigned char* color = (*pi)->IsBySpectator() ? color4::white : teamHandler->Team((*pi)->GetTeamID())->color; font->SetTextColor(color[0]/255.0f, color[1]/255.0f, color[2]/255.0f, 1.0f); //FIXME (overload!) font->glWorldPrint(pos, 26.0f, (*pi)->GetLabel()); } visibleLabels.clear(); } glDepthMask(1); }
void CGrassDrawer::DrawNearBillboards(const std::vector<InviewNearGrass>& inviewNearGrass) { CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(inviewNearGrass.size() * numTurfs * 4, 0, VA_SIZE_TN); for (std::vector<InviewNearGrass>::const_iterator gi = inviewNearGrass.begin(); gi != inviewNearGrass.end(); ++gi) { const int x = (*gi).x; const int y = (*gi).y; rng.Seed(y * 1025 + x); for (int a = 0; a < numTurfs; a++) { const float dx = (x + rng.RandFloat()) * gSSsq; const float dy = (y + rng.RandFloat()) * gSSsq; const float col = 1.0f; float3 pos(dx, CGround::GetHeightReal(dx, dy, false) + 0.5f, dy); pos.y -= (CGround::GetSlope(dx, dy, false) * 10.0f + 0.03f); va->AddVertexQTN(pos, 0.0f, 0.0f, float3(-partTurfSize, -partTurfSize, col)); va->AddVertexQTN(pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, -partTurfSize, col)); va->AddVertexQTN(pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize, partTurfSize, col)); va->AddVertexQTN(pos, 0.0f, 1.0f, float3(-partTurfSize, partTurfSize, col)); } } va->DrawArrayTN(GL_QUADS); }
void CProjectileDrawer::DrawFlyingPieces(int modelType, int numFlyingPieces, int* drawnPieces) { static FlyingPieceContainer* containers[MODELTYPE_OTHER] = { &ph->flyingPieces3DO, &ph->flyingPiecesS3O, NULL }; FlyingPieceContainer* container = containers[modelType]; FlyingPieceContainer::render_iterator fpi; if (container != NULL) { CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(numFlyingPieces * 4, 0, VA_SIZE_TN); size_t lastTex = -1; size_t lastTeam = -1; for (fpi = container->render_begin(); fpi != container->render_end(); ++fpi) { (*fpi)->Draw(modelType, &lastTeam, &lastTex, va); } (*drawnPieces) += (va->drawIndex() / 32); va->DrawArrayTN(GL_QUADS); } }
static void DrawRadialDisc() { //! SAME ALGORITHM AS FOR WATER-PLANE IN BFGroundDrawer.cpp! const float xsize = (gs->mapx * SQUARE_SIZE) >> 2; const float ysize = (gs->mapy * SQUARE_SIZE) >> 2; CVertexArray* va = GetVertexArray(); va->Initialize(); const float alphainc = fastmath::PI2 / 32; float alpha, r1, r2; float3 p(0.0f, 0.0f, 0.0f); const float size = std::min(xsize, ysize); for (int n = 0; n < 4 ; ++n) { r1 = n*n * size; if (n == 3) { r2 = (n + 0.5) * (n + 0.5) * size; } else { r2 = (n + 1) * (n + 1) * size; } for (alpha = 0.0f; (alpha - fastmath::PI2) < alphainc; alpha += alphainc) { p.x = r1 * fastmath::sin(alpha) + 2 * xsize; p.z = r1 * fastmath::cos(alpha) + 2 * ysize; va->AddVertex0(p); p.x = r2 * fastmath::sin(alpha) + 2 * xsize; p.z = r2 * fastmath::cos(alpha) + 2 * ysize; va->AddVertex0(p); } } va->DrawArray0(GL_TRIANGLE_STRIP); }
void DebugDrawerAI::TexSet::Draw() { if (!textures.empty()) { glEnable(GL_TEXTURE_2D); font->Begin(); font->SetTextColor(0.0f, 0.0f, 0.0f, 1.0f); CVertexArray* va = GetVertexArray(); for (std::map<int, TexSet::Texture*>::iterator it = textures.begin(); it != textures.end(); ++it) { const TexSet::Texture* tex = it->second; const float3& pos = tex->GetPos(); const float3& size = tex->GetSize(); glBindTexture(GL_TEXTURE_2D, tex->GetID()); va->Initialize(); va->AddVertexT(pos, 0.0f, 1.0f); va->AddVertexT(pos + float3(size.x, 0.0f, 0.0f), 1.0f, 1.0f); va->AddVertexT(pos + float3(size.x, size.y, 0.0f), 1.0f, 0.0f); va->AddVertexT(pos + float3( 0.0f, size.y, 0.0f), 0.0f, 0.0f); va->DrawArrayT(GL_QUADS); glBindTexture(GL_TEXTURE_2D, 0); const float tx = pos.x + size.x * 0.5f - ((tex->GetLabelWidth() * 0.5f) / globalRendering->viewSizeX) * size.x; const float ty = pos.y + size.y + ((tex->GetLabelHeight() * 0.5f) / globalRendering->viewSizeY) * size.y; font->glFormat(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, "%s", tex->GetLabel().c_str()); } font->End(); glDisable(GL_TEXTURE_2D); } }
void CDecalsDrawerGL4::UpdateOverlap_Initialize() { glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); //glClearColor(0.0f, 0.5f, 0.0f, 1.0f); //glClear(GL_COLOR_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 0, 0xFF); glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP); CVertexArray* va = GetVertexArray(); va->Initialize(); for (Decal& d: decals) { DRAW_DECAL(va, &d); } va->DrawArray2dT(GL_QUADS); /*const size_t datasize = 4 * OVERLAP_TEST_TEXTURE_SIZE * OVERLAP_TEST_TEXTURE_SIZE; unsigned char* img = new unsigned char[datasize]; memset(img, 0, datasize); glReadPixels(0, 0, OVERLAP_TEST_TEXTURE_SIZE, OVERLAP_TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, img); CBitmap bitmap(img, OVERLAP_TEST_TEXTURE_SIZE, OVERLAP_TEST_TEXTURE_SIZE); bitmap.Save("decals.png", true); delete[] img;*/ }
static void DrawThreadBarcode() { const float maxHist_f = 4.0f; const spring_time curTime = spring_now(); const spring_time maxHist = spring_secs(maxHist_f); auto& coreProf = profiler.profileCore; const auto numThreads = coreProf.size(); const float drawArea[4] = {0.01f, 0.30f, (start_x / 2), 0.35f}; // 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] + 10 * globalRendering->pixelY, 0.0f); va->AddVertex0(drawArea[2] + 10 * globalRendering->pixelX, drawArea[3] + 10 * 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 font->glFormat(drawArea[0], drawArea[3], 0.7f, FONT_TOP | DBG_FONT_FLAGS, "ThreadPool (%.0fsec)", maxHist_f); // bars glColor4f(1.0f,0.0f,0.0f, 0.6f); int i = 0; for (auto& frames: coreProf) { float drawArea2[4] = {drawArea[0], 0.f, drawArea[2], 0.f}; drawArea2[1] = drawArea[1] + ((drawArea[3] - drawArea[1]) / numThreads) * i++; drawArea2[3] = drawArea[1] + ((drawArea[3] - drawArea[1]) / numThreads) * i - 4 * globalRendering->pixelY; DrawTimeSlice(frames, curTime, maxHist, drawArea2); } // feeder //const float y1 = 0.0f; //const float y2 = 0.1f * numThreads; //CVertexArray* va = GetVertexArray(); va->Initialize(); 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 + 5 * globalRendering->pixelX, drawArea[3], 0.0f); va->AddVertex0(xf + 5 * globalRendering->pixelX, drawArea[1], 0.0f); glColor3f(1.0f,0.0f,0.0f); va->DrawArray0(GL_QUADS); }
std::vector<int> CDecalsDrawerGL4::UpdateOverlap_CheckQueries() { // query the results of the last issued test (if any pixels were rendered for the decal) std::vector<int> candidatesForRemoval; candidatesForRemoval.reserve(waitingOverlapGlQueries.size()); for (auto& p: waitingOverlapGlQueries) { GLint rendered = GL_FALSE; glGetQueryObjectiv(p.second, GL_QUERY_RESULT, &rendered); glDeleteQueries(1, &p.second); if (rendered == GL_FALSE) { candidatesForRemoval.push_back(p.first); } } waitingOverlapGlQueries.clear(); // no candidates left, restart with stage 0 if (candidatesForRemoval.empty()) { overlapStage = 0; return candidatesForRemoval; } //FIXME comment auto sortBeginIt = candidatesForRemoval.begin(); auto sortEndIt = candidatesForRemoval.end(); while (sortBeginIt != sortEndIt) { std::sort(sortBeginIt, sortEndIt, [&](const int& idx1, const int& idx2){ return decals[idx1].generation < decals[idx2].generation; }); sortEndIt = std::partition(sortBeginIt+1, sortEndIt, [&](const int& idx){ return !Overlap(decals[*sortBeginIt], decals[idx]); }); ++sortBeginIt; } auto eraseIt = sortEndIt; // free one decal (+ remove it from the overlap texture) int freed = 0; CVertexArray* va = GetVertexArray(); glStencilFunc(GL_ALWAYS, 0, 0xFF); glStencilOp(GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP); va->Initialize(); for (auto it = candidatesForRemoval.begin(); it != eraseIt; ++it) { const int curIndex = *it; const Decal& d = decals[curIndex]; DRAW_DECAL(va, &d); FreeDecal(curIndex); freed++; } va->DrawArray2dT(GL_QUADS); candidatesForRemoval.erase(candidatesForRemoval.begin(), eraseIt); //FIXME LOG_L(L_ERROR, "Query freed: %i of %i (decals:%i groups:%i)", freed, int(candidatesForRemoval.size()), int(decals.size() - freeIds.size()), int(groups.size())); // overlap texture changed, so need to retest the others return candidatesForRemoval; }
void CSMFGroundDrawer::CreateWaterPlanes(bool camOufOfMap) { glDisable(GL_TEXTURE_2D); glDepthMask(GL_FALSE); const float xsize = (smfMap->mapSizeX) >> 2; const float ysize = (smfMap->mapSizeZ) >> 2; const float size = std::min(xsize, ysize); CVertexArray* va = GetVertexArray(); va->Initialize(); const unsigned char fogColor[4] = { (unsigned char)(255 * mapInfo->atmosphere.fogColor[0]), (unsigned char)(255 * mapInfo->atmosphere.fogColor[1]), (unsigned char)(255 * mapInfo->atmosphere.fogColor[2]), 255 }; const unsigned char planeColor[4] = { (unsigned char)(255 * mapInfo->water.planeColor[0]), (unsigned char)(255 * mapInfo->water.planeColor[1]), (unsigned char)(255 * mapInfo->water.planeColor[2]), 255 }; const float alphainc = fastmath::PI2 / 32; float alpha,r1,r2; float3 p(0.0f, std::min(-200.0f, smfMap->initMinHeight - 400.0f), 0.0f); for (int n = (camOufOfMap) ? 0 : 1; n < 4 ; ++n) { if ((n == 1) && !camOufOfMap) { // don't render vertices under the map r1 = 2 * size; } else { r1 = n*n * size; } if (n == 3) { // last stripe: make it thinner (looks better with fog) r2 = (n+0.5)*(n+0.5) * size; } else { r2 = (n+1)*(n+1) * size; } for (alpha = 0.0f; (alpha - fastmath::PI2) < alphainc ; alpha += alphainc) { p.x = r1 * fastmath::sin(alpha) + 2 * xsize; p.z = r1 * fastmath::cos(alpha) + 2 * ysize; va->AddVertexC(p, planeColor ); p.x = r2 * fastmath::sin(alpha) + 2 * xsize; p.z = r2 * fastmath::cos(alpha) + 2 * ysize; va->AddVertexC(p, (n==3) ? fogColor : planeColor); } } va->DrawArrayC(GL_TRIANGLE_STRIP); glDepthMask(GL_TRUE); }
void CGrassDrawer::CreateGrassDispList(int listNum) { CVertexArray* va = GetVertexArray(); va->Initialize(); grng.Seed(15); for (int a = 0; a < strawPerTurf; ++a) { // draw a single blade const float lngRnd = grng.NextFloat(); const float length = mapInfo->grass.bladeHeight * (1.0f + lngRnd); const float maxAng = mapInfo->grass.bladeAngle * std::max(grng.NextFloat(), 1.0f - smoothstep(0.0f, 1.0f, lngRnd)); float3 sideVect; sideVect.x = grng.NextFloat() - 0.5f; sideVect.z = grng.NextFloat() - 0.5f; sideVect.ANormalize(); float3 bendVect = sideVect.cross(UpVector); // direction to bend into sideVect *= mapInfo->grass.bladeWidth * (-0.15f * lngRnd + 1.0f); const float3 basePos = grng.NextVector2D() * (turfSize - (bendVect * std::sin(maxAng) * length).Length2D()); // select one of the 16 color shadings const float xtexCoord = grng.NextInt(16) / 16.0f; const int numSections = 2 + int(maxAng * 1.2f + length * 0.2f); float3 normalBend = -bendVect; // start btm va->AddVertexTN(basePos + sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord , 0.f, normalBend); va->AddVertexTN(basePos - sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord + (1.0f / 16), 0.f, normalBend); for (float h = 0.0f; h < 1.0f; h += (1.0f / numSections)) { const float ang = maxAng * h; const float3 n = (normalBend * std::cos(ang) + UpVector * std::sin(ang)).ANormalize(); const float3 edgePos = (UpVector * std::cos(ang) + bendVect * std::sin(ang)) * length * h; const float3 edgePosL = edgePos - sideVect * (1.0f - h); const float3 edgePosR = edgePos + sideVect * (1.0f - h); va->AddVertexTN(basePos + edgePosR, xtexCoord + (1.0f / 32) * h , h, (n + sideVect * 0.04f).ANormalize()); va->AddVertexTN(basePos + edgePosL, xtexCoord - (1.0f / 32) * h + (1.0f / 16), h, (n - sideVect * 0.04f).ANormalize()); } // end top tip (single triangle) const float3 edgePos = (UpVector * std::cos(maxAng) + bendVect * std::sin(maxAng)) * length; const float3 n = (normalBend * std::cos(maxAng) + UpVector * std::sin(maxAng)).ANormalize(); va->AddVertexTN(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f, n); // next blade va->EndStrip(); } glNewList(listNum, GL_COMPILE); va->DrawArrayTN(GL_TRIANGLE_STRIP); glEndList(); }
void CInMapDraw::Draw(void) { GML_STDMUTEX_LOCK(inmap); //! Draw glDepthMask(0); CVertexArray* va = GetVertexArray(); va->Initialize(); CVertexArray* lineva = GetVertexArray(); lineva->Initialize(); //font->Begin(); font->SetColors(); //! default InMapDraw_QuadDrawer drawer; drawer.imd = this; drawer.lineva = lineva; drawer.va = va; drawer.texture = texture; readmap->GridVisibility(camera, DRAW_QUAD_SIZE, 3000.0f, &drawer); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); glLineWidth(3.f); lineva->DrawArrayC(GL_LINES); //! draw lines // XXX hopeless drivers, retest in a year or so... // width greater than 2 causes GUI flicker on ATI hardware as of driver version 9.3 // so redraw lines with width 1 if (gu->atiHacks) { glLineWidth(1.f); lineva->DrawArrayC(GL_LINES); } // draw points glLineWidth(1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); va->DrawArrayTC(GL_QUADS); //! draw point markers //font->End(); //! draw point markers text glDepthMask(1); }
/* * Draws a trigonometric circle in 'resolution' steps, with a slope modifier */ void glBallisticCircle(const float3& center, const float radius, const CWeapon* weapon, unsigned int resolution, float slope) { int rdiv = 50; resolution *= 2; rdiv *= 1; CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(resolution, 0, VA_SIZE_0); float3* vertices = reinterpret_cast<float3*>(va->drawArray); va->drawArrayPos = va->drawArray + resolution * 3; for_mt(0, resolution, [&](const int i) { const float radians = (2.0f * PI) * (float)i / (float)resolution; float rad = radius; float sinR = fastmath::sin(radians); float cosR = fastmath::cos(radians); float3 pos; pos.x = center.x + (sinR * rad); pos.z = center.z + (cosR * rad); pos.y = CGround::GetHeightAboveWater(pos.x, pos.z, false); float heightDiff = (pos.y - center.y) * 0.5f; rad -= heightDiff * slope; float adjRadius = weapon ? weapon->GetRange2D(heightDiff * weapon->heightMod) : rad; float adjustment = rad * 0.5f; float ydiff = 0; for(int j = 0; j < rdiv && math::fabs(adjRadius - rad) + ydiff > .01 * rad; j++) { if (adjRadius > rad) { rad += adjustment; } else { rad -= adjustment; adjustment /= 2; } pos.x = center.x + (sinR * rad); pos.z = center.z + (cosR * rad); float newY = CGround::GetHeightAboveWater(pos.x, pos.z, false); ydiff = math::fabs(pos.y - newY); pos.y = newY; heightDiff = (pos.y - center.y); adjRadius = weapon ? weapon->GetRange2D(heightDiff * weapon->heightMod) : rad; } pos.x = center.x + (sinR * adjRadius); pos.z = center.z + (cosR * adjRadius); pos.y = CGround::GetHeightAboveWater(pos.x, pos.z, false) + 5.0f; vertices[i] = pos; }); va->DrawArray0(GL_LINE_LOOP); }
void CGrassDrawer::CreateGrassDispList(int listNum) { CVertexArray* va = GetVertexArray(); va->Initialize(); for (int a = 0; a < strawPerTurf; ++a) { const float maxAng = mapInfo->grass.bladeAngle * rng.RandFloat(); const float length = mapInfo->grass.bladeHeight + mapInfo->grass.bladeHeight * rng.RandFloat(); float3 sideVect(rng.RandFloat() - 0.5f, 0.0f, rng.RandFloat() - 0.5f); sideVect.ANormalize(); float3 forwardVect = sideVect.cross(UpVector); sideVect *= mapInfo->grass.bladeWidth; float3 basePos(30.0f, 0.0f, 30.0f); while (basePos.SqLength2D() > (turfSize * turfSize / 4)) { basePos = float3(rng.RandFloat() - 0.5f, 0.f, rng.RandFloat() - 0.5f) * turfSize; } const float xtexCoord = int(14.9999f * rng.RandFloat()) / 16.0f; const int numSections = 1 + int(maxAng * 5.0f); // draw single blade for (float h = 0; h <= 1.0f; h += (1.0f / numSections)) { const float ang = maxAng * h; const float3 edgePos = (UpVector * std::cos(ang) + forwardVect * std::sin(ang)) * length * h; const float3 edgePosL = edgePos - sideVect * (1.0f - h); const float3 edgePosR = edgePos + sideVect * (1.0f - h); if (h == 0.0f) { // start with a degenerated triangle va->AddVertexT(basePos + edgePosR - float3(0.0f, 0.1f, 0.0f), xtexCoord, h); va->AddVertexT(basePos + edgePosR - float3(0.0f, 0.1f, 0.0f), xtexCoord, h); } else { va->AddVertexT(basePos + edgePosR, xtexCoord, h); } va->AddVertexT(basePos + edgePosL, xtexCoord + (1.0f / 16), h); } // end with a degenerated triangle // -> this way we can render multiple blades in a single GL_TRIANGLE_STRIP const float3 edgePos = (UpVector * std::cos(maxAng) + forwardVect * std::sin(maxAng)) * length; va->AddVertexT(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f); va->AddVertexT(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f); } glNewList(listNum, GL_COMPILE); va->DrawArrayT(GL_TRIANGLE_STRIP); glEndList(); }
void CMiniMap::DrawNotes() { if (notes.empty()) { return; } const float baseSize = gs->mapx * SQUARE_SIZE; CVertexArray* va = GetVertexArray(); va->Initialize(); std::list<Notification>::iterator ni = notes.begin(); while (ni != notes.end()) { const float age = gu->gameTime - ni->creationTime; if (age > 2) { ni = notes.erase(ni); continue; } for (int a = 0; a < 3; ++a) { const float modage = age + a * 0.1f; const float rot = modage * 3; float size = baseSize - modage * baseSize * 0.9f; if (size < 0){ if (size < -baseSize * 0.4f) { continue; } else if (size > -baseSize * 0.2f) { size = modage * baseSize * 0.9f - baseSize; } else { size = baseSize * 1.4f - modage * baseSize * 0.9f; } } const float sinSize = fastmath::sin(rot) * size; const float cosSize = fastmath::cos(rot) * size; const unsigned char color[4] = { (unsigned char)(ni->color[0] * 255), (unsigned char)(ni->color[1] * 255), (unsigned char)(ni->color[2] * 255), (unsigned char)(ni->color[3] * 255) }; va->AddVertexC(float3(ni->pos.x + sinSize, ni->pos.z + cosSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x + cosSize, ni->pos.z - sinSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x + cosSize, ni->pos.z - sinSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x - sinSize, ni->pos.z - cosSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x - sinSize, ni->pos.z - cosSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x - cosSize, ni->pos.z + sinSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x - cosSize, ni->pos.z + sinSize, 0.0f),color); va->AddVertexC(float3(ni->pos.x + sinSize, ni->pos.z + cosSize, 0.0f),color); } ++ni; } va->DrawArrayC(GL_LINES); }
void CFeatureHandler::Draw() { fadeFeatures.clear(); fadeFeaturesS3O.clear(); drawFar.clear(); GML_RECMUTEX_LOCK(feat); // Draw if(gu->drawFog) { glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); } unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); // S3O features can have transparent bits glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER,0.5f); unitDrawer->DrawQuedS3O(); glPopAttrib(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.8f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size()*4,0,VA_SIZE_TN); for (vector<CFeature*>::iterator usi = drawFar.begin(); usi != drawFar.end(); ++usi) { DrawFar(*usi, va); } va->DrawArrayTN(GL_QUADS); glDisable(GL_ALPHA_TEST); } glDisable(GL_FOG); }
void CGrassDrawer::DrawFarBillboards(const std::vector<GrassStruct*>& inviewFarGrass) { // update far grass blocks if (updateBillboards) { updateBillboards = false; for_mt(0, inviewFarGrass.size(), [&](const int i) { GrassStruct& g = *inviewFarGrass[i]; if (g.lastFar == 0) { // TODO: VA's need to be uploaded each frame, switch to VBO's // force the patch-quads to be recreated g.lastFar = globalRendering->drawFrame; g.lastDist = -1.0f; } const float distSq = GetGrassBlockCamDist((g.posX + 0.5f) * grassBlockSize, (g.posZ + 0.5f) * grassBlockSize, true); if (distSq == g.lastDist) return; const bool inAlphaRange1 = ( distSq < Square(maxDetailedDist + 128.0f * 1.5f)) || ( distSq > Square(maxGrassDist - 128.0f)); const bool inAlphaRange2 = (g.lastDist < Square(maxDetailedDist + 128.0f * 1.5f)) || (g.lastDist > Square(maxGrassDist - 128.0f)); if (!inAlphaRange1 && (inAlphaRange1 == inAlphaRange2)) return; g.lastDist = distSq; CVertexArray* va = &g.va; va->Initialize(); // (4*4)*numTurfs quads for (int y2 = g.posZ * grassBlockSize; y2 < (g.posZ + 1) * grassBlockSize; ++y2) { for (int x2 = g.posX * grassBlockSize; x2 < (g.posX + 1) * grassBlockSize; ++x2) { if (!grassMap[y2 * mapDims.mapx / grassSquareSize + x2]) continue; const float dist = GetGrassBlockCamDist(x2, y2); auto* va_tn = va->GetTypedVertexArray<VA_TYPE_TN>(numTurfs * 4); DrawBillboard(x2, y2, dist, va_tn); } } }); } // render far grass blocks for (GrassStruct* g: inviewFarGrass) { g->va.DrawArrayTN(GL_QUADS); } }
/** * Draws a trigonometric circle in 'resolution' steps. */ static void defSurfaceCircle(const float3& center, float radius, unsigned int res) { CVertexArray* va = GetVertexArray(); va->Initialize(); for (unsigned int i = 0; i < res; ++i) { const float radians = math::TWOPI * (float)i / (float)res; float3 pos; pos.x = center.x + (fastmath::sin(radians) * radius); pos.z = center.z + (fastmath::cos(radians) * radius); pos.y = CGround::GetHeightAboveWater(pos.x, pos.z, false) + 5.0f; va->AddVertex0(pos); } va->DrawArray0(GL_LINE_LOOP); }
static void DrawInfoText() { // background CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(0.01f - 10 * globalRendering->pixelX, 0.02f - 10 * globalRendering->pixelY, 0.0f); va->AddVertex0(0.01f - 10 * globalRendering->pixelX, 0.16f + 20 * globalRendering->pixelY, 0.0f); va->AddVertex0(start_x - 0.05f + 10 * globalRendering->pixelX, 0.16f + 20 * globalRendering->pixelY, 0.0f); va->AddVertex0(start_x - 0.05f + 10 * globalRendering->pixelX, 0.02f - 10 * globalRendering->pixelY, 0.0f); glColor4f(0.0f,0.0f,0.0f, 0.5f); va->DrawArray0(GL_QUADS); //print some infos (fps,gameframe,particles) font->SetTextColor(1,1,0.5f,0.8f); font->glFormat(0.01f, 0.02f, 1.0f, DBG_FONT_FLAGS, "FPS: %0.1f SimFPS: %0.1f SimFrame: %d Speed: %2.2f (%2.2f) Particles: %d (%d)", globalRendering->FPS, gu->simFPS, gs->frameNum, gs->speedFactor, gs->wantedSpeedFactor, projectileHandler->syncedProjectiles.size() + projectileHandler->unsyncedProjectiles.size(), projectileHandler->currentParticles); // 16ms := 60fps := 30simFPS + 30drawFPS font->glFormat(0.01f, 0.07f, 0.7f, DBG_FONT_FLAGS, "avgFrame: %s%2.1fms\b avgDrawFrame: %s%2.1fms\b avgSimFrame: %s%2.1fms\b", (gu->avgFrameTime > 30) ? "\xff\xff\x01\x01" : "", gu->avgFrameTime, (gu->avgDrawFrameTime > 16) ? "\xff\xff\x01\x01" : "", gu->avgDrawFrameTime, (gu->avgSimFrameTime > 16) ? "\xff\xff\x01\x01" : "", gu->avgSimFrameTime ); const int2 pfsUpdates = pathManager->GetNumQueuedUpdates(); const char* fmtString = "[%s-PFS] queued updates: %i %i"; switch (pathManager->GetPathFinderType()) { case PFS_TYPE_DEFAULT: { font->glFormat(0.01f, 0.12f, 0.7f, DBG_FONT_FLAGS, fmtString, "DEFAULT", pfsUpdates.x, pfsUpdates.y); } break; case PFS_TYPE_QTPFS: { font->glFormat(0.01f, 0.12f, 0.7f, DBG_FONT_FLAGS, fmtString, "QT", pfsUpdates.x, pfsUpdates.y); } break; } SLuaInfo luaInfo = {0, 0, 0, 0}; spring_lua_alloc_get_stats(&luaInfo); font->glFormat( 0.01f, 0.15f, 0.7f, DBG_FONT_FLAGS, "Lua-allocated memory: %.1fMB (%.5uK allocs : %.5u usecs : %.1u states)", luaInfo.allocedBytes / 1024.0f / 1024.0f, luaInfo.numLuaAllocs / 1000, luaInfo.luaAllocTime, luaInfo.numLuaStates ); }
void CProjectileHandler::DrawProjectilesMiniMap(const ProjectileContainer& pc) { if (pc.render_size() > 0) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays(pc.render_size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays(pc.render_size(), 0, VA_SIZE_C); for (ProjectileContainer::render_iterator pci = pc.render_begin(); pci != pc.render_end(); ++pci) { CProjectile* p = *pci; if ((p->owner() && (p->owner()->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } }
void CGrassDrawer::DrawFarBillboards(const std::vector<GrassStruct*>& inviewFarGrass) { // update far grass blocks if (updateBillboards) { updateBillboards = false; for_mt(0, inviewFarGrass.size(), [&](const int i){ GrassStruct& g = *inviewFarGrass[i]; if (!g.va) { //TODO vertex arrays need to be send each frame to the gpu, that's slow. switch to VBOs. CVertexArray* va = new CVertexArray; g.va = va; g.lastDist = -1; // force a recreate } const float distSq = GetCamDistOfGrassBlock((g.posX + 0.5f) * grassBlockSize, (g.posZ + 0.5f) * grassBlockSize, true); if (distSq == g.lastDist) return; bool inAlphaRange1 = ( distSq < Square(maxDetailedDist + 128.f * 1.5f)) || ( distSq > Square(maxGrassDist - 128.f)); bool inAlphaRange2 = (g.lastDist < Square(maxDetailedDist + 128.f * 1.5f)) || (g.lastDist > Square(maxGrassDist - 128.f)); if (!inAlphaRange1 && (inAlphaRange1 == inAlphaRange2)) { return; } g.lastDist = distSq; CVertexArray* va = g.va; va->Initialize(); for (int y2 = g.posZ * grassBlockSize; y2 < (g.posZ + 1) * grassBlockSize; ++y2) { for (int x2 = g.posX * grassBlockSize; x2 < (g.posX + 1) * grassBlockSize; ++x2) { if (!grassMap[y2 * mapDims.mapx / grassSquareSize + x2]) { continue; } const float dist = GetCamDistOfGrassBlock(x2, y2); auto* va_tn = va->GetTypedVertexArray<VA_TYPE_TN>(numTurfs * 4); DrawBillboard(x2, y2, dist, va_tn); } } }); } // render far grass blocks for (const GrassStruct* g: inviewFarGrass) { g->va->DrawArrayTN(GL_QUADS); } }
static void defSurfaceSquare(const float3& center, float xsize, float zsize) { // FIXME: terrain contouring const float3 p0 = center + float3(-xsize, 0.0f, -zsize); const float3 p1 = center + float3( xsize, 0.0f, -zsize); const float3 p2 = center + float3( xsize, 0.0f, zsize); const float3 p3 = center + float3(-xsize, 0.0f, zsize); CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(p0.x, CGround::GetHeightAboveWater(p0.x, p0.z, false), p0.z); va->AddVertex0(p1.x, CGround::GetHeightAboveWater(p1.x, p1.z, false), p1.z); va->AddVertex0(p2.x, CGround::GetHeightAboveWater(p2.x, p2.z, false), p2.z); va->AddVertex0(p3.x, CGround::GetHeightAboveWater(p3.x, p3.z, false), p3.z); va->DrawArray0(GL_LINE_LOOP); }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } if (!fbo.IsValid()) { queuedForRender.clear(); return; } // create new far-icons for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { const CSolidObject* obj = *it; if (!HaveFarIcon(obj)) { CreateFarTexture(obj); } } // render current queued far icons on the screen { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTextureID); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); ISky::SetupFog(); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); } queuedForRender.clear(); }
void CDecalsDrawerGL4::UpdateOverlap_GenerateQueries(const std::vector<int>& candidatesForOverlap) { glStencilFunc(GL_GREATER, MAX_OVERLAP, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); CVertexArray* va = GetVertexArray(); for (int i: candidatesForOverlap) { Decal& d0 = decals[i]; GLuint q; glGenQueries(1, &q); glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, q); va->Initialize(); DRAW_DECAL(va, &d0); va->DrawArray2dT(GL_QUADS); glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE); waitingOverlapGlQueries.emplace_back(i, q); } }
void QTPFSPathDrawer::DrawNodeTree(const MoveDef* md) const { QTPFS::QTNode* nt = pm->nodeTrees[md->pathType]; CVertexArray* va = GetVertexArray(); std::list<const QTPFS::QTNode*> nodes; std::list<const QTPFS::QTNode*>::const_iterator nodesIt; GetVisibleNodes(nt, nodes); va->Initialize(); va->EnlargeArrays(nodes.size() * 4, 0, VA_SIZE_C); for (nodesIt = nodes.begin(); nodesIt != nodes.end(); ++nodesIt) { DrawNode(*nodesIt, md, va, false, true, true); } glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); va->DrawArrayC(GL_QUADS); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1); }
void CFarTextureHandler::Draw() { if (queuedForRender.empty()) { return; } //! create new faricons for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { const CSolidObject& obj = **it; if (cache.size()<=obj.team || cache[obj.team].size()<=obj.model->id || !cache[obj.team][obj.model->id]) { CreateFarTexture(*it); } } glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, farTexture); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x); if (globalRendering->drawFog) { glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); glEnable(GL_FOG); } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T); for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) { DrawFarTexture(*it, va); } va->DrawArrayT(GL_QUADS); glDisable(GL_ALPHA_TEST); queuedForRender.clear(); }
void SmoothHeightMeshDrawer::Draw(float yoffset) { if (!drawEnabled) return; glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(1.0f); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_1D); glDisable(GL_CULL_FACE); const float quadSize = 4.0f * smoothGround->GetResolution(); const unsigned int numQuadsX = smoothGround->GetFMaxX() / quadSize; const unsigned int numQuadsZ = smoothGround->GetFMaxY() / quadSize; CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays((numQuadsX + 1) * (numQuadsZ + 1) * 4, 0, VA_SIZE_0); for (unsigned int zq = 0; zq <= numQuadsZ; zq++) { for (unsigned int xq = 0; xq <= numQuadsX; xq++) { const float x = xq * quadSize; const float z = zq * quadSize; const float h1 = smoothGround->GetHeightAboveWater(x, z ) + yoffset; const float h2 = smoothGround->GetHeightAboveWater(x + quadSize, z ) + yoffset; const float h3 = smoothGround->GetHeightAboveWater(x + quadSize, z + quadSize) + yoffset; const float h4 = smoothGround->GetHeightAboveWater(x, z + quadSize) + yoffset; va->AddVertexQ0(float3(x, h1, z )); va->AddVertexQ0(float3(x + quadSize, h2, z )); va->AddVertexQ0(float3(x + quadSize, h3, z + quadSize)); va->AddVertexQ0(float3(x, h4, z + quadSize)); } } glColor4ub(0, 255, 0, 255); va->DrawArray0(GL_QUADS); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); }
static void DrawTimeSlice(std::deque<TimeSlice>& frames, const spring_time curTime, const spring_time maxHist, const float drawArea[4]) { // remove old entries while (!frames.empty() && (curTime - frames.front().second) > maxHist) { frames.pop_front(); } const float y1 = drawArea[1]; const float y2 = drawArea[3]; // render CVertexArray* va = GetVertexArray(); va->Initialize(); for (TimeSlice& ts: frames) { float x1 = (ts.first % maxHist).toSecsf() / maxHist.toSecsf(); float x2 = (ts.second % maxHist).toSecsf() / maxHist.toSecsf(); x2 = std::max(x1 + globalRendering->pixelX, x2); x1 = drawArea[0] + x1 * (drawArea[2] - drawArea[0]); x2 = drawArea[0] + x2 * (drawArea[2] - drawArea[0]); va->AddVertex0(x1, y1, 0.0f); va->AddVertex0(x1, y2, 0.0f); va->AddVertex0(x2, y2, 0.0f); va->AddVertex0(x2, y1, 0.0f); const float mx1 = x1 + 3 * globalRendering->pixelX; const float mx2 = x2 - 3 * globalRendering->pixelX; if (mx1 < mx2) { va->AddVertex0(mx1, y1 + 3 * globalRendering->pixelX, 0.0f); va->AddVertex0(mx1, y2 - 3 * globalRendering->pixelX, 0.0f); va->AddVertex0(mx2, y2 - 3 * globalRendering->pixelX, 0.0f); va->AddVertex0(mx2, y1 + 3 * globalRendering->pixelX, 0.0f); } } va->DrawArray0(GL_QUADS); }
void CFeatureHandler::Draw() { fadeFeatures.clear(); fadeFeaturesS3O.clear(); drawFar.clear(); GML_RECMUTEX_LOCK(feat); // Draw glEnable(GL_FOG); glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); unitDrawer->SetupForUnitDrawing(); unitDrawer->SetupFor3DO(); DrawRaw(0, &drawFar); unitDrawer->CleanUp3DO(); unitDrawer->DrawQuedS3O(); unitDrawer->CleanUpUnitDrawing(); if (drawFar.size()>0) { glAlphaFunc(GL_GREATER, 0.8f); glEnable(GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID()); glColor3f(1.0f, 1.0f, 1.0f); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(drawFar.size()*4,0,VA_SIZE_TN); for (vector<CFeature*>::iterator usi = drawFar.begin(); usi != drawFar.end(); usi++) { DrawFar(*usi, va); } va->DrawArrayTN(GL_QUADS); glDisable(GL_ALPHA_TEST); } glDisable(GL_FOG); }