コード例 #1
0
        public static bool AddQuad(string material, ref MyQuadD quad, ref Color color, ref Vector3D vctPos, int priority = 0, int customViewProjection = -1)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return(false);
            }

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

            //VRageRender.MyBillboard billboard = m_preallocatedBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return(false);
            }

            billboard.Priority = priority;

            CreateBillboard(billboard, ref quad, material, ref color, ref vctPos, false, false, false, customViewProjection);

            VRageRender.MyRenderProxy.AddBillboard(billboard);

            return(true);
        }
コード例 #2
0
        private static void GetBillboardQuadRotated(VRageRender.MyBillboard billboard, ref Vector3D position, Vector2 radius, ref Matrix transform, Vector3 left, Vector3 up)
        {
            //	Two main vectors of a billboard rotated around the view axis/vector
            Vector3 billboardAxisX = new Vector3();

            billboardAxisX.X = radius.X * left.X;
            billboardAxisX.Y = radius.X * left.Y;
            billboardAxisX.Z = radius.X * left.Z;

            Vector3 billboardAxisY = new Vector3();

            billboardAxisY.X = radius.Y * up.X;
            billboardAxisY.Y = radius.Y * up.Y;
            billboardAxisY.Z = radius.Y * up.Z;

            Vector3D v1 = Vector3.TransformNormal(billboardAxisX + billboardAxisY, transform);
            Vector3D v2 = Vector3.TransformNormal(billboardAxisX - billboardAxisY, transform);

            //	Coordinates of four points of a billboard's quad
            billboard.Position0.X = position.X + v1.X;
            billboard.Position0.Y = position.Y + v1.Y;
            billboard.Position0.Z = position.Z + v1.Z;

            billboard.Position1.X = position.X - v2.X;
            billboard.Position1.Y = position.Y - v2.Y;
            billboard.Position1.Z = position.Z - v2.Z;

            billboard.Position2.X = position.X - v1.X;
            billboard.Position2.Y = position.Y - v1.Y;
            billboard.Position2.Z = position.Z - v1.Z;

            billboard.Position3.X = position.X + v2.X;
            billboard.Position3.Y = position.Y + v2.Y;
            billboard.Position3.Z = position.Z + v2.Z;
        }
コード例 #3
0
        public void PrepareForDraw()
        {
            //if (WasVisibleLastFrame != LastFrameVisibilityEnum.NotVisibleLastFrame)
            // if (RenderCounter == 0 || ((MyRender.RenderCounter - RenderCounter) < FRAMES_TO_SKIP)) //more than FRAMES_TO_SKIP frames consider effect as invisible
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Sort generations");
                m_sortedGenerations.Clear();

                foreach (IMyParticleGeneration generation in m_generations)
                {
                    m_sortedGenerations.Add(generation);
                }

                m_sortedGenerations.Sort();
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyBillboard effectBillboard = null;

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("PrepareForDraw generations");
                foreach (IMyParticleGeneration generation in m_sortedGenerations)
                {
                    generation.PrepareForDraw(ref effectBillboard);
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
コード例 #4
0
        internal static void AddBillboardOriented(string material,
                                                  Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, float softParticleDistanceScale = 1.0f,
                                                  int customViewProjection = -1)
        {
            if (!MyRender11.DebugOverrides.BillboardsDynamic)
            {
                return;
            }

            Debug.Assert(material != null);

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);

            MyBillboard billboard = MyBillboardRenderer.AddBillboardOnce();

            if (billboard == null)
            {
                return;
            }

            billboard.Priority             = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, softParticleDistanceScale);
        }
コード例 #5
0
        //  Add billboard for one frame only. This billboard isn't particle (it doesn't survive this frame, doesn't have update/draw methods, etc).
        //  This billboard isn't facing the camera. It's always oriented in specified direction. May be used as thrusts, or inner light of reflector.
        //  It's used by other classes when they want to draw some billboard (e.g. rocket thrusts, reflector glare).
        public static void AddBillboardOriented(string material,
                                                Vector4 color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius,
                                                int customViewProjection = -1, float reflection = 0)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }

            MyUtils.AssertIsValid(origin);
            MyUtils.AssertIsValid(leftVector);
            MyUtils.AssertIsValid(upVector);
            MyUtils.AssertIsValid(radius);
            MyDebug.AssertDebug(radius > 0);

            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();// m_preallocatedBillboards.Allocate();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return;
            }

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, customViewProjection, reflection);
            billboard.BlendType = MyBillboard.BlenType.Standard;

            VRageRender.MyRenderProxy.AddBillboard(billboard);
        }
コード例 #6
0
        internal static void AddBillboardOriented(string material,
                                                  Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float radius, int priority = 0, int customViewProjection = -1)
        {
            Debug.Assert(material != null);

            origin.AssertIsValid();
            leftVector.AssertIsValid();
            upVector.AssertIsValid();
            radius.AssertIsValid();
            MyDebug.AssertDebug(radius > 0);

            MyBillboard billboard = SpawnBillboard();

            if (billboard == null)
            {
                return;
            }

            billboard.Priority             = priority;
            billboard.CustomViewProjection = customViewProjection;

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, radius, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin);
        }
コード例 #7
0
        public void PrepareForDraw()
        {
            if (m_needSorting)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Sort generations");
                m_sortedGenerations.Clear();

                foreach (IMyParticleGeneration generation in m_generations)
                {
                    m_sortedGenerations.Add(generation);
                }

                m_sortedGenerations.Sort();
                m_drawGenerations = m_sortedGenerations;
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
            else
            {
                m_drawGenerations = m_generations;
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("PrepareForDraw generations");
            VRageRender.MyBillboard effectBillboard = null;
            foreach (IMyParticleGeneration generation in m_drawGenerations)
            {
                generation.PrepareForDraw(ref effectBillboard);
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
コード例 #8
0
        public static void AddBillboardOriented(string material,
                                                Vector4 color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float width, float height, Vector2 uvOffset,
                                                int customViewProjection = -1)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }

            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return;
            }

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, width, height, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, uvOffset, customViewProjection);
            billboard.BlendType = MyBillboard.BlenType.Standard;

            VRageRender.MyRenderProxy.AddBillboard(billboard);
        }
