Esempio n. 1
0
        private static void DrawNormalFlare(Vector3D position, ref Data flare, Vector3 L, float distance)
        {
            if (flare.Query == null)
            {
                return;
            }

            flare.Query.Position  = position;
            flare.Query.Size      = flare.Desc.QuerySize;
            flare.Query.FreqMinMs = flare.Desc.QueryFreqMinMs;
            flare.Query.FreqRndMs = flare.Desc.QueryFreqRndMs;
            flare.Query.Visible   = true;

            var intensity   = flare.Desc.Intensity;
            var maxDistance = flare.Desc.MaxDistance;

            float alpha = flare.Query.Result * flare.Query.Result * intensity;


            const float minFlareRadius = 0.2f;
            const float maxFlareRadius = 10;
            float       radius         = MathHelper.Clamp(flare.Desc.Range * 20, minFlareRadius, maxFlareRadius);

            float drawingRadius = radius * flare.Desc.Size;

            if (flare.Desc.Type == Lights.MyGlareTypeEnum.Directional)
            {
                float dot = Vector3.Dot(L, flare.DirectionWorld);
                alpha *= dot;
            }

            if (alpha <= MyMathConstants.EPSILON)
            {
                return;
            }

            if (distance > maxDistance * .5f)
            {
                // distance falloff
                float falloff = (distance - .5f * maxDistance) / (.5f * maxDistance);
                falloff        = (float)Math.Max(0, 1 - falloff);
                drawingRadius *= falloff;
                alpha         *= falloff;
            }

            if (drawingRadius <= float.Epsilon)
            {
                return;
            }

            var color = flare.Desc.Color;
            //color.A = 0;

            var material = MyTransparentMaterials.GetMaterial(flare.Desc.Material.ToString());

            MyBillboardsHelper.AddBillboardOriented(flare.Desc.Material.ToString(),
                                                    color * alpha, position, MyRender11.Environment.Matrices.InvView.Left, MyRender11.Environment.Matrices.InvView.Up, drawingRadius,
                                                    MyBillboard.BlenType.AdditiveTop);
        }
Esempio n. 2
0
        internal static void CreateBillboard(VRageRender.MyBillboard billboard, ref MyQuadD quad, string material, ref Color color, ref Vector3D origin,
                                             float softParticleDistanceScale = 1.0f, string blendMaterial = "Test", float textureBlendRatio = 0, Vector2 uvOffset = new Vector2(),
                                             bool near = false, bool lowres = false, float reflectivity = 0)
        {
            Debug.Assert(material != null);
            Debug.Assert(blendMaterial != null);

            if (string.IsNullOrEmpty(material) || !MyTransparentMaterials.ContainsMaterial(material))
            {
                material = "ErrorMaterial";
                color    = Vector4.One;
            }

            billboard.Material          = material;
            billboard.BlendMaterial     = blendMaterial;
            billboard.BlendTextureRatio = textureBlendRatio;

            quad.Point0.AssertIsValid();
            quad.Point1.AssertIsValid();
            quad.Point2.AssertIsValid();
            quad.Point3.AssertIsValid();


            //  Billboard vertexes
            billboard.Position0 = quad.Point0;
            billboard.Position1 = quad.Point1;
            billboard.Position2 = quad.Point2;
            billboard.Position3 = quad.Point3;

            billboard.UVOffset = uvOffset;
            billboard.UVSize   = Vector2.One;

            //  Distance for sorting
            //  IMPORTANT: Must be calculated before we do color and alpha misting, because we need distance there
            billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyRender11.Environment.Matrices.CameraPosition, origin);

            //  Color
            billboard.Color          = color;
            billboard.Reflectivity   = reflectivity;
            billboard.ColorIntensity = 1;

            billboard.Near     = near;
            billboard.Lowres   = lowres;
            billboard.ParentID = -1;

            //  Alpha depends on distance to camera. Very close bilboards are more transparent, so player won't see billboard errors or rotating billboards
            var mat = MyTransparentMaterials.GetMaterial(billboard.Material);

            if (mat.AlphaMistingEnable)
            {
                billboard.Color *= MathHelper.Clamp(((float)Math.Sqrt(billboard.DistanceSquared) - mat.AlphaMistingStart) / (mat.AlphaMistingEnd - mat.AlphaMistingStart), 0, 1);
            }

            billboard.Color *= mat.Color;
            billboard.SoftParticleDistanceScale = softParticleDistanceScale;

            billboard.ContainedBillboards.Clear();
        }
