void MapRenderer::draw(GameWorld* world, const MapInfo& mi) { renderer->pushDebugGroup("Map"); renderer->useProgram(rectProg); // World out the number of units per tile glm::vec2 worldSize(GAME_MAP_SIZE); const int mapBlockLine = 8; glm::vec2 tileSize = worldSize / (float)mapBlockLine; // Determine the scale to show the right number of world units on the screen float worldScale = mi.screenSize / mi.worldSize; auto proj = renderer->get2DProjection(); glm::mat4 view, model; renderer->setUniform(rectProg, "proj", proj); renderer->setUniform(rectProg, "model", glm::mat4()); renderer->setUniform(rectProg, "colour", glm::vec4(0.f, 0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(mi.screenPosition, 0.f)); if (mi.clipToSize) { glBindVertexArray( circle.getVAOName() ); glBindTexture(GL_TEXTURE_2D, 0); glm::mat4 circleView = glm::scale(view, glm::vec3(mi.screenSize)); renderer->setUniform(rectProg, "view", circleView); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); glColorMask(0x00, 0x00, 0x00, 0x00); glDrawArrays(GL_TRIANGLE_FAN, 0, 182); glColorMask(0xFF, 0xFF, 0xFF, 0xFF); glStencilFunc(GL_EQUAL, 1, 0xFF); } view = glm::scale(view, glm::vec3(worldScale)); view = glm::rotate(view, mi.rotation, glm::vec3(0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(glm::vec2(-1.f, 1.f) * mi.worldCenter, 0.f)); renderer->setUniform(rectProg, "view", view); glBindVertexArray( rect.getVAOName() ); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); // radar00 = -x, +y // incrementing in X, then Y int initX = -(mapBlockLine/2); int initY = -(mapBlockLine/2); for( int m = 0; m < MAP_BLOCK_SIZE; ++m ) { std::string num = (m < 10 ? "0" : ""); std::string name = "radar" + num + std::to_string(m); auto texture = world->data->textures[{name,""}]; glBindTexture(GL_TEXTURE_2D, texture->getName()); int mX = initX + (m % mapBlockLine); int mY = initY + (m / mapBlockLine); auto tc = glm::vec2(mX, mY) * tileSize + glm::vec2(tileSize/2.f); glm::mat4 tilemodel = model; tilemodel = glm::translate( tilemodel, glm::vec3( tc, 0.f ) ); tilemodel = glm::scale( tilemodel, glm::vec3( tileSize, 1.f ) ); renderer->setUniform(rectProg, "model", tilemodel); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } // From here on out we will work in screenspace renderer->setUniform(rectProg, "view", glm::mat4()); if (mi.clipToSize) { glDisable(GL_STENCIL_TEST); // We only need the outer ring if we're clipping. glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO); TextureData::Handle radarDisc = data->findTexture("radardisc"); glm::mat4 model; model = glm::translate(model, glm::vec3(mi.screenPosition, 0.0f)); model = glm::scale(model, glm::vec3(mi.screenSize*1.07)); renderer->setUniform(rectProg, "model", model); glBindTexture(GL_TEXTURE_2D, radarDisc->getName()); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); } for(auto& blip : world->state->radarBlips) { glm::vec2 blippos( blip.second.coord ); if( blip.second.target > 0 ) { GameObject* object = world->getBlipTarget(blip.second); if( object ) { blippos = glm::vec2( object->getPosition() ); } } drawBlip(blippos, view, mi, blip.second.texture); } // Draw the player blip auto player = world->pedestrianPool.find(world->state->playerObject); if( player ) { glm::vec2 plyblip(player->getPosition()); float hdg = glm::roll(player->getRotation()); drawBlip(plyblip, view, mi, "radar_centre", mi.rotation - hdg); } drawBlip(mi.worldCenter + glm::vec2(0.f, mi.worldSize), view, mi, "radar_north", 0.f, 24.f); glBindVertexArray( 0 ); glBindTexture(GL_TEXTURE_2D, 0); glUseProgram(0); /// @TODO migrate to using the renderer renderer->invalidate(); renderer->popDebugGroup(); }
void GameTacMap::render() { if (turn < 2) //Terrain not setup yet. Left,Right,Top,Bottom are poopy! return; gos_VERTEX corners[5]; gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero ); gos_SetRenderState( gos_State_Specular,FALSE ); gos_SetRenderState( gos_State_AlphaTest, FALSE ); gos_SetRenderState( gos_State_Filter, gos_FilterNone ); gos_SetRenderState( gos_State_ZWrite, 0 ); gos_SetRenderState( gos_State_ZCompare, 0 ); gos_SetRenderState( gos_State_Texture, textureHandle ); for ( int i = 0; i < 4; ++i ) { corners[i].rhw = 1.0f; corners[i].argb = 0xffffffff; corners[i].frgb = 0; corners[i].z = 0.0f; } corners[0].x = corners[2].x = left; corners[1].x = corners[3].x = right; corners[3].y = corners[2].y = bottom; corners[0].y = corners[1].y = top; corners[0].u = 2.f/(float)bmpWidth; corners[3].u = 128.f/(float)bmpWidth; corners[2].u = 2.f/(float)bmpWidth; corners[1].u = 128.f/(float)bmpWidth; corners[0].v = 2.f/(float)bmpWidth; corners[3].v = 128.f/(float)bmpHeight; corners[2].v = 128.f/(float)bmpHeight; corners[1].v = 2.f/(float)bmpWidth; gos_DrawTriangles( corners, 3 ); gos_DrawTriangles( &corners[1], 3 ); Stuff::Vector2DOf<long> screen; Stuff::Vector4D nScreen; Stuff::Vector3D world; //----------------------------------------------------------- // Render the objective markers long count = 0; for ( EList< CObjective*, CObjective* >::EIterator iter = Team::home->objectives.Begin(); !iter.IsDone(); iter++ ) { //We are there. Start flashing. if ((objectiveAnimationId == count) && objectiveNumFlashes) { objectiveFlashTime += g_deltaTime; if ( objectiveFlashTime > .5f ) { objectiveFlashTime = 0.0f; objectiveNumFlashes--; } else if ( objectiveFlashTime > 0.25f) { (*iter)->RenderMarkers(this, 0); } if (objectiveNumFlashes == 0) { //Flashing is done. We now return you to your regularly scheduled program. objectiveAnimationId = 0; } } else { (*iter)->RenderMarkers(this, 0); } count++; } // this is the little viewing rect // Routine that InverseProjects is slightly less accurate but an order of magnitude faster. // Can make more accurate later at very little expense to performance. // Easy to fix with camera later. -fs screen.x = 1; screen.y = 1; nScreen.x = nScreen.y = 1.0f; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[0] ); screen.y = Environment.screenHeight - 1; nScreen.y = (Environment.screenHeight * 0.6667f) - 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[1] ); screen.x = Environment.screenWidth - 1; nScreen.x = Environment.screenWidth - 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[2] ); screen.y = 1; nScreen.y = 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[3] ); corners[0].argb = 0xffffffff; corners[1].argb = 0xffffffff; corners[2].argb = 0xffffffff; corners[3].argb = 0xffffffff; corners[0].u = corners[1].u = 0.078125f; corners[3].u = corners[2].u = .99875f; corners[0].v = corners[3].v = 0.078125f; corners[1].v = corners[2].v = .99875f; corners[4] = corners[0]; gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha); gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud); gos_SetRenderState( gos_State_MonoEnable, 0); gos_SetRenderState( gos_State_Perspective, 0); gos_SetRenderState( gos_State_Clipping, 2); gos_SetRenderState( gos_State_AlphaTest, 0); gos_SetRenderState( gos_State_Specular, 0); gos_SetRenderState( gos_State_Dither, 1); gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate); gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear); gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap ); gos_SetRenderState( gos_State_ZCompare, 0); gos_SetRenderState( gos_State_ZWrite, 0); DWORD gosTextureHandle = mcTextureManager->get_gosTextureHandle(viewRectHandle); gos_SetRenderState( gos_State_Texture, gosTextureHandle ); gos_DrawQuads( &corners[0], 4 ); unsigned long colors[MAX_MOVERS]; unsigned long ringColors[MAX_MOVERS]; Stuff::Vector3D positions[MAX_MOVERS]; unsigned long ranges[MAX_MOVERS]; bool selected[MAX_MOVERS]; count = 0; //------------------------------------------------------------ // draw non-movers, must do separate check for vehicles, I'm not sure they // have sensors for ( i = 0; i < MAX_TEAMS; ++i ) { TeamSensorSystem* pSys = SensorManager->getTeamSensor( i ); if ( pSys ) { for ( int j = 0; j < pSys->numSensors; ++j ) { SensorSystem* pSensor = pSys->sensors[j]; if ( !pSensor ) continue; if ( pSensor->owner->isDestroyed() || pSensor->owner->isDisabled() || pSensor->owner->getStatus() == OBJECT_STATUS_SHUTDOWN ) continue; if ( pSensor->getRange() < 1.1 || pSensor->broken) continue; if (!pSensor->owner->getTeam()) continue; ObjectClass objClass = pSensor->owner->getObjectClass(); unsigned long colorBlip = pSensor->owner->getSelected() ? 0xff4bff4b : 0xff00cc00; unsigned long colorRing = 0xff00cc00; if ( pSensor->owner->getTeam()->isNeutral( Team::home ) ) { colorBlip = pSensor->owner->getSelected() ? 0xff4c4cff : 0xff0000ff; colorRing = 0xff0000ff; } else if ( pSensor->owner->getTeam()->isEnemy( Team::home ) ) // enemy { { colorBlip = pSensor->owner->getSelected() ? 0xffff3f3f : 0xffff0000; colorRing = 0xffff0000; } } if ( objClass != BATTLEMECH && objClass != GROUNDVEHICLE) { if ( objClass == ARTILLERY ) { // blink s_lastBlinkTime += g_deltaTime; if ( s_lastBlinkTime > s_blinkLength ) { colorBlip = 0; colorRing = 0; s_lastBlinkTime = 0.f; } } colors[count] = colorBlip; ringColors[count] = colorRing; ranges[count] = pSensor->getRange(); selected[count] = 0; positions[count] = pSensor->owner->getPosition(); count++; } } } } unsigned long colorBlip, colorRing; //----------------------------------------------------- // draw the movers for (i=0;i<(ObjectManager->numMovers);i++) { MoverPtr mover = ObjectManager->getMover(i); if (mover && mover->getExists() && !(mover->isDestroyed() || mover->isDisabled())) { SensorSystem* pSensor = mover->getSensorSystem(); float range = pSensor ? pSensor->getRange() : 0; long contactStatus = mover->getContactStatus(Team::home->getId(), true); if (mover->getTeamId() == Team::home->id) { if (mover->getCommanderId() == Commander::home->getId()) { if (mover->isOnGUI()) { colorBlip = mover->getSelected() ? 0xff4bff4b : 0xff00cc00; mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff00cc00; } else continue; } else { if (mover->isOnGUI() && land->IsGameSelectTerrainPosition(mover->getPosition()) && mover->pathLocks) { colorBlip = mover->getSelected() ? 0xff4b4bff : 0xff0000cc; mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff0000cc; } else continue; } } else if (g_dbgShowMovers || (MPlayer && MPlayer->allUnitsDestroyed[MPlayer->commanderID]) || ((mover->getTeamId() != Team::home->id) && ( contactStatus != CONTACT_NONE ) && (mover->getStatus() != OBJECT_STATUS_SHUTDOWN) && (!mover->hasNullSignature()) && (mover->getEcmRange() <= 0.0f) ) ) //Do not draw ECM mechs!!) { //Not on our side. Draw by contact status colorBlip = mover->getSelected() ? 0xffff3f3f : 0xffff0000; colorRing = 0xffff0000; } else continue; colors[count] = colorBlip; ringColors[count] = colorRing; ranges[count] = range; selected[count] = mover->getSelected(); positions[count] = mover->getPosition(); count++; } } for ( i = 0; i < count; i++ ) { drawSensor( positions[i], ranges[i], ringColors[i] ); } bool bSel = 0; // draw unselected first for ( int j = 0; j < 2; j++ ) { for ( int i = 0; i < count; i++ ) { if ( selected[i] == bSel ) { drawBlip( positions[i], colors[i], DOT_BLIP ); } } bSel = 1; } }
void Cockpit::drawRadar () { int i; float yf = -4.2, zf = -7.0; gl->enableAlphaBlending (); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.1); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); setColor (150); float xl, yl; int type; if (fplayer->o == &model_fig || fplayer->o == &model_figg) { gl->enableTextures (texradar2->textureID); xl = 1.4; yl = 1.3; type = 0; } else { gl->enableTextures (texradar1->textureID); xl = 1.3; yl = 1.2; type = 1; } glBegin (GL_QUADS); glTexCoord2d (0, 0); glVertex3f (-xl, yf - yl, zf); glTexCoord2d (0, 1); glVertex3f (-xl, yf + yl, zf); glTexCoord2d (1, 1); glVertex3f (xl, yf + yl, zf); glTexCoord2d (1, 0); glVertex3f (xl, yf - yl, zf); glEnd (); glDisable (GL_ALPHA_TEST); glDisable (GL_TEXTURE_2D); glLineWidth (LINEWIDTH(1.0F)); glBegin (GL_LINES); glVertex3f (0, yf - yl * 0.9, zf); glVertex3f (0, yf + yl * 0.9, zf); glVertex3f (-xl * 0.9, yf, zf); glVertex3f (xl * 0.9, yf, zf); glEnd (); int radarzoom = 1; if (fplayer->disttarget < 40) radarzoom = 2; for (i = 0; i < maxfighter; i ++) if (fighter [i] != fplayer && fighter [i]->active) { int aw = fplayer->getAngle (fighter [i]); if (aw < 0) aw += 360; float d = fplayer->distanceXZ (fighter [i]) / 100.0 * radarzoom; float px = -d * sine [aw]; float py = yf + d * cosi [aw]; if ((type == 0 && d < 1.2) || (type == 1 && px >= -1.2 && px <= 1.2 && py >= yf - 1.1 && py <= yf + 1.1)) { if (fighter [i] == fplayer->target) { drawBlip(SQUARE_BLIP, px, py, zf, 255, 200, 0); } else if (fighter [i]->party != fplayer->party) { drawBlip(SQUARE_BLIP, px, py, zf, 255, 0, 0); } else { drawBlip(SQUARE_BLIP, px, py, zf, 0, 0, 255); } } } for (i = 0; i < maxmissile; i ++) { if (missile [i]->target == fplayer && missile [i]->active) { int aw = fplayer->getAngle (missile [i]); if (aw < 0) aw += 360; float d = fplayer->distance (missile [i]) / 100.0 * radarzoom; float px = -d * sine [aw]; float py = yf + d * cosi [aw]; if ((type == 0 && d < 1.2) || (type == 1 && px >= -1.2 && px <= 1.2 && py >= yf - 1.1 && py <= yf + 1.1)) { drawBlip(TRIANGLE_BLIP, px, py, zf, 255, 255, 255); } } } gl->disableAlphaBlending (); }
//---------------------------------------------------------- void GroundMetalSegment::drawGL() { Config *config = Config::instance(); static float c0_clr[4] = { 0.65, 0.62, 0.53, 1.0 }; static float c1_clr[4] = { 0.79, 0.82, 0.69, 1.0 }; static float r0_clr[4] = { 0.07, 0.07, 0.13, 1.0 }; static float r1_clr[4] = { 0.31, 0.30, 0.30, 1.0 }; static float r2_clr[4] = { 0.31, 0.30, 0.30, 1.0 }; float S; float tmp; float rep; float tilt; float clr_sin; bool blipMirrorT = false; age += 1.0; clr_sin = 0.5*sin(parent->game->gameFrame*0.001); r1_clr[0] = 0.15+clr_sin; r2_clr[0] = 0.15+clr_sin; clr_sin = 0.2*sin(parent->game->gameFrame*0.0005); c0_clr[0] = 0.28+clr_sin; c0_clr[1] = 0.25+clr_sin; c0_clr[2] = 0.16+clr_sin; c1_clr[0] = 0.42+clr_sin; c1_clr[1] = 0.45+clr_sin; c1_clr[2] = 0.34+clr_sin; switch(parent->variation) { default: case 0: rep = 0.26; tilt = 0.1; S = -parent->game->frame*0.001; blipMirrorT = false; break; case 1: rep = 0.4; tilt = 0.2; S = -parent->game->frame*0.001; blipMirrorT = true; break; case 2: S = -parent->game->frame*0.005; tmp = sin(S); rep = 0.7+tmp; tilt = 0.5+tmp; blipMirrorT = true; break; } #ifdef EXPERIMENTAL drawMultiTex(rep, S, tilt, blipMirrorT, c0_clr, c1_clr, r0_clr, r1_clr, r2_clr); #else // EXPERIMENTAL if(config->gfxLevel() > 1) { drawBlip(rep, S, tilt, blipMirrorT); } if(true) { drawSurface(c0_clr, c1_clr, r0_clr, r1_clr, r2_clr); } #endif // EXPERIMENTAL }