コード例 #9
0
        public static void AddBillboardOriented(string material,
                                                Color color, Vector3D origin, Vector3 leftVector, Vector3 upVector, float width, float height, Vector2 uvOffset, int priority = 0, bool colorize = false, int customViewProjection = -1)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }

            //VRageRender.MyBillboard billboard = m_preallocatedBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return;
            }

            billboard.Priority = priority;

            MyQuadD quad;

            MyUtils.GetBillboardQuadOriented(out quad, ref origin, width, height, ref leftVector, ref upVector);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, uvOffset, colorize, false, false, customViewProjection);

            VRageRender.MyRenderProxy.AddBillboard(billboard);
        }
コード例 #10
0
        internal static void AddPointBillboard(string material,
                                               Color color, Vector3D origin, float radius, float angle, int priority = 0, int customViewProjection = -1)
        {
            if (!MyRender11.DebugOverrides.BillboardsDynamic)
            {
                return;
            }
            Debug.Assert(material != null);

            origin.AssertIsValid();
            angle.AssertIsValid();

            MyQuadD quad;

            if (MyUtils.GetBillboardQuadAdvancedRotated(out quad, origin, radius, angle, MyRender11.Environment.Matrices.CameraPosition) != false)
            {
                MyBillboard billboard = MyBillboardRenderer.AddBillboardOnce();
                if (billboard == null)
                {
                    return;
                }

                billboard.Priority             = priority;
                billboard.CustomViewProjection = customViewProjection;
                CreateBillboard(billboard, ref quad, material, ref color, ref origin);
            }
        }
コード例 #11
0
        /// <summary>
        /// Return quad whos face is always looking to the camera.
        /// IMPORTANT: This bilboard looks same as point vertexes (point sprites) - horizontal and vertical axes of billboard are always parallel to screen
        /// That means, if billboard is in the left-up corner of screen, it won't be distorted by perspective. If will look as 2D quad on screen. As I said, it's same as GPU points.
        /// </summary>
        private static void GetBillboardQuadRotated(VRageRender.MyBillboard billboard, ref Vector3D position, float radius, float angle)
        {
            float angleCos = radius * (float)Math.Cos(angle);
            float angleSin = radius * (float)Math.Sin(angle);

            //	Two main vectors of a billboard rotated around the view axis/vector
            Vector3D billboardAxisX = new Vector3D();

            billboardAxisX.X = angleCos * MyTransparentGeometry.Camera.Left.X + angleSin * MyTransparentGeometry.Camera.Up.X;
            billboardAxisX.Y = angleCos * MyTransparentGeometry.Camera.Left.Y + angleSin * MyTransparentGeometry.Camera.Up.Y;
            billboardAxisX.Z = angleCos * MyTransparentGeometry.Camera.Left.Z + angleSin * MyTransparentGeometry.Camera.Up.Z;

            Vector3D billboardAxisY = new Vector3D();

            billboardAxisY.X = -angleSin * MyTransparentGeometry.Camera.Left.X + angleCos * MyTransparentGeometry.Camera.Up.X;
            billboardAxisY.Y = -angleSin * MyTransparentGeometry.Camera.Left.Y + angleCos * MyTransparentGeometry.Camera.Up.Y;
            billboardAxisY.Z = -angleSin * MyTransparentGeometry.Camera.Left.Z + angleCos * MyTransparentGeometry.Camera.Up.Z;

            //	Coordinates of four points of a billboard's quad
            billboard.Position0.X = position.X + billboardAxisX.X + billboardAxisY.X;
            billboard.Position0.Y = position.Y + billboardAxisX.Y + billboardAxisY.Y;
            billboard.Position0.Z = position.Z + billboardAxisX.Z + billboardAxisY.Z;

            billboard.Position1.X = position.X - billboardAxisX.X + billboardAxisY.X;
            billboard.Position1.Y = position.Y - billboardAxisX.Y + billboardAxisY.Y;
            billboard.Position1.Z = position.Z - billboardAxisX.Z + billboardAxisY.Z;

            billboard.Position2.X = position.X - billboardAxisX.X - billboardAxisY.X;
            billboard.Position2.Y = position.Y - billboardAxisX.Y - billboardAxisY.Y;
            billboard.Position2.Z = position.Z - billboardAxisX.Z - billboardAxisY.Z;

            billboard.Position3.X = position.X + billboardAxisX.X - billboardAxisY.X;
            billboard.Position3.Y = position.Y + billboardAxisX.Y - billboardAxisY.Y;
            billboard.Position3.Z = position.Z + billboardAxisX.Z - billboardAxisY.Z;
        }
コード例 #12
0
        public static bool AddAttachedQuad(string material, ref MyQuadD quad, Vector4 color, ref Vector3D vctPos, int renderObjectID)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return(false);
            }

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

            //VRageRender.MyBillboard billboard = m_preallocatedBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return(false);
            }

            CreateBillboard(billboard, ref quad, material, ref color, ref vctPos);
            billboard.ParentID  = renderObjectID;
            billboard.BlendType = MyBillboard.BlenType.Standard;

            VRageRender.MyRenderProxy.AddBillboard(billboard);

            return(true);
        }
コード例 #13
0
        public static VRageRender.MyBillboard AddBillboardParticle(MyAnimatedParticle particle, VRageRender.MyBillboard effectBillboard, bool sort)
        {
            //MyBillboard billboard = m_preallocatedParticleBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard != null)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("item.Value.Draw");
                if (particle.Draw(billboard) == true)
                {
                    if (!sort)
                    {
                        effectBillboard.ContainedBillboards.Add(billboard);
                    }

                    MyPerformanceCounter.PerCameraDrawWrite.NewParticlesCount++;
                }

                billboard.CustomViewProjection = -1;

                MyTransparentGeometry.EndParticleProfilingBlock();
            }

            return(billboard);
        }
