void CInMapDraw::Draw(void) { glDepthMask(0); CVertexArray* va=GetVertexArray(); va->Initialize(); CVertexArray* lineva=GetVertexArray(); lineva->Initialize(); int cx=(int)(camera->pos.x/(SQUARE_SIZE*DRAW_QUAD_SIZE)); int cy=(int)(camera->pos.z/(SQUARE_SIZE*DRAW_QUAD_SIZE)); float drawDist=3000; int drawSquare=int(drawDist/(SQUARE_SIZE*DRAW_QUAD_SIZE))+1; int sy=cy-drawSquare; if(sy<0) sy=0; int ey=cy+drawSquare; if(ey>drawQuadsY-1) ey=drawQuadsY-1; for(int y=sy;y<=ey;y++){ int sx=cx-drawSquare; if(sx<0) sx=0; int ex=cx+drawSquare; if(ex>drawQuadsX-1) ex=drawQuadsX-1; float xtest,xtest2; std::vector<CBaseGroundDrawer::fline>::iterator fli; for(fli=groundDrawer->left.begin();fli!=groundDrawer->left.end();fli++){ xtest=((fli->base/SQUARE_SIZE+fli->dir*(y*DRAW_QUAD_SIZE))); xtest2=((fli->base/SQUARE_SIZE+fli->dir*((y*DRAW_QUAD_SIZE)+DRAW_QUAD_SIZE))); if(xtest>xtest2) xtest=xtest2; xtest=xtest/DRAW_QUAD_SIZE; if(xtest>sx) sx=(int)xtest; } for(fli=groundDrawer->right.begin();fli!=groundDrawer->right.end();fli++){ xtest=((fli->base/SQUARE_SIZE+fli->dir*(y*DRAW_QUAD_SIZE))); xtest2=((fli->base/SQUARE_SIZE+fli->dir*((y*DRAW_QUAD_SIZE)+DRAW_QUAD_SIZE))); if(xtest<xtest2) xtest=xtest2; xtest=xtest/DRAW_QUAD_SIZE; if(xtest<ex) ex=(int)xtest; } for(int x=sx;x<=ex;x++){/**/ DrawQuad* dq=&drawQuads[y*drawQuadsX+x]; glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D,texture); for(std::list<MapPoint>::iterator pi=dq->points.begin();pi!=dq->points.end();++pi){ 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;//intensity*255; float size=6; float3 pos1=pos; float3 pos2=pos1; pos2.y+=100; va->AddVertexTC(pos1-dir1*size, 0.25,0,col); va->AddVertexTC(pos1+dir1*size, 0.25,1,col); va->AddVertexTC(pos1+dir1*size+dir2*size, 0.00,1,col); va->AddVertexTC(pos1-dir1*size+dir2*size, 0.00,0,col); va->AddVertexTC(pos1-dir1*size,0.75,0,col); va->AddVertexTC(pos1+dir1*size,0.75,1,col); va->AddVertexTC(pos2+dir1*size,0.75,1,col); va->AddVertexTC(pos2-dir1*size,0.75,0,col); va->AddVertexTC(pos2-dir1*size, 0.25,0,col); va->AddVertexTC(pos2+dir1*size, 0.25,1,col); va->AddVertexTC(pos2+dir1*size-dir2*size, 0.00,1,col); va->AddVertexTC(pos2-dir1*size-dir2*size, 0.00,0,col); if(pi->label.size()>0){ glPushMatrix(); glTranslatef3(pi->pos+UpVector*105); glScalef(30,30,30); glColor4ub(pi->color[0],pi->color[1],pi->color[2],250); font->glWorldPrint("%s",pi->label.c_str()); glPopMatrix(); } } for(std::list<MapLine>::iterator li=dq->lines.begin();li!=dq->lines.end();++li){ lineva->AddVertexC(li->pos-(li->pos - camera->pos).Normalize()*26,li->color); lineva->AddVertexC(li->pos2-(li->pos2 - camera->pos).Normalize()*26,li->color); } } } glDisable(GL_TEXTURE_2D); glLineWidth(3); lineva->DrawArrayC(GL_LINES); glLineWidth(1); glEnable(GL_TEXTURE_2D); va->DrawArrayTC(GL_QUADS); glDepthMask(1); }
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 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) { // 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), }; const unsigned char color1[4] = { (unsigned char)( cmdColors.unitBox[0] * 255 ), (unsigned char)( cmdColors.unitBox[1] * 255 ), (unsigned char)( cmdColors.unitBox[2] * 255 ), (unsigned char)( cmdColors.unitBox[3] * 255 ) }; 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)) { const unsigned char color2[4] = { (unsigned char)( (1.0f - cmdColors.unitBox[0]) * 255 ), (unsigned char)( (1.0f - cmdColors.unitBox[1]) * 255 ), (unsigned char)( (1.0f - cmdColors.unitBox[2]) * 255 ), (unsigned char)( cmdColors.unitBox[3] * 255 ) }; 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->IsKeyPressed(SDLK_LSHIFT)) || ((guihandler->inCommand >= 0) && (guihandler->inCommand < int(guihandler->commands.size())) && (guihandler->commands[guihandler->inCommand].id < 0)))) { GML_STDMUTEX_LOCK(cai); // Draw bool myColor = true; glColor4fv(cmdColors.buildBox); std::list<CBuilderCAI*>::const_iterator bi; for (bi = uh->builderCAIs.begin(); bi != uh->builderCAIs.end(); ++bi) { CBuilderCAI* builder = *bi; if (builder->owner->team == gu->myTeam) { if (!myColor) { glColor4fv(cmdColors.buildBox); myColor = true; } commandDrawer->DrawQuedBuildingSquares(builder); } else if (teamHandler->AlliedTeams(builder->owner->team, gu->myTeam)) { if (myColor) { glColor4fv(cmdColors.allyBuildBox); myColor = false; } commandDrawer->DrawQuedBuildingSquares(builder); } } } } glLineWidth(1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(true); glEnable(GL_TEXTURE_2D); }
void 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 CTimeProfiler::Draw() { if(!gu->drawdebug) return; glPushMatrix(); glDisable(GL_TEXTURE_2D); glColor4f(0,0,0.5f,0.5f); if(!profile.empty()){ glBegin(GL_TRIANGLE_STRIP); glVertex3f(0.65f,0.99f,0); glVertex3f(0.99f,0.99f,0); glVertex3f(0.65f,0.99f-profile.size()*0.024-0.01,0); glVertex3f(0.99f,0.99f-profile.size()*0.024-0.01,0); glEnd(); } glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); map<string,TimeRecord>::iterator pi; int y=0; for(pi=profile.begin();pi!=profile.end();++pi,y++) font->glPrintAt(0.655f, 0.960-y*0.024f, 1.0f, "%20s %6.2fs %5.2f%%",pi->first.c_str(),((float)pi->second.total)/1000.,pi->second.percent*100); glTranslatef(0.655f,0.965f,0); glScalef(0.015f,0.02f,0.02f); glColor4f(1,1,1,1); glDisable(GL_TEXTURE_2D); for(pi=profile.begin();pi!=profile.end();++pi){ glColor3f(pi->second.color.x,pi->second.color.y,pi->second.color.z); glBegin(GL_QUADS); glVertex3f(0,0,0); glVertex3f(1,0,0); glVertex3f(1,1,0); glVertex3f(0,1,0); glEnd(); 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(); for(pi=profile.begin();pi!=profile.end();++pi){ if(!pi->second.showGraph) continue; CVertexArray* va=GetVertexArray(); va->Initialize(); for(int a=0;a<128;++a){ float p=((float)pi->second.frames[a])/1000.*30; va->AddVertexT(float3(0.6+a*0.003,0.02+p*0.4,0),0,0); } glColor3f(pi->second.color.x,pi->second.color.y,pi->second.color.z); va->DrawArrayT(GL_LINE_STRIP); } glEnable(GL_TEXTURE_2D); }
void CProjectileDrawer::DrawProjectilesMiniMap() { GML_RECMUTEX_LOCK(proj); // DrawProjectilesMiniMap typedef std::set<CProjectile*> ProjectileSet; typedef std::set<CProjectile*>::const_iterator ProjectileSetIt; typedef std::map<int, ProjectileSet> ProjectileBin; typedef std::map<int, ProjectileSet>::const_iterator ProjectileBinIt; for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { const ProjectileBin& projectileBin = modelRenderers[modelType]->GetProjectileBin(); if (!projectileBin.empty()) { for (ProjectileBinIt binIt = projectileBin.begin(); binIt != projectileBin.end(); ++binIt) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays((binIt->second).size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays((binIt->second).size(), 0, VA_SIZE_C); for (ProjectileSetIt setIt = (binIt->second).begin(); setIt != (binIt->second).end(); ++setIt) { CProjectile* p = *setIt; CUnit *owner = p->owner(); if ((owner && (owner->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } } } if (!renderProjectiles.empty()) { CVertexArray* lines = GetVertexArray(); CVertexArray* points = GetVertexArray(); lines->Initialize(); lines->EnlargeArrays(renderProjectiles.size() * 2, 0, VA_SIZE_C); points->Initialize(); points->EnlargeArrays(renderProjectiles.size(), 0, VA_SIZE_C); for (std::set<CProjectile*>::iterator it = renderProjectiles.begin(); it != renderProjectiles.end(); ++it) { CProjectile* p = *it; const CUnit* owner = p->owner(); if ((owner && (owner->allyteam == gu->myAllyTeam)) || gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) { p->DrawOnMinimap(*lines, *points); } } lines->DrawArrayC(GL_LINES); points->DrawArrayC(GL_POINTS); } }
void CProjectileDrawer::DrawGroundFlashes() { static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f}; glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glActiveTexture(GL_TEXTURE0); groundFXAtlas->BindTexture(); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.01f); glPolygonOffset(-20, -1000); glEnable(GL_POLYGON_OFFSET_FILL); glFogfv(GL_FOG_COLOR, black); { GML_STDMUTEX_LOCK(rflash); // DrawGroundFlashes projectileHandler->groundFlashes.delete_delayed(); projectileHandler->groundFlashes.add_delayed(); } CGroundFlash::va = GetVertexArray(); CGroundFlash::va->Initialize(); CGroundFlash::va->EnlargeArrays(8, 0, VA_SIZE_TC); GroundFlashContainer& gfc = projectileHandler->groundFlashes; GroundFlashContainer::render_iterator gfi; bool depthTest = true; bool depthMask = false; for (gfi = gfc.render_begin(); gfi != gfc.render_end(); ++gfi) { CGroundFlash* gf = *gfi; const bool los = gu->spectatingFullView || loshandler->InAirLos(gf->pos, gu->myAllyTeam); const bool vis = camera->InView(gf->pos, gf->size); if (depthTest != gf->depthTest) { depthTest = gf->depthTest; if (depthTest) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } if (depthMask != gf->depthMask) { depthMask = gf->depthMask; if (depthMask) { glDepthMask(GL_TRUE); } else { glDepthMask(GL_FALSE); } } if ((gf->alwaysVisible || los) && vis) { gf->Draw(); } CGroundFlash::va->DrawArrayTC(GL_QUADS); CGroundFlash::va->Initialize(); } glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); }
void CAdvWater::Draw(bool useBlending) { if (!mapInfo->water.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; const int numDivs = 20; base *= numDivs; float maxY = -0.1f; float yInc = 1.0f / numDivs; float screenY = 1; unsigned char col[4]; col[0] = (unsigned char)(waterSurfaceColor.x * 255); col[1] = (unsigned char)(waterSurfaceColor.y * 255); col[2] = (unsigned char)(waterSurfaceColor.z * 255); glDisable(GL_ALPHA_TEST); if (useBlending) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } glDepthMask(0); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, bumpTexture); GLfloat plan[] = {0.02f, 0, 0, 0}; glTexGeni(GL_S,GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_S,GL_EYE_PLANE, plan); glEnable(GL_TEXTURE_GEN_S); GLfloat plan2[] = {0, 0, 0.02f, 0}; glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_T, GL_EYE_PLANE, plan2); glEnable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, reflectTexture); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, waterFP); glEnable(GL_FRAGMENT_PROGRAM_ARB); float3 forward = camera->forward; forward.y = 0; forward.ANormalize(); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, forward.z, forward.x, 0, 0); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, -forward.x, forward.z, 0, 0); CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(5*numDivs*(numDivs + 1)*2, 5*numDivs, VA_SIZE_TC); //! alloc room for all vertexes and strips float3 dir, zpos; for (int a = 0; a < 5; ++a) { //! CAUTION: loop count must match EnlargeArrays above bool maxReached = false; for (int y = 0; y < numDivs; ++y) { dir = base; dir.ANormalize(); if (dir.y >= maxY) { maxReached = true; break; } xbase = base; for (int x = 0; x < numDivs + 1; ++x) { //! CAUTION: loop count must match EnlargeArrays above dir = xbase + dv; dir.ANormalize(); zpos = camera->GetPos() + dir*(camera->GetPos().y / -dir.y); zpos.y = math::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 = math::sin(zpos.z*0.1f + gs->frameNum*0.06f)*0.06f + 0.05f; col[3] = (unsigned char)((0.8f + 0.7f*dir.y)*255); va->AddVertexQTC(zpos, x*(1.0f/numDivs), screenY, col); xbase += dh; } va->EndStripQ(); base += dv; screenY -= yInc; } if (!maxReached) { break; } dv *= 0.5f; maxY *= 0.5f; yInc *= 0.5f; } va->DrawArrayTC(GL_TRIANGLE_STRIP); glDepthMask(1); glDisable(GL_FRAGMENT_PROGRAM_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glActiveTextureARB(GL_TEXTURE0_ARB); if (!useBlending) { // for translucent stuff like water, the default mode is blending and alpha testing enabled glEnable(GL_BLEND); } }
void 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 DrawQuad(int x, int y) { ITreeDrawer::TreeSquareStruct* tss = &td->trees[(y * td->treesX) + x]; float3 dif; dif.x = camera->GetPos().x - ((x * SQUARE_SIZE * TREE_SQUARE_SIZE) + (SQUARE_SIZE * TREE_SQUARE_SIZE / 2)); dif.y = 0.0f; dif.z = camera->GetPos().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(); const float3 side = UpVector.cross(dif); if (distFactor < MID_TREE_DIST_FACTOR) { // midle distance trees tss->lastSeen = gs->frameNum; if (tss->dispList == 0) { tss->dispList = glGenLists(1); va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes for (std::map<int, ITreeDrawer::TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { const ITreeDrawer::TreeStruct* ts = &ti->second; const CFeature* f = featureHandler->GetFeature(ts->id); if (!f->IsInLosForAllyTeam(gu->myAllyTeam)) continue; if (ts->type < 8) DrawTreeVertexMid1(ts->pos, false); else DrawTreeVertexMid2(ts->pos, false); } glNewList(tss->dispList, GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER, 0.5f); glCallList(tss->dispList); return; } if (distFactor < FAR_TREE_DIST_FACTOR) { // far trees tss->lastSeenFar = gs->frameNum; if ((tss->farDispList == 0) || (dif.dot(tss->viewVector) < 0.97f)) { if (tss->farDispList == 0) tss->farDispList = glGenLists(1); va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(4 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes tss->viewVector = dif; for (std::map<int, ITreeDrawer::TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) { const ITreeDrawer::TreeStruct* ts = &ti->second; const CFeature* f = featureHandler->GetFeature(ts->id); if (!f->IsInLosForAllyTeam(gu->myAllyTeam)) continue; if (ts->type < 8) { DrawTreeVertexFar1(ts->pos, side * MAX_TREE_HEIGHT_3, false); } else { DrawTreeVertexFar2(ts->pos, side * MAX_TREE_HEIGHT_3, false); } } glNewList(tss->farDispList, GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } if (distFactor > FADE_TREE_DIST_FACTOR){ // faded far trees const float trans = 1.0f - (distFactor - FADE_TREE_DIST_FACTOR) / (FAR_TREE_DIST_FACTOR - FADE_TREE_DIST_FACTOR); glEnable(GL_BLEND); glColor4f(1, 1, 1, trans); glAlphaFunc(GL_GREATER, trans / 2.0f); } else { glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER, 0.5f); } glCallList(tss->farDispList); } }
void CSelectedUnits::Draw() { glDisable(GL_TEXTURE_2D); glDepthMask(false); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); // for line smoothing glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(cmdColors.UnitBoxLineWidth()); GML_RECMUTEX_LOCK(grpsel); // Draw if (cmdColors.unitBox[3] > 0.0f) { glColor4fv(cmdColors.unitBox); const CUnitSet* unitSet; if (selectedGroup != -1) { unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units; } else { unitSet = &selectedUnits; } CVertexArray* va = GetVertexArray(); va->Initialize(); va->EnlargeArrays(unitSet->size()*4, 0, VA_SIZE_0); CUnitSet::const_iterator ui; for (ui = unitSet->begin(); ui != unitSet->end(); ++ui) { const CUnit* unit = *ui; if (unit->isIcon) { continue; } va->AddVertexQ0(unit->drawPos.x + unit->xsize * 4, unit->drawPos.y, unit->drawPos.z + unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x - unit->xsize * 4, unit->drawPos.y, unit->drawPos.z + unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x - unit->xsize * 4, unit->drawPos.y, unit->drawPos.z - unit->zsize * 4); va->AddVertexQ0(unit->drawPos.x + unit->xsize * 4, unit->drawPos.y, unit->drawPos.z - unit->zsize * 4); } va->DrawArray0(GL_QUADS); } // highlight queued build sites if we are about to build something // (or old-style, whenever the shift key is being held down) if (cmdColors.buildBox[3] > 0.0f) { if (!selectedUnits.empty() && ((cmdColors.BuildBoxesOnShift() && keys[SDLK_LSHIFT]) || ((guihandler->inCommand >= 0) && (guihandler->inCommand < int(guihandler->commands.size())) && (guihandler->commands[guihandler->inCommand].id < 0)))) { GML_STDMUTEX_LOCK(cai); // Draw bool myColor = true; glColor4fv(cmdColors.buildBox); std::list<CBuilderCAI*>::const_iterator bi; for (bi = uh->builderCAIs.begin(); bi != uh->builderCAIs.end(); ++bi) { CBuilderCAI* builder = *bi; if (builder->owner->team == gu->myTeam) { if (!myColor) { glColor4fv(cmdColors.buildBox); myColor = true; } builder->DrawQuedBuildingSquares(); } else if (teamHandler->AlliedTeams(builder->owner->team, gu->myTeam)) { if (myColor) { glColor4fv(cmdColors.allyBuildBox); myColor = false; } builder->DrawQuedBuildingSquares(); } } } } glLineWidth(1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(true); glEnable(GL_TEXTURE_2D); }
void CEndGameBox::Draw() { if (disabled) { 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->glPrintAt(box.x1+exitBox.x1+0.025f,box.y1+exitBox.y1+0.005f,1,"Exit"); font->glPrintAt(box.x1+playerBox.x1+0.015f,box.y1+playerBox.y1+0.005f,0.7f,"Player stats"); font->glPrintAt(box.x1+sumBox.x1+0.015f,box.y1+sumBox.y1+0.005f,0.7f,"Team stats"); font->glPrintAt(box.x1+difBox.x1+0.015f,box.y1+difBox.y1+0.005f,0.7f,"Team delta stats"); if(gs->Team(gu->myTeam)->isDead){ font->glPrintAt(box.x1+0.25f,box.y1+0.65f,1,"You lost the game"); } else { font->glPrintAt(box.x1+0.25f,box.y1+0.65f,1,"You won the game"); } if(dispMode==0){ float xpos=0.01f; string headers[]={"Name","MC/m","MP/m","KP/m","Cmds/m","ACS"}; for(int a=0;a<6;++a){ font->glPrintAt(box.x1+xpos,box.y1+0.55f,0.8f,headers[a].c_str()); xpos+=0.1f; } float ypos=0.5f; for(int a=0;a<gs->activePlayers;++a){ if(gs->players[a]->currentStats->mousePixels==0) continue; char values[6][100]; sprintf(values[0],"%s", gs->players[a]->playerName.c_str()); sprintf(values[1],"%i",(int)(gs->players[a]->currentStats->mouseClicks*60/game->totalGameTime)); sprintf(values[2],"%i",(int)(gs->players[a]->currentStats->mousePixels*60/game->totalGameTime)); sprintf(values[3],"%i",(int)(gs->players[a]->currentStats->keyPresses*60/game->totalGameTime)); sprintf(values[4],"%i",(int)(gs->players[a]->currentStats->numCommands*60/game->totalGameTime)); sprintf(values[5],"%i",(int) ( gs->players[a]->currentStats->numCommands != 0 ) ? ( gs->players[a]->currentStats->unitCommands/gs->players[a]->currentStats->numCommands) : ( 0 )); float xpos=0.01f; for(int a=0;a<6;++a){ font->glPrintAt(box.x1+xpos,box.y1+ypos,0.8f,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){ int sel=(int)floor(-(my-box.y1-0.57f)*50); 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(int a=0;a<stats.size();++a){ font->glPrintAt(box.x1+0.01f,box.y1+ypos,0.8f,stats[a].name.c_str()); 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)/CTeam::statsPeriod; int numPoints=stats[0].values[0].size(); float scalex=0.54f/max(1.0f,numPoints-1.0f); float scaley=0.54f/maxy; for (int a = 0; a < 5; ++a) { font->glPrintAt(box.x1 + 0.12f, box.y1 + 0.07f + (a * 0.135f), 0.8f, "%s", FloatToSmallString(maxy * 0.25f * a).c_str()); font->glPrintAt(box.x1 + 0.135f + (a * 0.135f), box.y1 + 0.057f, 0.8f, "%i:%2i", int(a * 0.25f * numPoints * CTeam::statsPeriod / 60), int(a * 0.25f * (numPoints - 1) * CTeam::statsPeriod) % 60); } font->glPrintAt(box.x1+0.55f,box.y1+0.65f,0.8f,"%s",stats[stat1].name.c_str()); font->glPrintAt(box.x1+0.55f,box.y1+0.63f,0.8f,"%s",stat2!=-1?stats[stat2].name.c_str():""); 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); glVertex3f(box.x1+0.55f,box.y1+0.64f,0); glEnd(); glDisable(GL_LINE_STIPPLE); for(int team=0; team<gs->activeTeams; team++){ if (gs->Team(team)->gaia) continue; glColor4ubv(gs->Team(team)->color); glBegin(GL_LINE_STRIP); for(int a=0;a<numPoints;++a){ float value=0; 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])/CTeam::statsPeriod; glVertex3f(box.x1+0.15f+a*scalex,box.y1+0.08f+value*scaley,0); } 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])/CTeam::statsPeriod; glVertex3f(box.x1+0.15f+a*scalex,box.y1+0.08f+value*scaley,0); } glEnd(); glDisable(GL_LINE_STIPPLE); } } } }
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((float)(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 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 CBasicTreeSquareDrawer::DrawQuad(int x,int y) { int treesX = td->treesX; CBasicTreeDrawer::TreeSquareStruct* tss=&td->trees[y*treesX+x]; float3 dif; dif.x=camera->pos.x-(x*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2); dif.y=0; dif.z=camera->pos.z-(y*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2); float dist=dif.Length(); dif/=dist; float distfactor = dist / treeDistance; if(distfactor < MID_TREE_DIST_FACTOR) { // midle distance trees tss->lastSeen=gs->frameNum; if(!tss->displist) { 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,CBasicTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin(); ti!=tss->trees.end(); ++ti) { CBasicTreeDrawer::TreeStruct* ts=&ti->second; if(ts->type<8) DrawTreeVertexMid1(ts->pos, false); else DrawTreeVertexMid2(ts->pos, false); } glNewList(tss->displist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } glColor4f(1,1,1,1); glDisable(GL_BLEND); 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) { 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); float3 up(0,1,0); float3 side=up.cross(dif); for(std::map<int,CBasicTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin(); ti!=tss->trees.end(); ++ti) { CBasicTreeDrawer::TreeStruct* ts=&ti->second; if(ts->type<8) { DrawTreeVertexFar1(ts->pos, side*MAX_TREE_HEIGHT_3, false); } else { DrawTreeVertexFar2(ts->pos, side*MAX_TREE_HEIGHT_3, false); } } glNewList(tss->farDisplist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } if(distfactor > FADE_TREE_DIST_FACTOR) { // faded far trees float trans = 1.0f - (distfactor - FADE_TREE_DIST_FACTOR) / (FAR_TREE_DIST_FACTOR - FADE_TREE_DIST_FACTOR); glEnable(GL_BLEND); glColor4f(1,1,1,trans); glAlphaFunc(GL_GREATER, trans / 2.0f); } else { glColor4f(1,1,1,1); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER,0.5f); } glCallList(tss->farDisplist); } }
void CAdvTreeDrawer::Draw(float treeDistance,bool drawReflection) { int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1]; bool drawDetailed=true; if(treeDistance<4) drawDetailed=false; if(drawReflection) drawDetailed=false; CBaseGroundDrawer *gd = readmap->GetGroundDrawer (); glEnable(GL_ALPHA_TEST); if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP ); glEnable(GL_VERTEX_PROGRAM_ARB); 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); if(shadowHandler->useFPShadows){ glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, treeGen->treeFPShadow ); glEnable( GL_FRAGMENT_PROGRAM_ARB ); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,1); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,1-mapInfo->light.groundShadowDensity*0.5f); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, activeFarTex); } else { glEnable(GL_TEXTURE_2D); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1-mapInfo->light.groundShadowDensity*0.5f); float texConstant[]={mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.0f}; glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,texConstant); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_ADD); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, activeFarTex); } glActiveTextureARB(GL_TEXTURE0_ARB); glMatrixMode(GL_MATRIX0_ARB); glLoadMatrixf(shadowHandler->shadowMatrix.m); glMatrixMode(GL_MODELVIEW); } else { glBindTexture(GL_TEXTURE_2D, activeFarTex); } glEnable(GL_TEXTURE_2D); int cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE)); int cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE)); CAdvTreeSquareDrawer drawer; drawer.td = this; drawer.cx = cx; drawer.cy = cy; drawer.treeDistance = treeDistance; drawer.drawDetailed = drawDetailed; GML_STDMUTEX_LOCK(tree); // Draw // draw far away trees using the map dependent grid visibility oldTreeDistance=treeDistance; readmap->GridVisibility (camera, TREE_SQUARE_SIZE, treeDistance*2*SQUARE_SIZE*TREE_SQUARE_SIZE, &drawer); if(drawDetailed){ int xstart=std::max(0,cx-2); int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2); int ystart=std::max(0,cy-2); int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2); if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeVP ); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glActiveTextureARB(GL_TEXTURE0_ARB); } else { glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeNSVP ); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),1.0f/(gs->pwr2mapx*SQUARE_SIZE),1); } glEnable( GL_VERTEX_PROGRAM_ARB ); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, mapInfo->light.groundSunColor.x,mapInfo->light.groundSunColor.y,mapInfo->light.groundSunColor.z,0.85f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.85f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT)); //w=alpha/height modifier glAlphaFunc(GL_GREATER,0.5f); glDisable(GL_BLEND); glColor4f(1,1,1,1); va=GetVertexArray(); va->Initialize(); struct FadeTree{ float3 pos; float relDist; float deltaY; int type; }; 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){ TreeStruct* ts=&ti->second; float3 pos(ts->pos); int type=ts->type; float dy; unsigned int displist; if(type<8){ dy=0.5f; displist=treeGen->pineDL+type; } else { type-=8; dy=0; displist=treeGen->leafDL+type; } if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){ float camDist=(pos-camera->pos).SqLength(); if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){ //draw detailed tree glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); } else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){ //draw fading tree float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15); glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); glAlphaFunc(GL_GREATER,0.5f); pFT->pos=pos; pFT->deltaY=dy; pFT->type=type; pFT->relDist=relDist; ++pFT; } else { //draw undetailed tree DrawTreeVertex(pos, type*0.125f, dy, false); } } } } } //draw trees that has been marked as falling glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0); for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){ float3 pos=fti->pos-UpVector*(fti->fallPos*20); if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){ float ang=fti->fallPos*PI; float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang)); float3 z(up.cross(float3(-1,0,0))); z.ANormalize(); float3 x(up.cross(z)); CMatrix44f transMatrix(pos,x,up,z); 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(); } } glDisable( GL_VERTEX_PROGRAM_ARB ); if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP ); glEnable(GL_VERTEX_PROGRAM_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, activeFarTex); glActiveTextureARB(GL_TEXTURE0_ARB); } else { 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); DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f); va->DrawArrayT(GL_QUADS); } } if(shadowHandler->drawShadows && !gd->DrawExtraTex()){ glDisable( GL_VERTEX_PROGRAM_ARB ); if(shadowHandler->useFPShadows){ glDisable(GL_FRAGMENT_PROGRAM_ARB); } glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); 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); } glDisable(GL_ALPHA_TEST); //clean out squares from memory that are no longer visible int startClean=lastListClean*20%(nTrees); lastListClean=gs->frameNum; int endClean=gs->frameNum*20%(nTrees); 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 ProfileDrawer::Draw() { GML_STDMUTEX_LOCK_NOPROF(time); // Draw glPushMatrix(); glDisable(GL_TEXTURE_2D); glColor4f(0,0,0.5f,0.5f); if(!profiler.profile.empty()){ glBegin(GL_TRIANGLE_STRIP); glVertex3f(0.65f,0.99f,0); glVertex3f(0.99f,0.99f,0); glVertex3f(0.65f,0.99f-profiler.profile.size()*0.024f-0.01f,0); glVertex3f(0.99f,0.99f-profiler.profile.size()*0.024f-0.01f,0); glEnd(); } std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; 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; } #endif font->glFormat(0.655f, 0.960f - y * 0.024f, 1.0f, FONT_SCALE | FONT_NORM, "%20s %6.2fs %5.2f%%", pi->first.c_str(), ((float)pi->second.total) / 1000.f, pi->second.percent * 100); } font->End(); glTranslatef(0.655f,0.965f,0); glScalef(0.015f,0.02f,0.02f); glDisable(GL_TEXTURE_2D); 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(); 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(); for(pi=profiler.profile.begin();pi!=profiler.profile.end();++pi){ if(!pi->second.showGraph) continue; CVertexArray* va=GetVertexArray(); va->Initialize(); for(int a=0;a<128;++a){ float p=((float)pi->second.frames[a])/1000.f*30; va->AddVertex0(float3(0.6f+a*0.003f,0.02f+p*0.4f,0.0f)); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glEnable(GL_TEXTURE_2D); }
void CAdvTreeSquareDrawer_SP::DrawQuad (int x,int y) { 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; dif.z=camera->pos.z-(y*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2); float dist=dif.Length(); dif/=dist; if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2 && dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance)){//far trees tss->lastSeenFar=gs->frameNum; if(!tss->farDisplist || dif.dot(tss->viewVector)<0.97f){ 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); float3 up(0,1,0); float3 side=up.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) DrawTreeVertexFar(ts->pos, side*HALF_MAX_TREE_HEIGHT, ts->type*0.125f, 0.5f, false); else DrawTreeVertexFar(ts->pos, side*HALF_MAX_TREE_HEIGHT, (ts->type-8)*0.125f, 0, false); } glNewList(tss->farDisplist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } if(dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance*2-1)){ float trans=(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE); glColor4f(1,1,1,trans); glAlphaFunc(GL_GREATER,(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE*2)); } else { glColor4f(1,1,1,1); glAlphaFunc(GL_GREATER,0.5f); } glCallList(tss->farDisplist); } if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //midle distance trees tss->lastSeen=gs->frameNum; if(!tss->displist){ 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) DrawTreeVertexMid(ts->pos, ts->type*0.125f, 0.5f, false); else DrawTreeVertexMid(ts->pos, (ts->type-8)*0.125f, 0, false); } glNewList(tss->displist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } glColor4f(1,1,1,1); glAlphaFunc(GL_GREATER,0.5f); glCallList(tss->displist); } }
void CProjectileDrawer::Draw(bool drawReflection, bool drawRefraction) { glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); ISky::SetupFog(); { GML_STDMUTEX_LOCK(rpiece); // Draw projectileHandler->flyingPieces3DO.delete_delayed(); projectileHandler->flyingPieces3DO.add_delayed(); projectileHandler->flyingPiecesS3O.delete_delayed(); projectileHandler->flyingPiecesS3O.add_delayed(); } zSortedProjectiles.clear(); int numFlyingPieces = projectileHandler->flyingPieces3DO.render_size() + projectileHandler->flyingPiecesS3O.render_size(); int drawnPieces = 0; Update(); { GML_RECMUTEX_LOCK(proj); // Draw unitDrawer->SetupForUnitDrawing(); for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { modelRenderers[modelType]->PushRenderState(); DrawProjectiles(modelType, numFlyingPieces, &drawnPieces, drawReflection, drawRefraction); modelRenderers[modelType]->PopRenderState(); } unitDrawer->CleanUpUnitDrawing(); // z-sort the model-less projectiles DrawProjectilesSet(renderProjectiles, drawReflection, drawRefraction); projectileHandler->currentParticles = 0; CProjectile::inArray = false; CProjectile::va = GetVertexArray(); CProjectile::va->Initialize(); // draw the particle effects for (std::set<CProjectile*, ProjectileDistanceComparator>::iterator it = zSortedProjectiles.begin(); it != zSortedProjectiles.end(); ++it) { (*it)->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(GL_FALSE); // note: nano-particles (CGfxProjectile instances) also // contribute to the count, but have their own creation // cutoff projectileHandler->currentParticles += CProjectile::DrawArray(); } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_ALPHA_TEST); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glDepthMask(GL_TRUE); projectileHandler->currentParticles = int(projectileHandler->currentParticles * 0.2f); projectileHandler->currentParticles += int(0.2f * drawnPieces + 0.3f * numFlyingPieces); projectileHandler->currentParticles += (renderProjectiles.size() * 0.8f); // NOTE: should projectiles that have a model be counted here? for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { projectileHandler->currentParticles += (modelRenderers[modelType]->GetNumProjectiles() * 0.8f); } projectileHandler->UpdateParticleSaturation(); }
void CAdvTreeDrawer::DrawShadowPass(void) { float treeDistance=oldTreeDistance; int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1]; bool drawDetailed=true; if(treeDistance<4) drawDetailed=false; glBindTexture(GL_TEXTURE_2D, activeFarTex); glEnable(GL_TEXTURE_2D); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP ); glEnable( GL_VERTEX_PROGRAM_ARB ); glEnable(GL_ALPHA_TEST); glPolygonOffset(1,1); glEnable(GL_POLYGON_OFFSET_FILL); CAdvTreeSquareDrawer_SP drawer; int cx = drawer.cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE)); int cy = drawer.cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE)); drawer.drawDetailed = drawDetailed; drawer.td = this; drawer.treeDistance = treeDistance; GML_STDMUTEX_LOCK(tree); // DrawShadowPass // draw with extraSize=1 readmap->GridVisibility (camera, TREE_SQUARE_SIZE, treeDistance*2*SQUARE_SIZE*TREE_SQUARE_SIZE, &drawer, 1); if(drawDetailed){ int xstart=std::max(0,cx-2); int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2); int ystart=std::max(0,cy-2); int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2); glBindTexture(GL_TEXTURE_2D, treeGen->barkTex); glEnable(GL_TEXTURE_2D); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeShadowVP ); glEnable( GL_VERTEX_PROGRAM_ARB ); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, 1,1,1,0.85f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT)); //w=alpha/height modifier glAlphaFunc(GL_GREATER,0.5f); glEnable(GL_ALPHA_TEST); glColor4f(1,1,1,1); va=GetVertexArray(); va->Initialize(); struct FadeTree{ float3 pos; float relDist; float deltaY; int type; }; 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){ TreeStruct* ts=&ti->second; float3 pos(ts->pos); int type=ts->type; float dy; unsigned int displist; if(type<8){ dy=0.5f; displist=treeGen->pineDL+type; } else { type-=8; dy=0; displist=treeGen->leafDL+type; } if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2+150)){ float camDist=(pos-camera->pos).SqLength(); if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){ //draw detailed tree glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); } else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){ //draw fading tree float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15); glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0); glCallList(displist); glAlphaFunc(GL_GREATER,0.5f); pFT->pos=pos; pFT->deltaY=dy; pFT->type=type; pFT->relDist=relDist; ++pFT; } else { //draw undetailed tree DrawTreeVertex(pos, type*0.125f, dy, false); } } } } } //draw trees that have been marked as falling glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0); for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){ float3 pos=fti->pos-UpVector*(fti->fallPos*20); if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){ float ang=fti->fallPos*PI; float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang)); float3 z(up.cross(float3(1,0,0))); z.ANormalize(); float3 x(z.cross(up)); CMatrix44f transMatrix(pos,x,up,z); 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(); } } glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP ); 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); DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false); glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f); va->DrawArrayT(GL_QUADS); } } glDisable(GL_POLYGON_OFFSET_FILL); glDisable( GL_VERTEX_PROGRAM_ARB ); glDisable(GL_TEXTURE_2D); glDisable(GL_ALPHA_TEST); }
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 CMiniMap::DrawForReal() { SCOPED_TIMER("Draw minimap"); setSurfaceCircleFunc(DrawSurfaceCircle); setSurfaceSquareFunc(DrawSurfaceSquare); cursorIcons.Enable(false); //glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LEQUAL); if (minimized) { if (!slaveDrawMode) { DrawMinimizedButton(); } cursorIcons.Enable(true); setSurfaceCircleFunc(NULL); setSurfaceSquareFunc(NULL); return; } glViewport(xpos, ypos, width, height); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0e6, +1.0e6); glMatrixMode(GL_MODELVIEW); glColor4f(0.6f, 0.6f, 0.6f, 1.0f); // draw the map glDisable(GL_BLEND); readmap->DrawMinimap(); glEnable(GL_BLEND); // move some of the transform to the GPU glTranslatef(0.0f, +1.0f, 0.0f); glScalef(+1.0f / (gs->mapx * SQUARE_SIZE), -1.0f / (gs->mapy * SQUARE_SIZE), 1.0); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f); GML_RECMUTEX_LOCK(unit); // DrawForReal // draw the units std::list<CUnit*>::iterator ui; for (ui = uh->renderUnits.begin(); ui != uh->renderUnits.end(); ui++) { DrawUnit(*ui); } // highlight the selected unit CUnit* unit = GetSelectUnit(GetMapPosition(mouse->lastx, mouse->lasty)); if (unit != NULL) { DrawUnitHighlight(unit); } glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); left.clear(); // add restraints for camera sides GetFrustumSide(cam2->bottom); GetFrustumSide(cam2->top); GetFrustumSide(cam2->rightside); GetFrustumSide(cam2->leftside); if (!minimap->maximized) { // draw the camera lines std::vector<fline>::iterator fli,fli2; for(fli=left.begin();fli!=left.end();fli++){ for(fli2=left.begin();fli2!=left.end();fli2++){ if(fli==fli2) continue; float colz=0; if(fli->dir-fli2->dir==0) continue; colz=-(fli->base-fli2->base)/(fli->dir-fli2->dir); if(fli2->left*(fli->dir-fli2->dir)>0){ if(colz>fli->minz && colz<400096) fli->minz=colz; } else { if(colz<fli->maxz && colz>-10000) fli->maxz=colz; } } } glColor4f(1,1,1,0.5f); glBegin(GL_LINES); for(fli = left.begin(); fli != left.end(); fli++) { if(fli->minz < fli->maxz) { DrawInMap2D(fli->base + (fli->dir * fli->minz), fli->minz); DrawInMap2D(fli->base + (fli->dir * fli->maxz), fli->maxz); } } glEnd(); } glRotatef(-90.0f, +1.0f, 0.0f, 0.0f); // real 'world' coordinates // draw the projectiles if (drawProjectiles) { GML_RECMUTEX_LOCK(proj); // DrawForReal if(ph->projectiles.render_size()>0) { CVertexArray* lines=GetVertexArray(); CVertexArray* points=GetVertexArray(); lines->Initialize(); lines->EnlargeArrays(ph->projectiles.render_size()*2,0,VA_SIZE_C); points->Initialize(); points->EnlargeArrays(ph->projectiles.render_size(),0,VA_SIZE_C); for(ThreadListSimRender<CProjectile*>::render_iterator psi = ph->projectiles.render_begin(); psi != ph->projectiles.render_end(); ++psi) { CProjectile* p = *psi; 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); } } // 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(); } glDisable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // 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); } } glRotatef(+90.0f, +1.0f, 0.0f, 0.0f); // revert to the 2d xform // 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()); glBegin(GL_LINE_LOOP); DrawInMap2D(oldPos.x, oldPos.z); DrawInMap2D(newPos.x, oldPos.z); DrawInMap2D(newPos.x, newPos.z); DrawInMap2D(oldPos.x, newPos.z); glEnd(); glLineWidth(1.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } DrawNotes(); // allow the LUA scripts to draw into the minimap eventHandler.DrawInMiniMap(); // reset the modelview glLoadIdentity(); if (!slaveDrawMode) { DrawButtons(); // outline glLineWidth(1.51f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glViewport(xpos - 1, ypos - 1, width + 2, height + 2); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glRectf(0.0f, 0.0f, 1.0f, 1.0f); glViewport(xpos - 2, ypos - 2, width + 4, height + 4); glColor4f(0.0f, 0.0f, 0.0f, 1.0f); glRectf(0.0f, 0.0f, 1.0f, 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.0f); } glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY); cursorIcons.Enable(true); setSurfaceCircleFunc(NULL); setSurfaceSquareFunc(NULL); }
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); }
void CBasicTreeSquareDrawer::DrawQuad (int x,int y) { int treesX = td->treesX; CBasicTreeDrawer::TreeSquareStruct* tss=&td->trees[y*treesX+x]; float3 dif; dif.x=camera->pos.x-(x*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2); dif.y=0; dif.z=camera->pos.z-(y*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2); float dist=dif.Length(); dif/=dist; if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2 && dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance)){//far trees tss->lastSeenFar=gs->frameNum; if(!tss->farDisplist || dif.dot(tss->viewVector)<0.97){ va=GetVertexArray(); va->Initialize(); tss->viewVector=dif; if(!tss->farDisplist) tss->farDisplist=glGenLists(1); float3 up(0,1,0); float3 side=up.cross(dif); for(std::map<int,CBasicTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){ CBasicTreeDrawer::TreeStruct* ts=&ti->second; if(ts->type<8){ float3 base(ts->pos); float height=MAX_TREE_HEIGHT; float width=MAX_TREE_HEIGHT*0.3; SetArray(0,0,base+side*width); SetArray(0,0.25,base+side*width+float3(0,height,0)); SetArray(0.5f,0.25,base-side*width+float3(0,height,0)); SetArray(0.5f,0,base-side*width); } else { float3 base(ts->pos); float height=MAX_TREE_HEIGHT; float width=MAX_TREE_HEIGHT*0.3; SetArray(0,0.25,base+side*width); SetArray(0,0.5,base+side*width+float3(0,height,0)); SetArray(0.25f,0.5,base-side*width+float3(0,height,0)); SetArray(0.25f,0.25,base-side*width); } } glNewList(td->trees[y*treesX+x].farDisplist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } if(dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance*2-1)){ float trans=(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE); glEnable(GL_BLEND); glColor4f(1,1,1,trans); glAlphaFunc(GL_GREATER,(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE*2)); } else { glColor4f(1,1,1,1); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER,0.5f); } glCallList(tss->farDisplist); } if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //midle distance trees tss->lastSeen=gs->frameNum; if(!tss->displist){ va=GetVertexArray(); va->Initialize(); tss->displist=glGenLists(1); for(std::map<int,CBasicTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){ CBasicTreeDrawer::TreeStruct* ts=&ti->second; if(ts->type<8){ float3 base(ts->pos); float height=MAX_TREE_HEIGHT; float width=MAX_TREE_HEIGHT*0.3; SetArray(0,0,base+float3(width,0,0)); SetArray(0,0.25,base+float3(width,height,0)); SetArray(0.5f,0.25,base+float3(-width,height,0)); SetArray(0.5f,0,base+float3(-width,0,0)); SetArray(0,0,base+float3(0,0,width)); SetArray(0,0.25,base+float3(0,height,width)); SetArray(0.5f,0.25,base+float3(0,height,-width)); SetArray(0.5f,0,base+float3(0,0,-width)); width*=1.2f; SetArray(0.5,0,base+float3(width,height*0.25,0)); SetArray(0.5,0.25,base+float3(0,height*0.25,-width)); SetArray(1,0.25,base+float3(-width,height*0.25,0)); SetArray(1,0,base+float3(0,height*0.25,width)); } else { float3 base(ts->pos); float height=MAX_TREE_HEIGHT; float width=MAX_TREE_HEIGHT*0.3; SetArray(0,0.25,base+float3(width,0,0)); SetArray(0,0.5,base+float3(width,height,0)); SetArray(0.25f,0.5,base+float3(-width,height,0)); SetArray(0.25f,0.25,base+float3(-width,0,0)); SetArray(0.25f,0.25,base+float3(0,0,width)); SetArray(0.25f,0.5,base+float3(0,height,width)); SetArray(0.5f,0.5,base+float3(0,height,-width)); SetArray(0.5f,0.25,base+float3(0,0,-width)); width*=1.2f; SetArray(0.5,0.25,base+float3(width,height*0.3,0)); SetArray(0.5,0.5,base+float3(0,height*0.3,-width)); SetArray(1,0.5,base+float3(-width,height*0.3,0)); SetArray(1,0.25,base+float3(0,height*0.3,width)); } } glNewList(tss->displist,GL_COMPILE); va->DrawArrayT(GL_QUADS); glEndList(); } glColor4f(1,1,1,1); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER,0.5f); glCallList(tss->displist); } }