Пример #1
0
        private static void ensureAvailable()
        {
            if(FontBufferVAO != null && FontBufferVBO != 0)
            {
                return;
            }

            FontBufferVBO = Helper.GenBufferU();

            FontBufferVAO = new VertexArray(0, 3, new []
            {
                new VertexArrayAttribute((int)TextShaderDescription.VertexAttribs.Position, 2, VertexAttribPointerType.Float, false, FontBufferVBO, 8 * sizeof(float), 0), 
                new VertexArrayAttribute((int)TextShaderDescription.VertexAttribs.TexCoord, 2, VertexAttribPointerType.Float, false, FontBufferVBO, 8 * sizeof(float), 2 * sizeof(float)), 
                new VertexArrayAttribute((int)TextShaderDescription.VertexAttribs.Color, 4, VertexAttribPointerType.Float, false, FontBufferVBO, 8 * sizeof(float), 4 * sizeof(float))
            });
        }
Пример #2
0
        public void Render()
        {
            if(buffer.Any())
            {
                if (glBuffer == 0)
                {
                    glBuffer = Helper.GenBufferU();
                    var attribs = new[]
                    {
                        new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Position, 3,
                            VertexAttribPointerType.Float, false, glBuffer, 6 * sizeof(float), 0),
                        new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Color, 3,
                            VertexAttribPointerType.Float, false, glBuffer, 6 * sizeof(float), 3 * sizeof(float))
                    };
                    vertexArray = new VertexArray(0, 2, attribs);
                }

                GL.BindBuffer(BufferTarget.ArrayBuffer, glBuffer);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(buffer.Count * Marshal.SizeOf(buffer[0])), IntPtr.Zero, BufferUsageHint.StreamDraw);

                unsafe
                {
                    var data = (float*) GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly);
                    var b = buffer.ToArray();
                    fixed (float* buf = b[0])
                        Helper.PointerCopy(buf, data, 3);
                    GL.UnmapBuffer(BufferTarget.ArrayBuffer);
                }

                vertexArray.Bind();
                GL.DrawArrays(PrimitiveType.Lines, 0, buffer.Count / 2);
            }

            Helper.FillArray(0.0f, color);
            buffer.Clear();
        }
Пример #3
0
        public unsafe void RenderRoom(Room room, Matrix4 modelViewMatrix, Matrix4 modelViewProjectionMatrix, Matrix4 projection)
        {
            var needStencil = false;
            if (STENCIL_FRUSTUM)
            {
                // start test stencil test code
                if(room.Frustum.Any())
                {
                    needStencil = room.OverlappedRoomList.Any(r => renderList.Contains(r));

                    if(needStencil)
                    {
                        var shader = ShaderManager.GetStencilShader();
                        GL.UseProgram(shader.Program);
                        GL.UniformMatrix4(shader.ModelViewProjection, false, ref EngineCamera.GLViewProjMat);
                        GL.Enable(EnableCap.StencilTest);
                        GL.Clear(ClearBufferMask.StencilBufferBit);
                        GL.StencilFunc(StencilFunction.Never, 1, 0x00);
                        GL.StencilOp(StencilOp.Replace, StencilOp.Keep, StencilOp.Keep);

                        var stencilVBO = Helper.GenBufferU();

                        var attribs = new[]
                        {
                            new VertexArrayAttribute((int) UnlitShaderDescription.VertexAttribs.Position, 3,
                                VertexAttribPointerType.Float, false, stencilVBO, 3 * sizeof(float), 0)
                        };

                        var array = new VertexArray(0, 1, attribs);
                        array.Bind();

                        foreach (var f in room.Frustum)
                        {
                            GL.BindBuffer(BufferTarget.ArrayBuffer, stencilVBO);
                            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(f.Vertices.Count * sizeof(Vector3)), IntPtr.Zero, BufferUsageHint.StreamDraw);

                            unsafe
                            {
                                var v = (float*) GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly);

                                foreach(var it in f.Vertices.AsEnumerable().Reverse())
                                {
                                    *v++ = it.X;
                                    *v++ = it.Y;
                                    *v++ = it.Z;
                                }

                                GL.UnmapBuffer(BufferTarget.ArrayBuffer);
                            }

                            GL.DrawArrays(PrimitiveType.TriangleFan, 0, f.Vertices.Count);
                        }

                        GL.StencilFunc(StencilFunction.Equal, 1, 0xFF);
                        GL.DeleteBuffer(stencilVBO);
                    }
                }
            }

            if(!skipRoom && room.Mesh != null)
            {
                var modelViewProjectionTransform = modelViewProjectionMatrix.MultiplyByTransform(room.Transform);

                var shader = ShaderManager.GetRoomShader(room.LightMode == 1, room.Flags.HasFlagUns(1));

                var tint = new float[4];
                EngineWorld.CalculateWaterTint(tint, true);
                GL.UseProgram(shader.Program);

                GL.Uniform4(shader.TintMult, 1, tint);
                GL.Uniform1(shader.CurrentTick, SDL.SDL_GetTicks());
                GL.Uniform1(shader.Sampler, 0);
                GL.UniformMatrix4(shader.ModelViewProjection, false, ref modelViewProjectionTransform);
                RenderMesh(room.Mesh);
            }

            if(room.StaticMesh.Any())
            {
                GL.UseProgram(ShaderManager.GetStaticMeshShader().Program);
                foreach (var sm in room.StaticMesh)
                {
                    if(sm.WasRendered != 0 || !sm.OBB.IsVisibleInRoom(room, Camera))
                    {
                        continue;
                    }

                    if(sm.Hide && !drawDummyStatics)
                    {
                        continue;
                    }

                    var transform = modelViewProjectionMatrix.MultiplyByTransform(sm.Transform);
                    GL.UniformMatrix4(ShaderManager.GetStaticMeshShader().ModelViewProjection, false, ref transform);

                    var tint = sm.Tint.CloneArr();

                    // If this static mesh is in a water room
                    if(room.Flags.HasFlagUns(RoomFlag.Water))
                    {
                        EngineWorld.CalculateWaterTint(tint, false);
                    }
                    GL.Uniform4(ShaderManager.GetStaticMeshShader().TintMult, 1, tint);
                    RenderMesh(sm.Mesh);
                    sm.WasRendered = 1;
                }
            }

            if(room.Containers.Any())
            {
                foreach (var cont in room.Containers)
                {
                    switch(cont.ObjectType)
                    {
                        case OBJECT_TYPE.Entity:
                            var ent = (Entity) cont.Object;
                            if(!ent.WasRendered)
                            {
                                if(ent.OBB.IsVisibleInRoom(room, Camera))
                                {
                                    RenderEntity(ent, modelViewMatrix, modelViewProjectionMatrix, projection);
                                }
                                ent.WasRendered = true;
                            }
                            break;
                    }
                }
            }

            if(STENCIL_FRUSTUM)
            {
                if(needStencil)
                {
                    GL.Disable(EnableCap.StencilTest);
                }
            }
        }