コード例 #14
0
        public static void AddLineBillboard(string material,
                                            Color color, Vector3D origin, int renderObjectID, ref MatrixD worldToLocal, Vector3 directionNormalized, float length, float thickness, int priority = 0, bool near = false, int customViewProjection = -1)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }


            MyDebug.AssertIsValid(origin);
            MyDebug.AssertIsValid(length);
            MyDebug.AssertDebug(length > 0);
            MyDebug.AssertDebug(thickness > 0);

            //VRageRender.MyBillboard billboard = m_preallocatedBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard == null)
            {
                return;
            }

            billboard.Priority = priority;
            billboard.UVOffset = Vector2.Zero;
            billboard.UVSize   = Vector2.One;

            MyPolyLineD polyLine;

            polyLine.LineDirectionNormalized = directionNormalized;
            polyLine.Point0    = origin;
            polyLine.Point1    = origin + directionNormalized * length;
            polyLine.Thickness = thickness;

            MyQuadD  quad;
            Vector3D cameraPosition = customViewProjection == -1 ? MyTransparentGeometry.Camera.Translation : VRageRender.MyRenderProxy.BillboardsViewProjectionWrite[customViewProjection].CameraPosition;

            MyUtils.GetPolyLineQuad(out quad, ref polyLine, cameraPosition);

            CreateBillboard(billboard, ref quad, material, ref color, ref origin, false, near, false, customViewProjection);

            if (renderObjectID != -1)
            {
                Vector3D.Transform(ref billboard.Position0, ref worldToLocal, out billboard.Position0);
                Vector3D.Transform(ref billboard.Position1, ref worldToLocal, out billboard.Position1);
                Vector3D.Transform(ref billboard.Position2, ref worldToLocal, out billboard.Position2);
                Vector3D.Transform(ref billboard.Position3, ref worldToLocal, out billboard.Position3);
                billboard.ParentID = renderObjectID;
            }

            billboard.Position0.AssertIsValid();
            billboard.Position1.AssertIsValid();
            billboard.Position2.AssertIsValid();
            billboard.Position3.AssertIsValid();

            VRageRender.MyRenderProxy.AddBillboard(billboard);
        }
コード例 #15
0
        /// <summary>Render depth and normals of windows to the specified target</summary>
        /// <returns>True if windows to be rendered found</returns>
        /// <param name="squaredDistanceMin">Squared distance internal minor</param>
        internal static bool RenderWindowsDepthOnly(IDepthStencil depthStencil, IRtvBindable gbuffer1,
                                                    float squaredDistanceMin, float squaredDistanceMax)
        {
            int offset          = 0;
            int windowsCount    = 0;
            int windowsCountMax = WindowCountSafe;

            for (int it = 0; it < windowsCountMax; it++)
            {
                // Interval is [min, max)
                MyBillboard billboard = m_sortedBuffer[m_sorteWindowIndices[it]];
                if (billboard.DistanceSquared >= squaredDistanceMax)
                {
                    break;
                }

                if (billboard.DistanceSquared < squaredDistanceMin)
                {
                    offset++;
                }
                else
                {
                    windowsCount++;
                }
            }

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

            TransferDataBillboards(offset, windowsCount, ref m_arrayDataWindows);

            RC.SetRtv(depthStencil, MyDepthStencilAccess.ReadWrite, gbuffer1);
            BindResourcesCommon();

            RC.SetBlendState(null);
            RC.VertexShader.Set(m_vsDepthOnly);
            RC.PixelShader.Set(m_psDepthOnly);


            if (!MyStereoRender.Enable)
            {
                RC.DrawIndexed(m_windowCount * 6, 0, 0);
            }
            else
            {
                MyStereoRender.DrawIndexedBillboards(RC, m_windowCount * 6, 0, 0);
            }
            MyStatsUpdater.Passes.DrawBillboards++;

            RC.SetRasterizerState(null);
            return(true);
        }
コード例 #16
0
        /// <returns>True if window has decals and is not too far</returns>
        static bool HandleWindow(MyBillboard billboard)
        {
            uint parentID = (uint)billboard.ParentID;

            if (MyScreenDecals.HasEntityDecals(parentID) && billboard.DistanceSquared < MyScreenDecals.VISIBLE_DECALS_SQ_TH)
            {
                m_windowsWithDecals.Add(parentID);
                return(true);
            }

            return(false);
        }
コード例 #17
0
        //  This method is like a constructor (which we can't use because billboards are allocated from a pool).
        //  It starts/initializes a billboard. Refs used only for optimalization
        public static void CreateBillboard(VRageRender.MyBillboard billboard, ref MyQuadD quad, string material,
                                           ref Vector4 color, ref Vector3D origin, Vector2 uvOffset, int customViewProjection = -1, float reflectivity = 0)
        {
            System.Diagnostics.Debug.Assert(material != null);

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

            billboard.Material = material;

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


            //  Billboard vertices
            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
            Vector3D cameraPosition = customViewProjection == -1 ? MyTransparentGeometry.Camera.Translation : VRageRender.MyRenderProxy.BillboardsViewProjectionWrite[customViewProjection].CameraPosition;

            billboard.DistanceSquared = (float)Vector3D.DistanceSquared(cameraPosition, origin);

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

            billboard.CustomViewProjection      = customViewProjection;
            billboard.ParentID                  = -1;
            billboard.SoftParticleDistanceScale = 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;
        }
コード例 #18
0
        static void PreGatherBillboard(MyBillboard billboard)
        {
            var material = MyTransparentMaterials.GetMaterial(billboard.Material);

            if (material.NeedSort)
            {
                m_sortedCount++;
            }
            else
            {
                m_unsortedCount++;
            }
        }