Esempio n. 3
0
        protected unsafe sealed override void RecordCommandsInternal(MyRenderableProxy proxy)
        {
            if (proxy.Material.Info.GeometryTextureRef.IsUsed)
            {
                MyRenderProxy.Fail(String.Format("Ensure all glass materials for model '{0}' are dynamic materials inside Environment.sbc", proxy.Mesh.Info.Name));
                return;
            }

            MyTransparentMaterial material;

            if (!MyTransparentMaterials.TryGetMaterial(proxy.Material.Info.Name.String, out material))
            {
                MyRenderProxy.Fail(String.Format("Missing transparent material '{0}'", proxy.Material.Info.Name));
                return;
            }

            Stats.Draws++;

            MyRenderUtils.BindShaderBundle(RC, proxy.Shaders);

            SetProxyConstants(proxy);
            BindProxyGeometry(proxy, RC);

            ISrvBindable texture = MyManagers.FileTextures.GetTexture(material.Texture, MyFileTextureEnum.GUI, true);

            RC.PixelShader.SetSrv(0, texture);

            StaticGlassConstants glassConstants = new StaticGlassConstants();

            var glassCB = MyCommon.GetObjectCB(sizeof(StaticGlassConstants));

            RC.PixelShader.SetConstantBuffer(2, glassCB);
            var mapping = MyMapping.MapDiscard(glassCB);

            glassConstants.Color      = material.Color;
            glassConstants.Reflective = material.Reflectivity;
            mapping.WriteAndPosition(ref glassConstants);

            mapping.Unmap();

            var submesh = proxy.DrawSubmesh;

            if (proxy.InstanceCount == 0)
            {
                RC.DrawIndexed(submesh.IndexCount, submesh.StartIndex, submesh.BaseVertex);
                ++Stats.Instances;
                Stats.Triangles += submesh.IndexCount / 3;
            }
            else
            {
                RC.DrawIndexedInstanced(submesh.IndexCount, proxy.InstanceCount, submesh.StartIndex, submesh.BaseVertex, proxy.StartInstance);
                Stats.Instances += proxy.InstanceCount;
                Stats.Triangles += proxy.InstanceCount * submesh.IndexCount / 3;
            }
        }
Esempio n. 4
0
        static void PreGatherBillboard(MyBillboard billboard)
        {
            var material = MyTransparentMaterials.GetMaterial(billboard.Material);

            if (material.NeedSort)
            {
                m_sortedCount++;
            }
            else
            {
                m_unsortedCount++;
            }
        }
Esempio n. 5
0
        private static void DrawNormalFlare(Vector3D position, ref MyFlareDesc flare, Vector3 L, float distance)
        {
            //if (m_occlusionRatio <= MyMathConstants.EPSILON)
            //    return;

            var intensity   = flare.Intensity;
            var maxDistance = flare.MaxDistance;

            //float alpha = m_occlusionRatio * intensity;
            float alpha = intensity;


            const float minFlareRadius = 0.2f;
            const float maxFlareRadius = 10;
            float       radius         = MathHelper.Clamp(flare.Range * 20, minFlareRadius, maxFlareRadius);

            float drawingRadius = radius * flare.Size;

            if (flare.Type == Lights.MyGlareTypeEnum.Directional)
            {
                float dot = Vector3.Dot(L, flare.Direction);
                alpha *= dot;
            }

            if (alpha <= MyMathConstants.EPSILON)
            {
                return;
            }

            if (distance > maxDistance * .5f)
            {
                // distance falloff
                float falloff = (distance - .5f * maxDistance) / (.5f * maxDistance);
                falloff        = (float)Math.Max(0, 1 - falloff);
                drawingRadius *= falloff;
                alpha         *= falloff;
            }

            if (drawingRadius <= float.Epsilon)
            {
                return;
            }

            var color = flare.Color;
            //color.A = 0;

            var material = MyTransparentMaterials.GetMaterial(flare.Material.ToString());

            MyBillboardsHelper.AddBillboardOriented(flare.Material.ToString(),
                                                    color * alpha, position, MyRender11.Environment.Matrices.InvView.Left, MyRender11.Environment.Matrices.InvView.Up, drawingRadius);
        }
