From a542385cd7de68e096e8bfe8d1fbe2a6065dcd19 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 15 Aug 2019 02:52:21 +0200 Subject: [PATCH] - force texture and buffer updating to go through RenderDevice --- Source/Core/Data/DataManager.cs | 8 +- Source/Core/Data/ImageData.cs | 4 +- Source/Core/GZBuilder/md3/ModelReader.cs | 10 +- Source/Core/Rendering/CustomTextLabel.cs | 4 +- Source/Core/Rendering/IndexBuffer.cs | 8 - Source/Core/Rendering/Mesh.cs | 10 +- Source/Core/Rendering/RenderDevice.cs | 118 ++++++++++++++- Source/Core/Rendering/Renderer2D.cs | 30 ++-- Source/Core/Rendering/Renderer3D.cs | 8 +- Source/Core/Rendering/SurfaceManager.cs | 12 +- Source/Core/Rendering/TextLabel.cs | 10 +- Source/Core/Rendering/Texture.cs | 60 +------- Source/Core/Rendering/VertexBuffer.cs | 38 ----- Source/Core/Rendering/VisualVertexHandle.cs | 4 +- Source/Core/VisualModes/VisualSector.cs | 4 +- Source/Core/VisualModes/VisualThing.cs | 6 +- Source/Native/IndexBuffer.cpp | 16 +- Source/Native/IndexBuffer.h | 4 +- Source/Native/OpenGLContext.cpp | 8 +- Source/Native/OpenGLContext.h | 1 + Source/Native/RenderDevice.cpp | 153 +++++++++++++++++++- Source/Native/RenderDevice.h | 16 +- Source/Native/Texture.cpp | 67 ++++++--- Source/Native/Texture.h | 9 ++ Source/Native/VertexBuffer.cpp | 26 +--- Source/Native/VertexBuffer.h | 5 +- Source/Native/exports.def | 19 +-- 27 files changed, 410 insertions(+), 248 deletions(-) diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index a7ea7ed8..908d4e73 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -3449,7 +3449,7 @@ namespace CodeImp.DoomBuilder.Data yscale *= 1.65f; // Make cubemap texture - CubeTexture cubemap = new CubeTexture(cubemaptexsize); + CubeTexture cubemap = new CubeTexture(General.Map.Graphics, cubemaptexsize); // Set render settings... General.Map.Graphics.SetZEnable(false); @@ -3643,7 +3643,7 @@ namespace CodeImp.DoomBuilder.Data // sides[] must contain 6 square Po2 images in this order: North, East, South, West, Top, Bottom private static CubeTexture MakeSkyBox(Bitmap[] sides, int targetsize, bool fliptop) { - CubeTexture cubemap = new CubeTexture(targetsize); + CubeTexture cubemap = new CubeTexture(General.Map.Graphics, targetsize); // Draw faces sides[3].RotateFlip(RotateFlipType.Rotate90FlipNone); @@ -3669,7 +3669,7 @@ namespace CodeImp.DoomBuilder.Data private static void DrawCubemapFace(CubeTexture texture, CubeMapFace face, Bitmap image) { - texture.SetPixels(face, image); + General.Map.Graphics.SetPixels(texture, face, image); } private static Bitmap ResizeImage(Image image, int width, int height) @@ -3745,7 +3745,7 @@ namespace CodeImp.DoomBuilder.Data { using (var bitmap = new Bitmap(image)) { - return new Texture(bitmap); + return new Texture(General.Map.Graphics, bitmap); } } diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index 3be3ccc4..1f9c35a4 100755 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -467,7 +467,7 @@ namespace CodeImp.DoomBuilder.Data Bitmap img = bitmap; if(loadfailed) img = Properties.Resources.Failed; - texture = new Texture(img); + texture = new Texture(General.Map.Graphics, img); if(dynamictexture) { @@ -492,7 +492,7 @@ namespace CodeImp.DoomBuilder.Data { if((texture != null) && !texture.Disposed) { - texture.SetPixels(bitmap); + General.Map.Graphics.SetPixels(texture, bitmap); } } } diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index 8d555511..77f9b11f 100755 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -989,7 +989,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 } //mesh - Mesh mesh = new Mesh(vertexElements, vertList.ToArray(), polyIndecesList.ToArray()); + Mesh mesh = new Mesh(General.Map.Graphics, vertexElements, vertList.ToArray(), polyIndecesList.ToArray()); //store in result result.Meshes.Add(mesh); @@ -1163,11 +1163,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 // Create texture new Texture(bmp.Width) using(Bitmap bmp = CreateVoxelTexture(palette)) { - mde.Model.Textures.Add(new Texture(bmp)); + mde.Model.Textures.Add(new Texture(General.Map.Graphics, bmp)); } // Create mesh - Mesh mesh = new Mesh(vertexElements, verts.ToArray(), indices.ToArray()); + Mesh mesh = new Mesh(General.Map.Graphics, vertexElements, verts.ToArray(), indices.ToArray()); // Add mesh mde.Model.Meshes.Add(mesh); @@ -1667,7 +1667,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 if(bitmap != null) { - texture = new Texture(bitmap); + texture = new Texture(General.Map.Graphics, bitmap); } return texture; @@ -1676,7 +1676,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 private static void CreateMesh(ref MD3LoadResult result, List verts, List indices) { //create mesh - Mesh mesh = new Mesh(vertexElements, verts.ToArray(), indices.ToArray()); + Mesh mesh = new Mesh(General.Map.Graphics, vertexElements, verts.ToArray(), indices.ToArray()); //store in result result.Meshes.Add(mesh); diff --git a/Source/Core/Rendering/CustomTextLabel.cs b/Source/Core/Rendering/CustomTextLabel.cs index d500e1a6..92b37125 100755 --- a/Source/Core/Rendering/CustomTextLabel.cs +++ b/Source/Core/Rendering/CustomTextLabel.cs @@ -21,9 +21,9 @@ namespace CodeImp.DoomBuilder.Rendering public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } } public SizeF TextSize { get { return label.TextSize; } } - public void Update(float translatex, float translatey, float scalex, float scaley) + public void Update(RenderDevice graphics, float translatex, float translatey, float scalex, float scaley) { - label.Update(translatex, translatey, scalex, scaley); + label.Update(graphics, translatex, translatey, scalex, scaley); } } } diff --git a/Source/Core/Rendering/IndexBuffer.cs b/Source/Core/Rendering/IndexBuffer.cs index f4d2d1c2..61cd310b 100644 --- a/Source/Core/Rendering/IndexBuffer.cs +++ b/Source/Core/Rendering/IndexBuffer.cs @@ -21,11 +21,6 @@ namespace CodeImp.DoomBuilder.Rendering Dispose(); } - public void SetBufferData(int[] data) - { - IndexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf()); - } - public bool Disposed { get { return Handle == IntPtr.Zero; } } public void Dispose() @@ -44,8 +39,5 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void IndexBuffer_Delete(IntPtr handle); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void IndexBuffer_SetBufferData(IntPtr handle, int[] data, long size); } } diff --git a/Source/Core/Rendering/Mesh.cs b/Source/Core/Rendering/Mesh.cs index c5f00816..411cd75a 100644 --- a/Source/Core/Rendering/Mesh.cs +++ b/Source/Core/Rendering/Mesh.cs @@ -8,13 +8,13 @@ namespace CodeImp.DoomBuilder.Rendering { internal class Mesh : IDisposable { - public Mesh(VertexElement[] vertexDecl, WorldVertex[] vertexData, int[] indexData) + public Mesh(RenderDevice graphics, VertexElement[] vertexDecl, WorldVertex[] vertexData, int[] indexData) { VertexDecl = new VertexDeclaration(vertexDecl); unsafe { Vertices = new VertexBuffer(sizeof(WorldVertex)); } - Vertices.SetBufferData(vertexData); + graphics.SetBufferData(Vertices, vertexData); Indices = new IndexBuffer(sizeof(int) * indexData.Length); - Indices.SetBufferData(indexData); + graphics.SetBufferData(Indices, indexData); Count = indexData.Length; } @@ -25,15 +25,13 @@ namespace CodeImp.DoomBuilder.Rendering internal void Draw(RenderDevice device) { - /* device.SetVertexDeclaration(VertexDecl); device.SetVertexBuffer(0, Vertices, 0, WorldVertex.Stride); device.SetIndexBuffer(Indices); - device.DrawElements(0, Count); + device.DrawIndexed(PrimitiveType.TriangleList, 0, Count); device.SetIndexBuffer(null); device.SetVertexBuffer(0, null, 0, 0); device.SetVertexDeclaration(null); - */ } public void Dispose() diff --git a/Source/Core/Rendering/RenderDevice.cs b/Source/Core/Rendering/RenderDevice.cs index 863a56c2..d137a782 100755 --- a/Source/Core/Rendering/RenderDevice.cs +++ b/Source/Core/Rendering/RenderDevice.cs @@ -28,9 +28,9 @@ using System.Runtime.InteropServices; namespace CodeImp.DoomBuilder.Rendering { - internal class RenderDevice : IDisposable + public class RenderDevice : IDisposable { - internal RenderDevice(RenderTargetControl rendertarget) + public RenderDevice(RenderTargetControl rendertarget) { Handle = RenderDevice_New(rendertarget.Handle); if (Handle == IntPtr.Zero) @@ -230,19 +230,24 @@ namespace CodeImp.DoomBuilder.Rendering RenderDevice_SetSamplerState(Handle, unit, addressU, addressV, addressW); } + public void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) + { + RenderDevice_DrawIndexed(Handle, type, startIndex, primitiveCount); + } + public void DrawPrimitives(PrimitiveType type, int startIndex, int primitiveCount) { - RenderDevice_DrawPrimitives(Handle, type, startIndex, primitiveCount); + RenderDevice_Draw(Handle, type, startIndex, primitiveCount); } public void DrawUserPrimitives(PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data) { - RenderDevice_DrawUserPrimitives(Handle, type, startIndex, primitiveCount, data); + RenderDevice_DrawStreamed(Handle, type, startIndex, primitiveCount, data); } public void SetVertexDeclaration(VertexDeclaration decl) { - RenderDevice_SetVertexDeclaration(Handle, decl.Handle); + RenderDevice_SetVertexDeclaration(Handle, decl != null ? decl.Handle : IntPtr.Zero); } public void StartRendering(bool clear, Color4 backcolor) @@ -275,6 +280,75 @@ namespace CodeImp.DoomBuilder.Rendering RenderDevice_CopyTexture(Handle, src.Handle, dst.Handle, face); } + public void SetBufferData(IndexBuffer buffer, int[] data) + { + RenderDevice_SetIndexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf()); + } + + public void SetBufferData(VertexBuffer buffer, FlatVertex[] data) + { + RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf()); + } + + public void SetBufferData(VertexBuffer buffer, WorldVertex[] data) + { + RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf()); + } + + public void SetBufferSubdata(VertexBuffer buffer, long destOffset, FlatVertex[] data) + { + RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset, data, data.Length * Marshal.SizeOf()); + } + + public void SetBufferSubdata(VertexBuffer buffer, long destOffset, WorldVertex[] data) + { + RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset, data, data.Length * Marshal.SizeOf()); + } + + public void SetBufferSubdata(VertexBuffer buffer, long destOffset, FlatVertex[] data, long offset, long size) + { + if (data.Length < size || size < 0) throw new ArgumentOutOfRangeException("size"); + RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset, data, size * Marshal.SizeOf()); + } + + public void SetPixels(Texture texture, System.Drawing.Bitmap bitmap) + { + System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( + new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), + System.Drawing.Imaging.ImageLockMode.ReadOnly, + System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + RenderDevice_SetPixels(Handle, texture.Handle, bmpdata.Scan0); + + bitmap.UnlockBits(bmpdata); + } + + public void SetPixels(CubeTexture texture, CubeMapFace face, System.Drawing.Bitmap bitmap) + { + System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( + new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), + System.Drawing.Imaging.ImageLockMode.ReadOnly, + System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + RenderDevice_SetCubePixels(Handle, texture.Handle, face, bmpdata.Scan0); + + bitmap.UnlockBits(bmpdata); + } + + internal Plotter LockPlotter(Texture texture, int visibleWidth, int visibleHeight) + { + unsafe + { + IntPtr data = RenderDevice_LockTexture(Handle, texture.Handle); + return new Plotter((PixelColor*)data.ToPointer(), texture.Width, texture.Height, Math.Min(texture.Width, visibleWidth), Math.Min(texture.Height, visibleHeight)); + } + } + + public void UnlockPlotter(Texture texture) + { + RenderDevice_UnlockTexture(Handle, texture.Handle); + } + internal void RegisterResource(IRenderResource res) { } @@ -391,10 +465,13 @@ namespace CodeImp.DoomBuilder.Rendering static extern void RenderDevice_SetSamplerState(IntPtr handle, int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void RenderDevice_DrawPrimitives(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount); + static extern void RenderDevice_Draw(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void RenderDevice_DrawUserPrimitives(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data); + static extern void RenderDevice_DrawIndexed(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_DrawStreamed(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void RenderDevice_SetVertexDeclaration(IntPtr handle, IntPtr decl); @@ -417,6 +494,33 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void RenderDevice_CopyTexture(IntPtr handle, IntPtr src, IntPtr dst, CubeMapFace face); + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetIndexBufferData(IntPtr handle, IntPtr buffer, int[] data, long size); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, FlatVertex[] data, long size); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, WorldVertex[] data, long size); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, FlatVertex[] data, long sizeInBytes); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, WorldVertex[] data, long sizeInBytes); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void RenderDevice_SetPixels(IntPtr handle, IntPtr texture, IntPtr data); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void RenderDevice_SetCubePixels(IntPtr handle, IntPtr texture, CubeMapFace face, IntPtr data); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern IntPtr RenderDevice_LockTexture(IntPtr handle, IntPtr texture); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + protected static extern void RenderDevice_UnlockTexture(IntPtr handle, IntPtr texture); + //mxd. Anisotropic filtering steps public static readonly List AF_STEPS = new List { 1.0f, 2.0f, 4.0f, 8.0f, 16.0f }; diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index e923176e..0d8167a7 100755 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -385,7 +385,7 @@ namespace CodeImp.DoomBuilder.Rendering // Make screen vertices FlatVertex[] verts = CreateScreenVerts(structsize); - screenverts.SetBufferData(verts); + graphics.SetBufferData(screenverts, verts); // Force update of view lastgridscale = -1f; @@ -623,7 +623,7 @@ namespace CodeImp.DoomBuilder.Rendering if(plottertex != null) { // Create structures plotter - plotter = plottertex.LockPlotter(structsize.Width, structsize.Height); + plotter = graphics.LockPlotter(plottertex, structsize.Width, structsize.Height); // Redraw grid when structures image was cleared if(clear) @@ -709,7 +709,7 @@ namespace CodeImp.DoomBuilder.Rendering // Clean up plotter if(renderlayer == RenderLayers.Plotter) { - if(plottertex != null) plottertex.UnlockPlotter(); + if(plottertex != null) graphics.UnlockPlotter(plottertex); plotter = null; } @@ -778,7 +778,7 @@ namespace CodeImp.DoomBuilder.Rendering lastgridx != offsetx || lastgridy != offsety || drawmapcenter != lastdrawmapcenter) { // Create a plotter - Plotter gridplotter = backtex.LockPlotter(backsize.Width, backsize.Height); + Plotter gridplotter = graphics.LockPlotter(backtex, backsize.Width, backsize.Height); gridplotter.Clear(); if(General.Settings.RenderGrid) //mxd @@ -831,8 +831,8 @@ namespace CodeImp.DoomBuilder.Rendering gridplotter.DrawLineSolid(cx - MAP_CENTER_SIZE, cy, cx + MAP_CENTER_SIZE, cy, ref c); } - // Done - backtex.UnlockPlotter(); + // Done + graphics.UnlockPlotter(backtex); lastgridscale = scale; lastgridsize = General.Map.Grid.GridSizeF; lastgridx = offsetx; @@ -1258,7 +1258,7 @@ namespace CodeImp.DoomBuilder.Rendering if(buffercount == locksize) { // Write to buffer - thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw! graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); @@ -1270,7 +1270,7 @@ namespace CodeImp.DoomBuilder.Rendering } // Write to buffer - if(buffercount > 0) thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + if(buffercount > 0) graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw what's still remaining if(buffercount > 0) @@ -1397,7 +1397,7 @@ namespace CodeImp.DoomBuilder.Rendering if(buffercount == locksize) { // Write to buffer - thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw! graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); @@ -1410,7 +1410,7 @@ namespace CodeImp.DoomBuilder.Rendering } // Write to buffer - thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw what's still remaining if(buffercount > 0) graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); @@ -1441,7 +1441,7 @@ namespace CodeImp.DoomBuilder.Rendering if(buffercount == locksize) { // Write to buffer - thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw! graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); @@ -1453,7 +1453,7 @@ namespace CodeImp.DoomBuilder.Rendering } // Write to buffer - if(buffercount > 0) thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); + if(buffercount > 0) graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6); // Draw what's still remaining if(buffercount > 0) @@ -1662,7 +1662,7 @@ namespace CodeImp.DoomBuilder.Rendering public void RenderText(ITextLabel label) { //mxd. Update the text if needed - label.Update(translatex, translatey, scale, -scale); + label.Update(graphics, translatex, translatey, scale, -scale); if(label.SkipRendering) return; // Set renderstates for rendering @@ -1691,7 +1691,7 @@ namespace CodeImp.DoomBuilder.Rendering foreach(ITextLabel label in labels) { // Update the text if needed - label.Update(translatex, translatey, scale, -scale); + label.Update(graphics, translatex, translatey, scale, -scale); if(label.SkipRendering) skipped++; } @@ -1932,7 +1932,7 @@ namespace CodeImp.DoomBuilder.Rendering // Write to buffer VertexBuffer vb = new VertexBuffer(FlatVertex.Stride * verts.Length); - vb.SetBufferData(verts); + graphics.SetBufferData(vb, verts); // Set renderstates for rendering graphics.SetCullMode(Cull.None); diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 27962dc3..a3ae586e 100755 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -708,7 +708,7 @@ namespace CodeImp.DoomBuilder.Rendering } VertexBuffer vb = new VertexBuffer(WorldVertex.Stride * verts.Length); - vb.SetBufferData(verts); + graphics.SetBufferData(vb, verts); //begin rendering graphics.SetAlphaBlendEnable(true); @@ -771,7 +771,7 @@ namespace CodeImp.DoomBuilder.Rendering if(!object.ReferenceEquals(g.Sector, sector)) { // Update the sector if needed - if(g.Sector.NeedsUpdateGeo) g.Sector.Update(); + if(g.Sector.NeedsUpdateGeo) g.Sector.Update(graphics); // Only do this sector when a vertexbuffer is created //mxd. No Map means that sector was deleted recently, I suppose @@ -1045,7 +1045,7 @@ namespace CodeImp.DoomBuilder.Rendering if(!object.ReferenceEquals(g.Sector, sector)) { // Update the sector if needed - if(g.Sector.NeedsUpdateGeo) g.Sector.Update(); + if(g.Sector.NeedsUpdateGeo) g.Sector.Update(graphics); // Only do this sector when a vertexbuffer is created //mxd. No Map means that sector was deleted recently, I suppose @@ -1754,7 +1754,7 @@ namespace CodeImp.DoomBuilder.Rendering if(!object.ReferenceEquals(g.Sector, sector)) { // Update the sector if needed - if(g.Sector.NeedsUpdateGeo) g.Sector.Update(); + if(g.Sector.NeedsUpdateGeo) g.Sector.Update(graphics); // Only do this sector when a vertexbuffer is created //mxd. No Map means that sector was deleted recently, I suppose diff --git a/Source/Core/Rendering/SurfaceManager.cs b/Source/Core/Rendering/SurfaceManager.cs index 74d058d5..c258eba3 100755 --- a/Source/Core/Rendering/SurfaceManager.cs +++ b/Source/Core/Rendering/SurfaceManager.cs @@ -146,8 +146,8 @@ namespace CodeImp.DoomBuilder.Rendering { if(e.bufferindex == i) { - b.SetBufferSubdata(e.vertexoffset * FlatVertex.Stride, e.floorvertices); - b.SetBufferSubdata((e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); + General.Map.Graphics.SetBufferSubdata(b, e.vertexoffset * FlatVertex.Stride, e.floorvertices); + General.Map.Graphics.SetBufferSubdata(b, (e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); } } @@ -323,8 +323,8 @@ namespace CodeImp.DoomBuilder.Rendering if(!resourcesunloaded) { // Fill buffer - set.buffers[bufferindex].SetBufferSubdata(vertexoffset * FlatVertex.Stride, e.floorvertices); - set.buffers[bufferindex].SetBufferSubdata((vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); + General.Map.Graphics.SetBufferSubdata(set.buffers[bufferindex], vertexoffset * FlatVertex.Stride, e.floorvertices); + General.Map.Graphics.SetBufferSubdata(set.buffers[bufferindex], (vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); } // Set the new location in the buffer @@ -445,8 +445,8 @@ namespace CodeImp.DoomBuilder.Rendering if(!resourcesunloaded) { VertexBuffer vb = set.buffers[e.bufferindex]; - vb.SetBufferSubdata(e.vertexoffset * FlatVertex.Stride, e.floorvertices); - vb.SetBufferSubdata((e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); + General.Map.Graphics.SetBufferSubdata(vb, e.vertexoffset * FlatVertex.Stride, e.floorvertices); + General.Map.Graphics.SetBufferSubdata(vb, (e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); } } } diff --git a/Source/Core/Rendering/TextLabel.cs b/Source/Core/Rendering/TextLabel.cs index 423d72ca..59797672 100755 --- a/Source/Core/Rendering/TextLabel.cs +++ b/Source/Core/Rendering/TextLabel.cs @@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.Rendering PixelColor Color { get; set; } PixelColor BackColor { get; set; } - void Update(float translatex, float translatey, float scalex, float scaley); + void Update(RenderDevice graphics, float translatex, float translatey, float scalex, float scaley); } public class TextLabel : IDisposable, IRenderResource, ITextLabel @@ -106,7 +106,7 @@ namespace CodeImp.DoomBuilder.Rendering public string Text { get { return text; } set { if(text != value) { text = value; textsize = Size.Empty; textureupdateneeded = true; } } } public Font Font { get { return font; } set { font.Dispose(); font = value; textsize = Size.Empty; textureupdateneeded = true; } } //mxd public bool TransformCoords { get { return transformcoords; } set { transformcoords = value; updateneeded = true; } } - public SizeF TextSize { get { if(textureupdateneeded) Update(General.Map.Renderer2D.TranslateX, General.Map.Renderer2D.TranslateY, General.Map.Renderer2D.Scale, -General.Map.Renderer2D.Scale); return textsize; } } + public SizeF TextSize { get { if(textureupdateneeded) Update(General.Map.Graphics, General.Map.Renderer2D.TranslateX, General.Map.Renderer2D.TranslateY, General.Map.Renderer2D.Scale, -General.Map.Renderer2D.Scale); return textsize; } } public TextAlignmentX AlignX { get { return alignx; } set { alignx = value; updateneeded = true; } } public TextAlignmentY AlignY { get { return aligny; } set { aligny = value; updateneeded = true; } } public PixelColor Color { get { return color; } set { if(!color.Equals(value)) { color = value; textureupdateneeded = true; } } } @@ -239,7 +239,7 @@ namespace CodeImp.DoomBuilder.Rendering } // This updates the text if needed - public void Update(float translatex, float translatey, float scalex, float scaley) + public void Update(RenderDevice graphics, float translatex, float translatey, float scalex, float scaley) { // Check if transformation changed and needs to be updated if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey || @@ -329,7 +329,7 @@ namespace CodeImp.DoomBuilder.Rendering // Create label image using (Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin)) { - texture = new Texture(img); + texture = new Texture(graphics, img); } } @@ -340,7 +340,7 @@ namespace CodeImp.DoomBuilder.Rendering } FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + texturesize.Width, beginy + texturesize.Height); - textbuffer.SetBufferData(quad.Vertices); + graphics.SetBufferData(textbuffer, quad.Vertices); } else { diff --git a/Source/Core/Rendering/Texture.cs b/Source/Core/Rendering/Texture.cs index 87032f93..b62f4b70 100644 --- a/Source/Core/Rendering/Texture.cs +++ b/Source/Core/Rendering/Texture.cs @@ -43,20 +43,8 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height); - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - protected static extern void Texture_SetPixels(IntPtr handle, IntPtr data); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - protected static extern IntPtr Texture_Lock(IntPtr handle); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - protected static extern void Texture_Unlock(IntPtr handle); - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] protected static extern void Texture_SetCubeImage(IntPtr handle, int size); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - protected static extern void Texture_SetCubePixels(IntPtr handle, CubeMapFace face, IntPtr data); } public class Texture : BaseTexture @@ -68,22 +56,22 @@ namespace CodeImp.DoomBuilder.Rendering Texture_Set2DImage(Handle, Width, Height); } - public Texture(System.Drawing.Bitmap bitmap) + public Texture(RenderDevice device, System.Drawing.Bitmap bitmap) { Width = bitmap.Width; Height = bitmap.Height; Texture_Set2DImage(Handle, Width, Height); - SetPixels(bitmap); + device.SetPixels(this, bitmap); } - public Texture(System.Drawing.Image image) + public Texture(RenderDevice device, System.Drawing.Image image) { using (var bitmap = new System.Drawing.Bitmap(image)) { Width = bitmap.Width; Height = bitmap.Height; Texture_Set2DImage(Handle, Width, Height); - SetPixels(bitmap); + device.SetPixels(this, bitmap); } } @@ -91,52 +79,14 @@ namespace CodeImp.DoomBuilder.Rendering public int Height { get; private set; } public object Tag { get; set; } - - public void SetPixels(System.Drawing.Bitmap bitmap) - { - System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( - new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, - System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - Texture_SetPixels(Handle, bmpdata.Scan0); - - bitmap.UnlockBits(bmpdata); - } - - internal Plotter LockPlotter(int visibleWidth, int visibleHeight) - { - unsafe - { - IntPtr data = Texture_Lock(Handle); - return new Plotter((PixelColor*)data.ToPointer(), Width, Height, Math.Min(Width, visibleWidth), Math.Min(Height, visibleHeight)); - } - } - - public void UnlockPlotter() - { - Texture_Unlock(Handle); - } } public class CubeTexture : BaseTexture { - public CubeTexture(int size) + public CubeTexture(RenderDevice device, int size) { Texture_SetCubeImage(Handle, size); } - - public void SetPixels(CubeMapFace face, System.Drawing.Bitmap bitmap) - { - System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits( - new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, - System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - Texture_SetCubePixels(Handle, face, bmpdata.Scan0); - - bitmap.UnlockBits(bmpdata); - } } public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ } diff --git a/Source/Core/Rendering/VertexBuffer.cs b/Source/Core/Rendering/VertexBuffer.cs index 07672a86..2cf735cc 100644 --- a/Source/Core/Rendering/VertexBuffer.cs +++ b/Source/Core/Rendering/VertexBuffer.cs @@ -21,32 +21,6 @@ namespace CodeImp.DoomBuilder.Rendering Dispose(); } - public void SetBufferData(FlatVertex[] data) - { - VertexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf()); - } - - public void SetBufferData(WorldVertex[] data) - { - VertexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf()); - } - - public void SetBufferSubdata(long destOffset, FlatVertex[] data) - { - VertexBuffer_SetBufferSubdata(Handle, destOffset, data, data.Length * Marshal.SizeOf()); - } - - public void SetBufferSubdata(long destOffset, WorldVertex[] data) - { - VertexBuffer_SetBufferSubdata(Handle, destOffset, data, data.Length * Marshal.SizeOf()); - } - - public void SetBufferSubdata(long destOffset, FlatVertex[] data, long offset, long size) - { - if (data.Length < size || size < 0) throw new ArgumentOutOfRangeException("size"); - VertexBuffer_SetBufferSubdata(Handle, destOffset, data, size * Marshal.SizeOf()); - } - public bool Disposed { get { return Handle == IntPtr.Zero; } } public void Dispose() @@ -65,17 +39,5 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void VertexBuffer_Delete(IntPtr handle); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void VertexBuffer_SetBufferData(IntPtr handle, FlatVertex[] data, long size); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void VertexBuffer_SetBufferData(IntPtr handle, WorldVertex[] data, long size); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void VertexBuffer_SetBufferSubdata(IntPtr handle, long destOffset, FlatVertex[] data, long sizeInBytes); - - [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] - static extern void VertexBuffer_SetBufferSubdata(IntPtr handle, long destOffset, WorldVertex[] data, long sizeInBytes); } } diff --git a/Source/Core/Rendering/VisualVertexHandle.cs b/Source/Core/Rendering/VisualVertexHandle.cs index 3e0b7679..78d3b375 100755 --- a/Source/Core/Rendering/VisualVertexHandle.cs +++ b/Source/Core/Rendering/VisualVertexHandle.cs @@ -85,7 +85,7 @@ namespace CodeImp.DoomBuilder.Rendering v3, v0 }; upper = new VertexBuffer(WorldVertex.Stride * vu.Length); - upper.SetBufferData(vu); + General.Map.Graphics.SetBufferData(upper, vu); WorldVertex[] vl = new[]{ c, v4, c, v5, @@ -98,7 +98,7 @@ namespace CodeImp.DoomBuilder.Rendering v7, v4 }; lower = new VertexBuffer(WorldVertex.Stride * vl.Length); - lower.SetBufferData(vl); + General.Map.Graphics.SetBufferData(lower, vl); } // This is called before a device is reset diff --git a/Source/Core/VisualModes/VisualSector.cs b/Source/Core/VisualModes/VisualSector.cs index 8b60e6d7..c1b2d6fa 100755 --- a/Source/Core/VisualModes/VisualSector.cs +++ b/Source/Core/VisualModes/VisualSector.cs @@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.VisualModes public virtual void UpdateSectorGeometry(bool includeneighbours) { } // This updates the visual sector - public void Update() + public void Update(RenderDevice graphics) { int numverts = 0; int v = 0; @@ -144,7 +144,7 @@ namespace CodeImp.DoomBuilder.VisualModes { if((g.Vertices != null) && (g.Vertices.Length > 0)) { - geobuffer.SetBufferSubdata(v * WorldVertex.Stride, g.Vertices); + graphics.SetBufferSubdata(geobuffer, v * WorldVertex.Stride, g.Vertices); g.VertexOffset = v; v += g.Vertices.Length; } diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index dae0b897..fea5e1a9 100755 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -511,6 +511,8 @@ namespace CodeImp.DoomBuilder.VisualModes // This updates the visual thing public virtual void Update() { + RenderDevice graphics = General.Map.Graphics; + // Do we need to update the geometry buffer? if(updategeo) { @@ -528,7 +530,7 @@ namespace CodeImp.DoomBuilder.VisualModes geobuffers[i] = new VertexBuffer(WorldVertex.Stride * vertices[i].Length); // Fill the buffer - geobuffers[i].SetBufferData(vertices[i]); + graphics.SetBufferData(geobuffers[i], vertices[i]); } } @@ -613,7 +615,7 @@ namespace CodeImp.DoomBuilder.VisualModes WorldVertex[] cv = cageverts.ToArray(); cagelength = cv.Length / 2; cagebuffer = new VertexBuffer(WorldVertex.Stride * cv.Length); - cagebuffer.SetBufferData(cv); + graphics.SetBufferData(cagebuffer, cv); // Done updatecage = false; diff --git a/Source/Native/IndexBuffer.cpp b/Source/Native/IndexBuffer.cpp index d5a17f82..f822e07a 100644 --- a/Source/Native/IndexBuffer.cpp +++ b/Source/Native/IndexBuffer.cpp @@ -2,7 +2,7 @@ #include "Precomp.h" #include "IndexBuffer.h" -IndexBuffer::IndexBuffer(int sizeInBytes) : mData(sizeInBytes) +IndexBuffer::IndexBuffer(int sizeInBytes) : mSize(sizeInBytes) { } @@ -11,20 +11,13 @@ IndexBuffer::~IndexBuffer() // To do: move mBuffer to a delete list as this might be called by a finalizer in a different thread } -void IndexBuffer::SetBufferData(const void* data, int64_t size) -{ - if (size > 0 && size <= (int64_t)mData.size()) - memcpy(mData.data(), data, size); -} - GLuint IndexBuffer::GetBuffer() { if (mBuffer == 0) { glGenBuffers(1, &mBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mData.size(), mData.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSize, nullptr, GL_STREAM_DRAW); } return mBuffer; } @@ -40,8 +33,3 @@ void IndexBuffer_Delete(IndexBuffer* buffer) { delete buffer; } - -void IndexBuffer_SetBufferData(IndexBuffer* handle, void* data, int64_t size) -{ - handle->SetBufferData(data, size); -} diff --git a/Source/Native/IndexBuffer.h b/Source/Native/IndexBuffer.h index 93010593..6f89b4a9 100644 --- a/Source/Native/IndexBuffer.h +++ b/Source/Native/IndexBuffer.h @@ -6,11 +6,9 @@ public: IndexBuffer(int sizeInBytes); ~IndexBuffer(); - void SetBufferData(const void* data, int64_t size); - GLuint GetBuffer(); private: - std::vector mData; + int64_t mSize = 0; GLuint mBuffer = 0; }; diff --git a/Source/Native/OpenGLContext.cpp b/Source/Native/OpenGLContext.cpp index 596380e2..54c57294 100644 --- a/Source/Native/OpenGLContext.cpp +++ b/Source/Native/OpenGLContext.cpp @@ -96,12 +96,16 @@ OpenGLContext::~OpenGLContext() void OpenGLContext::Begin() { - wglMakeCurrent(dc, context); + refcount++; + if (refcount == 1) + wglMakeCurrent(dc, context); } void OpenGLContext::End() { - wglMakeCurrent(0, 0); + refcount--; + if (refcount == 0) + wglMakeCurrent(0, 0); } void OpenGLContext::SwapBuffers() diff --git a/Source/Native/OpenGLContext.h b/Source/Native/OpenGLContext.h index 59ea8c5a..dc9e1e8b 100644 --- a/Source/Native/OpenGLContext.h +++ b/Source/Native/OpenGLContext.h @@ -19,6 +19,7 @@ private: HWND window; HDC dc; HGLRC context; + int refcount = 0; }; class OpenGLCreationHelper diff --git a/Source/Native/RenderDevice.cpp b/Source/Native/RenderDevice.cpp index 4c3196b9..8ff7f8bc 100644 --- a/Source/Native/RenderDevice.cpp +++ b/Source/Native/RenderDevice.cpp @@ -174,7 +174,7 @@ void RenderDevice::SetSamplerState(int index, TextureAddress addressU, TextureAd mNeedApply = true; } -void RenderDevice::DrawPrimitives(PrimitiveType type, int startIndex, int primitiveCount) +void RenderDevice::Draw(PrimitiveType type, int startIndex, int primitiveCount) { static const int modes[] = { GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP }; static const int toVertexCount[] = { 2, 3, 1 }; @@ -186,7 +186,19 @@ void RenderDevice::DrawPrimitives(PrimitiveType type, int startIndex, int primit Context.End(); } -void RenderDevice::DrawUserPrimitives(PrimitiveType type, int startIndex, int primitiveCount, const void* data) +void RenderDevice::DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) +{ + static const int modes[] = { GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP }; + static const int toVertexCount[] = { 2, 3, 1 }; + static const int toVertexStart[] = { 0, 0, 2 }; + + Context.Begin(); + if (mNeedApply) ApplyChanges(); + glDrawElements(modes[(int)type], toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type], GL_UNSIGNED_INT, (const void*)(startIndex * sizeof(uint32_t))); + Context.End(); +} + +void RenderDevice::DrawStreamed(PrimitiveType type, int startIndex, int primitiveCount, const void* data) { } @@ -225,10 +237,88 @@ void RenderDevice::Present() void RenderDevice::ClearTexture(int backcolor, Texture* texture) { + glBindFramebuffer(GL_FRAMEBUFFER, texture->GetFramebuffer(false)); + glViewport(0, 0, texture->GetWidth(), texture->GetHeight()); + glClearColor(RPART(backcolor) / 255.0f, GPART(backcolor) / 255.0f, BPART(backcolor) / 255.0f, APART(backcolor) / 255.0f); + glClear(GL_COLOR_BUFFER_BIT); } void RenderDevice::CopyTexture(Texture* src, Texture* dst, CubeMapFace face) { + glBindFramebuffer(GL_FRAMEBUFFER, src->GetFramebuffer(false)); + + GLint oldTexture = 0; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); + glBindTexture(GL_TEXTURE_2D, dst->GetTexture()); + glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, 0, 0, dst->GetWidth(), dst->GetHeight(), 0); + glBindTexture(GL_TEXTURE_2D, oldTexture); +} + +void RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size) +{ + Context.Begin(); + GLint oldbinding = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding); + glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer()); + glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, oldbinding); + Context.End(); +} + +void RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) +{ + Context.Begin(); + GLint oldbinding = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding); + glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer()); + glBufferSubData(GL_ARRAY_BUFFER, destOffset, size, data); + glBindBuffer(GL_ARRAY_BUFFER, oldbinding); + Context.End(); +} + +void RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size) +{ + Context.Begin(); + GLint oldbinding = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldbinding); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer()); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldbinding); + Context.End(); +} + +void RenderDevice::SetPixels(Texture* texture, const void* data) +{ + texture->SetPixels(data); + InvalidateTexture(texture); +} + +void RenderDevice::SetCubePixels(Texture* texture, CubeMapFace face, const void* data) +{ + texture->SetCubePixels(face, data); + InvalidateTexture(texture); +} + +void* RenderDevice::LockTexture(Texture* texture) +{ + return texture->Lock(); +} + +void RenderDevice::UnlockTexture(Texture* texture) +{ + texture->Unlock(); + InvalidateTexture(texture); +} + +void RenderDevice::InvalidateTexture(Texture* texture) +{ + if (texture->IsTextureCreated()) + { + Context.Begin(); + texture->Invalidate(); + Context.End(); + mNeedApply = true; + } } void RenderDevice::CheckError() @@ -460,7 +550,16 @@ void RenderDevice::ApplyTextures() void RenderDevice::ApplyRenderTarget(Texture* target, bool usedepthbuffer) { - glViewport(0, 0, Context.GetWidth(), Context.GetHeight()); + if (target) + { + glBindFramebuffer(GL_FRAMEBUFFER, target->GetFramebuffer(usedepthbuffer)); + glViewport(0, 0, target->GetWidth(), target->GetHeight()); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, Context.GetWidth(), Context.GetHeight()); + } } ///////////////////////////////////////////////////////////////////////////// @@ -599,14 +698,19 @@ void RenderDevice_SetSamplerState(RenderDevice* device, int unit, TextureAddress device->SetSamplerState(unit, addressU, addressV, addressW); } -void RenderDevice_DrawPrimitives(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount) +void RenderDevice_Draw(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount) { - device->DrawPrimitives(type, startIndex, primitiveCount); + device->Draw(type, startIndex, primitiveCount); } -void RenderDevice_DrawUserPrimitives(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount, const void* data) +void RenderDevice_DrawIndexed(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount) { - device->DrawUserPrimitives(type, startIndex, primitiveCount, data); + device->DrawIndexed(type, startIndex, primitiveCount); +} + +void RenderDevice_DrawStreamed(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount, const void* data) +{ + device->DrawStreamed(type, startIndex, primitiveCount, data); } void RenderDevice_SetVertexDeclaration(RenderDevice* device, VertexDeclaration* decl) @@ -638,3 +742,38 @@ void RenderDevice_CopyTexture(RenderDevice* device, Texture* src, Texture* dst, { device->CopyTexture(src, dst, face); } + +void RenderDevice_SetVertexBufferData(RenderDevice* device, VertexBuffer* buffer, void* data, int64_t size) +{ + device->SetVertexBufferData(buffer, data, size); +} + +void RenderDevice_SetVertexBufferSubdata(RenderDevice* device, VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) +{ + device->SetVertexBufferSubdata(buffer, destOffset, data, size); +} + +void RenderDevice_SetIndexBufferData(RenderDevice* device, IndexBuffer* buffer, void* data, int64_t size) +{ + device->SetIndexBufferData(buffer, data, size); +} + +void RenderDevice_SetPixels(RenderDevice* device, Texture* texture, const void* data) +{ + device->SetPixels(texture, data); +} + +void RenderDevice_SetCubePixels(RenderDevice* device, Texture* texture, CubeMapFace face, const void* data) +{ + device->SetCubePixels(texture, face, data); +} + +void* RenderDevice_LockTexture(RenderDevice* device, Texture* texture) +{ + return device->LockTexture(texture); +} + +void RenderDevice_UnlockTexture(RenderDevice* device, Texture* texture) +{ + device->UnlockTexture(texture); +} diff --git a/Source/Native/RenderDevice.h b/Source/Native/RenderDevice.h index 1b92d5c8..47db71d2 100644 --- a/Source/Native/RenderDevice.h +++ b/Source/Native/RenderDevice.h @@ -101,8 +101,9 @@ public: void SetTexture(int unit, Texture* texture); void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy); void SetSamplerState(int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW); - void DrawPrimitives(PrimitiveType type, int startIndex, int primitiveCount); - void DrawUserPrimitives(PrimitiveType type, int startIndex, int primitiveCount, const void* data); + void Draw(PrimitiveType type, int startIndex, int primitiveCount); + void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount); + void DrawStreamed(PrimitiveType type, int startIndex, int primitiveCount, const void* data); void SetVertexDeclaration(VertexDeclaration* decl); void StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer); void FinishRendering(); @@ -110,6 +111,17 @@ public: void ClearTexture(int backcolor, Texture* texture); void CopyTexture(Texture* src, Texture* dst, CubeMapFace face); + void SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size); + void SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size); + void SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size); + + void SetPixels(Texture* texture, const void* data); + void SetCubePixels(Texture* texture, CubeMapFace face, const void* data); + void* LockTexture(Texture* texture); + void UnlockTexture(Texture* texture); + + void InvalidateTexture(Texture* texture); + void ApplyChanges(); void ApplyVertexBuffers(); void ApplyIndexBuffer(); diff --git a/Source/Native/Texture.cpp b/Source/Native/Texture.cpp index 52e950c8..fd48ce8c 100644 --- a/Source/Native/Texture.cpp +++ b/Source/Native/Texture.cpp @@ -47,6 +47,18 @@ void Texture::Unlock() { } +void Texture::Invalidate() +{ + if (mDepthRenderbuffer) glDeleteRenderbuffers(1, &mDepthRenderbuffer); + if (mFramebuffer) glDeleteFramebuffers(1, &mFramebuffer); + if (mFramebufferDepth) glDeleteFramebuffers(1, &mFramebufferDepth); + if (mTexture) glDeleteTextures(1, &mTexture); + mTexture = 0; + mFramebuffer = 0; + mFramebufferDepth = 0; + mTexture = 0; +} + GLuint Texture::GetTexture() { if (mTexture == 0) @@ -88,6 +100,41 @@ GLuint Texture::GetTexture() return mTexture; } +GLuint Texture::GetFramebuffer(bool usedepthbuffer) +{ + if (!usedepthbuffer) + { + if (mFramebuffer == 0) + { + GLuint texture = GetTexture(); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); + } + return mFramebuffer; + } + else + { + if (mFramebuffer == mFramebufferDepth) + { + if (mDepthRenderbuffer == 0) + { + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + GLuint texture = GetTexture(); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + } + return mFramebufferDepth; + } +} + ///////////////////////////////////////////////////////////////////////////// Texture* Texture_New() @@ -105,27 +152,7 @@ void Texture_Set2DImage(Texture* handle, int width, int height) handle->Set2DImage(width, height); } -void Texture_SetPixels(Texture* handle, const void* data) -{ - handle->SetPixels(data); -} - -void* Texture_Lock(Texture* handle) -{ - return handle->Lock(); -} - -void Texture_Unlock(Texture* handle) -{ - handle->Unlock(); -} - void Texture_SetCubeImage(Texture* handle, int size) { handle->SetCubeImage(size); } - -void Texture_SetCubePixels(Texture* handle, CubeMapFace face, const void *data) -{ - handle->SetCubePixels(face, data); -} diff --git a/Source/Native/Texture.h b/Source/Native/Texture.h index f547ba98..1f9cbe96 100644 --- a/Source/Native/Texture.h +++ b/Source/Native/Texture.h @@ -26,8 +26,14 @@ public: void Unlock(); bool IsCubeTexture() const { return mCubeTexture; } + int GetWidth() const { return mWidth; } + int GetHeight() const { return mHeight; } + + bool IsTextureCreated() const { return mTexture; } + void Invalidate(); GLuint GetTexture(); + GLuint GetFramebuffer(bool usedepthbuffer); private: int mWidth = 0; @@ -35,4 +41,7 @@ private: bool mCubeTexture = false; std::map> mPixels; GLuint mTexture = 0; + GLuint mFramebuffer = 0; + GLuint mFramebufferDepth = 0; + GLuint mDepthRenderbuffer = 0; }; diff --git a/Source/Native/VertexBuffer.cpp b/Source/Native/VertexBuffer.cpp index 62d0671a..530ea102 100644 --- a/Source/Native/VertexBuffer.cpp +++ b/Source/Native/VertexBuffer.cpp @@ -2,7 +2,7 @@ #include "Precomp.h" #include "VertexBuffer.h" -VertexBuffer::VertexBuffer(int sizeInBytes) : mData(sizeInBytes) +VertexBuffer::VertexBuffer(int sizeInBytes) : mSize(sizeInBytes) { } @@ -11,25 +11,13 @@ VertexBuffer::~VertexBuffer() // To do: move mBuffer to a delete list as this might be called by a finalizer in a different thread } -void VertexBuffer::SetBufferData(const void* data, int64_t size) -{ - if (size > 0 && size <= (int64_t)mData.size()) - memcpy(mData.data(), data, size); -} - -void VertexBuffer::SetBufferSubdata(int64_t destOffset, const void* data, int64_t size) -{ - if (destOffset >= 0 && size > 0 && size <= (int64_t)mData.size() - destOffset) - memcpy(mData.data() + destOffset, data, size); -} - GLuint VertexBuffer::GetBuffer() { if (mBuffer == 0) { glGenBuffers(1, &mBuffer); glBindBuffer(GL_ARRAY_BUFFER, mBuffer); - glBufferData(GL_ARRAY_BUFFER, mData.size(), mData.data(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mSize, nullptr, GL_STREAM_DRAW); } return mBuffer; } @@ -45,13 +33,3 @@ void VertexBuffer_Delete(VertexBuffer* buffer) { delete buffer; } - -void VertexBuffer_SetBufferData(VertexBuffer* handle, void* data, int64_t size) -{ - handle->SetBufferData(data, size); -} - -void VertexBuffer_SetBufferSubdata(VertexBuffer* handle, int64_t destOffset, void* data, int64_t size) -{ - handle->SetBufferSubdata(destOffset, data, size); -} diff --git a/Source/Native/VertexBuffer.h b/Source/Native/VertexBuffer.h index b5da3aef..4d885a39 100644 --- a/Source/Native/VertexBuffer.h +++ b/Source/Native/VertexBuffer.h @@ -6,12 +6,9 @@ public: VertexBuffer(int sizeInBytes); ~VertexBuffer(); - void SetBufferData(const void* data, int64_t size); - void SetBufferSubdata(int64_t destOffset, const void* data, int64_t size); - GLuint GetBuffer(); private: - std::vector mData; + int64_t mSize = 0; GLuint mBuffer = 0; }; diff --git a/Source/Native/exports.def b/Source/Native/exports.def index 9f8e52aa..c75da68c 100644 --- a/Source/Native/exports.def +++ b/Source/Native/exports.def @@ -26,28 +26,29 @@ EXPORTS RenderDevice_SetTexture RenderDevice_SetSamplerFilter RenderDevice_SetSamplerState - RenderDevice_DrawPrimitives - RenderDevice_DrawUserPrimitives + RenderDevice_Draw + RenderDevice_DrawIndexed + RenderDevice_DrawStreamed RenderDevice_SetVertexDeclaration RenderDevice_StartRendering RenderDevice_FinishRendering RenderDevice_Present RenderDevice_ClearTexture RenderDevice_CopyTexture + RenderDevice_SetVertexBufferData + RenderDevice_SetVertexBufferSubdata + RenderDevice_SetIndexBufferData + RenderDevice_SetPixels + RenderDevice_SetCubePixels + RenderDevice_LockTexture + RenderDevice_UnlockTexture VertexBuffer_New VertexBuffer_Delete - VertexBuffer_SetBufferData - VertexBuffer_SetBufferSubdata VertexDeclaration_New VertexDeclaration_Delete IndexBuffer_New IndexBuffer_Delete - IndexBuffer_SetBufferData Texture_New Texture_Delete Texture_Set2DImage - Texture_SetPixels - Texture_Lock - Texture_Unlock Texture_SetCubeImage - Texture_SetCubePixels