コード例 #19
0
        public static VRageRender.MyBillboard AddBillboardEffect(MyParticleEffect effect)
        {
            //VRageRender.MyBillboard billboard = m_preallocatedParticleBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard != null)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("AddBillboardEffect");

                billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyTransparentGeometry.Camera.Translation, effect.WorldMatrix.Translation);

                billboard.CustomViewProjection = -1;

                MyTransparentGeometry.EndParticleProfilingBlock();
            }
            return(billboard);
        }
コード例 #20
0
        public void PrepareForDraw(ref VRageRender.MyBillboard effectBillboard)
        {
            m_billboards.Clear();

            if (m_particles.Count == 0)
            {
                return;
            }

            if (UseLayerSorting && effectBillboard == null)
            {
                effectBillboard = MyTransparentGeometry.AddBillboardEffect(m_effect);
                if (effectBillboard != null)
                {
                    m_billboards.Add(effectBillboard);
                }
            }

            using (ParticlesLock.AcquireSharedUsing())
            {
                foreach (MyAnimatedParticle particle in m_particles)
                {
                    MyTransparentGeometry.StartParticleProfilingBlock("m_preallocatedBillboards.Allocate()");

                    VRageRender.MyBillboard billboard = MyTransparentGeometry.AddBillboardParticle(particle, effectBillboard, !UseLayerSorting);
                    if (billboard != null)
                    {
                        if (!UseLayerSorting)
                        {
                            billboard.Position0.AssertIsValid();
                            billboard.Position1.AssertIsValid();
                            billboard.Position2.AssertIsValid();
                            billboard.Position3.AssertIsValid();

                            m_billboards.Add(billboard);
                        }
                    }
                    MyTransparentGeometry.EndParticleProfilingBlock();
                    if (billboard == null)
                    {
                        break;
                    }
                }
            }
        }
コード例 #21
0
            /// <summary>Compare using squared distance from camera</summary>
            public int Compare(int x, int y)
            {
                MyBillboard billx = m_sortedBuffer[x];
                MyBillboard billy = m_sortedBuffer[y];

                if (billx.DistanceSquared < billy.DistanceSquared)
                {
                    return(-1);
                }
                else if (billx.DistanceSquared == billy.DistanceSquared)
                {
                    return(0);
                }
                else
                {
                    return(1);
                }
            }
コード例 #22
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++;
            }
        }
コード例 #23
0
        //  Add billboard for one frame only. This billboard isn't particle (it doesn't survive this frame, doesn't have update/draw methods, etc).
        //  It's used by other classes when they want to draw some billboard (e.g. rocket thrusts, reflector glare).
        public static void AddPointBillboard(string material,
                                             Vector4 color, Vector3D origin, int renderObjectID, ref MatrixD worldToLocal, float radius, float angle,
                                             int customViewProjection = -1, MyBillboard.BlenType blendType = MyBillboard.BlenType.Standard)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }

            MyDebug.AssertIsValid(origin);
            MyDebug.AssertIsValid(angle);

            MyQuadD quad;
            Vector3 diff = MyTransparentGeometry.Camera.Translation - origin;

            if (MyUtils.GetBillboardQuadAdvancedRotated(out quad, origin, radius, radius, angle, (origin + (Vector3D)MyTransparentGeometry.Camera.Forward * diff.Length())) != false)
            {
                VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
                if (billboard == null)
                {
                    return;
                }

                CreateBillboard(billboard, ref quad, material, ref color, ref origin, customViewProjection);
                billboard.BlendType = blendType;

                if (renderObjectID != -1)
                {
                    Vector3D.Transform(ref billboard.Position0, ref worldToLocal, out billboard.Position0);
                    Vector3D.Transform(ref billboard.Position1, ref worldToLocal, out billboard.Position1);
                    Vector3D.Transform(ref billboard.Position2, ref worldToLocal, out billboard.Position2);
                    Vector3D.Transform(ref billboard.Position3, ref worldToLocal, out billboard.Position3);
                    billboard.ParentID = renderObjectID;
                }

                VRageRender.MyRenderProxy.AddBillboard(billboard);
            }
        }
コード例 #24
0
        //  Add billboard for one frame only. This billboard isn't particle (it doesn't survive this frame, doesn't have update/draw methods, etc).
        //  It's used by other classes when they want to draw some billboard (e.g. rocket thrusts, reflector glare).
        public static void AddPointBillboard(string material,
                                             Color color, Vector3D origin, int renderObjectID, ref MatrixD worldToLocal, float radius, float angle, int priority = 0, bool colorize = false, bool near = false, bool lowres = false, int customViewProjection = -1)
        {
            Debug.Assert(material != null);
            if (!IsEnabled)
            {
                return;
            }

            MyDebug.AssertIsValid(origin);
            MyDebug.AssertIsValid(angle);

            MyQuadD quad;

            if (MyUtils.GetBillboardQuadAdvancedRotated(out quad, origin, radius, radius, angle, MyTransparentGeometry.Camera.Translation) != false)
            {
                VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
                if (billboard == null)
                {
                    return;
                }

                billboard.Priority = priority;
                CreateBillboard(billboard, ref quad, material, ref color, ref origin, colorize, near, lowres, customViewProjection);

                if (renderObjectID != -1)
                {
                    Vector3D.Transform(ref billboard.Position0, ref worldToLocal, out billboard.Position0);
                    Vector3D.Transform(ref billboard.Position1, ref worldToLocal, out billboard.Position1);
                    Vector3D.Transform(ref billboard.Position2, ref worldToLocal, out billboard.Position2);
                    Vector3D.Transform(ref billboard.Position3, ref worldToLocal, out billboard.Position3);
                    billboard.ParentID = renderObjectID;
                }

                VRageRender.MyRenderProxy.AddBillboard(billboard);
            }
        }
