Ejemplo n.º 1
0
        private void addPolygon(ref BSPNode root, BSPFaceRef face, Polygon transformed)
        {
            if(root == null) root = new BSPNode();

            if(root.PolygonsFront.Count == 0)
            {
                // We though root.Front == null && root.Back == null
                root.Plane = transformed.Plane;
                root.PolygonsFront = new List<BSPFaceRef> { face };
                return;
            }

            var positive = 0;
            var negative = 0;
            var inPlane = 0;

            foreach(var v in transformed.Vertices)
            {
                var dist = root.Plane.Distance(v.Position);
                if (dist > SPLIT_EPSILON)
                    positive++;
                else if (dist < -SPLIT_EPSILON)
                    negative++;
                else
                    inPlane++;
            }

            if(positive > 0 && negative == 0) // SPLIT_FRONT
            {
                addPolygon(ref root.Front, face, transformed);
            }
            else if(positive == 0 && negative > 0) // SPLIT_BACK
            {
                addPolygon(ref root.Back, face, transformed);
            }
            else // SPLIT_IN_PLANE
            {
                if(transformed.Plane.Normal.Dot(root.Plane.Normal) > 0.9)
                {
                    root.PolygonsFront.Add(face);
                }
                else
                {
                    root.PolygonsBack.Add(face);
                }
            }
        }
Ejemplo n.º 2
0
        public void RenderPolygonTransparency(BlendingMode currentTransparency, BSPFaceRef bspRef,
            UnlitTintedShaderDescription shader)
        {
            // Blending mode switcher.
            // Note that modes above 2 aren't explicitly used in TR textures, only for
            // internal particle processing. Theoretically it's still possible to use
            // them if you will force type via TRTextur utility.
            var refe = bspRef.Polygon;
            var p = refe.Polygon;
            if(currentTransparency != p.BlendMode)
            {
                currentTransparency = p.BlendMode;
                switch (p.BlendMode)
                {
                    case BlendingMode.Multiply: // Classic PC alpha
                        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One);
                        break;

                    case BlendingMode.InvertSrc: // Inversion by src (PS darkness) - SAME AS IN TR3-TR5
                        GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.OneMinusSrcAlpha);
                        break;

                    case BlendingMode.InvertDst: // Inversion by dest
                        GL.BlendFunc(BlendingFactorSrc.OneMinusSrcColor, BlendingFactorDest.OneMinusSrcAlpha);
                        break;

                    case BlendingMode.Screen: // Screen (smoke, etc.)
                        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
                        break;

                    case BlendingMode.AnimatedTexture:
                        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero);
                        break;
                }
            }

            var mvp = Camera.GLViewProjMat.MultiplyByTransform(bspRef.Transform);

            GL.UniformMatrix4(shader.ModelViewProjection, false, ref mvp);

            refe.UsedVertexArray.Bind();
            GL.BindTexture(TextureTarget.Texture2D, World.Textures[p.TexIndex]);

            GL.DrawElements(PrimitiveType.Triangles, (int)refe.Count, DrawElementsType.UnsignedInt, (int)(sizeof(uint) * refe.FirstIndex));
        }