- force texture and buffer updating to go through RenderDevice

This commit is contained in:
Magnus Norddahl 2019-08-15 02:52:21 +02:00
parent b41cb07eaa
commit a542385cd7
27 changed files with 410 additions and 248 deletions

View file

@ -3449,7 +3449,7 @@ namespace CodeImp.DoomBuilder.Data
yscale *= 1.65f; yscale *= 1.65f;
// Make cubemap texture // Make cubemap texture
CubeTexture cubemap = new CubeTexture(cubemaptexsize); CubeTexture cubemap = new CubeTexture(General.Map.Graphics, cubemaptexsize);
// Set render settings... // Set render settings...
General.Map.Graphics.SetZEnable(false); 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 // 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) 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 // Draw faces
sides[3].RotateFlip(RotateFlipType.Rotate90FlipNone); sides[3].RotateFlip(RotateFlipType.Rotate90FlipNone);
@ -3669,7 +3669,7 @@ namespace CodeImp.DoomBuilder.Data
private static void DrawCubemapFace(CubeTexture texture, CubeMapFace face, Bitmap image) 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) private static Bitmap ResizeImage(Image image, int width, int height)
@ -3745,7 +3745,7 @@ namespace CodeImp.DoomBuilder.Data
{ {
using (var bitmap = new Bitmap(image)) using (var bitmap = new Bitmap(image))
{ {
return new Texture(bitmap); return new Texture(General.Map.Graphics, bitmap);
} }
} }

View file

@ -467,7 +467,7 @@ namespace CodeImp.DoomBuilder.Data
Bitmap img = bitmap; Bitmap img = bitmap;
if(loadfailed) img = Properties.Resources.Failed; if(loadfailed) img = Properties.Resources.Failed;
texture = new Texture(img); texture = new Texture(General.Map.Graphics, img);
if(dynamictexture) if(dynamictexture)
{ {
@ -492,7 +492,7 @@ namespace CodeImp.DoomBuilder.Data
{ {
if((texture != null) && !texture.Disposed) if((texture != null) && !texture.Disposed)
{ {
texture.SetPixels(bitmap); General.Map.Graphics.SetPixels(texture, bitmap);
} }
} }
} }

View file

@ -989,7 +989,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
} }
//mesh //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 //store in result
result.Meshes.Add(mesh); result.Meshes.Add(mesh);
@ -1163,11 +1163,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
// Create texture new Texture(bmp.Width) // Create texture new Texture(bmp.Width)
using(Bitmap bmp = CreateVoxelTexture(palette)) using(Bitmap bmp = CreateVoxelTexture(palette))
{ {
mde.Model.Textures.Add(new Texture(bmp)); mde.Model.Textures.Add(new Texture(General.Map.Graphics, bmp));
} }
// Create mesh // 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 // Add mesh
mde.Model.Meshes.Add(mesh); mde.Model.Meshes.Add(mesh);
@ -1667,7 +1667,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
if(bitmap != null) if(bitmap != null)
{ {
texture = new Texture(bitmap); texture = new Texture(General.Map.Graphics, bitmap);
} }
return texture; return texture;
@ -1676,7 +1676,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
private static void CreateMesh(ref MD3LoadResult result, List<WorldVertex> verts, List<int> indices) private static void CreateMesh(ref MD3LoadResult result, List<WorldVertex> verts, List<int> indices)
{ {
//create mesh //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 //store in result
result.Meshes.Add(mesh); result.Meshes.Add(mesh);

View file

@ -21,9 +21,9 @@ namespace CodeImp.DoomBuilder.Rendering
public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } } public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } }
public SizeF TextSize { get { return label.TextSize; } } 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);
} }
} }
} }

View file

@ -21,11 +21,6 @@ namespace CodeImp.DoomBuilder.Rendering
Dispose(); Dispose();
} }
public void SetBufferData(int[] data)
{
IndexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf<int>());
}
public bool Disposed { get { return Handle == IntPtr.Zero; } } public bool Disposed { get { return Handle == IntPtr.Zero; } }
public void Dispose() public void Dispose()
@ -44,8 +39,5 @@ namespace CodeImp.DoomBuilder.Rendering
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void IndexBuffer_Delete(IntPtr handle); static extern void IndexBuffer_Delete(IntPtr handle);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void IndexBuffer_SetBufferData(IntPtr handle, int[] data, long size);
} }
} }

