// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyEntity entity, MyDecalTexturesEnum decalTexture) { Entity = entity; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; if (MyDecals.IsLargeTexture(decalTexture) == true) { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { //m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacity * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyVoxelMap voxelMap, ref MyMwcVector3Int renderCellCoord, MyDecalTexturesEnum decalTexture, ref BoundingBox renderCellBoundingBox) { VoxelMap = voxelMap; RenderCellCoord = renderCellCoord; DecalTexture = decalTexture; m_status = MyDecalsBufferState.READY; m_fadingOutStartTime = 0; RenderCellBoundingBox = renderCellBoundingBox; if (MyDecals.IsLargeTexture(decalTexture) == true) { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_LARGE; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_LARGE_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_LARGE_MAX_NEIGHBOUR_TRIANGLES; } else { m_capacityAfterStart = MyDecalsConstants.MAX_DECAL_TRIANGLES_IN_BUFFER_SMALL; m_fadingOutStartLimit = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_START_LIMIT_PERCENT); m_fadingOutMinimalTriangleCount = (int)(m_capacityAfterStart * MyDecalsConstants.TEXTURE_SMALL_FADING_OUT_MINIMAL_TRIANGLE_COUNT_PERCENT); MaxNeighbourTriangles = MyDecalsConstants.TEXTURE_SMALL_MAX_NEIGHBOUR_TRIANGLES; } }
public void Draw(MyVertexFormatDecal[] vertices, Effects.MyEffectDecals effect, MyTexture2D[] texturesDiffuse, MyTexture2D[] texturesNormalMap) { CheckIfBufferIsFull(); // Sort buffers by texture m_sortTriangleBuffersByTexture.Clear(); foreach (MyDecalsForVoxelsTriangleBuffer buffer in m_usedTriangleBuffers) { // Check if render cell is close enought and visible in the view frustum if (//(buffer.VoxelMap.GetSmallestDistanceFromCameraToRenderCell(ref buffer.RenderCellCoord) <= (MyDecals.GetMaxDistanceForDrawingDecals())) && (MyCamera.IsInFrustum(ref buffer.RenderCellBoundingBox) == true)) { float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals(); if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut) { fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS; } if (buffer.VoxelMap.GetSmallestDistanceFromCameraToRenderCell(ref buffer.RenderCellCoord) <= fadeoutDistance) { m_sortTriangleBuffersByTexture.Add(buffer); } } } m_sortTriangleBuffersByTexture.Sort(); if (m_sortTriangleBuffersByTexture.Count <= 0) { return; } // Draw decals - sorted by texture MyDecalTexturesEnum?lastDecalTexture = null; for (int i = 0; i < m_sortTriangleBuffersByTexture.Count; i++) { MyDecalsForVoxelsTriangleBuffer buffer = m_sortTriangleBuffersByTexture[i]; int trianglesCount = buffer.CopyDecalsToVertexBuffer(vertices); if (trianglesCount <= 0) { continue; } // Switch texture only if different than previous one if ((lastDecalTexture == null) || (lastDecalTexture != buffer.DecalTexture)) { int textureIndex = (int)buffer.DecalTexture; effect.SetDecalDiffuseTexture(texturesDiffuse[textureIndex]); effect.SetDecalNormalMapTexture(texturesNormalMap[textureIndex]); lastDecalTexture = buffer.DecalTexture; } // This will move all voxel maps back to position [0,0,0] effect.SetVoxelMapPosition(buffer.VoxelMap.PositionLeftBottomCorner - MyCamera.Position); effect.SetViewProjectionMatrix(MyCamera.ViewProjectionMatrixAtZero); // Set fadeout distance float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals(); if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut) { fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS; } effect.SetFadeoutDistance(fadeoutDistance); if (!MyRenderConstants.RenderQualityProfile.ForwardRender) { effect.SetTechnique(Effects.MyEffectDecals.Technique.Voxels); } else { effect.SetTechnique(Effects.MyEffectDecals.Technique.VoxelsForward); } MyMinerGame.Static.GraphicsDevice.VertexDeclaration = MyVertexFormatDecal.VertexDeclaration; effect.Begin(); MyMinerGame.Static.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, 0, trianglesCount, vertices); effect.End(); MyPerformanceCounter.PerCameraDraw.DecalsForVoxelsInFrustum += trianglesCount; } }
// Copy triangles to array of vertexes (which is then copyed to vertex buffer) and return count of triangles to draw public int CopyDecalsToVertexBuffer(MyVertexFormatDecal[] vertices) { CheckIfBufferIsFull(); float fadingOutAlpha = 1; if ((m_status == MyDecalsBufferState.FADING_OUT_ONLY_BEGINNING) || (m_status == MyDecalsBufferState.FADING_OUT_ALL)) { fadingOutAlpha = 1 - MathHelper.Clamp((float)(MyMinerGame.TotalGamePlayTimeInMilliseconds - m_fadingOutStartTime) / (float)MyDecalsConstants.DECALS_FADE_OUT_INTERVAL_MILISECONDS, 0, 1); } int trianglesToDraw = 0; int i = 0; foreach (MyDecalTriangle decalTriangle in m_trianglesQueue) { if (decalTriangle.Draw == true) { float alpha = 1; // If fading-out, we blend first 'm_fadingOutRealTriangleCount' triangles if (m_status == MyDecalsBufferState.FADING_OUT_ALL) { alpha = fadingOutAlpha; } else if ((m_status == MyDecalsBufferState.FADING_OUT_ONLY_BEGINNING) && (i < m_fadingOutRealTriangleCount)) { alpha = fadingOutAlpha; } int vertexIndexStart = trianglesToDraw * MyDecalsConstants.VERTEXES_PER_DECAL; vertices[vertexIndexStart + 0].Position = decalTriangle.Position0; vertices[vertexIndexStart + 1].Position = decalTriangle.Position1; vertices[vertexIndexStart + 2].Position = decalTriangle.Position2; vertices[vertexIndexStart + 0].TexCoord = decalTriangle.TexCoord0; vertices[vertexIndexStart + 1].TexCoord = decalTriangle.TexCoord1; vertices[vertexIndexStart + 2].TexCoord = decalTriangle.TexCoord2; Vector4 color0 = decalTriangle.Color0; Vector4 color1 = decalTriangle.Color1; Vector4 color2 = decalTriangle.Color2; //color0.W = 1; //color1.W = 1; //color2.W = 1; color0 *= alpha; color1 *= alpha; color2 *= alpha; vertices[vertexIndexStart + 0].Color = color0; vertices[vertexIndexStart + 1].Color = color1; vertices[vertexIndexStart + 2].Color = color2; vertices[vertexIndexStart + 0].Normal = decalTriangle.Normal0; vertices[vertexIndexStart + 1].Normal = decalTriangle.Normal1; vertices[vertexIndexStart + 2].Normal = decalTriangle.Normal2; vertices[vertexIndexStart + 0].Binormal = decalTriangle.Binormal0; vertices[vertexIndexStart + 1].Binormal = decalTriangle.Binormal1; vertices[vertexIndexStart + 2].Binormal = decalTriangle.Binormal2; vertices[vertexIndexStart + 0].Tangent = decalTriangle.Tangent0; vertices[vertexIndexStart + 1].Tangent = decalTriangle.Tangent1; vertices[vertexIndexStart + 2].Tangent = decalTriangle.Tangent2; float emisivity = MyDecals.UpdateDecalEmissivity(decalTriangle, alpha, null); vertices[vertexIndexStart + 0].EmissiveRatio = emisivity; vertices[vertexIndexStart + 1].EmissiveRatio = emisivity; vertices[vertexIndexStart + 2].EmissiveRatio = emisivity; trianglesToDraw++; } i++; } return(trianglesToDraw); }
public void Draw(MyVertexFormatDecal[] vertices, MyEffectDecals effect, MyTexture2D[] texturesDiffuse, MyTexture2D[] texturesNormalMap) { CheckIfBufferIsFull(); // SortForSAP buffers by texture m_sortTriangleBuffersByTexture.Clear(); foreach (MyDecalsForPhysObjectsTriangleBuffer buffer in m_usedTriangleBuffers) { if (buffer.Entity.IsVisible() == true) { if ((buffer.Entity == MyGuiScreenGamePlay.Static.ControlledEntity || buffer.Entity.Parent == MyGuiScreenGamePlay.Static.ControlledEntity) && MyGuiScreenGamePlay.Static.IsFirstPersonView) { // Don't draw decals if they are on an entity in which the camera is continue; } // Decal with "ExplosionSmut" texture is much larger, so it must be drawed to larger distance. float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals(); if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut) { fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS; } //if (Vector3.Distance(MyCamera.m_initialSunWindPosition, buffer.PhysObject.GetPosition()) >= (MyDecals.GetMaxDistanceForDrawingDecals())) //if (buffer.PhysObject.GetDistanceBetweenCameraAndBoundingSphere() >= MyDecals.GetMaxDistanceForDrawingDecals()) if (buffer.Entity.GetDistanceBetweenCameraAndBoundingSphere() >= fadeoutDistance) { continue; } m_sortTriangleBuffersByTexture.Add(buffer); } } m_sortTriangleBuffersByTexture.Sort(); // Draw decals - sorted by texture MyDecalTexturesEnum?lastDecalTexture = null; for (int i = 0; i < m_sortTriangleBuffersByTexture.Count; i++) { MyDecalsForPhysObjectsTriangleBuffer buffer = m_sortTriangleBuffersByTexture[i]; int trianglesCount = buffer.CopyDecalsToVertices(vertices); if (trianglesCount <= 0) { continue; } // Switch texture only if different than previous one if ((lastDecalTexture == null) || (lastDecalTexture != buffer.DecalTexture)) { int textureIndex = (int)buffer.DecalTexture; effect.SetDecalDiffuseTexture(texturesDiffuse[textureIndex]); effect.SetDecalNormalMapTexture(texturesNormalMap[textureIndex]); lastDecalTexture = buffer.DecalTexture; } //effect.SetWorldMatrix(buffer.Entity.WorldMatrix * Matrix.CreateTranslation(-MyCamera.Position)); effect.SetWorldMatrix(buffer.Entity.GetWorldMatrixForDraw()); effect.SetViewProjectionMatrix(MyCamera.ViewProjectionMatrixAtZero); // set FadeoutDistance float fadeoutDistance = MyDecals.GetMaxDistanceForDrawingDecals(); if (buffer.DecalTexture == MyDecalTexturesEnum.ExplosionSmut) { fadeoutDistance *= MyDecalsConstants.DISTANCE_MULTIPLIER_FOR_LARGE_DECALS; } effect.SetFadeoutDistance(fadeoutDistance); if (!MyRenderConstants.RenderQualityProfile.ForwardRender) { effect.SetTechnique(MyEffectDecals.Technique.Model); } else { effect.SetTechnique(MyEffectDecals.Technique.ModelForward); } MyMinerGame.Static.GraphicsDevice.VertexDeclaration = MyVertexFormatDecal.VertexDeclaration; effect.Begin(); MyMinerGame.Static.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, 0, trianglesCount, vertices); effect.End(); MyPerformanceCounter.PerCameraDraw.DecalsForEntitiesInFrustum += trianglesCount; } }