コード例 #25
0
        public static VRageRender.MyBillboard AddBillboardParticle(MyAnimatedParticle particle)
        {
            //MyBillboard billboard = m_preallocatedParticleBillboards.Allocate();
            //VRageRender.MyBillboard billboard = new VRageRender.MyBillboard();
            VRageRender.MyBillboard billboard = VRageRender.MyRenderProxy.BillboardsPoolWrite.Allocate();
            if (billboard != null)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("item.Value.Draw");
                billboard.BlendType = MyBillboard.BlenType.Standard;

                if (particle.Draw(billboard) == true)
                {
                    billboard.CustomViewProjection = -1;
                }
                else
                {
                    billboard = null;
                }

                MyTransparentGeometry.EndParticleProfilingBlock();
            }

            return(billboard);
        }
コード例 #26
0
 private static void GetBillboardQuadRotated(VRageRender.MyBillboard billboard, ref Vector3D position, Vector2 radius, ref Matrix transform)
 {
     GetBillboardQuadRotated(billboard, ref position, radius, ref transform, MyTransparentGeometry.Camera.Left, MyTransparentGeometry.Camera.Up);
 }
コード例 #27
0
ファイル: MyRenderProxy.cs プロジェクト: rem02/SpaceEngineers
        public static void AddBillboard(MyBillboard billboard)
        {
            if (!DebugOverrides.BillboardsStatic)
                return;
            System.Diagnostics.Debug.Assert(billboard != null);

            billboard.Position0.AssertIsValid();
            billboard.Position1.AssertIsValid();
            billboard.Position2.AssertIsValid();
            billboard.Position3.AssertIsValid();

            BillboardsWrite.Add(billboard);
        }