View file

@ -8,13 +8,13 @@ namespace CodeImp.DoomBuilder.Rendering
{ {
internal class Mesh : IDisposable 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); VertexDecl = new VertexDeclaration(vertexDecl);
unsafe { Vertices = new VertexBuffer(sizeof(WorldVertex)); } unsafe { Vertices = new VertexBuffer(sizeof(WorldVertex)); }
Vertices.SetBufferData(vertexData); graphics.SetBufferData(Vertices, vertexData);
Indices = new IndexBuffer(sizeof(int) * indexData.Length); Indices = new IndexBuffer(sizeof(int) * indexData.Length);
Indices.SetBufferData(indexData); graphics.SetBufferData(Indices, indexData);
Count = indexData.Length; Count = indexData.Length;
} }
@ -25,15 +25,13 @@ namespace CodeImp.DoomBuilder.Rendering
internal void Draw(RenderDevice device) internal void Draw(RenderDevice device)
{ {
/*
device.SetVertexDeclaration(VertexDecl); device.SetVertexDeclaration(VertexDecl);
device.SetVertexBuffer(0, Vertices, 0, WorldVertex.Stride); device.SetVertexBuffer(0, Vertices, 0, WorldVertex.Stride);
device.SetIndexBuffer(Indices); device.SetIndexBuffer(Indices);
device.DrawElements(0, Count); device.DrawIndexed(PrimitiveType.TriangleList, 0, Count);
device.SetIndexBuffer(null); device.SetIndexBuffer(null);
device.SetVertexBuffer(0, null, 0, 0); device.SetVertexBuffer(0, null, 0, 0);
device.SetVertexDeclaration(null); device.SetVertexDeclaration(null);
*/
} }
public void Dispose() public void Dispose()

View file

@ -28,9 +28,9 @@ using System.Runtime.InteropServices;
namespace CodeImp.DoomBuilder.Rendering 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); Handle = RenderDevice_New(rendertarget.Handle);
if (Handle == IntPtr.Zero) if (Handle == IntPtr.Zero)
@ -230,19 +230,24 @@ namespace CodeImp.DoomBuilder.Rendering
RenderDevice_SetSamplerState(Handle, unit, addressU, addressV, addressW); 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) 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) 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) 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) public void StartRendering(bool clear, Color4 backcolor)
@ -275,6 +280,75 @@ namespace CodeImp.DoomBuilder.Rendering
RenderDevice_CopyTexture(Handle, src.Handle, dst.Handle, face); 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<int>());
}
public void SetBufferData(VertexBuffer buffer, FlatVertex[] data)
{
RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<FlatVertex>());
}
public void SetBufferData(VertexBuffer buffer, WorldVertex[] data)
{
RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<WorldVertex>());
}
public void SetBufferSubdata(VertexBuffer buffer, long destOffset, FlatVertex[] data)
{
RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset, data, data.Length * Marshal.SizeOf<FlatVertex>());
}
public void SetBufferSubdata(VertexBuffer buffer, long destOffset, WorldVertex[] data)
{
RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset, data, data.Length * Marshal.SizeOf<WorldVertex>());
}
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<FlatVertex>());
}
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) 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); static extern void RenderDevice_SetSamplerState(IntPtr handle, int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [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)] [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)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexDeclaration(IntPtr handle, IntPtr decl); static extern void RenderDevice_SetVertexDeclaration(IntPtr handle, IntPtr decl);
@ -417,6 +494,33 @@ namespace CodeImp.DoomBuilder.Rendering
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_CopyTexture(IntPtr handle, IntPtr src, IntPtr dst, CubeMapFace face); 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 //mxd. Anisotropic filtering steps
public static readonly List<float> AF_STEPS = new List<float> { 1.0f, 2.0f, 4.0f, 8.0f, 16.0f }; public static readonly List<float> AF_STEPS = new List<float> { 1.0f, 2.0f, 4.0f, 8.0f, 16.0f };

View file

