Esempio n. 1
0
void AtlasViewActor::SetParam(const std::wstring& name, const AtlasMessage::Color& value)
{
	if (name == L"background")
	{
		m_ActorViewer->SetBackgroundColor(SColor4ub(value.r, value.g, value.b, 255));
	}
}
Esempio n. 2
0
static SColor4ub sse_ConvertRGBColorTo4ub(const RGBColor& src)
{
	const __m128 zero = _mm_setzero_ps();
	const __m128 _255 = _mm_set_ss(255.0f);
	__m128 r = _mm_load_ss(&src.X);
	__m128 g = _mm_load_ss(&src.Y);
	__m128 b = _mm_load_ss(&src.Z);

	// C = min(255, 255*max(C, 0)) ( == clamp(255*C, 0, 255) )
	r = _mm_max_ss(r, zero);
	g = _mm_max_ss(g, zero);
	b = _mm_max_ss(b, zero);

	r = _mm_mul_ss(r, _255);
	g = _mm_mul_ss(g, _255);
	b = _mm_mul_ss(b, _255);

	r = _mm_min_ss(r, _255);
	g = _mm_min_ss(g, _255);
	b = _mm_min_ss(b, _255);

	// convert to integer and combine channels using bit logic
	int ri = _mm_cvtss_si32(r);
	int gi = _mm_cvtss_si32(g);
	int bi = _mm_cvtss_si32(b);

	return SColor4ub(ri, gi, bi, 0xFF);
}
Esempio n. 3
0
ActorViewer::ActorViewer()
	: m(*new ActorViewerImpl())
{
	m.WalkEnabled = false;
	m.GroundEnabled = true;
	m.WaterEnabled = false;
	m.ShadowsEnabled = g_Renderer.GetOptionBool(CRenderer::OPT_SHADOWS);
	m.SelectionBoxEnabled = false;
	m.AxesMarkerEnabled = false;
	m.PropPointsMode = 0;
	m.Background = SColor4ub(0, 0, 0, 255);

	// Create a tiny empty piece of terrain, just so we can put shadows
	// on it without having to think too hard
	m.Terrain.Initialize(2, NULL);
	CTerrainTextureEntry* tex = g_TexMan.FindTexture("whiteness");
	if (tex)
	{
		for (ssize_t pi = 0; pi < m.Terrain.GetPatchesPerSide(); ++pi)
		{
			for (ssize_t pj = 0; pj < m.Terrain.GetPatchesPerSide(); ++pj)
			{
				CPatch* patch = m.Terrain.GetPatch(pi, pj);
				for (ssize_t i = 0; i < PATCH_SIZE; ++i)
				{
					for (ssize_t j = 0; j < PATCH_SIZE; ++j)
					{
						CMiniPatch& mp = patch->m_MiniPatches[i][j];
						mp.Tex = tex;
						mp.Priority = 0;
					}
				}
			}
		}
	}
	else
	{
		debug_warn(L"Failed to load whiteness texture");
	}

	// Start the simulation
	m.Simulation2.LoadDefaultScripts();
	m.Simulation2.ResetState();

	// Tell the simulation we've already loaded the terrain
	CmpPtr<ICmpTerrain> cmpTerrain(m.Simulation2, SYSTEM_ENTITY);
	if (cmpTerrain)
		cmpTerrain->ReloadTerrain(false);

	// Remove FOW since we're in Atlas
	CmpPtr<ICmpRangeManager> cmpRangeManager(m.Simulation2, SYSTEM_ENTITY);
	if (cmpRangeManager)
		cmpRangeManager->SetLosRevealAll(-1, true);
}
Esempio n. 4
0
// Build vertex buffer for water vertices over our patch
void CPatchRData::BuildWater()
{
	PROFILE3("build water");

	// number of vertices in each direction in each patch
	ENSURE((PATCH_SIZE % water_cell_size) == 0);

	if (m_VBWater)
	{
		g_VBMan.Release(m_VBWater);
		m_VBWater = 0;
	}
	if (m_VBWaterIndices)
	{
		g_VBMan.Release(m_VBWaterIndices);
		m_VBWaterIndices = 0;
	}
	m_WaterBounds.SetEmpty();

	// We need to use this to access the water manager or we may not have the
	// actual values but some compiled-in defaults
	CmpPtr<ICmpWaterManager> cmpWaterManager(*m_Simulation, SYSTEM_ENTITY);
	if (!cmpWaterManager)
		return;
	
	// Build data for water
	std::vector<SWaterVertex> water_vertex_data;
	std::vector<GLushort> water_indices;
	u16 water_index_map[PATCH_SIZE+1][PATCH_SIZE+1];
	memset(water_index_map, 0xFF, sizeof(water_index_map));

	// TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults
	WaterManager* WaterMgr = g_Renderer.GetWaterManager();

	if (WaterMgr->m_NeedsFullReloading && !g_AtlasGameLoop->running)
	{
		WaterMgr->m_NeedsFullReloading = false;
		WaterMgr->CreateSuperfancyInfo(m_Simulation);
	}
	CPatch* patch = m_Patch;
	CTerrain* terrain = patch->m_Parent;

	ssize_t mapSize = (size_t)terrain->GetVerticesPerSide();

	ssize_t x1 = m_Patch->m_X*PATCH_SIZE;
	ssize_t z1 = m_Patch->m_Z*PATCH_SIZE;

	// build vertices, uv, and shader varying
	for (ssize_t z = 0; z < PATCH_SIZE; z += water_cell_size)
	{
		for (ssize_t x = 0; x <= PATCH_SIZE; x += water_cell_size)
		{
			// Check that the edge at x is partially underwater
			float startTerrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) };
			float startWaterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) };
			if (startTerrainHeight[0] >= startWaterHeight[0] && startTerrainHeight[1] >= startWaterHeight[1])
				continue;

			// Move x back one cell (unless at start of patch), then scan rightwards
			bool belowWater = true;
			ssize_t stripStart;
			for (stripStart = x = std::max(x-water_cell_size, (ssize_t)0); x <= PATCH_SIZE; x += water_cell_size)
			{
				// If this edge is not underwater, and neither is the previous edge
				// (i.e. belowWater == false), then stop this strip since we've reached
				// a cell that's entirely above water
				float terrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) };
				float waterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) };
				if (terrainHeight[0] >= waterHeight[0] && terrainHeight[1] >= waterHeight[1])
				{
					if (!belowWater)
						break;
					belowWater = false;
				}
				else
					belowWater = true;

				// Edge (x,z)-(x,z+1) is at least partially underwater, so extend the water plane strip across it

				// Compute vertex data for the 2 points on the edge
				for (int j = 0; j < 2; j++)
				{
					// Check if we already computed this vertex from an earlier strip
					if (water_index_map[z+j*water_cell_size][x] != 0xFFFF)
						continue;

					SWaterVertex vertex;

					terrain->CalcPosition(x+x1, z+z1 + j*water_cell_size, vertex.m_Position);
					float depth = waterHeight[j] - vertex.m_Position.Y;
					vertex.m_Position.Y = waterHeight[j];
					m_WaterBounds += vertex.m_Position;

					// NB: Usually this factor is view dependent, but for performance reasons
					// we do not take it into account with basic non-shader based water.
					// Average constant Fresnel effect for non-fancy water
					float alpha = clamp(depth / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha);

					// Split the depth data across 24 bits, so the fancy-water shader can reconstruct
					// the depth value while the simple-water can just use the precomputed alpha
					float depthInt = floor(depth);
					float depthFrac = depth - depthInt;
					vertex.m_DepthData = SColor4ub(
						u8(clamp(depthInt, 0.0f, 255.0f)),
						u8(clamp(-depthInt, 0.0f, 255.0f)),
						u8(clamp(depthFrac*255.0f, 0.0f, 255.0f)),
						u8(clamp(alpha*255.0f, 0.0f, 255.0f)));

					int tx = x+x1;
					int ty = z+z1 + j*water_cell_size;

					if (g_AtlasGameLoop->running)
					{
						// currently no foam is used so push whatever
						vertex.m_WaterData = CVector4D(0.0f,0.0f,0.0f,0.0f);
					}
					else
					{
						vertex.m_WaterData = CVector4D(WaterMgr->m_WaveX[tx + ty*mapSize],
												   WaterMgr->m_WaveZ[tx + ty*mapSize],
												   WaterMgr->m_DistanceToShore[tx + ty*mapSize],
												   WaterMgr->m_FoamFactor[tx + ty*mapSize]);
					}
					water_index_map[z+j*water_cell_size][x] = water_vertex_data.size();
					water_vertex_data.push_back(vertex);
				}

				// If this was not the first x in the strip, then add a quad
				// using the computed vertex data

				if (x <= stripStart)
					continue;

				water_indices.push_back(water_index_map[z + water_cell_size][x - water_cell_size]);
				water_indices.push_back(water_index_map[z][x - water_cell_size]);
				water_indices.push_back(water_index_map[z][x]);
				water_indices.push_back(water_index_map[z + water_cell_size][x]);
			}
		}
	}

	// no vertex buffers if no data generated
	if (water_indices.size() == 0)
		return;

	// allocate vertex buffer
	m_VBWater = g_VBMan.Allocate(sizeof(SWaterVertex), water_vertex_data.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER);
	m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater, &water_vertex_data[0]);

	// Construct indices buffer
	m_VBWaterIndices = g_VBMan.Allocate(sizeof(GLushort), water_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
	m_VBWaterIndices->m_Owner->UpdateChunkVertices(m_VBWaterIndices, &water_indices[0]);
}