コード例 #28
0
        //  Update position, check collisions, etc. and draw if particle still lives.
        //  Return false if particle dies/timeouts in this tick.
        public bool Draw(VRageRender.MyBillboard billboard)
        {
            if (Pivot != null)
            {
                if (PivotRotation != null)
                {
                    Matrix pivotRotationTransform =
                        Matrix.CreateRotationX(MathHelper.ToRadians(m_actualPivotRotation.X) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS) *
                        Matrix.CreateRotationY(MathHelper.ToRadians(m_actualPivotRotation.Y) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS) *
                        Matrix.CreateRotationZ(MathHelper.ToRadians(m_actualPivotRotation.Z) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS);

                    m_actualPivot = Vector3.TransformNormal(m_actualPivot, pivotRotationTransform);
                }

                m_actualPivot = Vector3D.TransformNormal(m_actualPivot, m_generation.GetEffect().WorldMatrix);
            }

            var actualPosition = m_actualPosition + m_actualPivot;

            MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation");
            //  This time is scaled according to planned lifespan of the particle

            // Distance for sorting
            billboard.DistanceSquared = (float)Vector3D.DistanceSquared(MyTransparentGeometry.Camera.Translation, actualPosition);

            MyTransparentGeometry.EndParticleProfilingBlock();

            // If distance to camera is really small don't draw it.
            if (billboard.DistanceSquared <= 0.1f)
            {
                return(false);
            }

            MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation");

            MyTransparentGeometry.StartParticleProfilingBlock("actualRadius");
            float actualRadius = 1;

            Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius);
            MyTransparentGeometry.EndParticleProfilingBlock();

            float actualAlphaCutout = 0;

            if (AlphaCutout != null)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("AlphaCutout calculation");

                AlphaCutout.GetInterpolatedValue <float>(m_normalizedTime, out actualAlphaCutout);

                MyTransparentGeometry.EndParticleProfilingBlock();
            }

            billboard.ContainedBillboards.Clear();

            billboard.Near   = m_generation.GetEffect().Near;
            billboard.Lowres = m_generation.GetEffect().LowRes || VRageRender.MyRenderConstants.RenderQualityProfile.LowResParticles;
            billboard.CustomViewProjection = -1;
            billboard.ParentID             = -1;
            billboard.AlphaCutout          = actualAlphaCutout;
            billboard.UVOffset             = Vector2.Zero;
            billboard.UVSize = Vector2.One;



            float alpha = 1;


            Matrix  transform = Matrix.Identity;
            Vector3 normal    = Vector3.Forward;

            Vector3 actualVelocity = (Vector3)(m_actualPosition - m_previousPosition);

            float radiusBySpeed = m_generation.RadiusBySpeed;

            if (radiusBySpeed > 0)
            {
                float actualSpeed = actualVelocity.Length();
                actualRadius = Math.Max(actualRadius, actualRadius * m_generation.RadiusBySpeed * actualSpeed);
            }


            if (Type == MyParticleTypeEnum.Point)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated");

                Vector2 actualRadiusV2 = new Vector2(actualRadius, actualRadius);

                if (Thickness > 0)
                {
                    actualRadiusV2.Y = Thickness;
                }

                if (m_generation.RotationReference == MyRotationReference.Camera)
                {
                    transform =
                        Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Right, m_actualAngle.X) *
                        Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Up, m_actualAngle.Y) *
                        Matrix.CreateFromAxisAngle(MyTransparentGeometry.Camera.Forward, m_actualAngle.Z);

                    GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, MyTransparentGeometry.Camera.Left, MyTransparentGeometry.Camera.Up);
                }
                else if (m_generation.RotationReference == MyRotationReference.Local)
                {
                    transform = Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Right, m_actualAngle.X) *
                                Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Up, m_actualAngle.Y) *
                                Matrix.CreateFromAxisAngle(m_generation.GetEffect().WorldMatrix.Forward, m_actualAngle.Z);

                    GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, m_generation.GetEffect().WorldMatrix.Left, m_generation.GetEffect().WorldMatrix.Up);
                }
                else if (m_generation.RotationReference == MyRotationReference.Velocity)
                {
                    if (actualVelocity.LengthSquared() < 0.00001f)
                    {
                        return(false);
                    }

                    Matrix velocityRef = Matrix.CreateFromDir(Vector3.Normalize(actualVelocity));

                    transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) *
                                Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) *
                                Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z);

                    GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up);
                }
                else if (m_generation.RotationReference == MyRotationReference.VelocityAndCamera)
                {
                    if (actualVelocity.LengthSquared() < 0.0001f)
                    {
                        return(false);
                    }

                    Vector3 cameraToPoint = Vector3.Normalize(m_actualPosition - MyTransparentGeometry.Camera.Translation);
                    Vector3 velocityDir   = Vector3.Normalize(actualVelocity);

                    Vector3 sideVector = Vector3.Cross(cameraToPoint, velocityDir);
                    Vector3 upVector   = Vector3.Cross(sideVector, velocityDir);

                    Matrix velocityRef = Matrix.CreateWorld(m_actualPosition, velocityDir, upVector);

                    transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) *
                                Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) *
                                Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z);

                    GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up);
                }
                else if (m_generation.RotationReference == MyRotationReference.LocalAndCamera)
                {
                    Vector3 cameraToPoint = Vector3.Normalize(m_actualPosition - MyTransparentGeometry.Camera.Translation);
                    Vector3 localDir      = m_generation.GetEffect().WorldMatrix.Forward;

                    Vector3 sideVector = Vector3.Cross(cameraToPoint, localDir);
                    Vector3 upVector   = Vector3.Cross(sideVector, localDir);

                    Matrix velocityRef = Matrix.CreateWorld(m_actualPosition, localDir, upVector);

                    transform = Matrix.CreateFromAxisAngle(velocityRef.Right, m_actualAngle.X) *
                                Matrix.CreateFromAxisAngle(velocityRef.Up, m_actualAngle.Y) *
                                Matrix.CreateFromAxisAngle(velocityRef.Forward, m_actualAngle.Z);

                    GetBillboardQuadRotated(billboard, ref actualPosition, actualRadiusV2, ref transform, velocityRef.Left, velocityRef.Up);
                }
                else
                {
                    System.Diagnostics.Debug.Fail("Unknown RotationReference enum");
                }

                MyTransparentGeometry.EndParticleProfilingBlock();
            }
            else if (Type == MyParticleTypeEnum.Line)
            {
                if (MyUtils.IsZero(Velocity.LengthSquared()))
                {
                    Velocity = MyUtils.GetRandomVector3Normalized();
                }

                MyQuadD quad = new MyQuadD();

                MyPolyLineD polyLine = new MyPolyLineD();
                //polyLine.LineDirectionNormalized = MyUtils.Normalize(Velocity);
                if (actualVelocity.LengthSquared() > 0)
                {
                    polyLine.LineDirectionNormalized = MyUtils.Normalize(actualVelocity);
                }
                else
                {
                    polyLine.LineDirectionNormalized = MyUtils.Normalize(Velocity);
                }

                if (m_actualAngle.Z != 0)
                {
                    polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(m_actualAngle.Z));
                }

                polyLine.Point0   = actualPosition;
                polyLine.Point1.X = actualPosition.X - polyLine.LineDirectionNormalized.X * actualRadius;
                polyLine.Point1.Y = actualPosition.Y - polyLine.LineDirectionNormalized.Y * actualRadius;
                polyLine.Point1.Z = actualPosition.Z - polyLine.LineDirectionNormalized.Z * actualRadius;

                if (m_actualAngle.LengthSquared() > 0)
                { //centerize
                    polyLine.Point0.X = polyLine.Point0.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point0.Y = polyLine.Point0.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point0.Z = polyLine.Point0.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                    polyLine.Point1.X = polyLine.Point1.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point1.Y = polyLine.Point1.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point1.Z = polyLine.Point1.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                }

                polyLine.Thickness = Thickness;
                var camPos = MyTransparentGeometry.Camera.Translation;
                MyUtils.GetPolyLineQuad(out quad, ref polyLine, camPos);

                transform.Forward = polyLine.LineDirectionNormalized;

                billboard.Position0 = quad.Point0;
                billboard.Position1 = quad.Point1;
                billboard.Position2 = quad.Point2;
                billboard.Position3 = quad.Point3;
            }
            else if (Type == MyParticleTypeEnum.Trail)
            {
                if (Quad.Point0 == Quad.Point2) //not moving particle
                {
                    return(false);
                }
                if (Quad.Point1 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }
                if (Quad.Point0 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }

                billboard.Position0 = Quad.Point0;
                billboard.Position1 = Quad.Point1;
                billboard.Position2 = Quad.Point2;
                billboard.Position3 = Quad.Point3;
            }
            else
            {
                throw new NotSupportedException(Type + " is not supported particle type");
            }

            if (this.m_generation.AlphaAnisotropic)
            {
                normal = Vector3.Normalize(Vector3.Cross(billboard.Position0 - billboard.Position1, billboard.Position0 - billboard.Position2));

                Vector3 forward = (billboard.Position0 + billboard.Position1 + billboard.Position2 + billboard.Position3) / 4 - MyTransparentGeometry.Camera.Translation;

                //Vector3 forward = MyTransparentGeometry.Camera.Forward;

                float angle = Math.Abs(Vector3.Dot(MyUtils.Normalize(forward), normal));


                float alphaCone = 1 - (float)Math.Pow(1 - angle, 4);
                alpha = alphaCone;
            }


            MyTransparentGeometry.EndParticleProfilingBlock();

            MyTransparentGeometry.StartParticleProfilingBlock("Material calculation");

            Vector4 color = Vector4.One;

            if (Color.GetKeysCount() > 0)
            {
                Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color);
            }

            if (m_arrayIndex != -1)
            {
                Vector3 arraySize = m_generation.ArraySize;
                if (arraySize.X > 0 && arraySize.Y > 0)
                {
                    int arrayOffset = m_generation.ArrayOffset;
                    int arrayModulo = m_generation.ArrayModulo == 0 ? (int)arraySize.X * (int)arraySize.Y : m_generation.ArrayModulo;

                    m_arrayIndex = m_arrayIndex % arrayModulo + arrayOffset;

                    float xDiv   = 1.0f / arraySize.X;
                    float yDiv   = 1.0f / arraySize.Y;
                    int   xIndex = m_arrayIndex % (int)arraySize.X;
                    int   yIndex = m_arrayIndex / (int)arraySize.X;

                    billboard.UVOffset = new Vector2(xDiv * xIndex, yDiv * yIndex);
                    billboard.UVSize   = new Vector2(xDiv, yDiv);
                }
            }


            var   material1         = MyTransparentMaterials.GetMaterial("ErrorMaterial");
            var   material2         = MyTransparentMaterials.GetMaterial("ErrorMaterial");
            float textureBlendRatio = 0;

            if ((Flags & ParticleFlags.BlendTextures) != 0)
            {
                float prevTime, nextTime, difference;
                Material.GetPreviousValue(m_normalizedTime, out material1, out prevTime);
                Material.GetNextValue(m_normalizedTime, out material2, out nextTime, out difference);

                if (prevTime != nextTime)
                {
                    textureBlendRatio = (m_normalizedTime - prevTime) * difference;
                }
            }
            else
            {
                Material.GetInterpolatedValue(m_normalizedTime, out material1);
            }

            MyTransparentGeometry.EndParticleProfilingBlock();

            //This gets 0.44ms for 2000 particles
            MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start");

            if (material1 != null)
            {
                billboard.Material = material1.Name;
            }

            billboard.BlendMaterial     = material2.Name;
            billboard.BlendTextureRatio = textureBlendRatio;
            billboard.EnableColorize    = false;

            billboard.Color          = color * alpha * m_generation.GetEffect().UserColorMultiplier;
            billboard.ColorIntensity = ColorIntensity;

            MyTransparentGeometry.EndParticleProfilingBlock();

            return(true);
        }