@ -385,7 +385,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Make screen vertices // Make screen vertices
FlatVertex[] verts = CreateScreenVerts(structsize); FlatVertex[] verts = CreateScreenVerts(structsize);
screenverts.SetBufferData(verts); graphics.SetBufferData(screenverts, verts);
// Force update of view // Force update of view
lastgridscale = -1f; lastgridscale = -1f;
@ -623,7 +623,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(plottertex != null) if(plottertex != null)
{ {
// Create structures plotter // 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 // Redraw grid when structures image was cleared
if(clear) if(clear)
@ -709,7 +709,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Clean up plotter // Clean up plotter
if(renderlayer == RenderLayers.Plotter) if(renderlayer == RenderLayers.Plotter)
{ {
if(plottertex != null) plottertex.UnlockPlotter(); if(plottertex != null) graphics.UnlockPlotter(plottertex);
plotter = null; plotter = null;
} }
@ -778,7 +778,7 @@ namespace CodeImp.DoomBuilder.Rendering
lastgridx != offsetx || lastgridy != offsety || drawmapcenter != lastdrawmapcenter) lastgridx != offsetx || lastgridy != offsety || drawmapcenter != lastdrawmapcenter)
{ {
// Create a plotter // Create a plotter
Plotter gridplotter = backtex.LockPlotter(backsize.Width, backsize.Height); Plotter gridplotter = graphics.LockPlotter(backtex, backsize.Width, backsize.Height);
gridplotter.Clear(); gridplotter.Clear();
if(General.Settings.RenderGrid) //mxd 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); gridplotter.DrawLineSolid(cx - MAP_CENTER_SIZE, cy, cx + MAP_CENTER_SIZE, cy, ref c);
} }
// Done // Done
backtex.UnlockPlotter(); graphics.UnlockPlotter(backtex);
lastgridscale = scale; lastgridscale = scale;
lastgridsize = General.Map.Grid.GridSizeF; lastgridsize = General.Map.Grid.GridSizeF;
lastgridx = offsetx; lastgridx = offsetx;
@ -1258,7 +1258,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(buffercount == locksize) if(buffercount == locksize)
{ {
// Write to buffer // Write to buffer
thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6);
// Draw! // Draw!
graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
@ -1270,7 +1270,7 @@ namespace CodeImp.DoomBuilder.Rendering
} }
// Write to buffer // 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 // Draw what's still remaining
if(buffercount > 0) if(buffercount > 0)
@ -1397,7 +1397,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(buffercount == locksize) if(buffercount == locksize)
{ {
// Write to buffer // Write to buffer
thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6);
// Draw! // Draw!
graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
@ -1410,7 +1410,7 @@ namespace CodeImp.DoomBuilder.Rendering
} }
// Write to buffer // Write to buffer
thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6);
// Draw what's still remaining // Draw what's still remaining
if(buffercount > 0) graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); if(buffercount > 0) graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
@ -1441,7 +1441,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(buffercount == locksize) if(buffercount == locksize)
{ {
// Write to buffer // Write to buffer
thingsvertices.SetBufferSubdata(0, verts, 0, buffercount * 6); graphics.SetBufferSubdata(thingsvertices, 0, verts, 0, buffercount * 6);
// Draw! // Draw!
graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
@ -1453,7 +1453,7 @@ namespace CodeImp.DoomBuilder.Rendering
} }
// Write to buffer // 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 // Draw what's still remaining
if(buffercount > 0) if(buffercount > 0)
@ -1662,7 +1662,7 @@ namespace CodeImp.DoomBuilder.Rendering
public void RenderText(ITextLabel label) public void RenderText(ITextLabel label)
{ {
//mxd. Update the text if needed //mxd. Update the text if needed
label.Update(translatex, translatey, scale, -scale); label.Update(graphics, translatex, translatey, scale, -scale);
if(label.SkipRendering) return; if(label.SkipRendering) return;
// Set renderstates for rendering // Set renderstates for rendering
@ -1691,7 +1691,7 @@ namespace CodeImp.DoomBuilder.Rendering
foreach(ITextLabel label in labels) foreach(ITextLabel label in labels)
{ {
// Update the text if needed // Update the text if needed
label.Update(translatex, translatey, scale, -scale); label.Update(graphics, translatex, translatey, scale, -scale);
if(label.SkipRendering) skipped++; if(label.SkipRendering) skipped++;
} }
@ -1932,7 +1932,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Write to buffer // Write to buffer
VertexBuffer vb = new VertexBuffer(FlatVertex.Stride * verts.Length); VertexBuffer vb = new VertexBuffer(FlatVertex.Stride * verts.Length);
vb.SetBufferData(verts); graphics.SetBufferData(vb, verts);
// Set renderstates for rendering // Set renderstates for rendering
graphics.SetCullMode(Cull.None); graphics.SetCullMode(Cull.None);

View file

@ -708,7 +708,7 @@ namespace CodeImp.DoomBuilder.Rendering
} }
VertexBuffer vb = new VertexBuffer(WorldVertex.Stride * verts.Length); VertexBuffer vb = new VertexBuffer(WorldVertex.Stride * verts.Length);
vb.SetBufferData(verts); graphics.SetBufferData(vb, verts);
//begin rendering //begin rendering
graphics.SetAlphaBlendEnable(true); graphics.SetAlphaBlendEnable(true);
@ -771,7 +771,7 @@ namespace CodeImp.DoomBuilder.Rendering
if(!object.ReferenceEquals(g.Sector, sector)) if(!object.ReferenceEquals(g.Sector, sector))
{ {
// Update the sector if needed // 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 // Only do this sector when a vertexbuffer is created
//mxd. No Map means that sector was deleted recently, I suppose //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)) if(!object.ReferenceEquals(g.Sector, sector))
{ {
// Update the sector if needed // 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 // Only do this sector when a vertexbuffer is created
//mxd. No Map means that sector was deleted recently, I suppose //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)) if(!object.ReferenceEquals(g.Sector, sector))
{ {
// Update the sector if needed // 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 // Only do this sector when a vertexbuffer is created
//mxd. No Map means that sector was deleted recently, I suppose //mxd. No Map means that sector was deleted recently, I suppose

View file

@ -146,8 +146,8 @@ namespace CodeImp.DoomBuilder.Rendering
{ {
if(e.bufferindex == i) if(e.bufferindex == i)
{ {
b.SetBufferSubdata(e.vertexoffset * FlatVertex.Stride, e.floorvertices); General.Map.Graphics.SetBufferSubdata(b, e.vertexoffset * FlatVertex.Stride, e.floorvertices);
b.SetBufferSubdata((e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); General.Map.Graphics.SetBufferSubdata(b, (e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices);
} }
} }
@ -323,8 +323,8 @@ namespace CodeImp.DoomBuilder.Rendering
if(!resourcesunloaded) if(!resourcesunloaded)
{ {
// Fill buffer // Fill buffer
set.buffers[bufferindex].SetBufferSubdata(vertexoffset * FlatVertex.Stride, e.floorvertices); General.Map.Graphics.SetBufferSubdata(set.buffers[bufferindex], 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 + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices);
} }
// Set the new location in the buffer // Set the new location in the buffer
@ -445,8 +445,8 @@ namespace CodeImp.DoomBuilder.Rendering
if(!resourcesunloaded) if(!resourcesunloaded)
{ {
VertexBuffer vb = set.buffers[e.bufferindex]; VertexBuffer vb = set.buffers[e.bufferindex];
vb.SetBufferSubdata(e.vertexoffset * FlatVertex.Stride, e.floorvertices); General.Map.Graphics.SetBufferSubdata(vb, e.vertexoffset * FlatVertex.Stride, e.floorvertices);
vb.SetBufferSubdata((e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices); General.Map.Graphics.SetBufferSubdata(vb, (e.vertexoffset + e.floorvertices.Length) * FlatVertex.Stride, e.ceilvertices);
} }
} }
} }

View file

@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.Rendering
PixelColor Color { get; set; } PixelColor Color { get; set; }
PixelColor BackColor { 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 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 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 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 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 TextAlignmentX AlignX { get { return alignx; } set { alignx = value; updateneeded = true; } }
public TextAlignmentY AlignY { get { return aligny; } set { aligny = 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; } } } 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 // 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 // Check if transformation changed and needs to be updated
if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey || if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey ||
@ -329,7 +329,7 @@ namespace CodeImp.DoomBuilder.Rendering
// Create label image // Create label image
using (Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin)) 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); FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + texturesize.Width, beginy + texturesize.Height);
textbuffer.SetBufferData(quad.Vertices); graphics.SetBufferData(textbuffer, quad.Vertices);
} }
else else
{ {

View file

@ -43,20 +43,8 @@ namespace CodeImp.DoomBuilder.Rendering
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height); 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)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_SetCubeImage(IntPtr handle, int size); 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 public class Texture : BaseTexture
@ -68,22 +56,22 @@ namespace CodeImp.DoomBuilder.Rendering
Texture_Set2DImage(Handle, Width, Height); Texture_Set2DImage(Handle, Width, Height);
} }
public Texture(System.Drawing.Bitmap bitmap) public Texture(RenderDevice device, System.Drawing.Bitmap bitmap)
{ {
Width = bitmap.Width; Width = bitmap.Width;
Height = bitmap.Height; Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, 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)) using (var bitmap = new System.Drawing.Bitmap(image))
{ {
Width = bitmap.Width; Width = bitmap.Width;
Height = bitmap.Height; Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, 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 int Height { get; private set; }
public object Tag { get; 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 class CubeTexture : BaseTexture
{ {
public CubeTexture(int size) public CubeTexture(RenderDevice device, int size)
{ {
Texture_SetCubeImage(Handle, 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 } public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ }

View file

@ -21,32 +21,6 @@ namespace CodeImp.DoomBuilder.Rendering
Dispose(); Dispose();
} }
public void SetBufferData(FlatVertex[] data)
{
VertexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf<FlatVertex>());
}
public void SetBufferData(WorldVertex[] data)
{
VertexBuffer_SetBufferData(Handle, data, data.Length * Marshal.SizeOf<WorldVertex>());
}
public void SetBufferSubdata(long destOffset, FlatVertex[] data)
{
VertexBuffer_SetBufferSubdata(Handle, destOffset, data, data.Length * Marshal.SizeOf<FlatVertex>());
}
public void SetBufferSubdata(long destOffset, WorldVertex[] data)
{
VertexBuffer_SetBufferSubdata(Handle, destOffset, data, data.Length * Marshal.SizeOf<WorldVertex>());
}
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<FlatVertex>());
}
public bool Disposed { get { return Handle == IntPtr.Zero; } } public bool Disposed { get { return Handle == IntPtr.Zero; } }
public void Dispose() public void Dispose()
@ -65,17 +39,5 @@ namespace CodeImp.DoomBuilder.Rendering
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void VertexBuffer_Delete(IntPtr handle); 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);
} }
} }

