public MyDecalsForRenderObjectsTriangleBuffer GetTrianglesBuffer(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { MyDecalsForModelsDictionaryKey key = new MyDecalsForModelsDictionaryKey(renderObject, decalTexture); MyDecalsForRenderObjectsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue)) { // Combination of model/texture was found in dictionary, so we can return in right now return(outValue); } else { if (m_triangleBuffersByKey.Count >= m_capacity) { // We are full, can't place decal on a new model/texture. Need to wait for next CheckBufferFull. return(null); } else { // This is first time we want to place decal on this model/texture, so here we allocate and initialize buffer MyDecalsForRenderObjectsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop(); m_triangleBuffersByKey.Add(key, newBuffer); m_usedTriangleBuffers.Add(newBuffer); newBuffer.Start(renderObject, decalTexture); return(newBuffer); } } }
public MyDecalsForRenderObjectsTriangleBuffer GetTrianglesBuffer(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { MyDecalsForModelsDictionaryKey key = new MyDecalsForModelsDictionaryKey(renderObject, decalTexture); MyDecalsForRenderObjectsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue)) { // Combination of model/texture was found in dictionary, so we can return in right now return outValue; } else { if (m_triangleBuffersByKey.Count >= m_capacity) { // We are full, can't place decal on a new model/texture. Need to wait for next CheckBufferFull. return null; } else { // This is first time we want to place decal on this model/texture, so here we allocate and initialize buffer MyDecalsForRenderObjectsTriangleBuffer newBuffer = m_freeTriangleBuffers.Pop(); m_triangleBuffersByKey.Add(key, newBuffer); m_usedTriangleBuffers.Add(newBuffer); newBuffer.Start(renderObject, decalTexture); return newBuffer; } } }
public void AddRenderObject(MyRenderObject renderObject, MatrixD?childToParent = null) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; MatrixD childMatrix; if (childToParent != null) { childMatrix = childToParent.Value; } else { childMatrix = renderEntity.WorldMatrix * m_invWorldMatrix; } renderEntity.WorldMatrix = childMatrix; renderObject.ParentCullObject = this; var box = renderObject.WorldAABB; renderObject.ProxyData = CulledObjects.AddProxy(ref box, renderObject, 0); EntitiesContained++; SetDirty(); }
private static void DrawVoxels(MySortedElements sortedElements, MyLodTypeEnum lod, MyRenderVoxelBatchType batchType, ref int ibChangesStats) { int index = sortedElements.GetVoxelIndex(lod, batchType); var matDict = sortedElements.Voxels[index]; if (matDict.RenderElementCount == 0) { return; } var tech = GetTechnique(batchType == MyRenderVoxelBatchType.SINGLE_MATERIAL ? MyMeshDrawTechnique.VOXEL_MAP_SINGLE : MyMeshDrawTechnique.VOXEL_MAP_MULTI); var shader = (MyEffectVoxels)tech.PrepareAndBeginShader(m_currentSetup, lod); MyPerformanceCounter.PerCameraDrawWrite.TechniqueChanges[(int)lod]++; foreach (var mat in matDict.Voxels) { var firstElement = mat.Value.FirstOrDefault(); if (firstElement == null) { continue; } // Setup material tech.SetupVoxelMaterial(shader, firstElement.VoxelBatch); MyPerformanceCounter.PerCameraDrawWrite.MaterialChanges[(int)lod]++; MyRenderObject lastRenderObject = null; VertexBuffer lastVertexBuffer = null; foreach (var renderElement in mat.Value) { if (!object.ReferenceEquals(lastVertexBuffer, renderElement.VertexBuffer)) { lastVertexBuffer = renderElement.VertexBuffer; GraphicsDevice.Indices = renderElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; } if (lastRenderObject != renderElement.RenderObject) { lastRenderObject = renderElement.RenderObject; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } } shader.End(); // Technique End }
// Add decal and all surounding triangles for model intersection internal static void AddDecal(MyRenderObject renderObject, ref MyDecalTriangle_Data triangle, int trianglesToAdd, MyDecalTexturesEnum decalTexture, Vector3D position, float lightSize, float emissivity) { IMyDecalsBuffer decalsBuffer = null; if (renderObject is MyRenderVoxelCell) { // If we get null, buffer is full so no new decals can't be placed decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(renderObject as MyRenderVoxelCell, decalTexture); } else if (renderObject is MyRenderTransformObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } if (renderObject is MyManualCullableRenderObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } // If we get null, buffer is full so no new decals can't be placed if (decalsBuffer == null) { return; } if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; decalsBuffer.Add(triangle, trianglesToAdd, position, lightSize, emissivity); } }
internal void Clear() { RenderObject = null; Material = null; IndexBuffer = null; VertexBuffer = null; InstanceBuffer = null; }
public void MoveRenderObject(MyRenderObject renderObject) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; BoundingBoxD aabb = renderEntity.WorldAABB; CulledObjects.MoveProxy(renderObject.ProxyData, ref aabb, Vector3D.Zero); SetDirty(); }
public void RemoveRenderObject(MyRenderObject renderObject) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; CulledObjects.RemoveProxy(renderObject.ProxyData); renderObject.ParentCullObject = null; renderEntity.WorldMatrix = renderEntity.WorldMatrix * WorldMatrix; renderObject.ProxyData = MyElement.PROXY_UNASSIGNED; EntitiesContained--; SetDirty(); }
// We can just erase decal triangles, because here we don't have 'free triangles stack' as voxel decals do. public void Clear(bool destroy = false) { while (m_trianglesQueue.Count > 0) { MyDecalTriangle triangle = m_trianglesQueue.Dequeue(); triangle.Close(); m_freeTriangles.Push(triangle); } if (destroy) { RenderObject = null; } }
public void ReturnTrianglesBuffer(MyRenderObject renderObject) { foreach (byte value in Enum.GetValues(typeof(MyDecalTexturesEnum))) { var key = new MyDecalsForModelsDictionaryKey(renderObject, (MyDecalTexturesEnum)value); MyDecalsForRenderObjectsTriangleBuffer outValue; if (m_triangleBuffersByKey.TryGetValue(key, out outValue)) { MyDecalsForRenderObjectsTriangleBuffer usedBuffer = outValue; m_triangleBuffersByKey.Remove(key); usedBuffer.Clear(); m_usedTriangleBuffers.Remove(usedBuffer); m_freeTriangleBuffers.Push(usedBuffer); } } }
public void AddRenderObject(MyRenderObject renderObject, MatrixD? childToParent = null) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; MatrixD childMatrix; if (childToParent != null) childMatrix = childToParent.Value; else childMatrix = renderEntity.WorldMatrix * m_invWorldMatrix; renderEntity.WorldMatrix = childMatrix; renderObject.ParentCullObject = this; var box = renderObject.WorldAABB; renderObject.ProxyData = CulledObjects.AddProxy(ref box, renderObject, 0); EntitiesContained++; SetDirty(); }
// Because this class is reused in buffers, it isn't really initialized by constructor. We make real initialization here. public void Start(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { RenderObject = renderObject; 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; } }
private static void DrawModels(MySortedElements sortedElements, MyLodTypeEnum lod, ref int ibChangesStats) { for (int i = 0; i < MySortedElements.DrawTechniqueCount; i++) { var technique = (MyMeshDrawTechnique)i; int index = sortedElements.GetModelIndex(lod, technique); var matDict = sortedElements.Models[index]; if (matDict.RenderElementCount == 0) { continue; } // Technique start var tech = GetTechnique(technique); var shader = tech.PrepareAndBeginShader(m_currentSetup, m_currentLodDrawPass); RasterizerState currentRasterizer = RasterizerState.Current; bool doubleSided = tech.GetType() == typeof(MyDrawTechniqueAlphaMasked) || tech.GetType() == typeof(MyDrawTechniqueMeshInstancedGenericMasked); if (doubleSided) { RasterizerState alphaMaskedRasterizer = new RasterizerState { CullMode = Cull.None }; alphaMaskedRasterizer.Apply(); } MyPerformanceCounter.PerCameraDrawWrite.TechniqueChanges[(int)lod]++; foreach (var mat in matDict.Models) { if (mat.Value.RenderElementCount == 0) { continue; } // Setup material tech.SetupMaterial(shader, mat.Key); MyPerformanceCounter.PerCameraDrawWrite.MaterialChanges[(int)lod]++; #if !ATI_INSTANCES foreach (var vb in mat.Value.Models) { // Set vb var firstElement = vb.Value.FirstOrDefault(); if (firstElement == null) { continue; } GraphicsDevice.Indices = firstElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, firstElement.VertexBuffer, 0, firstElement.VertexStride); GraphicsDevice.VertexDeclaration = firstElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; MyRenderObject lastRenderObject = null; int[] lastBonesSet = null; foreach (var renderElement in vb.Value) { if (renderElement.InstanceBuffer == null) { MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); } else { GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; GraphicsDevice.SetStreamSourceFrequency(0, renderElement.InstanceCount, StreamSource.IndexedData); GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.SetStreamSourceFrequency(1, 1, StreamSource.InstanceData); GraphicsDevice.SetStreamSource(1, renderElement.InstanceBuffer, renderElement.InstanceStride * renderElement.InstanceStart, renderElement.InstanceStride); } if (lastRenderObject != renderElement.RenderObject || lastBonesSet != renderElement.BonesUsed) { lastRenderObject = renderElement.RenderObject; lastBonesSet = renderElement.BonesUsed; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); if (technique == MyMeshDrawTechnique.ATMOSPHERE) { RasterizerState.CullClockwise.Apply(); BlendState.Additive.Apply(); } else if (technique == MyMeshDrawTechnique.PLANET_SURFACE) { if ((lastRenderObject as MyRenderAtmosphere).IsInside(MyRenderCamera.Position)) { RasterizerState.CullClockwise.Apply(); } } else { currentRasterizer.Apply(); BlendState.Opaque.Apply(); } shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } #else foreach (var vb in mat.Value.Models) { // Set vb var firstElement = vb.Value.FirstOrDefault(); if (firstElement == null) { continue; } GraphicsDevice.Indices = firstElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, firstElement.VertexBuffer, 0, firstElement.VertexStride); GraphicsDevice.VertexDeclaration = firstElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; MyRenderObject lastRenderObject = null; foreach (var renderElement in vb.Value) { if (renderElement.InstanceBuffer == null) { MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); } else { GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; int totalInstCount = renderElement.InstanceCount; int maxbuff = 1024; int offset = 0; while (totalInstCount > 0) { int count = totalInstCount >= maxbuff ? maxbuff : totalInstCount; totalInstCount -= count; GraphicsDevice.SetStreamSourceFrequency(0, count, StreamSource.IndexedData); GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.SetStreamSourceFrequency(1, 1, StreamSource.InstanceData); GraphicsDevice.SetStreamSource(1, renderElement.InstanceBuffer, renderElement.InstanceStride * (renderElement.InstanceStart + offset), renderElement.InstanceStride); offset += count; if (lastRenderObject != renderElement.RenderObject) { lastRenderObject = renderElement.RenderObject; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } } } #endif } } MyRender.GraphicsDevice.ResetStreamSourceFrequency(0); MyRender.GraphicsDevice.ResetStreamSourceFrequency(1); shader.End(); // Technique End if (doubleSided) { currentRasterizer.Apply(); } } } }
internal static void AddRenderObjectToDraw(MyRenderObject renderObject) { m_renderObjectsToDraw.Add(renderObject); m_renderObjectsToDebugDraw.Add(renderObject); MyRenderProxy.VisibleObjectsWrite.Add(renderObject.ID); }
public static MyRenderObject GetAnyIntersectionWithLine(MyDynamicAABBTreeD tree, ref VRageMath.LineD line, MyRenderObject ignoreObject0, MyRenderObject ignoreObject, List<MyLineSegmentOverlapResult<MyElement>> elementList) { tree.OverlapAllLineSegment(ref line, elementList); foreach (MyLineSegmentOverlapResult<MyElement> element in elementList) { MyRenderObject renderObject = ((MyRenderObject)element.Element); Debug.Assert(!renderObject.NearFlag); //Debug.Assert(renderObject.Visible); // Objects to ignore if ((renderObject == ignoreObject0) || (renderObject == ignoreObject)) continue; //Vector3? testResultEx; if (renderObject.GetIntersectionWithLine(ref line)) { return renderObject; } /* if (testResultEx != null) { Vector3 dir = line.Direction; if (Vector3.Dot((testResultEx.Value - line.From), dir) > 0) { if (ret == null) { ret = testResultEx; currentObject = renderObject; } if ((testResultEx.Value - line.From).Length() < (ret.Value - line.From).Length()) { ret = testResultEx; currentObject = renderObject; } } } */ } return null; }
internal static void UpdateRenderObject(MyRenderObject renderObject, bool sortIntoCullobjects = false) { GetRenderProfiler().StartProfilingBlock("UpdateRenderObject"); if (renderObject.ProxyData != MyElement.PROXY_UNASSIGNED) { RenderObjectUpdatesCounter++; if (sortIntoCullobjects) { GetRenderProfiler().StartProfilingBlock("RemoveRenderObject"); RemoveRenderObject(renderObject); GetRenderProfiler().EndProfilingBlock(); GetRenderProfiler().StartProfilingBlock("AddRenderObject"); AddRenderObject(renderObject, false); GetRenderProfiler().EndProfilingBlock(); } else { GetRenderProfiler().StartProfilingBlock("MoveRenderObject"); MoveRenderObject(renderObject); GetRenderProfiler().EndProfilingBlock(); } GetRenderProfiler().ProfileCustomValue("Updated objects count", RenderObjectUpdatesCounter); } GetRenderProfiler().EndProfilingBlock(); }
internal static void MoveRenderObject(MyRenderObject renderObject) { if (renderObject.ParentCullObject != null) { renderObject.ParentCullObject.MoveRenderObject(renderObject); return; } var aabb = renderObject.WorldAABB; if (renderObject is MyManualCullableRenderObject) { m_manualCullingStructure.MoveProxy(renderObject.ProxyData, ref aabb, Vector3D.Zero); } else if (renderObject is MyCullableRenderObject) { m_cullingStructure.MoveProxy(renderObject.ProxyData, ref aabb, Vector3D.Zero); } else { if (renderObject.CullObject != null) { //Cannot use move because cullobject aabb then does not fit //renderObject.CullObject.CulledObjects.MoveProxy(renderObject.ProxyData, ref aabb, Vector3.Zero); RemoveRenderObject(renderObject, false); renderObject.SetDirty(); renderObject.ProxyData = m_prunningStructure.AddProxy(ref aabb, renderObject, 0, true); renderObject.CullObject = null; } else { m_prunningStructure.MoveProxy(renderObject.ProxyData, ref aabb, Vector3D.Zero); } if (renderObject.ShadowProxyData != MyElement.PROXY_UNASSIGNED) { m_shadowPrunningStructure.MoveProxy(renderObject.ShadowProxyData, ref aabb, Vector3D.Zero); } } if (renderObject is IMyBackgroundDrawableRenderObject) { m_farObjectsPrunningStructure.MoveProxy((renderObject as IMyBackgroundDrawableRenderObject).BackgroundProxyData, ref aabb, Vector3D.Zero); } }
public static float UpdateDecalEmissivity(MyDecalTriangle decalTriangle, float alpha, MyRenderObject renderObject) { float emisivity = 0; if (decalTriangle.Emissivity > 0) { //emisivity = (float)(Math.Sin(decalTriangle.RandomOffset + decalTriangle.RandomOffset * MySandboxGame.TotalGamePlayTimeInMilliseconds / 1000.0f)) * 0.4f + 0.7f; // 2 seconds default, more emissive lit longer float stableLength = 2000 * decalTriangle.Emissivity; if ((MyRender.RenderTimeInMS - decalTriangle.RandomOffset) < stableLength) emisivity = 1; else { emisivity = (float)(500 - (MyRender.RenderTimeInMS - stableLength - decalTriangle.RandomOffset)) / 500.0f; if (emisivity < 0) emisivity = 0; } emisivity *= decalTriangle.Emissivity; if (emisivity > 0) { Color color = MyDecalsConstants.PROJECTILE_DECAL_COLOR; Vector3D position; MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject; if (transformObject != null) { position = Vector3D.Transform(decalTriangle.Position, transformObject.WorldMatrix); } else if (renderObject is MyManualCullableRenderObject) { position = Vector3D.Transform(decalTriangle.Position, (renderObject as MyManualCullableRenderObject).WorldMatrix); } else { position = decalTriangle.Position; } MyTransparentGeometry.AddPointBillboard( "DecalGlare", color * alpha, (Vector3)position, 1.5f * emisivity, 0); if (decalTriangle.Light != null) { decalTriangle.Light.Color = color; decalTriangle.Light.SetPosition(position); float range = Math.Max(3 * emisivity * alpha, 0.1f); decalTriangle.Light.Range = range; } } } return emisivity; }
public MyDecalsForModelsDictionaryKey(MyRenderObject renderObject, MyDecalTexturesEnum decalTexture) { RenderObject = renderObject; DecalTexture = decalTexture; }
internal static void AddRenderObjectFromProxy(MyRenderObject renderObject, bool rebalance = true) { AddRenderObject(renderObject, rebalance); m_renderObjects.Add(renderObject.ID, renderObject); }
public static float UpdateDecalEmissivity(MyDecalTriangle decalTriangle, float alpha, MyRenderObject renderObject) { float emisivity = 0; if (decalTriangle.Emissivity > 0) { //emisivity = (float)(Math.Sin(decalTriangle.RandomOffset + decalTriangle.RandomOffset * MySandboxGame.TotalGamePlayTimeInMilliseconds / 1000.0f)) * 0.4f + 0.7f; // 2 seconds default, more emissive lit longer float stableLength = 2000 * decalTriangle.Emissivity; if ((MyRender.RenderTimeInMS - decalTriangle.RandomOffset) < stableLength) { emisivity = 1; } else { emisivity = (float)(500 - (MyRender.RenderTimeInMS - stableLength - decalTriangle.RandomOffset)) / 500.0f; if (emisivity < 0) { emisivity = 0; } } emisivity *= decalTriangle.Emissivity; if (emisivity > 0) { Color color = MyDecalsConstants.PROJECTILE_DECAL_COLOR; Vector3D position; MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject; if (transformObject != null) { position = Vector3D.Transform(decalTriangle.Position, transformObject.WorldMatrix); } else if (renderObject is MyManualCullableRenderObject) { position = Vector3D.Transform(decalTriangle.Position, (renderObject as MyManualCullableRenderObject).WorldMatrix); } else { position = decalTriangle.Position; } MyTransparentGeometry.AddPointBillboard( "DecalGlare", color * alpha, (Vector3)position, 1.5f * emisivity, 0); if (decalTriangle.Light != null) { decalTriangle.Light.Color = color; decalTriangle.Light.SetPosition(position); float range = Math.Max(3 * emisivity * alpha, 0.1f); decalTriangle.Light.Range = range; } } } return(emisivity); }
internal static void RemoveRenderObject(MyRenderObject renderObject, bool includeShadowObject = true) { if (renderObject is MyManualCullableRenderObject) { m_manualCullingStructure.RemoveProxy(renderObject.ProxyData); renderObject.ProxyData = MyElement.PROXY_UNASSIGNED; MyManualCullableRenderObject cullableObject = renderObject as MyManualCullableRenderObject; //return query to pool cullableObject.UnloadContent(); if (includeShadowObject) RemoveShadowRenderObject(renderObject); return; } if (renderObject.ParentCullObject != null) { renderObject.ParentCullObject.RemoveRenderObject(renderObject); return; } if (m_nearObjects.Contains(renderObject)) { m_nearObjects.Remove(renderObject); } else if (renderObject.ProxyData != MyElement.PROXY_UNASSIGNED) { if (renderObject is MyCullableRenderObject) { MyCullableRenderObject cullableObject = renderObject as MyCullableRenderObject; //Move all existing included objects to render prunning structure var aabb = BoundingBoxD.CreateInvalid(); cullableObject.CulledObjects.OverlapAllBoundingBox(ref aabb, m_renderObjectListForDraw); foreach (MyRenderObject ro in m_renderObjectListForDraw) { Debug.Assert(!ro.NearFlag); cullableObject.CulledObjects.RemoveProxy(ro.ProxyData); var roAABB = ro.WorldAABB; ro.ProxyData = m_prunningStructure.AddProxy(ref roAABB, ro, 0); ro.CullObject = null; } //destroy cull object m_cullingStructure.RemoveProxy(cullableObject.ProxyData); cullableObject.ProxyData = MyElement.PROXY_UNASSIGNED; //return query to pool cullableObject.UnloadContent(); } else { if (renderObject.CullObject != null) { renderObject.CullObject.CulledObjects.RemoveProxy(renderObject.ProxyData); renderObject.CullObject.EntitiesContained--; renderObject.ProxyData = MyElement.PROXY_UNASSIGNED; if (renderObject.CullObject.EntitiesContained == 0) { RemoveRenderObject(renderObject.CullObject, false); m_renderObjects.Remove(renderObject.CullObject.ID); renderObject.CullObject.UnloadContent(); } renderObject.CullObject = null; } else { if (renderObject is MyRenderAtmosphere) { m_atmospherePurunnigStructure.RemoveProxy(renderObject.ProxyData); } else { m_prunningStructure.RemoveProxy(renderObject.ProxyData); } if (renderObject is IMyBackgroundDrawableRenderObject) { m_farObjectsPrunningStructure.RemoveProxy((renderObject as IMyBackgroundDrawableRenderObject).BackgroundProxyData); (renderObject as IMyBackgroundDrawableRenderObject).BackgroundProxyData = MyElement.PROXY_UNASSIGNED; } renderObject.ProxyData = MyElement.PROXY_UNASSIGNED; } } } if (includeShadowObject) RemoveShadowRenderObject(renderObject); }
internal static void RemoveShadowRenderObject(MyRenderObject renderObject) { if (renderObject.ShadowProxyData != MyElement.PROXY_UNASSIGNED) { m_shadowPrunningStructure.RemoveProxy(renderObject.ShadowProxyData); renderObject.ShadowProxyData = MyElement.PROXY_UNASSIGNED; } }
internal static void AddRenderObject(MyRenderObject renderObject, bool rebalance = true) { if (renderObject is MyManualCullableRenderObject) { var boundingBox = renderObject.WorldAABB; renderObject.ProxyData = m_manualCullingStructure.AddProxy(ref boundingBox, renderObject, 0, rebalance); MyManualCullableRenderObject cullableObject = renderObject as MyManualCullableRenderObject; System.Diagnostics.Debug.Assert(cullableObject.GetQuery(MyOcclusionQueryID.MAIN_RENDER).OcclusionQuery == null); cullableObject.LoadContent(); cullableObject.RenderCounter = m_renderObjectIncrementalCounter % OCCLUSION_INTERVAL; AddShadowRenderObject(renderObject, rebalance); return; } if (renderObject.NearFlag && !m_nearObjects.Contains(renderObject)) { m_nearObjects.Add(renderObject); } else if (renderObject.ProxyData == MyElement.PROXY_UNASSIGNED) { var aabb = renderObject.WorldAABB; renderObject.SetDirty(); if (renderObject is MyCullableRenderObject) { MyCullableRenderObject cullableObject = renderObject as MyCullableRenderObject; renderObject.ProxyData = m_cullingStructure.AddProxy(ref aabb, renderObject, 0); //Move all existing included proxies to cull objects m_prunningStructure.OverlapAllBoundingBox(ref aabb, m_renderObjectListForDraw); foreach (MyRenderObject ro in m_renderObjectListForDraw) { System.Diagnostics.Debug.Assert(!(ro is MyCullableRenderObject)); Debug.Assert(!ro.NearFlag); var roAABB = ro.WorldAABB; if (ro.CullObject == null && aabb.Contains(roAABB) == VRageMath.ContainmentType.Contains) { RemoveRenderObject(ro, false); ro.ProxyData = cullableObject.CulledObjects.AddProxy(ref roAABB, ro, 0); cullableObject.EntitiesContained++; ro.CullObject = cullableObject; } } System.Diagnostics.Debug.Assert(cullableObject.GetQuery(MyOcclusionQueryID.MAIN_RENDER).OcclusionQuery == null); cullableObject.LoadContent(); cullableObject.RenderCounter = m_renderObjectIncrementalCounter % OCCLUSION_INTERVAL; m_renderObjectIncrementalCounter++; } else { GetRenderProfiler().StartProfilingBlock("Overlap"); //find potential cull objects and move render object to it if it is fully included m_cullingStructure.OverlapAllBoundingBox(ref aabb, m_cullObjectListForDraw); GetRenderProfiler().EndProfilingBlock(); bool contained = false; MyCullableRenderObject mostSuitableCO = null; double minVolume = double.MaxValue; foreach (MyCullableRenderObject co in m_cullObjectListForDraw) { if (co.WorldAABB.Contains(aabb) == VRageMath.ContainmentType.Contains) { var volume = co.WorldAABB.Volume; if (volume < minVolume) { minVolume = volume; mostSuitableCO = co; } } } if (renderObject is MyRenderAtmosphere) { renderObject.ProxyData = m_atmospherePurunnigStructure.AddProxy(ref aabb, renderObject, 0, rebalance); } else { if (mostSuitableCO != null) { GetRenderProfiler().StartProfilingBlock("AddProxy"); renderObject.ProxyData = mostSuitableCO.CulledObjects.AddProxy(ref aabb, renderObject, 0, rebalance); GetRenderProfiler().EndProfilingBlock(); mostSuitableCO.EntitiesContained++; renderObject.CullObject = mostSuitableCO; contained = true; } if (!contained) { renderObject.ProxyData = m_prunningStructure.AddProxy(ref aabb, renderObject, 0, rebalance); renderObject.CullObject = null; } if (renderObject.CastShadows) { AddShadowRenderObject(renderObject, rebalance); } } if (renderObject is IMyBackgroundDrawableRenderObject) { (renderObject as IMyBackgroundDrawableRenderObject).BackgroundProxyData = m_farObjectsPrunningStructure.AddProxy(ref aabb, renderObject, 0, rebalance); } } } }
// Add decal and all surounding triangles for model intersection internal static void AddDecal(MyRenderObject renderObject, ref MyDecalTriangle_Data triangle, int trianglesToAdd, MyDecalTexturesEnum decalTexture, Vector3D position, float lightSize, float emissivity) { IMyDecalsBuffer decalsBuffer = null; if (renderObject is MyRenderVoxelCell) // If we get null, buffer is full so no new decals can't be placed decalsBuffer = m_decalsForVoxels.GetTrianglesBuffer(renderObject as MyRenderVoxelCell, decalTexture); else if (renderObject is MyRenderTransformObject) decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); if (renderObject is MyManualCullableRenderObject) { decalsBuffer = m_decalsForModels.GetTrianglesBuffer(renderObject, decalTexture); } // If we get null, buffer is full so no new decals can't be placed if (decalsBuffer == null) return; if (decalsBuffer.CanAddTriangles(trianglesToAdd)) { Vector3 normalSum = Vector3.Zero; decalsBuffer.Add(triangle, trianglesToAdd, position, lightSize, emissivity); } }
private static void DrawVoxels(MySortedElements sortedElements, MyLodTypeEnum lod, MyRenderVoxelBatchType batchType, ref int ibChangesStats) { int index = sortedElements.GetVoxelIndex(lod, batchType); var matDict = sortedElements.Voxels[index]; if (matDict.RenderElementCount == 0) { return; } var tech = GetTechnique(batchType == MyRenderVoxelBatchType.SINGLE_MATERIAL ? MyMeshDrawTechnique.VOXEL_MAP_SINGLE : MyMeshDrawTechnique.VOXEL_MAP_MULTI); var shader = (MyEffectVoxels)tech.PrepareAndBeginShader(m_currentSetup, lod); MyPerformanceCounter.PerCameraDrawWrite.TechniqueChanges[(int)lod]++; if (lod == MyLodTypeEnum.LOD_BACKGROUND) { shader.SetAmbientMinimumAndIntensity(new Vector4(AmbientColor * AmbientMultiplier, EnvAmbientIntensity)); shader.SetSunDirection(m_sun.Direction); shader.SetSunColorAndIntensity(new Vector3(m_sun.Color.X, m_sun.Color.Y, m_sun.Color.Z), m_sun.Intensity); shader.SetBacklightColorAndIntensity(new Vector3(m_sun.BackColor.X, m_sun.BackColor.Y, m_sun.BackColor.Z), m_sun.BackIntensity); var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.VolumetricFog) as MyPostProcessVolumetricFog; shader.EnableFog(postProcess.Enabled); shader.SetSunSpecularColor(m_sun.SpecularColor); } foreach (var mat in matDict.Voxels) { var firstElement = mat.Value.FirstOrDefault(); if (firstElement == null) { continue; } // Setup material tech.SetupVoxelMaterial(shader, firstElement.VoxelBatch); MyPerformanceCounter.PerCameraDrawWrite.MaterialChanges[(int)lod]++; MyRenderObject lastRenderObject = null; VertexBuffer lastVertexBuffer = null; foreach (var renderElement in mat.Value) { if (!object.ReferenceEquals(lastVertexBuffer, renderElement.VertexBuffer)) { lastVertexBuffer = renderElement.VertexBuffer; GraphicsDevice.Indices = renderElement.IndexBuffer; GraphicsDevice.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); GraphicsDevice.VertexDeclaration = renderElement.VertexDeclaration; MyPerformanceCounter.PerCameraDrawWrite.VertexBufferChanges[(int)lod]++; ibChangesStats++; } if (lastRenderObject != renderElement.RenderObject) { lastRenderObject = renderElement.RenderObject; MyPerformanceCounter.PerCameraDrawWrite.EntityChanges[(int)lod]++; tech.SetupEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } GraphicsDevice.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDrawWrite.TotalDrawCalls++; } } shader.End(); // Technique End }
internal static void AddShadowRenderObject(MyRenderObject renderObject, bool rebalance = true) { if (renderObject.ShadowProxyData != MyElement.PROXY_UNASSIGNED) RemoveShadowRenderObject(renderObject); if (renderObject.ShadowProxyData == MyElement.PROXY_UNASSIGNED && renderObject.CastShadows) { var aabb = renderObject.WorldAABB; renderObject.SetDirty(); renderObject.ShadowProxyData = m_shadowPrunningStructure.AddProxy(ref aabb, renderObject, 0, rebalance); } }