コード例 #29
0
        /// <returns>True if window has decals and is not too far</returns>
        static bool HandleWindow(MyBillboard billboard)
        {
            uint parentID = (uint)billboard.ParentID;
            if (MyScreenDecals.HasEntityDecals(parentID) && billboard.DistanceSquared < MyScreenDecals.VISIBLE_DECALS_SQ_TH)
            {
                m_windowsWithDecals.Add(parentID);
                return true;
            }

            return false;
        }
コード例 #30
0
        public static void AddBillboard(MyBillboard billboard)
        {
            System.Diagnostics.Debug.Assert(billboard != null);

            billboard.Position0.AssertIsValid();
            billboard.Position1.AssertIsValid();
            billboard.Position2.AssertIsValid();
            billboard.Position3.AssertIsValid();

            BillboardsWrite.Add(billboard);
        }
コード例 #31
0
        private static void SetupCustomViewProjection(MyEffectTransparentGeometry effect, ref Viewport originalViewport, MyBillboard lastBillboard, ref bool ignoreDepth, ref Matrix projectionMatrix)
        {
            if (lastBillboard.CustomViewProjection != -1 && MyRenderProxy.BillboardsViewProjectionRead.ContainsKey(lastBillboard.CustomViewProjection))
            {
                var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[lastBillboard.CustomViewProjection];
                effect.SetViewMatrix(ref billboardViewProjection.ViewAtZero);
                effect.SetProjectionMatrix(ref billboardViewProjection.Projection);


                Matrix invProjectionMatrix = Matrix.Invert((MyRenderCamera.m_backupMatrix.HasValue ? MyRenderCamera.m_backupMatrix.Value : MyRenderCamera.ProjectionMatrix));
                effect.SetInverseDefaultProjectionMatrix(ref invProjectionMatrix);

                Viewport viewport = new Viewport((int)billboardViewProjection.Viewport.OffsetX, (int)billboardViewProjection.Viewport.OffsetY,
                    (int)billboardViewProjection.Viewport.Width, (int)billboardViewProjection.Viewport.Height);
                if (MyRender.GetScreenshot() != null)
                    viewport = new Viewport((int)(billboardViewProjection.Viewport.OffsetX * MyRender.GetScreenshot().SizeMultiplier.X),
                                            (int)(billboardViewProjection.Viewport.OffsetY * MyRender.GetScreenshot().SizeMultiplier.Y),
                                            (int)(billboardViewProjection.Viewport.Width * MyRender.GetScreenshot().SizeMultiplier.X),
                                            (int)(billboardViewProjection.Viewport.Height * MyRender.GetScreenshot().SizeMultiplier.Y));
                MyRender.SetDeviceViewport(viewport);
                ignoreDepth = !billboardViewProjection.DepthRead;
                projectionMatrix = billboardViewProjection.Projection;
            }
            else
            {
                var viewMatrix = MyRenderCamera.ViewMatrixAtZero;
                effect.SetViewMatrix(ref viewMatrix);
                effect.SetProjectionMatrix(ref MyRenderCamera.ProjectionMatrix);
                MyRender.SetDeviceViewport(originalViewport);
                ignoreDepth = false;
                projectionMatrix = MyRenderCamera.ProjectionMatrix;
            }
        }
コード例 #32
0
 public static void CreateBillboard(VRageRender.MyBillboard billboard, ref MyQuadD quad, string material,
                                    ref Vector4 color, ref Vector3D origin, int customViewProjection = -1, float reflection = 0)
 {
     CreateBillboard(billboard, ref quad, material, ref color, ref origin, Vector2.Zero, customViewProjection, reflection);
 }
コード例 #33
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++;
        }
コード例 #34
0
 private static bool DefaultWindowHanlder(MyBillboard billboard)
 {
     return(true);
 }