Esempio n. 6
0
        static void PreGatherBillboard(MyBillboard billboard)
        {
            var material = MyTransparentMaterials.GetMaterial(billboard.Material);

            if (material.NeedSort)
            {
                m_sortedCount++;
            }
            else
            {
                m_unsortedCount++;
            }

            if (billboard.Window && MyScreenDecals.HasEntityDecals((uint)billboard.ParentID))
            {
                m_windowCount++;
            }
        }
        static void PreGatherList(List <MyBillboard> list)
        {
            for (int i = 0; i < list.Count; i++)
            {
                var billboard = list[i];

                if (billboard.ContainedBillboards.Count == 0 && billboard.Material != null)
                {
                    var material = MyTransparentMaterials.GetMaterial(billboard.Material);
                    m_sortedNum += material.NeedSort ? 1 : 0;
                }

                for (int j = 0; j < billboard.ContainedBillboards.Count; j++)
                {
                    var material = MyTransparentMaterials.GetMaterial(billboard.ContainedBillboards[j].Material);
                    m_sortedNum += material.NeedSort ? 1 : 0;
                }
            }
        }
        static void GatherList(List <MyBillboard> list)
        {
            for (int i = 0; i < list.Count; i++)
            {
                var billboard = list[i];

                if (billboard.ContainedBillboards.Count == 0 && billboard.Material != null)
                {
                    var material = MyTransparentMaterials.GetMaterial(billboard.Material);
                    if (material.Reflectivity > 0)
                    {
                    }
                    if (material.NeedSort)
                    {
                        m_sortBuffer[m_sorted++] = billboard;
                    }
                    else
                    {
                        m_sortBuffer[m_sortedNum + m_unsorted++] = billboard;
                    }
                }

                for (int j = 0; j < billboard.ContainedBillboards.Count; j++)
                {
                    if (billboard.ContainedBillboards[j].Material != null)
                    {
                        var material = MyTransparentMaterials.GetMaterial(billboard.ContainedBillboards[j].Material);

                        if (material.NeedSort)
                        {
                            m_sortBuffer[m_sorted++] = billboard.ContainedBillboards[j];
                        }
                        else
                        {
                            m_sortBuffer[m_sortedNum + m_unsorted++] = billboard.ContainedBillboards[j];
                        }
                    }
                }
            }
        }
