public void DrawEntityDebugLines(Entity entity, Render render) { if(entity.WasRenderedLines || !(render.drawAxis || render.drawNormals || render.drawBoxes) || !entity.Visible) { return; } if(render.drawBoxes) { DebugDrawer.SetColor(0.0f, 0.0f, 1.0f); DebugDrawer.DrawOBB(entity.OBB); } if(render.drawAxis) { // If this happens, the lines after this will get drawn with random colors. I don't care. DebugDrawer.DrawAxis(1000.0f, entity.Transform); } if(entity.Bf.Animations.Model != null && entity.Bf.Animations.Model.Animations.Any()) { DebugDrawer.DrawSkeletalModelDebugLines(entity.Bf, entity.Transform, render); } entity.WasRenderedLines = true; }
public void DrawRoomDebugLines(Room room, Render render, Camera cam) { if(render.drawRoomBoxes) { DebugDrawer.SetColor(0.0f, 0.1f, 0.9f); DebugDrawer.DrawBBox(room.BBMin, room.BBMax, null); } if(render.drawPortals) { DebugDrawer.SetColor(0.0f, 0.0f, 0.0f); foreach (var p in room.Portals) { DebugDrawer.DrawPortal(p); } } if(render.drawFrustums) { DebugDrawer.SetColor(1.0f, 0.0f, 0.0f); foreach (var frus in room.Frustum) { DebugDrawer.DrawFrustum(frus); } } if(!render.skipRoom && room.Mesh != null) { DebugDrawer.DrawMeshDebugLines(room.Mesh, room.Transform, new List<Vector3>(), new List<Vector3>(), render); } foreach (var sm in room.StaticMesh) { if(sm.WasRenderedLines != 0 || sm.OBB.IsVisibleInRoom(room, cam) || (sm.Hide && !render.drawDummyStatics)) { continue; } if(render.drawBoxes) { DebugDrawer.SetColor(0.0f, 1.0f, 0.1f); DebugDrawer.DrawOBB(sm.OBB); } if(render.drawAxis) { DebugDrawer.DrawAxis(1000.0f, sm.Transform); } DebugDrawer.DrawMeshDebugLines(sm.Mesh, sm.Transform, new List<Vector3>(), new List<Vector3>(), render); sm.WasRenderedLines = 1; } foreach (var cont in room.Containers) { switch(cont.ObjectType) { case OBJECT_TYPE.Entity: var ent = (Entity) cont.Object; if(!ent.WasRenderedLines) { if(ent.OBB.IsVisibleInRoom(room, cam)) { DebugDrawer.DrawEntityDebugLines(ent, render); } ent.WasRenderedLines = true; } break; } } }
public void DrawSkeletalModelDebugLines(SSBoneFrame bframe, Transform transform, Render render) { if(render.drawNormals) { foreach (var btag in bframe.BoneTags) { var tr = transform * btag.FullTransform; DrawMeshDebugLines(btag.MeshBase, tr, new List<Vector3>(), new List<Vector3>(), render); } } }
public void DrawMeshDebugLines(BaseMesh mesh, Transform transform, List<Vector3> overrideVertices, List<Vector3> overrideNormals, Render render) { if(render.drawNormals) { SetColor(0.8f, 0.0f, 0.9f); if(overrideVertices.Any()) { for (var i = 0; i < mesh.Vertices.Count; i++) { var ov = overrideVertices[i]; var on = overrideNormals[i]; var v = transform * ov; buffer.Add(v.ToArray()); buffer.Add(color); v += transform.Basis.MultiplyByVector(on) * 128; buffer.Add(v.ToArray()); buffer.Add(color); } } else { foreach (var mv in mesh.Vertices) { var v = transform * mv.Position; buffer.Add(v.ToArray()); buffer.Add(color); v += transform.Basis.MultiplyByVector(mv.Normal) * 128; buffer.Add(v.ToArray()); buffer.Add(color); } } } }
public static Frustum PortalFrustumIntersect(Portal portal, Frustum emitter, Render render) { if (portal.DestRoom == null) return null; if (portal.Normal.Distance(render.Camera.Position) < SPLIT_EPSILON) // non face or degenerate to the line portal return null; if (portal.DestRoom.Frustum.Count > 0 && emitter.HasParent(portal.DestRoom.Frustum[0])) return null; // Abort infinite loop! var inDist = false; var inFace = false; foreach (var v in portal.Vertices) { if (!inDist && render.Camera.Frustum.Normal.Distance(v) < render.Camera.DistFar) inDist = true; if (!inFace && emitter.Normal.Distance(v) > 0.0) inFace = true; if (inDist && inFace) break; } if (!inDist || !inDist) return null; // Search for the first free room's frustum portal.DestRoom.Frustum.Add(new Frustum()); var currentGen = portal.DestRoom.Frustum.Last(); currentGen.SplitPrepare(portal); // prepare for clipping if (currentGen.SplitByPlane(emitter.Normal)) // splitting by main frustum clip plane { for (var i = 0; i < emitter.Vertices.Count; i++) { if(!currentGen.SplitByPlane(emitter.Planes[i])) { portal.DestRoom.Frustum.RemoveAt(portal.DestRoom.Frustum.Count - 1); return null; } } currentGen.GenClipPlanes(render.Camera); // all is OK, let's generate clip planes currentGen.Parent = emitter; // add parent pointer currentGen.ParentsCount = emitter.ParentsCount + 1; portal.DestRoom.MaxPath = Math.Max(portal.DestRoom.MaxPath, currentGen.ParentsCount); // maximum path to the room return currentGen; } portal.DestRoom.Frustum.RemoveAt(portal.DestRoom.Frustum.Count - 1); return null; }
public unsafe void GenVBO(Render renderer) { if (VBOIndexArray != 0 || VBOVertexArray != 0 || VBOSkinArray != 0) return; // now, begin VBO filling! VBOVertexArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, VBOVertexArray); var vsa = Vertices.Select(x => x.ToStruct()).ToArray(); fixed (VertexStruct* ptr = vsa) { GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (vsa.Length * sizeof(VertexStruct)), (IntPtr)ptr, BufferUsageHint.StaticDraw); } // Store additional skinning information if (MatrixIndices.Count > 0) { VBOSkinArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, VBOSkinArray); var tmp = MatrixIndices.Select(x => x.ToStruct()).ToArray(); fixed (MatrixIndexStruct* ptr = tmp) GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (Marshal.SizeOf(typeof (MatrixIndexStruct)) * MatrixIndices.Count), (IntPtr) ptr, BufferUsageHint.StaticDraw); } // Fill indices vbo VBOIndexArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndexArray); long elementsSize = sizeof (uint) * AlphaElements; for (var i = 0; i < TexturePageCount; i++) { elementsSize += sizeof (uint) * (long) ElementsPerTexture[i]; } { var tmp = Elements.ToArray(); fixed (uint* ptr = tmp) GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) elementsSize, (IntPtr) ptr, BufferUsageHint.StaticDraw); } // Prepare vertex array var attribs = new[] { new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Position, 3, VertexAttribPointerType.Float, false, VBOVertexArray, Marshal.SizeOf(typeof (Vertex)), (int) Marshal.OffsetOf(typeof (Vertex), "Position")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Normal, 3, VertexAttribPointerType.Float, false, VBOVertexArray, Marshal.SizeOf(typeof (Vertex)), (int) Marshal.OffsetOf(typeof (Vertex), "Normal")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Color, 4, VertexAttribPointerType.Float, false, VBOVertexArray, Marshal.SizeOf(typeof (Vertex)), (int) Marshal.OffsetOf(typeof (Vertex), "Color")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.TexCoord, 2, VertexAttribPointerType.Float, false, VBOVertexArray, Marshal.SizeOf(typeof (Vertex)), (int) Marshal.OffsetOf(typeof (Vertex), "TexCoord")), // Only used for skinned meshes new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.MatrixIndex, 2, VertexAttribPointerType.UnsignedByte, false, VBOSkinArray, 2, 0) }; var numAttribs = MatrixIndices.Count == 0 ? 4 : 5; MainVertexArray = new VertexArray(VBOIndexArray, numAttribs, attribs); // Now for animated polygons, if any if (AllAnimatedElements.Count > 0) { // And upload. AnimatedVBOVertexArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, AnimatedVBOVertexArray); { var tmp = AnimatedVertices.ToArray(); fixed (AnimatedVertex* ptr = tmp) GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (Marshal.SizeOf(typeof (AnimatedVertex)) * AnimatedVertices.Count), (IntPtr) ptr, BufferUsageHint.StaticDraw); } AnimatedVBOIndexArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, AnimatedVBOIndexArray); { var tmp = AllAnimatedElements.ToArray(); fixed (uint* ptr = tmp) GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (sizeof (uint) * AllAnimatedElements.Count), (IntPtr) ptr, BufferUsageHint.StaticDraw); } // Prepare empty buffer for tex coords AnimatedVBOTexCoordArray = (uint) GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, AnimatedVBOTexCoordArray); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (2 * sizeof(float) * AnimatedVertices.Count), IntPtr.Zero, BufferUsageHint.StreamDraw); var attribs2 = new[] { new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Position, 3, VertexAttribPointerType.Float, false, AnimatedVBOVertexArray, Marshal.SizeOf(typeof (AnimatedVertex)), (int) Marshal.OffsetOf(typeof (AnimatedVertex), "Position")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Color, 4, VertexAttribPointerType.Float, false, AnimatedVBOVertexArray, Marshal.SizeOf(typeof (AnimatedVertex)), (int) Marshal.OffsetOf(typeof (AnimatedVertex), "Color")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Normal, 3, VertexAttribPointerType.Float, false, AnimatedVBOVertexArray, Marshal.SizeOf(typeof (AnimatedVertex)), (int) Marshal.OffsetOf(typeof (AnimatedVertex), "Normal")), new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.TexCoord, 2, VertexAttribPointerType.Float, false, AnimatedVBOTexCoordArray, 2 * sizeof(float), 0) }; AnimatedVertexArray = new VertexArray(AnimatedVBOIndexArray, 4, attribs2); } else { // No animated data AnimatedVBOVertexArray = 0; AnimatedVBOTexCoordArray = 0; AnimatedVertexArray = null; } // Update references for transparent polygons for (var i = 0; i < TransparentPolygons.Count; i++) { var p = TransparentPolygons[i]; p.UsedVertexArray = p.IsAnimated ? AnimatedVertexArray : MainVertexArray; TransparentPolygons[i] = p; } }
public static void InitDefaultGlobals() { ConsoleInfo.Instance.InitGlobals(); Controls.InitGlobals(); Game.InitGlobals(); Renderer = new Render(); Renderer.InitGlobals(); #if !NO_AUDIO Audio.InitGlobals(); #endif }