示例#1
0
        unsafe static void DrawBatch(MyScreenDecalType decalType)
        {
            if (m_matrices.Count > 0)
            {
                var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * MAX_DECALS);

                var N       = (int)(Math.Min(MAX_DECALS, m_matrices.Count));
                var mapping = MyMapping.MapDiscard(decalCb);
                for (int i = 0; i < N; ++i)
                {
                    MyMatrix4x3 worldMatrix = new MyMatrix4x3();
                    worldMatrix.Matrix4x4 = m_matrices[i];

                    mapping.stream.Write(worldMatrix);
                    mapping.stream.Write(new Vector4(decalType == MyScreenDecalType.ScreenDecalBump ? 1 : 0, 0, 0, 0));
                    mapping.stream.Write(Matrix.Transpose(Matrix.Invert(m_matrices[i])));
                }
                mapping.Unmap();

                MyImmediateRC.RC.Context.DrawIndexed(36 * N, 0, 0);
            }
            m_matrices.Clear();
        }
        unsafe static void DrawBatches(MyRenderContext RC, MyStringId material, int matIndex, bool transparent)
        {
            if (m_jobs.Count == 0)
            {
                return;
            }

            var matDesc            = m_materials[material][matIndex];
            MyScreenDecalType type = matDesc.DecalType;

            if (transparent)
            {
                // Always fallback to colormap for transparent surface decals
                type = MyScreenDecalType.ColorMap;
            }

            switch (type)
            {
            case MyScreenDecalType.NormalMap:
                BindResources(RC);
                RC.SetPS(m_psNormalMap);
                RC.SetBS(MyRender11.BlendDecalNormal);
                break;

            case MyScreenDecalType.ColorMap:
                if (transparent)
                {
                    BindResourcesTransparentBillboards(RC);
                    RC.SetPS(m_psColorMapTransparent);
                }
                else
                {
                    BindResources(RC);
                    RC.SetPS(m_psColorMap);
                    RC.SetBS(MyRender11.BlendDecalColor);
                }
                break;

            case MyScreenDecalType.NormalColorMap:
                BindResources(RC);
                RC.SetPS(m_psNormalColorMap);
                RC.SetBS(MyRender11.BlendDecalNormalColor);
                break;

            case MyScreenDecalType.NormalColorExtMap:
                BindResources(RC);
                RC.SetPS(m_psNormalColorExtMap);
                RC.SetBS(MyRender11.BlendDecalNormalColorExt);
                break;

            default:
                throw new Exception("Unknown decal type");
            }

            // factor 1 makes overwriting of gbuffer color & subtracting from ao
            RC.DeviceContext.PixelShader.SetShaderResource(3, MyTextures.GetView(matDesc.AlphamaskTexture));
            RC.DeviceContext.PixelShader.SetShaderResource(4, MyTextures.GetView(matDesc.ColorMetalTexture));
            RC.DeviceContext.PixelShader.SetShaderResource(5, MyTextures.GetView(matDesc.NormalmapTexture));
            RC.DeviceContext.PixelShader.SetShaderResource(6, MyTextures.GetView(matDesc.ExtensionsTexture));

            var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * DECAL_BATCH_SIZE);

            int batchCount = m_jobs.Count / DECAL_BATCH_SIZE + 1;
            int offset     = 0;

            for (int i1 = 0; i1 < batchCount; i1++)
            {
                var mapping = MyMapping.MapDiscard(decalCb);

                int leftDecals = m_jobs.Count - offset;
                int decalCount = leftDecals > DECAL_BATCH_SIZE ? DECAL_BATCH_SIZE : leftDecals;
                for (int i2 = 0; i2 < decalCount; ++i2)
                {
                    MyDecalConstants constants = new MyDecalConstants();
                    EncodeJobConstants(i2, ref constants);
                    mapping.WriteAndPosition(ref constants);
                }

                mapping.Unmap();

                // Draw a box without buffer: 36 vertices -> 12 triangles. 2 triangles per face -> 6 faces
                MyImmediateRC.RC.DeviceContext.DrawIndexed(36 * decalCount, 0, 0);

                offset += DECAL_BATCH_SIZE;
            }
        }
示例#3
0
        // can be on another job
        internal unsafe static void Draw()
        {
            var decals = IdIndex.Values.ToArray();

            // sort visible decals by material
            Array.Sort(decals, DecalsMaterialComparer);

            ///
            // copy gbuffer with normals for read (uhoh)
            // bind copy and depth for read
            // bind gbuffer for write

            var RC = MyImmediateRC.RC;

            RC.Context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            RC.SetIB(m_IB.Buffer, m_IB.Format);
            RC.SetIL(null);
            RC.Context.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y);
            RC.SetCB(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);
            RC.BindDepthRT(
                MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.DepthReadOnly,
                MyGBuffer.Main.Get(MyGbufferSlot.GBuffer0),
                MyGBuffer.Main.Get(MyGbufferSlot.GBuffer1),
                MyGBuffer.Main.Get(MyGbufferSlot.GBuffer2));
            RC.SetVS(m_vs);
            RC.SetPS(m_ps);
            RC.SetDS(MyDepthStencilState.DepthTest);
            RC.Context.PixelShader.SetSamplers(0, MyRender11.StandardSamplers);

            RC.BindSRV(0, MyGBuffer.Main.DepthStencil.Depth);
            RC.Context.PixelShader.SetShaderResources(1, MyRender11.m_gbuffer1Copy.ShaderView);

            var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * MAX_DECALS);

            RC.SetCB(2, decalCb);

            var prevMaterial            = new MyStringId();
            MyScreenDecalType decalType = MyScreenDecalType.ScreenDecalBump;

            for (int i = 0; i < decals.Length; ++i)
            {
                var index = decals[i];

                var material = Decals.Data[index].Material;
                if (i == 0 || material != prevMaterial)
                {
                    DrawBatch(decalType);

                    var matDesc = Materials[material];

                    decalType = matDesc.DecalType;
                    // factor 1 makes overwriting of gbuffer color & subtracting from ao
                    RC.SetBS(MyRender11.BlendDecal, matDesc.DecalType == MyScreenDecalType.ScreenDecalBump ? new SharpDX.Color4(0) : SharpDX.Color4.White);
                    RC.Context.PixelShader.SetShaderResources(3, MyTextures.GetView(matDesc.AlphamaskTexture), MyTextures.GetView(matDesc.ColorMetalTexture), MyTextures.GetView(matDesc.NormalmapTexture));
                }

                var parent = MyIDTracker <MyActor> .FindByID(Decals.Data[index].ParentID);

                if (parent != null)
                {
                    var parentMatrix = parent.WorldMatrix;
                    var volumeMatrix = Decals.Data[index].LocalOBB * parentMatrix * Matrix.CreateTranslation(-MyEnvironment.CameraPosition);

                    m_matrices.Add(volumeMatrix);
                }
            }
            DrawBatch(decalType);

            RC.SetBS(null);
        }