Esempio n. 9
0
        static void GatherList(List <MyBillboard> list, ref int sortedIndex, ref int unsortedIndex)
        {
            for (int i = 0; i < list.Count; i++)
            {
                var billboard = list[i];

                if (billboard.ContainedBillboards.Count == 0 && billboard.Material != null)
                {
                    var material = MyTransparentMaterials.GetMaterial(billboard.Material);
                    if (material.NeedSort)
                    {
                        m_sortedBuffer[sortedIndex++] = billboard;
                    }
                    else
                    {
                        m_sortedBuffer[m_sortedCount + unsortedIndex++] = billboard;
                    }
                }

                for (int j = 0; j < billboard.ContainedBillboards.Count; j++)
                {
                    if (billboard.ContainedBillboards[j].Material != null)
                    {
                        var material = MyTransparentMaterials.GetMaterial(billboard.ContainedBillboards[j].Material);
                        if (material.NeedSort)
                        {
                            m_sortedBuffer[sortedIndex++] = billboard.ContainedBillboards[j];
                        }
                        else
                        {
                            m_sortedBuffer[m_sortedCount + unsortedIndex++] = billboard.ContainedBillboards[j];
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        static bool GatherInternal(Func <MyBillboard, bool> handleWindow)
        {
            m_batches.Clear();

            // counting sorted billboards
            m_sortedCount   = 0;
            m_unsortedCount = 0;
            m_windowCount   = 0;
            PreGatherList(MyRenderProxy.BillboardsRead);
            PreGatherList(m_billboardsOnce);

            if (BillboardCount == 0)
            {
                return(false);
            }

            ResizeStorage();

            int sortedIndex   = 0;
            int unsortedIndex = 0;

            GatherList(MyRenderProxy.BillboardsRead, ref sortedIndex, ref unsortedIndex);
            GatherList(m_billboardsOnce, ref sortedIndex, ref unsortedIndex);

            Array.Sort(m_sortedBuffer, 0, m_sortedCount);

            int                   i             = 0;
            bool                  resetBindings = false;
            int                   windowidx     = 0;
            var                   N             = BillboardCountSafe;
            int                   currentOffset = 0;
            ISrvBindable          prevTex       = null;
            ISrvBindable          batchTex      = null;
            MyTransparentMaterial prevMaterial  = null;

            while (true)
            {
                if (i == N)
                {
                    AddBatch(N, currentOffset, prevTex, prevMaterial);
                    break;
                }

                MyBillboard           billboard = m_sortedBuffer[i];
                MyTransparentMaterial material  = MyTransparentMaterials.GetMaterial(billboard.Material);
                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);
                    batchTex = atlasItem.Texture;
                }
                else
                {
                    MyFileTextureManager texManager = MyManagers.FileTextures;
                    switch (material.TextureType)
                    {
                    case MyTransparentMaterialTextureType.FileTexture:
                        batchTex = texManager.GetTexture(material.Texture, MyFileTextureEnum.GUI, true);
                        break;

                    case MyTransparentMaterialTextureType.RenderTarget:
                        batchTex      = MyRender11.DrawSpritesOffscreen(material.Name, material.TargetSize.X, material.TargetSize.Y);
                        resetBindings = true;
                        break;

                    default:
                        throw new Exception();
                    }
                }

                bool closeBatch = i > 0 && (batchTex != prevTex || i == m_sortedCount);
                if (closeBatch)
                {
                    AddBatch(i, currentOffset, prevTex, prevMaterial);
                    currentOffset = i;
                }

                var billboardData     = new MyBillboardData();
                var billboardVertices = new MyBillboardVertexData();

                billboardData.CustomProjectionID = billboard.CustomViewProjection;
                billboardData.Color                     = billboard.Color;
                billboardData.Color.X                  *= billboard.ColorIntensity;
                billboardData.Color.Y                  *= billboard.ColorIntensity;
                billboardData.Color.Z                  *= billboard.ColorIntensity;
                billboardData.AlphaCutout               = billboard.AlphaCutout;
                billboardData.AlphaSaturation           = material.AlphaSaturation;
                billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale;

                billboardData.Reflective = billboard.Reflectivity;
                Vector3D pos0 = billboard.Position0;
                Vector3D pos1 = billboard.Position1;
                Vector3D pos2 = billboard.Position2;
                Vector3D pos3 = billboard.Position3;

                if (billboard.ParentID != -1)
                {
                    if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null)
                    {
                        var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix;

                        Vector3D.Transform(ref pos0, ref matrix, out pos0);
                        Vector3D.Transform(ref pos1, ref matrix, out pos1);
                        Vector3D.Transform(ref pos2, ref matrix, out pos2);
                        Vector3D.Transform(ref pos3, ref matrix, out pos3);
                    }
                }

                MyEnvironmentMatrices envMatrices = MyRender11.Environment.Matrices;
                if (MyStereoRender.Enable)
                {
                    if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesLeftEye;
                    }
                    else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesRightEye;
                    }
                }

                if (billboard.CustomViewProjection != -1)
                {
                    var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection];

                    //pos0 -= envMatrices.CameraPosition;
                    //pos1 -= envMatrices.CameraPosition;
                    //pos2 -= envMatrices.CameraPosition;
                    //pos3 -= envMatrices.CameraPosition;
                }
                else
                {
                    pos0 -= envMatrices.CameraPosition;
                    pos1 -= envMatrices.CameraPosition;
                    pos2 -= envMatrices.CameraPosition;
                    pos3 -= envMatrices.CameraPosition;
                }

                var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0);
                normal.Normalize();

                billboardData.Normal = normal;

                billboardVertices.V0.Position = pos0;
                billboardVertices.V1.Position = pos1;
                billboardVertices.V2.Position = pos2;
                billboardVertices.V3.Position = pos3;

                var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);
                var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);

                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);

                    uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                }

                billboardVertices.V0.Texcoord = new HalfVector2(uv0);
                billboardVertices.V1.Texcoord = new HalfVector2(uv1);
                billboardVertices.V2.Texcoord = new HalfVector2(uv2);
                billboardVertices.V3.Texcoord = new HalfVector2(uv3);

                pos0.AssertIsValid();
                pos1.AssertIsValid();
                pos2.AssertIsValid();
                pos3.AssertIsValid();


                MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard;
                if (triBillboard != null)
                {
                    billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer

                    billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0);
                    billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1);
                    billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2);

                    billboardData.Normal = triBillboard.Normal0;
                }

                m_arrayDataBillboards.Data[i]   = billboardData;
                m_arrayDataBillboards.Vertex[i] = billboardVertices;

                if (billboard.Window && handleWindow(billboard))
                {
                    m_sorteWindowIndices[windowidx] = i;
                    windowidx++;
                }

                prevTex      = batchTex;
                prevMaterial = material;
                i++;
            }

            // Sort windows data from closer to farest
            int windowCount = WindowCountSafe;

            Array.Sort(m_sorteWindowIndices, 0, windowCount, BillboardComparer);
            for (int it = 0; it < windowCount; it++)
            {
                m_arrayDataWindows.Data[it]   = m_arrayDataBillboards.Data[m_sorteWindowIndices[it]];
                m_arrayDataWindows.Vertex[it] = m_arrayDataBillboards.Vertex[m_sorteWindowIndices[it]];
            }

            return(resetBindings);
        }
        static void Gather()
        {
            // counting sorted billboards
            m_batches.Clear();
            m_sortedNum = 0;

            PreGatherList(MyRenderProxy.BillboardsRead);
            PreGatherList(m_billboardsOnce);

            m_sortedBillboardsNum = m_sortedNum;

            m_unsorted = 0;
            m_sorted   = 0;

            GatherList(MyRenderProxy.BillboardsRead);
            GatherList(m_billboardsOnce);

            Array.Sort(m_sortBuffer, 0, m_sortedNum);
            //Array.Reverse(m_sortBuffer, 0, m_sortedNum);
            //Array.Sort(m_sortBuffer, m_sortedNum, m_unsorted);

            var N = m_sorted + m_unsorted;

            var batch = new MyBillboardBatch();
            //MyAssetTexture prevTexture = null;
            var prevTexId     = TexId.NULL;
            int currentOffset = 0;

            if (N > 0)
            {
                var material = MyTransparentMaterials.GetMaterial(m_sortBuffer[0].Material);

                if (material.UseAtlas)
                {
                    var item = m_atlasedTextures[material.Texture];
                    prevTexId = item.TextureId;
                }
                else
                {
                    PreloadTexture(material.Texture);
                    //prevTexture = MyTextureManager.GetTextureFast(material.Texture);
                    prevTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true);
                }
            }

            TexId batchTexId = TexId.NULL;
            MyTransparentMaterial prevMaterial = null;

            for (int i = 0; i < N; i++)
            {
                var billboard = m_sortBuffer[i];
                var material  = MyTransparentMaterials.GetMaterial(billboard.Material);

                var billboardData = new MyBillboardData();

                billboardData.CustomProjectionID = billboard.CustomViewProjection;
                billboardData.Color = billboard.Color;
                if (material.UseAtlas)
                {
                    var atlasItem = m_atlasedTextures[material.Texture];
                    //billboardData.UvModifiers = new HalfVector4(atlasItem.UvOffsetScale);
                    batchTexId = atlasItem.TextureId;
                }
                else
                {
                    batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true);
                }

                billboardData.Reflective = billboard.Reflectivity;
                Vector3D pos0 = billboard.Position0;
                Vector3D pos1 = billboard.Position1;
                Vector3D pos2 = billboard.Position2;
                Vector3D pos3 = billboard.Position3;

                if (billboard.ParentID != -1)
                {
                    if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null)
                    {
                        var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix;

                        Vector3D.Transform(ref pos0, ref matrix, out pos0);
                        Vector3D.Transform(ref pos1, ref matrix, out pos1);
                        Vector3D.Transform(ref pos2, ref matrix, out pos2);
                        Vector3D.Transform(ref pos3, ref matrix, out pos3);
                    }
                }

                if (billboard.CustomViewProjection != -1)
                {
                    var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection];

                    //pos0 -= MyEnvironment.CameraPosition;
                    //pos1 -= MyEnvironment.CameraPosition;
                    //pos2 -= MyEnvironment.CameraPosition;
                    //pos3 -= MyEnvironment.CameraPosition;
                }
                else
                {
                    pos0 -= MyEnvironment.CameraPosition;
                    pos1 -= MyEnvironment.CameraPosition;
                    pos2 -= MyEnvironment.CameraPosition;
                    pos3 -= MyEnvironment.CameraPosition;
                }

                var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0);
                normal.Normalize();

                billboardData.Normal = normal;

                m_vertexData[i * 4 + 0].Position = pos0;
                m_vertexData[i * 4 + 1].Position = pos1;
                m_vertexData[i * 4 + 2].Position = pos2;
                m_vertexData[i * 4 + 3].Position = pos3;

                var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y);
                var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y);

                if (material.UseAtlas)
                {
                    var atlasItem = m_atlasedTextures[material.Texture];

                    uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                }

                m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(uv0);
                m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(uv1);
                m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(uv2);
                m_vertexData[i * 4 + 3].Texcoord = new HalfVector2(uv3);

                pos0.AssertIsValid();
                pos1.AssertIsValid();
                pos2.AssertIsValid();
                pos3.AssertIsValid();


                MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard;
                if (triBillboard != null)
                {
                    m_vertexData[i * 4 + 3].Position = pos2; // second triangle will die in rasterizer

                    m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(triBillboard.UV0);
                    m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(triBillboard.UV1);
                    m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(triBillboard.UV2);

                    billboardData.Normal = triBillboard.Normal0; // pew pew pew :O
                }

                m_billboardData[i] = billboardData;

                bool closeBatch = (batchTexId != prevTexId) || ((i == m_sortedNum) && (i > 0));

                if (closeBatch)
                {
                    batch = new MyBillboardBatch();

                    batch.Offset  = currentOffset;
                    batch.Num     = i - currentOffset;
                    batch.Texture = prevTexId != TexId.NULL ? MyTextures.Views[prevTexId.Index] : null;

                    batch.Lit = prevMaterial.CanBeAffectedByOtherLights;

                    m_batches.Add(batch);
                    currentOffset = i;
                }

                prevTexId    = batchTexId;
                prevMaterial = material;
            }

            if (N > 0)
            {
                batch         = new MyBillboardBatch();
                batch.Offset  = currentOffset;
                batch.Num     = N - currentOffset;
                batch.Texture = prevTexId != TexId.NULL ? MyTextures.GetView(prevTexId) : null;

                batch.Lit = prevMaterial.CanBeAffectedByOtherLights;

                m_batches.Add(batch);
            }
        }
