Esempio n. 1
0
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);
}
Esempio n. 2
0
		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);
			}
		}
Esempio n. 3
0
		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();
		}
Esempio n. 4
0
		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));
					}
				}
			}
		}
Esempio n. 5
0
File: IObject.hpp Progetto: rAum/rum
    /// 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();
    }
Esempio n. 6
0
		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());
			}
		}
Esempio n. 7
0
	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());
				}
			}
		}
Esempio n. 10
0
	Vector4 operator *(const Matrix4& mat, const Vector3& v){
		return mat * MakeVector4(v.x, v.y, v.z, 1.f);
	}
Esempio n. 11
0
		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));
		}
Esempio n. 12
0
		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);
		}
Esempio n. 13
0
		void SWModelRenderer::RenderInner(spades::draw::SWModel *model,
									 const client::ModelRenderParam &param) {
			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;
			}
		}
Esempio n. 14
0
		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;
Esempio n. 16
0
		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);
		}
Esempio n. 17
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);
					
				}
			}
		}
Esempio n. 18
0
		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);
		}