View file

@ -85,7 +85,7 @@ namespace CodeImp.DoomBuilder.Rendering
v3, v0 }; v3, v0 };
upper = new VertexBuffer(WorldVertex.Stride * vu.Length); upper = new VertexBuffer(WorldVertex.Stride * vu.Length);
upper.SetBufferData(vu); General.Map.Graphics.SetBufferData(upper, vu);
WorldVertex[] vl = new[]{ c, v4, WorldVertex[] vl = new[]{ c, v4,
c, v5, c, v5,
@ -98,7 +98,7 @@ namespace CodeImp.DoomBuilder.Rendering
v7, v4 }; v7, v4 };
lower = new VertexBuffer(WorldVertex.Stride * vl.Length); lower = new VertexBuffer(WorldVertex.Stride * vl.Length);
lower.SetBufferData(vl); General.Map.Graphics.SetBufferData(lower, vl);
} }
// This is called before a device is reset // This is called before a device is reset

View file

@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.VisualModes
public virtual void UpdateSectorGeometry(bool includeneighbours) { } public virtual void UpdateSectorGeometry(bool includeneighbours) { }
// This updates the visual sector // This updates the visual sector
public void Update() public void Update(RenderDevice graphics)
{ {
int numverts = 0; int numverts = 0;
int v = 0; int v = 0;
@ -144,7 +144,7 @@ namespace CodeImp.DoomBuilder.VisualModes
{ {
if((g.Vertices != null) && (g.Vertices.Length > 0)) 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; g.VertexOffset = v;
v += g.Vertices.Length; v += g.Vertices.Length;
} }

View file

@ -511,6 +511,8 @@ namespace CodeImp.DoomBuilder.VisualModes
// This updates the visual thing // This updates the visual thing
public virtual void Update() public virtual void Update()
{ {
RenderDevice graphics = General.Map.Graphics;
// Do we need to update the geometry buffer? // Do we need to update the geometry buffer?
if(updategeo) if(updategeo)
{ {
@ -528,7 +530,7 @@ namespace CodeImp.DoomBuilder.VisualModes
geobuffers[i] = new VertexBuffer(WorldVertex.Stride * vertices[i].Length); geobuffers[i] = new VertexBuffer(WorldVertex.Stride * vertices[i].Length);
// Fill the buffer // 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(); WorldVertex[] cv = cageverts.ToArray();
cagelength = cv.Length / 2; cagelength = cv.Length / 2;
cagebuffer = new VertexBuffer(WorldVertex.Stride * cv.Length); cagebuffer = new VertexBuffer(WorldVertex.Stride * cv.Length);
cagebuffer.SetBufferData(cv); graphics.SetBufferData(cagebuffer, cv);
// Done // Done
updatecage = false; updatecage = false;

View file

@ -2,7 +2,7 @@
#include "Precomp.h" #include "Precomp.h"
#include "IndexBuffer.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 // 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() GLuint IndexBuffer::GetBuffer()
{ {
if (mBuffer == 0) if (mBuffer == 0)
{ {
glGenBuffers(1, &mBuffer); glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mData.size(), mData.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSize, nullptr, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
return mBuffer; return mBuffer;
} }
@ -40,8 +33,3 @@ void IndexBuffer_Delete(IndexBuffer* buffer)
{ {
delete buffer; delete buffer;
} }
void IndexBuffer_SetBufferData(IndexBuffer* handle, void* data, int64_t size)
{
handle->SetBufferData(data, size);
}

View file

@ -6,11 +6,9 @@ public:
IndexBuffer(int sizeInBytes); IndexBuffer(int sizeInBytes);
~IndexBuffer(); ~IndexBuffer();
void SetBufferData(const void* data, int64_t size);
GLuint GetBuffer(); GLuint GetBuffer();
private: private:
std::vector<uint8_t> mData; int64_t mSize = 0;
GLuint mBuffer = 0; GLuint mBuffer = 0;
}; };

View file

@ -96,12 +96,16 @@ OpenGLContext::~OpenGLContext()
void OpenGLContext::Begin() void OpenGLContext::Begin()
{ {
wglMakeCurrent(dc, context); refcount++;
if (refcount == 1)
wglMakeCurrent(dc, context);
} }
void OpenGLContext::End() void OpenGLContext::End()
{ {
wglMakeCurrent(0, 0); refcount--;
if (refcount == 0)
wglMakeCurrent(0, 0);
} }
void OpenGLContext::SwapBuffers() void OpenGLContext::SwapBuffers()

View file

@ -19,6 +19,7 @@ private:
HWND window; HWND window;
HDC dc; HDC dc;
HGLRC context; HGLRC context;
int refcount = 0;
}; };
class OpenGLCreationHelper class OpenGLCreationHelper

View file

@ -174,7 +174,7 @@ void RenderDevice::SetSamplerState(int index, TextureAddress addressU, TextureAd
mNeedApply = true; 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 modes[] = { GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP };
static const int toVertexCount[] = { 2, 3, 1 }; static const int toVertexCount[] = { 2, 3, 1 };
@ -186,7 +186,19 @@ void RenderDevice::DrawPrimitives(PrimitiveType type, int startIndex, int primit
Context.End(); 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) 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) 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() void RenderDevice::CheckError()
@ -460,7 +550,16 @@ void RenderDevice::ApplyTextures()
void RenderDevice::ApplyRenderTarget(Texture* target, bool usedepthbuffer) 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); 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) 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); 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);
}