Пример #4
0
        public static unsafe void FillCrosshairBuffer()
        {
            var crosshairBuf = new[]
            {
                GuiBufferEntryS.ctor(new[] {Global.ScreenInfo.W / 2.0f - 5, Global.ScreenInfo.H / 2.0f}, new byte[] {255, 0, 0, 255}),
                GuiBufferEntryS.ctor(new[] {Global.ScreenInfo.W / 2.0f + 5, Global.ScreenInfo.H / 2.0f}, new byte[] {255, 0, 0, 255}),
                GuiBufferEntryS.ctor(new[] {Global.ScreenInfo.W / 2.0f, Global.ScreenInfo.H / 2.0f - 5}, new byte[] {255, 0, 0, 255}),
                GuiBufferEntryS.ctor(new[] {Global.ScreenInfo.W / 2.0f, Global.ScreenInfo.H / 2.0f + 5}, new byte[] {255, 0, 0, 255})
            };

            GL.BindBuffer(BufferTarget.ArrayBuffer, CrosshairBuffer);
            fixed (GuiBufferEntryS* ptr = crosshairBuf)
                GL.BufferData(BufferTarget.ArrayBuffer,
                    (IntPtr) (Marshal.SizeOf(typeof (GuiBufferEntryS)) * crosshairBuf.Length), (IntPtr) ptr,
                    BufferUsageHint.StaticDraw);

            var attribs = new[]
            {
                new VertexArrayAttribute((int) GuiShaderDescription.VertexAttribs.Position, 2,
                    VertexAttribPointerType.Float, false, CrosshairBuffer,
                    Marshal.SizeOf(typeof (GuiBufferEntryS)),
                    (int) Marshal.OffsetOf(typeof (GuiBufferEntryS), "Position")),
                new VertexArrayAttribute((int) GuiShaderDescription.VertexAttribs.Color, 4,
                    VertexAttribPointerType.UnsignedByte, true, CrosshairBuffer,
                    Marshal.SizeOf(typeof (GuiBufferEntryS)),
                    (int) Marshal.OffsetOf(typeof (GuiBufferEntryS), "Color"))
            };
            CrosshairArray = new VertexArray(0, 2, attribs);
        }
Пример #5
0
        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;
            }
        }