TVector4 Str_Vector4N (const string &s, const TVector4 def) { float x, y, z, w; istringstream is(s); is >> x >> y >> z >> w; if (is.fail()) return def; else return MakeVector4 (x, y, z, w); }
Vector4 ChatWindow::GetColor(char c){ switch(c){ case MsgColorTeam1: if(client->GetWorld()) return ConvertColor(client->GetWorld()->GetTeam(0).color); case MsgColorTeam2: if(client->GetWorld()) return ConvertColor(client->GetWorld()->GetTeam(1).color); case MsgColorTeam3: if(client->GetWorld()) return ConvertColor(client->GetWorld()->GetTeam(2).color); case MsgColorRed: return MakeVector4(1,0,0,1); case MsgColorSysInfo: return MakeVector4(0,1,0,1); default: return MakeVector4(1,1,1,1); } }
void MainScreen::DrawStartupScreen() { SPADES_MARK_FUNCTION(); Handle<client::IImage> img; Vector2 scrSize = {renderer->ScreenWidth(), renderer->ScreenHeight()}; renderer->SetColorAlphaPremultiplied(MakeVector4(0, 0, 0, 1.)); img = renderer->RegisterImage("Gfx/White.tga"); renderer->DrawImage(img, AABB2(0, 0, scrSize.x, scrSize.y)); std::string str = _Tr("MainScreen", "NOW LOADING"); Vector2 size = font->Measure(str); Vector2 pos = MakeVector2(scrSize.x - 16.f, scrSize.y - 16.f); pos -= size; font->DrawShadow(str, pos, 1.f, MakeVector4(1,1,1,1), MakeVector4(0,0,0,0.5)); renderer->FrameDone(); renderer->Flip(); }
void PaletteView::Draw() { Handle<IImage> img = renderer->RegisterImage("Gfx/Palette.png"); int sel = GetSelectedIndex(); float scrW = renderer->ScreenWidth(); float scrH = renderer->ScreenHeight(); for(size_t phase = 0; phase < 2; phase++){ for(size_t i = 0; i < colors.size(); i++){ if((sel == i) != (phase == 1)) continue; int row = i / 8; int col = i % 8; bool selected = sel == i; // draw color IntVector3 icol = colors[i]; Vector4 cl; cl.x = icol.x / 255.f; cl.y = icol.y / 255.f; cl.z = icol.z / 255.f; cl.w = 1.f; float x = scrW - 100.f + 10.f * col; float y = scrH - 96.f + 10.f * row - 40.f; renderer->SetColorAlphaPremultiplied(cl); if(selected){ renderer->DrawImage(img, MakeVector2(x, y), AABB2(0, 16, 16, 16)); }else{ renderer->DrawImage(img, MakeVector2(x, y), AABB2(0, 0, 16, 16)); } renderer->SetColorAlphaPremultiplied(MakeVector4(1, 1, 1, 1)); if(selected){ renderer->DrawImage(img, MakeVector2(x, y), AABB2(16, 16, 16, 16)); }else{ renderer->DrawImage(img, MakeVector2(x, y), AABB2(16, 0, 16, 16)); } } } }
/// Computes normal vector for object /// \param point point in space, where w = 1 and point is near object (almost hit or hit) /// \return normal vector virtual Vector4D Normal(const Point4D& point) const { static double e = 0.00005; Vector4D n; n[0] = dist(MakeVector4(point[0] + e, point[1], point[2])) - dist(MakeVector4(point[0] - e, point[1], point[2])); n[1] = dist(MakeVector4(point[0], point[1] + e, point[2])) - dist(MakeVector4(point[0], point[1] - e, point[2])); n[2] = dist(MakeVector4(point[0], point[1], point[2] + e)) - dist(MakeVector4(point[0], point[1], point[2] - e)); return n.Norm(); }
void Client::PlayerSentChatMessage(spades::client::Player *p, bool global, const std::string &msg){ { std::string s; if(global) /// prefix added to global chat messages. s = _Tr("Client", "[Global] "); s += ChatWindow::TeamColorMessage(p->GetName(), p->GetTeamId()); s += ": "; s += msg; chatWindow->AddMessage(s); } { std::string s; if(global) s = "[Global] "; s += p->GetName(); s += ": "; s += msg; auto col = p->GetTeamId() < 2 ? world->GetTeam(p->GetTeamId()).color : IntVector3::Make(255, 255, 255); scriptedUI->RecordChatLog(s, MakeVector4(col.x / 255.f, col.y / 255.f, col.z / 255.f, 0.8f)); } if(global) NetLog("[Global] %s (%s): %s", p->GetName().c_str(), world->GetTeam(p->GetTeamId()).name.c_str(), msg.c_str()); else NetLog("[Team] %s (%s): %s", p->GetName().c_str(), world->GetTeam(p->GetTeamId()).name.c_str(), msg.c_str()); if((!IsMuted()) && (int)cg_chatBeep) { Handle<IAudioChunk> chunk = audioDevice->RegisterSound("Sounds/Feedback/Chat.wav"); audioDevice->PlayLocal(chunk, AudioParam()); } }
Vector4 operator *(const Matrix4& mat, const Vector4& v){ float x, y, z, w; x = mat.m[0] * v.x; y = mat.m[1] * v.x; z = mat.m[2] * v.x; w = mat.m[3] * v.x; x += mat.m[4] * v.y; y += mat.m[5] * v.y; z += mat.m[6] * v.y; w += mat.m[7] * v.y; x += mat.m[8] * v.z; y += mat.m[9] * v.z; z += mat.m[10] * v.z; w += mat.m[11] * v.z; x += mat.m[12] * v.w; y += mat.m[13] * v.w; z += mat.m[14] * v.w; w += mat.m[15] * v.w; return MakeVector4(x, y, z, w); }
void Client::PlayerLeaving(spades::client::Player *p) { { std::string msg; msg = _Tr("Client", "Player {0} has left", chatWindow->TeamColorMessage(p->GetName(), p->GetTeamId())); chatWindow->AddMessage(msg); } { std::string msg; msg = _Tr("Client", "Player {0} has left", p->GetName()); auto col = p->GetTeamId() < 2 ? world->GetTeam(p->GetTeamId()).color : IntVector3::Make(255, 255, 255); NetLog("%s", msg.c_str()); scriptedUI->RecordChatLog(msg, MakeVector4(col.x / 255.f, col.y / 255.f, col.z / 255.f, 0.8f)); } }
void Client::TeamWon(int teamId){ std::string msg; msg = chatWindow->TeamColorMessage(world->GetTeam(teamId).name, teamId); msg = _Tr("Client", "{0} wins!", msg); chatWindow->AddMessage(msg); msg = world->GetTeam(teamId).name; msg = _Tr("Client", "{0} Wins!", msg); NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); scriptedUI->RecordChatLog(msg, MakeVector4(1.f, 1.f, 1.f, 0.8f)); if(world->GetLocalPlayer()){ if(teamId == world->GetLocalPlayer()->GetTeamId()){ Handle<IAudioChunk> chunk = audioDevice->RegisterSound("Sounds/Feedback/Win.wav"); audioDevice->PlayLocal(chunk, AudioParam()); }else{ Handle<IAudioChunk> chunk = audioDevice->RegisterSound("Sounds/Feedback/Lose.wav"); audioDevice->PlayLocal(chunk, AudioParam()); } } }
Vector4 operator *(const Matrix4& mat, const Vector3& v){ return mat * MakeVector4(v.x, v.y, v.z, 1.f); }
void LimboView::Draw() { Handle<IImage> menuItemImage = renderer->RegisterImage("Gfx/Limbo/MenuItem.tga"); Handle<IImage> menuItemBigImage = renderer->RegisterImage("Gfx/Limbo/BigMenuItem.tga"); //Handle<IImage> menuItemRingImage = renderer->RegisterImage("Gfx/Limbo/MenuItemRing.tga"); IFont *font = client->textFont; float left = (renderer->ScreenWidth() - contentsWidth) * .5f; float top = renderer->ScreenHeight() - 150.f; { std::string msg = "Select Team:"; Vector2 pos; pos.x = left + 10.f; pos.y = top + 10.f; font->Draw(msg, pos + MakeVector2(0, 1), 1.f, MakeVector4(0,0,0,0.4)); font->Draw(msg, pos, 1.f, MakeVector4(1, 1, 1, 1)); } if(selectedTeam != 2){ std::string msg = "Select Weapon:"; Vector2 pos; pos.x = left + 260.f; pos.y = top + 10.f; font->Draw(msg, pos + MakeVector2(0, 1), 1.f, MakeVector4(0,0,0,0.4)); font->Draw(msg, pos, 1.f, MakeVector4(1, 1, 1, 1)); } for(size_t i = 0; i < items.size(); i++){ MenuItem& item = items[i]; bool selected = false; if(!item.visible) continue; switch(item.type){ case MenuTeam1: selected = selectedTeam == 0; break; case MenuTeam2: selected = selectedTeam == 1; break; case MenuTeamSpectator: selected = selectedTeam == 2; break; case MenuWeaponRifle: selected = selectedWeapon == RIFLE_WEAPON; break; case MenuWeaponSMG: selected = selectedWeapon == SMG_WEAPON; break; case MenuWeaponShotgun: selected = selectedWeapon == SHOTGUN_WEAPON; break; default: selected = false; } Vector4 fillColor = {0.2, 0.2, 0.2, 0.5}; Vector4 ringColor = {0, 0, 0, 0}; if(item.hover){ fillColor = MakeVector4(.4f, .4f, .4f, .7f); ringColor = MakeVector4(.8f, .8f, .8f, .7f); } if(selected){ fillColor = MakeVector4(.7f, .7f, .7f, .9f); } renderer->SetColor(fillColor); if(item.type == MenuSpawn){ renderer->DrawImage(menuItemBigImage, item.rect); std::string msg = item.text; IFont *bFont = client->textFont; Vector2 size = bFont->Measure(msg); Vector2 pos; pos.x = item.rect.GetMinX() + (item.rect.GetWidth() - size.x) / 2.f + 2.f; pos.y = item.rect.GetMinY() + (item.rect.GetHeight() - size.y) / 2.f + 2.f; bFont->Draw(msg, pos + MakeVector2(0, 2), 1.f, MakeVector4(0,0,0,0.4)); bFont->Draw(msg, pos, 1.f, MakeVector4(1, 1, 1, 1)); }else{ renderer->DrawImage(menuItemImage, item.rect); std::string msg = item.text; if(item.type == MenuTeam1) msg = client->GetWorld()->GetTeam(0).name; if(item.type == MenuTeam2) msg = client->GetWorld()->GetTeam(1).name; Vector2 size = font->Measure(msg); Vector2 pos; pos.x = item.rect.GetMinX() + 5.f; pos.y = item.rect.GetMinY() + (item.rect.GetHeight() - size.y) / 2.f + 2.f; font->Draw(msg, pos + MakeVector2(0, 1), 1.f, MakeVector4(0,0,0,0.4)); font->Draw(msg, pos, 1.f, MakeVector4(1, 1, 1, 1)); } } Handle<IImage> cursor = renderer->RegisterImage("Gfx/Limbo/Cursor.tga"); renderer->SetColor(MakeVector4(1, 1, 1, 1)); renderer->DrawImage(cursor, AABB2(cursorPos.x - 8, cursorPos.y - 8, 32, 32)); }
void ScoreboardView::Draw() { SPADES_MARK_FUNCTION(); world = client->GetWorld(); if(!world){ // no world return; } ctf = dynamic_cast<CTFGameMode *>(world->GetMode()); tc = dynamic_cast<TCGameMode *>(world->GetMode()); Handle<IImage>image; IFont *font; Vector2 pos, size; char buf[256]; std::string str; float scrWidth = renderer->ScreenWidth(); float scrHeight = renderer->ScreenHeight(); const Vector4 whiteColor = {1,1,1,1}; Handle<IImage> whiteImage = renderer->RegisterImage("Gfx/White.tga"); float teamBarTop = 120.f; float teamBarHeight = 60.f; float contentsLeft = scrWidth * .5f - 400.f; float contentsRight = scrWidth * .5f + 400.f; float playersHeight = 300.f; float playersTop = teamBarTop + teamBarHeight; float playersBottom = playersTop + playersHeight; // draw shadow image = renderer->RegisterImage("Gfx/Scoreboard/TopShadow.tga"); size.y = 32.f; renderer->SetColor(MakeVector4(0,0,0,0.2f)); renderer->DrawImage(image, AABB2(0, teamBarTop-size.y, scrWidth, size.y)); renderer->SetColor(MakeVector4(0,0,0,0.2f)); renderer->DrawImage(image, AABB2(0, playersBottom + size.y, scrWidth, -size.y)); // draw scores image = renderer->RegisterImage("Gfx/Scoreboard/ScoresBg.tga"); size = MakeVector2(180.f, 32.f); pos = MakeVector2((scrWidth - size.x) * .5f, teamBarTop - size.y); renderer->SetColor(MakeVector4(1.f, .45f, .2f, 1.f)); renderer->DrawImage(image, AABB2(pos.x,pos.y,size.x,size.y)); pos.y = pos.y + 5.f; font = client->designFont; sprintf(buf, "%d", GetTeamScore(0)); size = font->Measure(buf); pos.x = scrWidth * .5f - size.x - 16.f; font->Draw(buf, pos + MakeVector2(0, 1), 1.f, MakeVector4(0, 0, 0, 0.3)); font->Draw(buf, pos, 1.f, whiteColor); sprintf(buf, "%d", GetTeamScore(1)); size = font->Measure(buf); pos.x = scrWidth * .5f + 16.f; font->Draw(buf, pos + MakeVector2(0, 1), 1.f, MakeVector4(0, 0, 0, 0.3)); font->Draw(buf, pos, 1.f, whiteColor); sprintf(buf, "-"); size = font->Measure(buf); pos.x = scrWidth * .5f - size.x * .5f; font->Draw(buf, pos + MakeVector2(0, 1), 1.f, MakeVector4(0, 0, 0, 0.3)); font->Draw(buf, pos, 1.f, whiteColor); // draw team bar image = whiteImage; renderer->SetColor(AdjustColor(GetTeamColor(0), 0.8f, 0.3f)); renderer->DrawImage(image, AABB2(0, teamBarTop, scrWidth * .5f, teamBarHeight)); renderer->SetColor(AdjustColor(GetTeamColor(1), 0.8f, 0.3f)); renderer->DrawImage(image, AABB2(scrWidth * .5f, teamBarTop, scrWidth * .5f, teamBarHeight)); image = renderer->RegisterImage("Gfx/Scoreboard/Grunt.tga"); size.x = 120.f; size.y = 60.f; renderer->DrawImage(image, AABB2(contentsLeft, teamBarTop + teamBarHeight - size.y, size.x, size.y)); renderer->DrawImage(image, AABB2(contentsRight, teamBarTop + teamBarHeight - size.y, -size.x, size.y)); font = client->bigTextFont; str = world->GetTeam(0).name; pos.x = contentsLeft + 110.f; pos.y = teamBarTop + 5.f; font->Draw(str, pos + MakeVector2(0, 2), 1.f, MakeVector4(0, 0, 0, 0.5)); font->Draw(str, pos, 1.f, whiteColor); str = world->GetTeam(1).name; size = font->Measure(str); pos.x = contentsRight - 110.f - size.x; pos.y = teamBarTop + 5.f; font->Draw(str, pos + MakeVector2(0, 2), 1.f, MakeVector4(0, 0, 0, 0.5)); font->Draw(str, pos, 1.f, whiteColor); // players background image = renderer->RegisterImage("Gfx/Scoreboard/PlayersBg.tga"); renderer->SetColor(MakeVector4(0, 0, 0, 1.f)); renderer->DrawImage(image, AABB2(0, playersTop, scrWidth, playersHeight)); // draw players DrawPlayers(0, contentsLeft, playersTop, (contentsRight - contentsLeft) * .5f, playersHeight); DrawPlayers(1, scrWidth * .5f, playersTop, (contentsRight - contentsLeft) * .5f, playersHeight); }
void SWModelRenderer::RenderInner(spades::draw::SWModel *model, const client::ModelRenderParam ¶m) { auto& mat = param.matrix; auto origin = mat.GetOrigin(); auto axis1 = mat.GetAxis(0); auto axis2 = mat.GetAxis(1); auto axis3 = mat.GetAxis(2); auto *rawModel = model->GetRawModel(); auto rawModelOrigin = rawModel->GetOrigin(); rawModelOrigin += 0.1f; origin += axis1 * rawModelOrigin.x; origin += axis2 * rawModelOrigin.y; origin += axis3 * rawModelOrigin.z; int w = rawModel->GetWidth(); int h = rawModel->GetHeight(); //int d = rawModel->GetDepth(); // evaluate brightness for each normals uint8_t brights[3*3*3]; { auto lightVec = MakeVector3(0.f, -0.707f, -0.707f); float dot1 = Vector3::Dot(axis1, lightVec) * fastRSqrt(axis1.GetPoweredLength()); float dot2 = Vector3::Dot(axis2, lightVec) * fastRSqrt(axis2.GetPoweredLength()); float dot3 = Vector3::Dot(axis3, lightVec) * fastRSqrt(axis3.GetPoweredLength()); for(int x = 0; x < 3; x++){ float d; int cnt; switch(x){ case 0: d = -dot1; cnt = 1; break; case 1: d = 0.f; cnt = 0; break; case 2: d = dot1; cnt = 1; break; } for(int y = 0; y < 3; y++){ auto d2 = d; auto cnt2 = cnt; switch(y){ case 0: d2 -= dot2; cnt2++; break; case 1: break; case 2: d2 += dot2; cnt2++; break; } for(int z = 0; z < 3; z++) { auto d3 = d; auto cnt3 = cnt2; switch(y){ case 0: d3 -= dot3; cnt3++; break; case 1: break; case 2: d3 += dot3; cnt3++; break; } switch(cnt3){ case 2: d3 *= 0.707f; break; case 3: d3 *= 0.57735f; break; } d3 = 192.f + d3 * 62.f; brights[x + y * 3 + z * 9] = static_cast<uint8_t>(d3); } } } } // compute center coord. for culling { auto center = origin; auto localCenter = model->GetCenter(); center += axis1 * localCenter.x; center += axis2 * localCenter.y; center += axis3 * localCenter.z; float largestAxis = axis1.GetPoweredLength(); largestAxis = std::max(largestAxis, axis2.GetPoweredLength()); largestAxis = std::max(largestAxis, axis3.GetPoweredLength()); if(!r->SphereFrustrumCull(center, model->GetRadius() * sqrtf(largestAxis))) return; } Bitmap *fbmp = r->fb; auto *fb = fbmp->GetPixels(); int fw = fbmp->GetWidth(); int fh = fbmp->GetHeight(); auto *db = r->depthBuffer.data(); Matrix4 viewproj = r->GetProjectionViewMatrix(); Vector4 ndc2scrscale = {fw * 0.5f, -fh * 0.5f, 1.f, 1.f}; //Vector4 ndc2scroff = {fw * 0.5f, fh * 0.5f, 0.f, 0.f}; int ndc2scroffX = fw >> 1; int ndc2scroffY = fh >> 1; // render each points auto tOrigin = viewproj * MakeVector4(origin.x, origin.y, origin.z, 1.f); auto tAxis1 = viewproj * MakeVector4(axis1.x, axis1.y, axis1.z, 0.f); auto tAxis2 = viewproj * MakeVector4(axis2.x, axis2.y, axis2.z, 0.f); auto tAxis3 = viewproj * MakeVector4(axis3.x, axis3.y, axis3.z, 0.f); tOrigin *= ndc2scrscale; tAxis1 *= ndc2scrscale; tAxis2 *= ndc2scrscale; tAxis3 *= ndc2scrscale; float pointDiameter;// = largestAxis * 0.55f * fh * 0.5f; { float largestAxis = tAxis1.GetPoweredLength(); largestAxis = std::max(largestAxis, tAxis2.GetPoweredLength()); largestAxis = std::max(largestAxis, tAxis3.GetPoweredLength()); pointDiameter = sqrtf(largestAxis); } uint32_t customColor; customColor = ToFixed8(param.customColor.z) | (ToFixed8(param.customColor.y) << 8) | (ToFixed8(param.customColor.x) << 16); auto v1 = tOrigin; float zNear = r->sceneDef.zNear; for(int x = 0; x < w; x++) { auto v2 = v1; for(int y = 0; y < h; y++) { auto *mp = &model->renderData [model->renderDataAddr[x + y * w]]; while(*mp != -1) { uint32_t data = *(mp++); uint32_t normal = *(mp++); int z = static_cast<int>(data >> 24); //SPAssert(z < d); SPAssert(z >= 0); auto vv = v2 + tAxis3 * zvals[z]; if(vv.z < zNear) continue; // save Z value (don't divide this by W!) float zval = vv.z; // use vv.z for point radius to be divided by W vv.z = pointDiameter; // perspective division float scl = fastRcp(vv.w); vv *= scl; int ix = static_cast<int>(vv.x) + ndc2scroffX; int iy = static_cast<int>(vv.y) + ndc2scroffY; int idm = static_cast<int>(vv.z + .99f); idm = std::max(1, idm); int minX = ix - (idm >> 1); int minY = iy - (idm >> 1); if(minX >= fw || minY >= fh) continue; int maxX = ix + idm; int maxY = iy + idm; if(maxX <= 0 || maxY <= 0) continue; minX = std::max(minX, 0); minY = std::max(minY, 0); maxX = std::min(maxX, fw); maxY = std::min(maxY, fh); auto *fb2 = fb + (minX + minY * fw); auto *db2 = db + (minX + minY * fw); int w = maxX - minX; uint32_t color = data & 0xffffff; if(color == 0) color = customColor; SPAssert(normal < 27); int bright = brights[normal]; #if ENABLE_SSE2 if(lvl == SWFeatureLevel::SSE2) { auto m = _mm_setr_epi32(color, 0, 0, 0); auto f = _mm_set1_epi16(bright << 8); m = _mm_unpacklo_epi8(m, _mm_setzero_si128()); m = _mm_mulhi_epu16(m, f); m = _mm_packus_epi16(m, m); _mm_store_ss(reinterpret_cast<float*>(&color), _mm_castsi128_ps(m)); }else #endif { uint32_t c1 = color & 0xff00; uint32_t c2 = color & 0xff00ff; c1 *= bright; c2 *= bright; color = ((c1&0xff0000) | (c2&0xff00ff00)) >> 8; } for(int yy = minY; yy < maxY; yy++){ auto *fb3 = fb2; auto *db3 = db2; for(int xx = w; xx > 0; xx--) { if(zval < *db3) { *db3 = zval; *fb3 = color; } fb3++; db3++; } fb2 += fw; db2 += fw; } } v2 += tAxis2; } v1 += tAxis1; } }
static Vector4 ConvertColor(IntVector3 v){ return MakeVector4((float)v.x / 255.f, (float)v.y / 255.f, (float)v.z / 255.f, 1.f); }
void GLSoftLitSpriteRenderer::Render() { SPADES_MARK_FUNCTION(); if(sprites.empty()) return; // light every sprite const std::vector<GLDynamicLight>& lights = renderer->lights; for(size_t i = 0; i < sprites.size(); i++){ Sprite& spr = sprites[i]; if(spr.color.w < .0001f) { // maybe emissive sprite... spr.emission = spr.color.GetXYZ(); spr.color = MakeVector4(0.f, 0.f, 0.f, 0.f); }else{ spr.emission = MakeVector3(0.f, 0.f, 0.f); } spr.dlR = MakeVector4(0, 0, 0, 0); spr.dlG = MakeVector4(0, 0, 0, 0); spr.dlB = MakeVector4(0, 0, 0, 0); } for(size_t j = 0; j < lights.size(); j++) { const GLDynamicLight& l = lights[j]; const client::DynamicLightParam& dl = l.GetParam(); float spotTan = dl.type == client::DynamicLightTypeSpotlight ? tanf(dl.spotAngle * .5f) : 0.; for(size_t i = 0; i < sprites.size(); i++){ Sprite& spr = sprites[i]; Vector3 v = dl.origin - spr.center; float effectiveRadius = spr.radius + dl.radius; if(v.GetChebyshevLength() > effectiveRadius) continue; float powdist = v.GetPoweredLength(); if(powdist > effectiveRadius * effectiveRadius) continue; float att = 1.f - powdist / (effectiveRadius * effectiveRadius); float unif; float directionalFactor = 1.f; unif = 1.f - powdist / (spr.radius * spr.radius); unif = std::max(.2f, unif); if(dl.type == client::DynamicLightTypeSpotlight) { float forward = Vector3::Dot(v, dl.spotAxis[2]); if(forward > spr.radius) { continue; }else if(forward >= -spr.radius){ att *= .5f - (forward / spr.radius) * .5f; directionalFactor = 1.f; }else{ float cx = Vector3::Dot(spr.center - dl.origin, dl.spotAxis[0]); float cy = Vector3::Dot(spr.center - dl.origin, dl.spotAxis[1]); float sq = sqrtf(cx * cx + cy * cy); float sprTan = spr.radius / (-spr.radius - forward); float eff = sprTan + spotTan; sq /= -forward; if(sq > eff){ continue; } if(sq > eff - spotTan){ att *= (eff - sq) / spotTan; } } } Vector4 final; if(unif < .9999f) { Vector3 directional = v; directional *= att * directionalFactor * (1.f - unif) / sqrtf(powdist); final.x = directional.x; final.y = directional.y; final.z = directional.z;
void GLMapRenderer::RenderSunlightPass() { SPADES_MARK_FUNCTION(); GLProfiler profiler(device, "Map"); Vector3 eye = renderer->GetSceneDef().viewOrigin; // draw back face to avoid cheating. // without this, players can see through blocks by // covering themselves by ones. RenderBackface(); device->ActiveTexture(0); aoImage->Bind(IGLDevice::Texture2D); device->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureMinFilter, IGLDevice::Linear); device->ActiveTexture(1); detailImage->Bind(IGLDevice::Texture2D); device->Enable(IGLDevice::CullFace, true); device->Enable(IGLDevice::DepthTest, true); basicProgram->Use(); static GLShadowShader shadowShader; shadowShader(renderer, basicProgram, 2); static GLProgramUniform fogDistance("fogDistance"); fogDistance(basicProgram); fogDistance.SetValue(renderer->GetFogDistance()); static GLProgramUniform viewSpaceLight("viewSpaceLight"); viewSpaceLight(basicProgram); Vector3 vspLight = (renderer->GetViewMatrix() * MakeVector4(0, -1, -1, 0)).GetXYZ(); viewSpaceLight.SetValue(vspLight.x, vspLight.y, vspLight.z); static GLProgramUniform fogColor("fogColor"); fogColor(basicProgram); Vector3 fogCol = renderer->GetFogColorForSolidPass(); fogCol *= fogCol; // linearize fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z); static GLProgramUniform aoUniform("ambientOcclusionTexture"); aoUniform(basicProgram); aoUniform.SetValue(0); static GLProgramUniform detailTextureUnif("detailTexture"); detailTextureUnif(basicProgram); detailTextureUnif.SetValue(1); device->BindBuffer(IGLDevice::ArrayBuffer, 0); static GLProgramAttribute positionAttribute("positionAttribute"); static GLProgramAttribute ambientOcclusionCoordAttribute("ambientOcclusionCoordAttribute"); static GLProgramAttribute colorAttribute("colorAttribute"); static GLProgramAttribute normalAttribute("normalAttribute"); static GLProgramAttribute fixedPositionAttribute("fixedPositionAttribute"); positionAttribute(basicProgram); ambientOcclusionCoordAttribute(basicProgram); colorAttribute(basicProgram); normalAttribute(basicProgram); fixedPositionAttribute(basicProgram); device->EnableVertexAttribArray(positionAttribute(), true); if(ambientOcclusionCoordAttribute() != -1) device->EnableVertexAttribArray(ambientOcclusionCoordAttribute(), true); device->EnableVertexAttribArray(colorAttribute(), true); if(normalAttribute() != -1) device->EnableVertexAttribArray(normalAttribute(), true); device->EnableVertexAttribArray(fixedPositionAttribute(), true); static GLProgramUniform projectionViewMatrix("projectionViewMatrix"); projectionViewMatrix(basicProgram); projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix()); static GLProgramUniform viewMatrix("viewMatrix"); viewMatrix(basicProgram); viewMatrix.SetValue(renderer->GetViewMatrix()); RealizeChunks(eye); // draw from nearest to farthest int cx = (int)floorf(eye.x) / GLMapChunk::Size; int cy = (int)floorf(eye.y) / GLMapChunk::Size; int cz = (int)floorf(eye.z) / GLMapChunk::Size; DrawColumnSunlight(cx, cy, cz, eye); for(int dist = 1; dist <= 128 / GLMapChunk::Size; dist++) { for(int x = cx - dist; x <= cx + dist; x++){ DrawColumnSunlight(x, cy + dist, cz, eye); DrawColumnSunlight(x, cy - dist, cz, eye); } for(int y = cy - dist + 1; y <= cy + dist - 1; y++){ DrawColumnSunlight(cx + dist, y, cz, eye); DrawColumnSunlight(cx - dist, y, cz, eye); } } device->EnableVertexAttribArray(positionAttribute(), false); if(ambientOcclusionCoordAttribute() != -1) device->EnableVertexAttribArray(ambientOcclusionCoordAttribute(), false); device->EnableVertexAttribArray(colorAttribute(), false); if(normalAttribute() != -1) device->EnableVertexAttribArray(normalAttribute(), false); device->EnableVertexAttribArray(fixedPositionAttribute(), false); device->ActiveTexture(1); device->BindTexture(IGLDevice::Texture2D, 0); device->ActiveTexture(0); device->BindTexture(IGLDevice::Texture2D, 0); }
void MapView::Draw(){ World *world = client->GetWorld(); if(!world) return; Player *player = world->GetLocalPlayer(); if(client->IsFollowing()){ player = world->GetPlayer(client->followingPlayerId); } if(!player) return; if(largeMap) if(zoomState < .0001f) return; GameMap *map = world->GetMap(); Vector2 mapSize = MakeVector2(map->Width(), map->Height()); Vector3 pos = player->GetPosition();; if(player->GetTeamId() >= 2){ pos = client->followPos; } Vector2 center = {pos.x, pos.y}; float cfgMapSize = cg_minimapSize; if(cfgMapSize < 32) cfgMapSize = 32; if(cfgMapSize > 256) cfgMapSize = 256; Vector2 mapWndSize = {cfgMapSize, cfgMapSize}; float scale = actualScale; center = Mix(center, mapSize * .5f, zoomState); Vector2 zoomedSize = {512, 512}; if(renderer->ScreenWidth() < 512.f || renderer->ScreenHeight() < 512.f) zoomedSize = MakeVector2(256, 256); if(largeMap){ float per = zoomState; per = 1.f - per; per *= per; per = 1.f - per; per = Mix(.7f, 1.f, per); zoomedSize = Mix(MakeVector2(0, 0), zoomedSize, per); mapWndSize = zoomedSize; } Vector2 inRange = mapWndSize * .5f * scale; AABB2 inRect(center - inRange, center + inRange); if(largeMap){ inRect.min = MakeVector2(0, 0); inRect.max = mapSize; }else{ if(inRect.GetMinX() < 0.f) inRect = inRect.Translated(-inRect.GetMinX(), 0.f); if(inRect.GetMinY() < 0.f) inRect = inRect.Translated(0, -inRect.GetMinY()); if(inRect.GetMaxX() > mapSize.x) inRect = inRect.Translated(mapSize.x - inRect.GetMaxX(), 0.f); if(inRect.GetMaxY() > mapSize.y) inRect = inRect.Translated(0, mapSize.y - inRect.GetMaxY()); } AABB2 outRect(renderer->ScreenWidth() - mapWndSize.x - 16.f, 16.f, mapWndSize.x, mapWndSize.y); if(largeMap){ outRect.min = MakeVector2((renderer->ScreenWidth() - zoomedSize.x) * .5f, (renderer->ScreenHeight() - zoomedSize.y) * .5f); outRect.max =MakeVector2((renderer->ScreenWidth() + zoomedSize.x) * .5f, (renderer->ScreenHeight() + zoomedSize.y) * .5f); } float alpha = 1.f; if(largeMap){ alpha = zoomState; } // fades bg if(largeMap) { Handle<IImage> bg = renderer->RegisterImage("Gfx/MapBg.png"); Vector2 scrSize = {renderer->ScreenWidth(), renderer->ScreenHeight()}; float size = std::max(scrSize.x, scrSize.y); renderer->SetColorAlphaPremultiplied(MakeVector4(0, 0, 0,alpha * .5f)); renderer->DrawImage(bg, AABB2((scrSize.x - size) * .5f, (scrSize.y - size) * .5f, size, size)); } // draw border Handle<IImage> border; float borderWidth; AABB2 borderRect = outRect; if(largeMap) { border = renderer->RegisterImage("Gfx/MapBorder.png"); borderWidth = 3.f * outRect.GetHeight() / zoomedSize.y; }else{ border = renderer->RegisterImage("Gfx/MinimapBorder.png"); borderWidth = 2.f; } borderRect = borderRect.Inflate(borderWidth - 8.f); renderer->SetColorAlphaPremultiplied(MakeVector4(alpha,alpha,alpha,alpha)); renderer->DrawImage(border, AABB2(borderRect.GetMinX()-16, borderRect.GetMinY()-16, 16, 16), AABB2(0, 0, 16, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMaxX(), borderRect.GetMinY()-16, 16, 16), AABB2(16, 0, 16, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMinX()-16, borderRect.GetMaxY(), 16, 16), AABB2(0, 16, 16, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMaxX(), borderRect.GetMaxY(), 16, 16), AABB2(16, 16, 16, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMinX(), borderRect.GetMinY()-16, borderRect.GetWidth(), 16), AABB2(16, 0, 0, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMinX(), borderRect.GetMaxY(), borderRect.GetWidth(), 16), AABB2(16, 16, 0, 16)); renderer->DrawImage(border, AABB2(borderRect.GetMinX()-16, borderRect.GetMinY(), 16, borderRect.GetHeight()), AABB2(0, 16, 16, 0)); renderer->DrawImage(border, AABB2(borderRect.GetMaxX(), borderRect.GetMinY(), 16, borderRect.GetHeight()), AABB2(16, 16, 16, 0)); // draw map renderer->SetColorAlphaPremultiplied(MakeVector4(alpha,alpha,alpha,alpha)); renderer->DrawFlatGameMap(outRect, inRect); this->inRect = inRect; this->outRect = outRect; // draw grid renderer->SetColorAlphaPremultiplied(MakeVector4(0,0,0,0.8f*alpha)); Handle<IImage> dashLine = renderer->RegisterImage("Gfx/DashLine.tga"); for(float x = 64.f; x < map->Width(); x += 64.f){ float wx = (x - inRect.GetMinX()) / inRect.GetWidth(); if(wx < 0.f || wx >= 1.f) continue; wx = (wx * outRect.GetWidth()) + outRect.GetMinX(); wx = roundf(wx); renderer->DrawImage(dashLine, MakeVector2(wx, outRect.GetMinY()), AABB2(0, 0, 1.f, outRect.GetHeight())); } for(float y = 64.f; y < map->Height(); y += 64.f){ float wy = (y - inRect.GetMinY()) / inRect.GetHeight(); if(wy < 0.f || wy >= 1.f) continue; wy = (wy * outRect.GetHeight()) + outRect.GetMinY(); wy = roundf(wy); renderer->DrawImage(dashLine, MakeVector2(outRect.GetMinX(), wy), AABB2(0, 0, outRect.GetWidth(), 1.f)); } // draw grid label renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(0.8f*alpha)); Handle<IImage> mapFont = renderer->RegisterImage("Gfx/Fonts/MapFont.tga"); for(int i = 0; i < 8; i++){ float startX = (float)i * 64.f; float endX = startX + 64.f; if(startX > inRect.GetMaxX() || endX < inRect.GetMinX()) continue; float fade = std::min((std::min(endX, inRect.GetMaxX()) - std::max(startX, inRect.GetMinX())) / (endX - startX) * 2.f, 1.f); renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(fade * .8f * alpha)); float center = std::max(startX, inRect.GetMinX()); center = .5f * (center + std::min(endX, inRect.GetMaxX())); float wx = (center - inRect.GetMinX()) / inRect.GetWidth(); wx = (wx * outRect.GetWidth()) + outRect.GetMinX(); wx = roundf(wx); float fntX = static_cast<float>((i & 3) * 8); float fntY = static_cast<float>((i >> 2) * 8); renderer->DrawImage(mapFont, MakeVector2(wx - 4.f, outRect.GetMinY() + 4), AABB2(fntX, fntY, 8, 8)); } for(int i = 0; i < 8; i++){ float startY = (float)i * 64.f; float endY = startY + 64.f; if(startY > inRect.GetMaxY() || endY < inRect.GetMinY()) continue; float fade = std::min((std::min(endY, inRect.GetMaxY()) - std::max(startY, inRect.GetMinY())) / (endY - startY) * 2.f, 1.f); renderer->SetColorAlphaPremultiplied(MakeVector4(1,1,1,1)*(fade * .8f * alpha)); float center = std::max(startY, inRect.GetMinY()); center = .5f * (center + std::min(endY, inRect.GetMaxY())); float wy = (center - inRect.GetMinY()) / inRect.GetHeight(); wy = (wy * outRect.GetHeight()) + outRect.GetMinY(); wy = roundf(wy); int fntX = (i & 3) * 8; int fntY = (i >> 2) * 8 + 16; renderer->DrawImage(mapFont, MakeVector2(outRect.GetMinX() + 4, wy - 4.f), AABB2(fntX, fntY, 8, 8)); } //draw objects std::string iconmode = cg_Minimap_Player_Icon;//import variable from configuration file std::string colormode = cg_Minimap_Player_Color;//import variable from configuration file Handle<IImage> playerSMG = renderer->RegisterImage("Gfx/Map/SMG.png"); Handle<IImage> playerRifle = renderer->RegisterImage("Gfx/Map/Rifle.png"); Handle<IImage> playerShotgun = renderer->RegisterImage("Gfx/Map/Shotgun.png"); Handle<IImage> playerIcon = renderer->RegisterImage("Gfx/Map/Player.png"); { IntVector3 teamColor = world->GetLocalPlayer()->GetTeamId() >= 2 ? IntVector3::Make(200, 200, 200) : world->GetTeam(world->GetLocalPlayer()->GetTeamId()).color; Vector4 teamColorF = ModifyColor(teamColor); teamColorF *= alpha; // draw local player's view { Player *p = player; Handle<IImage> viewIcon = renderer->RegisterImage("Gfx/Map/View.png"); if(p->IsAlive()) { Vector3 front = p->GetFront2D(); float ang = atan2(front.x, -front.y); if(player->GetTeamId() >= 2){ ang = client->followYaw - static_cast<float>(M_PI) * .5f; } renderer->SetColorAlphaPremultiplied(teamColorF * 0.9f); DrawIcon(player->GetTeamId() >= 2 ? client->followPos : p->GetPosition(), viewIcon, ang); } } // draw player's icon for(int i = 0; i < world->GetNumPlayerSlots(); i++){ Player * p = world->GetPlayer(i); if(p == nullptr || p->GetTeamId() != world->GetLocalPlayer()->GetTeamId() || !p->IsAlive()) continue; Vector3 front = p->GetFront2D(); float ang = atan2(front.x, -front.y); if(player->GetTeamId() >= 2){ ang = client->followYaw - static_cast<float>(M_PI) * .5f; } //use a spec color for each player if ( colormode=="1"){ IntVector3 Colorplayer=IntVector3::Make(palette[i][0],palette[i][1],palette[i][2]); Vector4 ColorplayerF = ModifyColor(Colorplayer); ColorplayerF *=1.0f; renderer->SetColorAlphaPremultiplied(ColorplayerF); } else { renderer->SetColorAlphaPremultiplied(teamColorF); } //use a different icon in minimap according to weapon of player if( iconmode=="1"){ WeaponType weapon=world->GetPlayer(i)->GetWeaponType(); if (weapon == WeaponType::SMG_WEAPON){ DrawIcon(player->GetTeamId() >= 2 ? client->followPos : p->GetPosition(),playerSMG , ang); } else if (weapon == WeaponType::RIFLE_WEAPON){ DrawIcon(player->GetTeamId() >= 2 ? client->followPos : p->GetPosition(), playerRifle, ang); } else if (weapon == WeaponType::SHOTGUN_WEAPON){ DrawIcon(player->GetTeamId() >= 2 ? client->followPos : p->GetPosition(), playerShotgun, ang); } } else{//draw normal color DrawIcon(player->GetTeamId() >= 2 ? client->followPos : p->GetPosition(), playerIcon, ang); } } } IGameMode* mode = world->GetMode(); if( mode && IGameMode::m_CTF == mode->ModeType() ) { CTFGameMode *ctf = static_cast<CTFGameMode *>(mode); Handle<IImage> intelIcon = renderer->RegisterImage("Gfx/Map/Intel.png"); Handle<IImage> baseIcon = renderer->RegisterImage("Gfx/Map/CommandPost.png"); for(int tId = 0; tId < 2; tId++){ CTFGameMode::Team& team = ctf->GetTeam(tId); IntVector3 teamColor = world->GetTeam(tId).color; Vector4 teamColorF = ModifyColor(teamColor); teamColorF *= alpha; // draw base renderer->SetColorAlphaPremultiplied(teamColorF); DrawIcon(team.basePos, baseIcon, 0.f); // draw flag if(!ctf->GetTeam(1-tId).hasIntel){ renderer->SetColorAlphaPremultiplied(teamColorF); DrawIcon(team.flagPos, intelIcon, 0.f); }else if(world->GetLocalPlayer()->GetTeamId() == 1-tId){ // local player's team is carrying int cId = ctf->GetTeam(1-tId).carrier; // in some game modes, carrier becomes invalid if(cId < world->GetNumPlayerSlots()){ Player * carrier= world->GetPlayer(cId); if(carrier && carrier->GetTeamId() == world->GetLocalPlayer()->GetTeamId()){ Vector4 col = teamColorF; col *= fabsf(sinf(world->GetTime() * 4.f)); renderer->SetColorAlphaPremultiplied(col); DrawIcon(carrier->GetPosition(), intelIcon, 0.f); } } } } } else if( mode && IGameMode::m_TC == mode->ModeType() ) { TCGameMode *tc = static_cast<TCGameMode *>(mode); Handle<IImage> icon = renderer->RegisterImage("Gfx/Map/CommandPost.png"); int cnt = tc->GetNumTerritories(); for(int i = 0; i < cnt; i++){ TCGameMode::Territory *t = tc->GetTerritory(i); IntVector3 teamColor = {128,128,128}; if(t->ownerTeamId < 2){ teamColor = world->GetTeam(t->ownerTeamId).color; } Vector4 teamColorF = ModifyColor(teamColor); teamColorF *= alpha; // draw base renderer->SetColorAlphaPremultiplied(teamColorF); DrawIcon(t->pos, icon, 0.f); } } }
Vector4 ScoreboardView::GetTeamColor(int team) { IntVector3 c = world->GetTeam(team).color; return MakeVector4(c.x / 255.f, c.y / 255.f, c.z / 255.f, 1.f); }