View file

@ -101,8 +101,9 @@ public:
void SetTexture(int unit, Texture* texture); void SetTexture(int unit, Texture* texture);
void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy); void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy);
void SetSamplerState(int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW); void SetSamplerState(int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW);
void DrawPrimitives(PrimitiveType type, int startIndex, int primitiveCount); void Draw(PrimitiveType type, int startIndex, int primitiveCount);
void DrawUserPrimitives(PrimitiveType type, int startIndex, int primitiveCount, const void* data); void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount);
void DrawStreamed(PrimitiveType type, int startIndex, int primitiveCount, const void* data);
void SetVertexDeclaration(VertexDeclaration* decl); void SetVertexDeclaration(VertexDeclaration* decl);
void StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer); void StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer);
void FinishRendering(); void FinishRendering();
@ -110,6 +111,17 @@ public:
void ClearTexture(int backcolor, Texture* texture); void ClearTexture(int backcolor, Texture* texture);
void CopyTexture(Texture* src, Texture* dst, CubeMapFace face); 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 ApplyChanges();
void ApplyVertexBuffers(); void ApplyVertexBuffers();
void ApplyIndexBuffer(); void ApplyIndexBuffer();

View file

@ -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() GLuint Texture::GetTexture()
{ {
if (mTexture == 0) if (mTexture == 0)
@ -88,6 +100,41 @@ GLuint Texture::GetTexture()
return mTexture; 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() Texture* Texture_New()
@ -105,27 +152,7 @@ void Texture_Set2DImage(Texture* handle, int width, int height)
handle->Set2DImage(width, 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) void Texture_SetCubeImage(Texture* handle, int size)
{ {
handle->SetCubeImage(size); handle->SetCubeImage(size);
} }
void Texture_SetCubePixels(Texture* handle, CubeMapFace face, const void *data)
{
handle->SetCubePixels(face, data);
}

View file

@ -26,8 +26,14 @@ public:
void Unlock(); void Unlock();
bool IsCubeTexture() const { return mCubeTexture; } 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 GetTexture();
GLuint GetFramebuffer(bool usedepthbuffer);
private: private:
int mWidth = 0; int mWidth = 0;
@ -35,4 +41,7 @@ private:
bool mCubeTexture = false; bool mCubeTexture = false;
std::map<int, std::vector<uint32_t>> mPixels; std::map<int, std::vector<uint32_t>> mPixels;
GLuint mTexture = 0; GLuint mTexture = 0;
GLuint mFramebuffer = 0;
GLuint mFramebufferDepth = 0;
GLuint mDepthRenderbuffer = 0;
}; };

