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); } } }
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)); }