Esempio n. 12
0
 public override void DeserializeValue(XmlReader reader, out object value)
 {
     base.DeserializeValue(reader, out value);
     value = MyTransparentMaterials.GetMaterial((string)value);
 }
Esempio n. 13
0
        static bool GatherInternal()
        {
            m_batches.Clear();

            // counting sorted billboards
            ClearBucketCounts();
            PreGatherList(MyRenderProxy.BillboardsRead);
            PreGatherList(m_billboardsOnce);

            int billboardCount = 0;

            for (int j = 0; j < BUCKETS_COUNT; j++)
            {
                billboardCount += m_bucketCounts[j];
            }
            if (billboardCount == 0)
            {
                return(false);
            }

            m_billboardCountSafe = billboardCount > MAX_BILLBOARDS_SIZE ? MAX_BILLBOARDS_SIZE : billboardCount;

            InitGatherList(billboardCount, m_billboardCountSafe);
            InitBucketIndices();

            GatherList(MyRenderProxy.BillboardsRead);
            GatherList(m_billboardsOnce);

            InitBucketIndices();

            int i;

            for (i = 0; i < BUCKETS_COUNT; i++)
            {
                Array.Sort(m_tempBuffer, m_bucketIndices[i], m_bucketCounts[i]);
            }

            bool                  resetBindings = false;
            int                   currentOffset = 0;
            ISrvBindable          prevTex       = null;
            MyTransparentMaterial prevMaterial  = null;

            for (i = 0; i < m_billboardCountSafe; i++)
            {
                MyBillboard           billboard = m_tempBuffer[i];
                MyTransparentMaterial material  = MyTransparentMaterials.GetMaterial(billboard.Material);
                ISrvBindable          batchTex  = null;
                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);
                    batchTex = atlasItem.Texture;
                }
                else
                {
                    MyFileTextureManager texManager = MyManagers.FileTextures;
                    switch (material.TextureType)
                    {
                    case MyTransparentMaterialTextureType.FileTexture:
                        if (material.Texture == null || !m_fileTextures.TryGetValue(material.Texture, out batchTex))
                        {
                            batchTex = texManager.GetTexture(material.Texture, MyFileTextureEnum.GUI, true);
                            if (material.Texture != null)
                            {
                                m_fileTextures.Add(material.Texture, batchTex);
                            }
                            else
                            {
                                MyRenderProxy.Fail("Material: " + material.Name + " is missing a texture.");
                            }
                        }

                        break;

                    case MyTransparentMaterialTextureType.RenderTarget:
                        batchTex      = MyRender11.DrawSpritesOffscreen(material.Name, material.TargetSize.X, material.TargetSize.Y);
                        resetBindings = true;
                        break;

                    default:
                        throw new Exception();
                    }
                }

                bool boundary   = IsBucketBoundary(i);
                bool closeBatch = i > 0 && (batchTex != prevTex || boundary);
                if (closeBatch)
                {
                    AddBatch(i, currentOffset, prevTex, prevMaterial);
                    currentOffset = i;
                }


                var billboardData     = new MyBillboardData();
                var billboardVertices = new MyBillboardVertexData();

                billboardData.CustomProjectionID = billboard.CustomViewProjection;
                billboardData.Color                     = billboard.Color;
                billboardData.Color.X                  *= billboard.ColorIntensity;
                billboardData.Color.Y                  *= billboard.ColorIntensity;
                billboardData.Color.Z                  *= billboard.ColorIntensity;
                billboardData.AlphaCutout               = billboard.AlphaCutout;
                billboardData.AlphaSaturation           = material.AlphaSaturation;
                billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale;

                billboardData.Reflective = billboard.Reflectivity;
                Vector3D pos0 = billboard.Position0;
                Vector3D pos1 = billboard.Position1;
                Vector3D pos2 = billboard.Position2;
                Vector3D pos3 = billboard.Position3;

                if (billboard.ParentID != -1)
                {
                    var parent = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID);

                    if (parent != null)
                    {
                        var matrix = parent.WorldMatrix;
                        Vector3D.Transform(ref pos0, ref matrix, out pos0);
                        Vector3D.Transform(ref pos1, ref matrix, out pos1);
                        Vector3D.Transform(ref pos2, ref matrix, out pos2);
                        Vector3D.Transform(ref pos3, ref matrix, out pos3);
                    }
                }

                MyEnvironmentMatrices envMatrices = MyRender11.Environment.Matrices;
                if (MyStereoRender.Enable)
                {
                    if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesLeftEye;
                    }
                    else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesRightEye;
                    }
                }

                if (billboard.CustomViewProjection == -1)
                {
                    pos0 -= envMatrices.CameraPosition;
                    pos1 -= envMatrices.CameraPosition;
                    pos2 -= envMatrices.CameraPosition;
                    pos3 -= envMatrices.CameraPosition;
                }

                var normal = Vector3D.Cross(pos1 - pos0, pos2 - pos0);
                normal.Normalize();

                billboardData.Normal = normal;

                billboardVertices.V0.Position = pos0;
                billboardVertices.V1.Position = pos1;
                billboardVertices.V2.Position = pos2;
                billboardVertices.V3.Position = pos3;

                var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);
                var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);

                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);

                    uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                }

                billboardVertices.V0.Texcoord = new HalfVector2(uv0);
                billboardVertices.V1.Texcoord = new HalfVector2(uv1);
                billboardVertices.V2.Texcoord = new HalfVector2(uv2);
                billboardVertices.V3.Texcoord = new HalfVector2(uv3);

                pos0.AssertIsValid();
                pos1.AssertIsValid();
                pos2.AssertIsValid();
                pos3.AssertIsValid();


                MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard;
                if (triBillboard != null)
                {
                    billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer

                    billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0);
                    billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1);
                    billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2);

                    billboardData.Normal = triBillboard.Normal0;
                }

                m_arrayDataBillboards.Data[i]   = billboardData;
                m_arrayDataBillboards.Vertex[i] = billboardVertices;

                prevTex      = batchTex;
                prevMaterial = material;
            }
            AddBatch(m_billboardCountSafe, currentOffset, prevTex, prevMaterial);

            TransferDataCustomProjections();
            TransferDataBillboards(0, m_billboardCountSafe, ref m_arrayDataBillboards);

            return(resetBindings);
        }
        static void Gather()
        {
            m_batches.Clear();

            // counting sorted billboards
            m_sortedCount   = 0;
            m_unsortedCount = 0;
            m_windowCount   = 0;
            PreGatherList(MyRenderProxy.BillboardsRead);
            PreGatherList(m_billboardsOnce);

            if (BillboardCount == 0)
            {
                return;
            }

            ResizeStorage();

            int sortedIndex   = 0;
            int unsortedIndex = 0;

            GatherList(MyRenderProxy.BillboardsRead, ref sortedIndex, ref unsortedIndex);
            GatherList(m_billboardsOnce, ref sortedIndex, ref unsortedIndex);

            Array.Sort(m_sortedBuffer, 0, m_sortedCount);

            int   i             = 0;
            int   windowidx     = 0;
            var   N             = BillboardCountSafe;
            int   currentOffset = 0;
            TexId prevTexId     = TexId.NULL;
            TexId batchTexId    = TexId.NULL;
            MyTransparentMaterial prevMaterial = null;

            while (true)
            {
                if (i == N)
                {
                    AddBatch(N, currentOffset, prevTexId, prevMaterial);
                    break;
                }

                MyBillboard           billboard = m_sortedBuffer[i];
                MyTransparentMaterial material  = MyTransparentMaterials.GetMaterial(billboard.Material);
                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);
                    batchTexId = atlasItem.TextureId;
                }
                else
                {
                    batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true);
                }

                bool closeBatch = i > 0 && (batchTexId != prevTexId || i == m_sortedCount);
                if (closeBatch)
                {
                    AddBatch(i, currentOffset, prevTexId, prevMaterial);
                    currentOffset = i;
                }

                var billboardData     = new MyBillboardData();
                var billboardVertices = new MyBillboardVertexData();

                billboardData.CustomProjectionID = billboard.CustomViewProjection;
                billboardData.Color                     = billboard.Color;
                billboardData.Color.X                  *= billboard.ColorIntensity;
                billboardData.Color.Y                  *= billboard.ColorIntensity;
                billboardData.Color.Z                  *= billboard.ColorIntensity;
                billboardData.AlphaCutout               = billboard.AlphaCutout;
                billboardData.AlphaSaturation           = material.AlphaSaturation;
                billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale;

                billboardData.Reflective = billboard.Reflectivity;
                Vector3D pos0 = billboard.Position0;
                Vector3D pos1 = billboard.Position1;
                Vector3D pos2 = billboard.Position2;
                Vector3D pos3 = billboard.Position3;

                if (billboard.ParentID != -1)
                {
                    if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null)
                    {
                        var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix;

                        Vector3D.Transform(ref pos0, ref matrix, out pos0);
                        Vector3D.Transform(ref pos1, ref matrix, out pos1);
                        Vector3D.Transform(ref pos2, ref matrix, out pos2);
                        Vector3D.Transform(ref pos3, ref matrix, out pos3);
                    }
                }

                MyEnvironmentMatrices envMatrices = MyRender11.Environment;
                if (MyStereoRender.Enable)
                {
                    if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesLeftEye;
                    }
                    else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT)
                    {
                        envMatrices = MyStereoRender.EnvMatricesRightEye;
                    }
                }

                if (billboard.CustomViewProjection != -1)
                {
                    var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection];

                    //pos0 -= envMatrices.CameraPosition;
                    //pos1 -= envMatrices.CameraPosition;
                    //pos2 -= envMatrices.CameraPosition;
                    //pos3 -= envMatrices.CameraPosition;
                }
                else
                {
                    pos0 -= envMatrices.CameraPosition;
                    pos1 -= envMatrices.CameraPosition;
                    pos2 -= envMatrices.CameraPosition;
                    pos3 -= envMatrices.CameraPosition;
                }

                var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0);
                normal.Normalize();

                billboardData.Normal = normal;

                billboardVertices.V0.Position = pos0;
                billboardVertices.V1.Position = pos1;
                billboardVertices.V2.Position = pos2;
                billboardVertices.V3.Position = pos3;

                var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y);
                var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);
                var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y);

                if (material.UseAtlas)
                {
                    var atlasItem = m_atlas.FindElement(material.Texture);

                    uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                    uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y);
                }

                billboardVertices.V0.Texcoord = new HalfVector2(uv0);
                billboardVertices.V1.Texcoord = new HalfVector2(uv1);
                billboardVertices.V2.Texcoord = new HalfVector2(uv2);
                billboardVertices.V3.Texcoord = new HalfVector2(uv3);

                pos0.AssertIsValid();
                pos1.AssertIsValid();
                pos2.AssertIsValid();
                pos3.AssertIsValid();


                MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard;
                if (triBillboard != null)
                {
                    billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer

                    billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0);
                    billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1);
                    billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2);

                    billboardData.Normal = triBillboard.Normal0;
                }

                m_arrayDataBillboards.Data[i]   = billboardData;
                m_arrayDataBillboards.Vertex[i] = billboardVertices;

                if (billboard.Window && MyScreenDecals.HasEntityDecals((uint)billboard.ParentID))
                {
                    m_arrayDataWindows.Data[windowidx]   = billboardData;
                    m_arrayDataWindows.Vertex[windowidx] = billboardVertices;
                    windowidx++;
                }

                prevTexId    = batchTexId;
                prevMaterial = material;
                i++;
            }
        }