View file

@ -2,7 +2,7 @@
#include "Precomp.h" #include "Precomp.h"
#include "VertexBuffer.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 // 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() GLuint VertexBuffer::GetBuffer()
{ {
if (mBuffer == 0) if (mBuffer == 0)
{ {
glGenBuffers(1, &mBuffer); glGenBuffers(1, &mBuffer);
glBindBuffer(GL_ARRAY_BUFFER, 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; return mBuffer;
} }
@ -45,13 +33,3 @@ void VertexBuffer_Delete(VertexBuffer* buffer)
{ {
delete 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);
}

View file

@ -6,12 +6,9 @@ public:
VertexBuffer(int sizeInBytes); VertexBuffer(int sizeInBytes);
~VertexBuffer(); ~VertexBuffer();
void SetBufferData(const void* data, int64_t size);
void SetBufferSubdata(int64_t destOffset, const void* data, int64_t size);
GLuint GetBuffer(); GLuint GetBuffer();
private: private:
std::vector<uint8_t> mData; int64_t mSize = 0;
GLuint mBuffer = 0; GLuint mBuffer = 0;
}; };

View file

@ -26,28 +26,29 @@ EXPORTS
RenderDevice_SetTexture RenderDevice_SetTexture
RenderDevice_SetSamplerFilter RenderDevice_SetSamplerFilter
RenderDevice_SetSamplerState RenderDevice_SetSamplerState
RenderDevice_DrawPrimitives RenderDevice_Draw
RenderDevice_DrawUserPrimitives RenderDevice_DrawIndexed
RenderDevice_DrawStreamed
RenderDevice_SetVertexDeclaration RenderDevice_SetVertexDeclaration
RenderDevice_StartRendering RenderDevice_StartRendering
RenderDevice_FinishRendering RenderDevice_FinishRendering
RenderDevice_Present RenderDevice_Present
RenderDevice_ClearTexture RenderDevice_ClearTexture
RenderDevice_CopyTexture RenderDevice_CopyTexture
RenderDevice_SetVertexBufferData
RenderDevice_SetVertexBufferSubdata
RenderDevice_SetIndexBufferData
RenderDevice_SetPixels
RenderDevice_SetCubePixels
RenderDevice_LockTexture
RenderDevice_UnlockTexture
VertexBuffer_New VertexBuffer_New
VertexBuffer_Delete VertexBuffer_Delete
VertexBuffer_SetBufferData
VertexBuffer_SetBufferSubdata
VertexDeclaration_New VertexDeclaration_New
VertexDeclaration_Delete VertexDeclaration_Delete
IndexBuffer_New IndexBuffer_New
IndexBuffer_Delete IndexBuffer_Delete
IndexBuffer_SetBufferData
Texture_New Texture_New
Texture_Delete Texture_Delete
Texture_Set2DImage Texture_Set2DImage
Texture_SetPixels
Texture_Lock
Texture_Unlock
Texture_SetCubeImage Texture_SetCubeImage
Texture_SetCubePixels