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