コード例 #35
0
        /// <summary>
        /// Copies the billboard to vertex buffer.
        /// </summary>
        /// <param name="billboarIdx">The billboar idx.</param>
        static void CopyBillboardToVertices(int billboarIdx, MyBillboard billboard)
        {
            int startIndex = (billboarIdx) * MyTransparentGeometryConstants.VERTICES_PER_TRANSPARENT_GEOMETRY;
            HalfVector4 colorHalf = new HalfVector4(billboard.Color);
            MyTransparentMaterial materialProperties = MyTransparentMaterials.GetMaterial(billboard.Material);

            billboard.Position0.AssertIsValid();
            billboard.Position1.AssertIsValid();
            billboard.Position2.AssertIsValid();
            billboard.Position3.AssertIsValid();

            
            m_vertices[startIndex + 0].Color = colorHalf;
            m_vertices[startIndex + 0].TexCoord = new HalfVector4(materialProperties.UVOffset.X + billboard.UVOffset.X, materialProperties.UVOffset.Y + billboard.UVOffset.Y, billboard.BlendTextureRatio, materialProperties.Emissivity);

            
            m_vertices[startIndex + 1].Color = colorHalf;
            m_vertices[startIndex + 1].TexCoord = new HalfVector4(materialProperties.UVOffset.X + materialProperties.UVSize.X + billboard.UVOffset.X, materialProperties.UVOffset.Y + billboard.UVOffset.Y, billboard.BlendTextureRatio, materialProperties.Emissivity);

            
            m_vertices[startIndex + 2].Color = colorHalf;
            m_vertices[startIndex + 2].TexCoord = new HalfVector4(materialProperties.UVOffset.X + materialProperties.UVSize.X + billboard.UVOffset.X, materialProperties.UVOffset.Y + materialProperties.UVSize.Y + billboard.UVOffset.Y, billboard.BlendTextureRatio, materialProperties.Emissivity);

            m_vertices[startIndex + 3].Color = colorHalf;
            m_vertices[startIndex + 3].TexCoord = new HalfVector4(materialProperties.UVOffset.X + billboard.UVOffset.X, materialProperties.UVOffset.Y + materialProperties.UVSize.Y + billboard.UVOffset.Y, billboard.BlendTextureRatio, materialProperties.Emissivity);

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

            if (billboard.ParentID != -1)
            {
                MyRenderObject renderObject;
                if (MyRender.m_renderObjects.TryGetValue((uint)billboard.ParentID, out renderObject))
                {
                    MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject;
                    MyManualCullableRenderObject cullableObject = renderObject as MyManualCullableRenderObject;
                    if (transformObject != null)
                    {
                        var worldMatrix = transformObject.WorldMatrix;

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

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

            if (billboard.CustomViewProjection != -1)
            {
                System.Diagnostics.Debug.Assert(MyRenderProxy.BillboardsViewProjectionRead.ContainsKey(billboard.CustomViewProjection));

                if (MyRenderProxy.BillboardsViewProjectionRead.ContainsKey(billboard.CustomViewProjection))
                {
                    var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection];

                    pos0 -= billboardViewProjection.CameraPosition;
                    pos1 -= billboardViewProjection.CameraPosition;
                    pos2 -= billboardViewProjection.CameraPosition;
                    pos3 -= billboardViewProjection.CameraPosition;
                }
                else
                {
                    pos0 -= MyRenderCamera.Position;
                    pos1 -= MyRenderCamera.Position;
                    pos2 -= MyRenderCamera.Position;
                    pos3 -= MyRenderCamera.Position;
                }
            }
            else
            {
                pos0 -= MyRenderCamera.Position;
                pos1 -= MyRenderCamera.Position;
                pos2 -= MyRenderCamera.Position;
                pos3 -= MyRenderCamera.Position;
            }

            m_vertices[startIndex + 0].Position = pos0;
            m_vertices[startIndex + 1].Position = pos1;
            m_vertices[startIndex + 2].Position = pos2;
            m_vertices[startIndex + 3].Position = pos3;

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

            if (materialProperties.Reflectivity > 0)
            {
                var normal = Vector3.Cross(billboard.Position1 - billboard.Position0, billboard.Position2 - billboard.Position0);

                var NormalRefl = new HalfVector4(normal.X, normal.Y, normal.Z, billboard.Reflectivity);
                m_vertices[startIndex + 0].TexCoord2 = NormalRefl;
                m_vertices[startIndex + 1].TexCoord2 = NormalRefl;
                m_vertices[startIndex + 2].TexCoord2 = NormalRefl;
                m_vertices[startIndex + 3].TexCoord2 = NormalRefl;
            }
            else if (billboard.BlendTextureRatio > 0)
            {
                MyTransparentMaterial blendMaterialProperties = MyTransparentMaterials.GetMaterial(billboard.BlendMaterial);
                m_vertices[startIndex + 0].TexCoord2 = new HalfVector4(blendMaterialProperties.UVOffset.X + billboard.UVOffset.X, blendMaterialProperties.UVOffset.Y + billboard.UVOffset.Y, 0, 0);
                m_vertices[startIndex + 1].TexCoord2 = new HalfVector4(blendMaterialProperties.UVOffset.X + blendMaterialProperties.UVSize.X + billboard.UVOffset.X, blendMaterialProperties.UVOffset.Y + billboard.UVOffset.Y, 0, 0);
                m_vertices[startIndex + 2].TexCoord2 = new HalfVector4(blendMaterialProperties.UVOffset.X + blendMaterialProperties.UVSize.X + billboard.UVOffset.X, blendMaterialProperties.UVOffset.Y + blendMaterialProperties.UVSize.Y + billboard.UVOffset.Y, 0, 0);
                m_vertices[startIndex + 3].TexCoord2 = new HalfVector4(blendMaterialProperties.UVOffset.X + billboard.UVOffset.X, blendMaterialProperties.UVOffset.Y + blendMaterialProperties.UVSize.Y + billboard.UVOffset.Y, 0, 0);
            }

        }
コード例 #36
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);
        }