Fix the error handling: only create one call unless there's an error and only check for errors in functions that can fail

This commit is contained in:
Magnus Norddahl 2019-12-20 03:39:06 +01:00
parent 4274ee2893
commit 80f815cad9
5 changed files with 218 additions and 252 deletions

View file

@ -64,16 +64,10 @@ namespace CodeImp.DoomBuilder.Rendering
public bool Disposed { get { return Handle == IntPtr.Zero; } } public bool Disposed { get { return Handle == IntPtr.Zero; } }
public void ClearError() void ThrowIfFailed(bool result)
{ {
RenderDevice_GetError(Handle); if (!result)
} throw new RenderDeviceException(Marshal.PtrToStringAnsi(RenderDevice_GetError(Handle)));
private void CheckAndThrow()
{
string err = Marshal.PtrToStringAnsi(RenderDevice_GetError(Handle));
if (err != "")
throw new RenderDeviceException(err);
} }
public void Dispose() public void Dispose()
@ -88,249 +82,208 @@ namespace CodeImp.DoomBuilder.Rendering
public void SetShader(ShaderName shader) public void SetShader(ShaderName shader)
{ {
RenderDevice_SetShader(Handle, shader); RenderDevice_SetShader(Handle, shader);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, bool value) public void SetUniform(UniformName uniform, bool value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value ? 1.0f : 0.0f }, 1); RenderDevice_SetUniform(Handle, uniform, new float[] { value ? 1.0f : 0.0f }, 1);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, float value) public void SetUniform(UniformName uniform, float value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value }, 1); RenderDevice_SetUniform(Handle, uniform, new float[] { value }, 1);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, Vector2 value) public void SetUniform(UniformName uniform, Vector2 value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y }, 2); RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y }, 2);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, Vector3 value) public void SetUniform(UniformName uniform, Vector3 value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z }, 3); RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z }, 3);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, Vector4 value) public void SetUniform(UniformName uniform, Vector4 value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z, value.W }, 4); RenderDevice_SetUniform(Handle, uniform, new float[] { value.X, value.Y, value.Z, value.W }, 4);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, Color4 value) public void SetUniform(UniformName uniform, Color4 value)
{ {
RenderDevice_SetUniform(Handle, uniform, new float[] { value.Red, value.Green, value.Blue, value.Alpha }, 4); RenderDevice_SetUniform(Handle, uniform, new float[] { value.Red, value.Green, value.Blue, value.Alpha }, 4);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, Matrix matrix) public void SetUniform(UniformName uniform, Matrix matrix)
{ {
RenderDevice_SetUniform(Handle, uniform, ref matrix, 16); RenderDevice_SetUniform(Handle, uniform, ref matrix, 16);
CheckAndThrow();
} }
public void SetUniform(UniformName uniform, ref Matrix matrix) public void SetUniform(UniformName uniform, ref Matrix matrix)
{ {
RenderDevice_SetUniform(Handle, uniform, ref matrix, 16); RenderDevice_SetUniform(Handle, uniform, ref matrix, 16);
CheckAndThrow();
} }
public void SetVertexBuffer(VertexBuffer buffer) public void SetVertexBuffer(VertexBuffer buffer)
{ {
RenderDevice_SetVertexBuffer(Handle, buffer != null ? buffer.Handle : IntPtr.Zero); RenderDevice_SetVertexBuffer(Handle, buffer != null ? buffer.Handle : IntPtr.Zero);
CheckAndThrow();
} }
public void SetIndexBuffer(IndexBuffer buffer) public void SetIndexBuffer(IndexBuffer buffer)
{ {
RenderDevice_SetIndexBuffer(Handle, buffer != null ? buffer.Handle : IntPtr.Zero); RenderDevice_SetIndexBuffer(Handle, buffer != null ? buffer.Handle : IntPtr.Zero);
CheckAndThrow();
} }
public void SetAlphaBlendEnable(bool value) public void SetAlphaBlendEnable(bool value)
{ {
RenderDevice_SetAlphaBlendEnable(Handle, value); RenderDevice_SetAlphaBlendEnable(Handle, value);
CheckAndThrow();
} }
public void SetAlphaTestEnable(bool value) public void SetAlphaTestEnable(bool value)
{ {
RenderDevice_SetAlphaTestEnable(Handle, value); RenderDevice_SetAlphaTestEnable(Handle, value);
CheckAndThrow();
} }
public void SetCullMode(Cull mode) public void SetCullMode(Cull mode)
{ {
RenderDevice_SetCullMode(Handle, mode); RenderDevice_SetCullMode(Handle, mode);
CheckAndThrow();
} }
public void SetBlendOperation(BlendOperation op) public void SetBlendOperation(BlendOperation op)
{ {
RenderDevice_SetBlendOperation(Handle, op); RenderDevice_SetBlendOperation(Handle, op);
CheckAndThrow();
} }
public void SetSourceBlend(Blend blend) public void SetSourceBlend(Blend blend)
{ {
RenderDevice_SetSourceBlend(Handle, blend); RenderDevice_SetSourceBlend(Handle, blend);
CheckAndThrow();
} }
public void SetDestinationBlend(Blend blend) public void SetDestinationBlend(Blend blend)
{ {
RenderDevice_SetDestinationBlend(Handle, blend); RenderDevice_SetDestinationBlend(Handle, blend);
CheckAndThrow();
} }
public void SetFillMode(FillMode mode) public void SetFillMode(FillMode mode)
{ {
RenderDevice_SetFillMode(Handle, mode); RenderDevice_SetFillMode(Handle, mode);
CheckAndThrow();
} }
public void SetMultisampleAntialias(bool value) public void SetMultisampleAntialias(bool value)
{ {
RenderDevice_SetMultisampleAntialias(Handle, value); RenderDevice_SetMultisampleAntialias(Handle, value);
CheckAndThrow();
} }
public void SetZEnable(bool value) public void SetZEnable(bool value)
{ {
RenderDevice_SetZEnable(Handle, value); RenderDevice_SetZEnable(Handle, value);
CheckAndThrow();
} }
public void SetZWriteEnable(bool value) public void SetZWriteEnable(bool value)
{ {
RenderDevice_SetZWriteEnable(Handle, value); RenderDevice_SetZWriteEnable(Handle, value);
CheckAndThrow();
} }
public void SetTexture(BaseTexture value) public void SetTexture(BaseTexture value)
{ {
RenderDevice_SetTexture(Handle, value != null ? value.Handle : IntPtr.Zero); RenderDevice_SetTexture(Handle, value != null ? value.Handle : IntPtr.Zero);
CheckAndThrow();
} }
public void SetSamplerFilter(TextureFilter filter) public void SetSamplerFilter(TextureFilter filter)
{ {
SetSamplerFilter(filter, filter, TextureFilter.None, 0.0f); SetSamplerFilter(filter, filter, TextureFilter.None, 0.0f);
CheckAndThrow();
} }
public void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy) public void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy)
{ {
RenderDevice_SetSamplerFilter(Handle, minfilter, magfilter, mipfilter, maxanisotropy); RenderDevice_SetSamplerFilter(Handle, minfilter, magfilter, mipfilter, maxanisotropy);
CheckAndThrow();
} }
public void SetSamplerState(TextureAddress address) public void SetSamplerState(TextureAddress address)
{ {
RenderDevice_SetSamplerState(Handle, address); RenderDevice_SetSamplerState(Handle, address);
CheckAndThrow();
} }
public void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) public void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount)
{ {
RenderDevice_DrawIndexed(Handle, type, startIndex, primitiveCount); ThrowIfFailed(RenderDevice_DrawIndexed(Handle, type, startIndex, primitiveCount));
CheckAndThrow();
} }
public void Draw(PrimitiveType type, int startIndex, int primitiveCount) public void Draw(PrimitiveType type, int startIndex, int primitiveCount)
{ {
RenderDevice_Draw(Handle, type, startIndex, primitiveCount); ThrowIfFailed(RenderDevice_Draw(Handle, type, startIndex, primitiveCount));
CheckAndThrow();
} }
public void Draw(PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data) public void Draw(PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data)
{ {
RenderDevice_DrawData(Handle, type, startIndex, primitiveCount, data); ThrowIfFailed(RenderDevice_DrawData(Handle, type, startIndex, primitiveCount, data));
CheckAndThrow();
} }
public void StartRendering(bool clear, Color4 backcolor) public void StartRendering(bool clear, Color4 backcolor)
{ {
RenderDevice_StartRendering(Handle, clear, backcolor.ToArgb(), IntPtr.Zero, true); ThrowIfFailed(RenderDevice_StartRendering(Handle, clear, backcolor.ToArgb(), IntPtr.Zero, true));
CheckAndThrow();
} }
public void StartRendering(bool clear, Color4 backcolor, Texture target, bool usedepthbuffer) public void StartRendering(bool clear, Color4 backcolor, Texture target, bool usedepthbuffer)
{ {
RenderDevice_StartRendering(Handle, clear, backcolor.ToArgb(), target.Handle, usedepthbuffer); ThrowIfFailed(RenderDevice_StartRendering(Handle, clear, backcolor.ToArgb(), target.Handle, usedepthbuffer));
CheckAndThrow();
} }
public void FinishRendering() public void FinishRendering()
{ {
RenderDevice_FinishRendering(Handle); ThrowIfFailed(RenderDevice_FinishRendering(Handle));
CheckAndThrow();
} }
public void Present() public void Present()
{ {
RenderDevice_Present(Handle); ThrowIfFailed(RenderDevice_Present(Handle));
CheckAndThrow();
} }
public void ClearTexture(Color4 backcolor, Texture texture) public void ClearTexture(Color4 backcolor, Texture texture)
{ {
RenderDevice_ClearTexture(Handle, backcolor.ToArgb(), texture.Handle); ThrowIfFailed(RenderDevice_ClearTexture(Handle, backcolor.ToArgb(), texture.Handle));
CheckAndThrow();
} }
public void CopyTexture(CubeTexture dst, CubeMapFace face) public void CopyTexture(CubeTexture dst, CubeMapFace face)
{ {
RenderDevice_CopyTexture(Handle, dst.Handle, face); ThrowIfFailed(RenderDevice_CopyTexture(Handle, dst.Handle, face));
CheckAndThrow();
} }
public void SetBufferData(IndexBuffer buffer, int[] data) public void SetBufferData(IndexBuffer buffer, int[] data)
{ {
RenderDevice_SetIndexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<int>()); ThrowIfFailed(RenderDevice_SetIndexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<int>()));
CheckAndThrow();
} }
public void SetBufferData(VertexBuffer buffer, int length, VertexFormat format) public void SetBufferData(VertexBuffer buffer, int length, VertexFormat format)
{ {
int stride = (format == VertexFormat.Flat) ? FlatVertex.Stride : WorldVertex.Stride; int stride = (format == VertexFormat.Flat) ? FlatVertex.Stride : WorldVertex.Stride;
RenderDevice_SetVertexBufferData(Handle, buffer.Handle, IntPtr.Zero, length * stride, format); ThrowIfFailed(RenderDevice_SetVertexBufferData(Handle, buffer.Handle, IntPtr.Zero, length * stride, format));
CheckAndThrow();
} }
public void SetBufferData(VertexBuffer buffer, FlatVertex[] data) public void SetBufferData(VertexBuffer buffer, FlatVertex[] data)
{ {
RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<FlatVertex>(), VertexFormat.Flat); ThrowIfFailed(RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<FlatVertex>(), VertexFormat.Flat));
CheckAndThrow();
} }
public void SetBufferData(VertexBuffer buffer, WorldVertex[] data) public void SetBufferData(VertexBuffer buffer, WorldVertex[] data)
{ {
RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<WorldVertex>(), VertexFormat.World); ThrowIfFailed(RenderDevice_SetVertexBufferData(Handle, buffer.Handle, data, data.Length * Marshal.SizeOf<WorldVertex>(), VertexFormat.World));
CheckAndThrow();
} }
public void SetBufferSubdata(VertexBuffer buffer, long destOffset, FlatVertex[] data) public void SetBufferSubdata(VertexBuffer buffer, long destOffset, FlatVertex[] data)
{ {
RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset * FlatVertex.Stride, data, data.Length * FlatVertex.Stride); ThrowIfFailed(RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset * FlatVertex.Stride, data, data.Length * FlatVertex.Stride));
CheckAndThrow();
} }
public void SetBufferSubdata(VertexBuffer buffer, long destOffset, WorldVertex[] data) public void SetBufferSubdata(VertexBuffer buffer, long destOffset, WorldVertex[] data)
{ {
RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset * WorldVertex.Stride, data, data.Length * WorldVertex.Stride); ThrowIfFailed(RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, destOffset * WorldVertex.Stride, data, data.Length * WorldVertex.Stride));
CheckAndThrow();
} }
public void SetBufferSubdata(VertexBuffer buffer, FlatVertex[] data, long size) public void SetBufferSubdata(VertexBuffer buffer, FlatVertex[] data, long size)
{ {
if (size < 0 || size > data.Length) throw new ArgumentOutOfRangeException("size"); if (size < 0 || size > data.Length) throw new ArgumentOutOfRangeException("size");
RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, 0, data, size * FlatVertex.Stride); ThrowIfFailed(RenderDevice_SetVertexBufferSubdata(Handle, buffer.Handle, 0, data, size * FlatVertex.Stride));
CheckAndThrow();
} }
public void SetPixels(Texture texture, System.Drawing.Bitmap bitmap) public void SetPixels(Texture texture, System.Drawing.Bitmap bitmap)
@ -340,10 +293,14 @@ namespace CodeImp.DoomBuilder.Rendering
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Imaging.PixelFormat.Format32bppArgb);
RenderDevice_SetPixels(Handle, texture.Handle, bmpdata.Scan0); try
{
bitmap.UnlockBits(bmpdata); ThrowIfFailed(RenderDevice_SetPixels(Handle, texture.Handle, bmpdata.Scan0));
CheckAndThrow(); }
finally
{
bitmap.UnlockBits(bmpdata);
}
} }
public void SetPixels(CubeTexture texture, CubeMapFace face, System.Drawing.Bitmap bitmap) public void SetPixels(CubeTexture texture, CubeMapFace face, System.Drawing.Bitmap bitmap)
@ -353,29 +310,31 @@ namespace CodeImp.DoomBuilder.Rendering
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Imaging.PixelFormat.Format32bppArgb);
RenderDevice_SetCubePixels(Handle, texture.Handle, face, bmpdata.Scan0); try
{
bitmap.UnlockBits(bmpdata); ThrowIfFailed(RenderDevice_SetCubePixels(Handle, texture.Handle, face, bmpdata.Scan0));
CheckAndThrow(); }
finally
{
bitmap.UnlockBits(bmpdata);
}
} }
public unsafe void SetPixels(Texture texture, uint* pixeldata) public unsafe void SetPixels(Texture texture, uint* pixeldata)
{ {
RenderDevice_SetPixels(Handle, texture.Handle, new IntPtr(pixeldata)); ThrowIfFailed(RenderDevice_SetPixels(Handle, texture.Handle, new IntPtr(pixeldata)));
CheckAndThrow();
} }
public unsafe void* MapPBO(Texture texture) public unsafe void* MapPBO(Texture texture)
{ {
void* ptr = RenderDevice_MapPBO(Handle, texture.Handle).ToPointer(); void* ptr = RenderDevice_MapPBO(Handle, texture.Handle).ToPointer();
CheckAndThrow(); ThrowIfFailed(ptr != null);
return ptr; return ptr;
} }
public void UnmapPBO(Texture texture) public void UnmapPBO(Texture texture)
{ {
RenderDevice_UnmapPBO(Handle, texture.Handle); ThrowIfFailed(RenderDevice_UnmapPBO(Handle, texture.Handle));
CheckAndThrow();
} }
internal void RegisterResource(IRenderResource res) internal void RegisterResource(IRenderResource res)
@ -427,13 +386,13 @@ namespace CodeImp.DoomBuilder.Rendering
static extern IntPtr RenderDevice_GetError(IntPtr handle); static extern IntPtr RenderDevice_GetError(IntPtr handle);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr RenderDevice_SetShader(IntPtr handle, ShaderName name); static extern bool RenderDevice_SetShader(IntPtr handle, ShaderName name);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr RenderDevice_SetUniform(IntPtr handle, UniformName name, float[] data, int count); static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, float[] data, int count);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr RenderDevice_SetUniform(IntPtr handle, UniformName name, ref Matrix data, int count); static extern void RenderDevice_SetUniform(IntPtr handle, UniformName name, ref Matrix data, int count);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBuffer(IntPtr handle, IntPtr buffer); static extern void RenderDevice_SetVertexBuffer(IntPtr handle, IntPtr buffer);
@ -481,61 +440,58 @@ namespace CodeImp.DoomBuilder.Rendering
static extern void RenderDevice_SetSamplerState(IntPtr handle, TextureAddress address); static extern void RenderDevice_SetSamplerState(IntPtr handle, TextureAddress address);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_Draw(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount); static extern bool RenderDevice_Draw(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_DrawIndexed(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount); static extern bool RenderDevice_DrawIndexed(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_DrawData(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data); static extern bool RenderDevice_DrawData(IntPtr handle, PrimitiveType type, int startIndex, int primitiveCount, FlatVertex[] data);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_StartRendering(IntPtr handle, bool clear, int backcolor); static extern bool RenderDevice_StartRendering(IntPtr handle, bool clear, int backcolor, IntPtr target, bool usedepthbuffer);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_StartRendering(IntPtr handle, bool clear, int backcolor, IntPtr target, bool usedepthbuffer); static extern bool RenderDevice_FinishRendering(IntPtr handle);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_FinishRendering(IntPtr handle); static extern bool RenderDevice_Present(IntPtr handle);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_Present(IntPtr handle); static extern bool RenderDevice_ClearTexture(IntPtr handle, int backcolor, IntPtr texture);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_ClearTexture(IntPtr handle, int backcolor, IntPtr texture); static extern bool RenderDevice_CopyTexture(IntPtr handle, IntPtr dst, CubeMapFace face);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_CopyTexture(IntPtr handle, IntPtr dst, CubeMapFace face); static extern bool RenderDevice_SetIndexBufferData(IntPtr handle, IntPtr buffer, int[] data, long size);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetIndexBufferData(IntPtr handle, IntPtr buffer, int[] data, long size); static extern bool RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, IntPtr data, long size, VertexFormat format);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, IntPtr data, long size, VertexFormat format); static extern bool RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, FlatVertex[] data, long size, VertexFormat format);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, FlatVertex[] data, long size, VertexFormat format); static extern bool RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, WorldVertex[] data, long size, VertexFormat format);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBufferData(IntPtr handle, IntPtr buffer, WorldVertex[] data, long size, VertexFormat format); static extern bool RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, FlatVertex[] data, long sizeInBytes);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, FlatVertex[] data, long sizeInBytes); static extern bool RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, WorldVertex[] data, long sizeInBytes);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_SetVertexBufferSubdata(IntPtr handle, IntPtr buffer, long destOffset, WorldVertex[] data, long sizeInBytes); protected static extern bool RenderDevice_SetPixels(IntPtr handle, IntPtr texture, IntPtr data);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern void RenderDevice_SetPixels(IntPtr handle, IntPtr texture, IntPtr data);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern IntPtr RenderDevice_MapPBO(IntPtr handle, IntPtr texture); protected static extern IntPtr RenderDevice_MapPBO(IntPtr handle, IntPtr texture);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern void RenderDevice_UnmapPBO(IntPtr handle, IntPtr texture); protected static extern bool RenderDevice_UnmapPBO(IntPtr handle, IntPtr texture);
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
protected static extern void RenderDevice_SetCubePixels(IntPtr handle, IntPtr texture, CubeMapFace face, IntPtr data); protected static extern bool RenderDevice_SetCubePixels(IntPtr handle, IntPtr texture, CubeMapFace face, IntPtr data);
//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

@ -349,8 +349,6 @@ namespace CodeImp.DoomBuilder.Rendering
// Destroy rendertargets // Destroy rendertargets
DestroyRendertargets(); DestroyRendertargets();
graphics.ClearError();
// Get new width and height // Get new width and height
windowsize.Width = graphics.RenderTarget.ClientSize.Width; windowsize.Width = graphics.RenderTarget.ClientSize.Width;
windowsize.Height = graphics.RenderTarget.ClientSize.Height; windowsize.Height = graphics.RenderTarget.ClientSize.Height;

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include <map> #include <map>

View file

@ -49,9 +49,6 @@ RenderDevice::RenderDevice(void* disp, void* window)
DeclareUniform(UniformName::ignoreNormals, "ignoreNormals", UniformType::Float); DeclareUniform(UniformName::ignoreNormals, "ignoreNormals", UniformType::Float);
DeclareUniform(UniformName::spotLight, "spotLight", UniformType::Float); DeclareUniform(UniformName::spotLight, "spotLight", UniformType::Float);
memset(mLastError, 0, sizeof(mLastError));
memset(mReturnError, 0, sizeof(mReturnError));
Context = IOpenGLContext::Create(disp, window); Context = IOpenGLContext::Create(disp, window);
if (Context) if (Context)
{ {
@ -303,35 +300,29 @@ void RenderDevice::SetSamplerState(TextureAddress address)
} }
} }
void RenderDevice::ApplyViewport() bool RenderDevice::Draw(PrimitiveType type, int startIndex, int primitiveCount)
{
glViewport(0, 0, mViewportWidth, mViewportHeight);
CheckGLError();
}
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 };
static const int toVertexStart[] = { 0, 0, 2 }; static const int toVertexStart[] = { 0, 0, 2 };
if (mNeedApply) ApplyChanges(); if (mNeedApply && !ApplyChanges()) return false;
glDrawArrays(modes[(int)type], mVertexBufferStartIndex + startIndex, toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type]); glDrawArrays(modes[(int)type], mVertexBufferStartIndex + startIndex, toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type]);
CheckGLError(); return CheckGLError();
} }
void RenderDevice::DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) bool RenderDevice::DrawIndexed(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 };
static const int toVertexStart[] = { 0, 0, 2 }; static const int toVertexStart[] = { 0, 0, 2 };
if (mNeedApply) ApplyChanges(); if (mNeedApply && !ApplyChanges()) return false;
glDrawElementsBaseVertex(modes[(int)type], toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type], GL_UNSIGNED_INT, (const void*)(startIndex * sizeof(uint32_t)), mVertexBufferStartIndex); glDrawElementsBaseVertex(modes[(int)type], toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type], GL_UNSIGNED_INT, (const void*)(startIndex * sizeof(uint32_t)), mVertexBufferStartIndex);
CheckGLError(); return CheckGLError();
} }
void RenderDevice::DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) bool RenderDevice::DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data)
{ {
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 };
@ -339,17 +330,18 @@ void RenderDevice::DrawData(PrimitiveType type, int startIndex, int primitiveCou
int vertcount = toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type]; int vertcount = toVertexStart[(int)type] + primitiveCount * toVertexCount[(int)type];
if (mNeedApply) ApplyChanges(); if (mNeedApply && !ApplyChanges()) return false;
glBindBuffer(GL_ARRAY_BUFFER, mStreamVertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, mStreamVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertcount * (size_t)SharedVertexBuffer::FlatStride, static_cast<const uint8_t*>(data) + startIndex * (size_t)SharedVertexBuffer::FlatStride, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, vertcount * (size_t)SharedVertexBuffer::FlatStride, static_cast<const uint8_t*>(data) + startIndex * (size_t)SharedVertexBuffer::FlatStride, GL_STREAM_DRAW);
glBindVertexArray(mStreamVAO); glBindVertexArray(mStreamVAO);
glDrawArrays(modes[(int)type], 0, vertcount); glDrawArrays(modes[(int)type], 0, vertcount);
ApplyVertexBuffer(); if (!CheckGLError()) return false;
CheckGLError();
return ApplyVertexBuffer();
} }
void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer) bool RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer)
{ {
Context->MakeCurrent(); Context->MakeCurrent();
mContextIsCurrent = true; mContextIsCurrent = true;
@ -364,18 +356,19 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
catch (std::runtime_error& e) catch (std::runtime_error& e)
{ {
SetError("Error setting render target: %s", e.what()); SetError("Error setting render target: %s", e.what());
return false;
} }
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
mViewportWidth = target->GetWidth(); mViewportWidth = target->GetWidth();
mViewportHeight = target->GetHeight(); mViewportHeight = target->GetHeight();
ApplyViewport(); if (!ApplyViewport()) return false;
} }
else else
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
mViewportWidth = Context->GetWidth(); mViewportWidth = Context->GetWidth();
mViewportHeight = Context->GetHeight(); mViewportHeight = Context->GetHeight();
ApplyViewport(); if (!ApplyViewport()) return false;
} }
if (clear && usedepthbuffer) if (clear && usedepthbuffer)
@ -402,29 +395,29 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
mBlendStateChanged = true; mBlendStateChanged = true;
mRasterizerStateChanged = true; mRasterizerStateChanged = true;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::FinishRendering() bool RenderDevice::FinishRendering()
{ {
Context->ClearCurrent(); Context->ClearCurrent();
mContextIsCurrent = false; mContextIsCurrent = false;
return true;
} }
void RenderDevice::Present() bool RenderDevice::Present()
{ {
Context->SwapBuffers(); Context->SwapBuffers();
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ClearTexture(int backcolor, Texture* texture) bool RenderDevice::ClearTexture(int backcolor, Texture* texture)
{ {
StartRendering(true, backcolor, texture, false); if (!StartRendering(true, backcolor, texture, false)) return false;
FinishRendering(); return FinishRendering();
CheckGLError();
} }
void RenderDevice::CopyTexture(Texture* dst, CubeMapFace face) bool RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
{ {
static const GLenum facegl[] = { static const GLenum facegl[] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
@ -445,11 +438,12 @@ void RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture); glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
return result;
} }
void RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format) bool RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format)
{ {
if (!mContextIsCurrent) Context->MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
@ -490,11 +484,12 @@ void RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t
glBufferSubData(GL_ARRAY_BUFFER, buffer->BufferOffset, size, data); glBufferSubData(GL_ARRAY_BUFFER, buffer->BufferOffset, size, data);
glBindBuffer(GL_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ARRAY_BUFFER, oldbinding);
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
return result;
} }
void RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) bool RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size)
{ {
if (!mContextIsCurrent) Context->MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint oldbinding = 0; GLint oldbinding = 0;
@ -502,11 +497,12 @@ void RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffs
glBindBuffer(GL_ARRAY_BUFFER, mSharedVertexBuffers[(int)buffer->Format]->GetBuffer()); glBindBuffer(GL_ARRAY_BUFFER, mSharedVertexBuffers[(int)buffer->Format]->GetBuffer());
glBufferSubData(GL_ARRAY_BUFFER, buffer->BufferOffset + destOffset, size, data); glBufferSubData(GL_ARRAY_BUFFER, buffer->BufferOffset + destOffset, size, data);
glBindBuffer(GL_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ARRAY_BUFFER, oldbinding);
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
return result;
} }
void RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size) bool RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size)
{ {
if (!mContextIsCurrent) Context->MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint oldbinding = 0; GLint oldbinding = 0;
@ -514,22 +510,21 @@ void RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t s
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer());
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldbinding);
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
return result;
} }
void RenderDevice::SetPixels(Texture* texture, const void* data) bool RenderDevice::SetPixels(Texture* texture, const void* data)
{ {
texture->SetPixels(data); texture->SetPixels(data);
InvalidateTexture(texture); return InvalidateTexture(texture);
CheckGLError();
} }
void RenderDevice::SetCubePixels(Texture* texture, CubeMapFace face, const void* data) bool RenderDevice::SetCubePixels(Texture* texture, CubeMapFace face, const void* data)
{ {
texture->SetCubePixels(face, data); texture->SetCubePixels(face, data);
InvalidateTexture(texture); return InvalidateTexture(texture);
CheckGLError();
} }
void* RenderDevice::MapPBO(Texture* texture) void* RenderDevice::MapPBO(Texture* texture)
@ -538,12 +533,17 @@ void* RenderDevice::MapPBO(Texture* texture)
GLint pbo = texture->GetPBO(); GLint pbo = texture->GetPBO();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
void* buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); void* buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
CheckGLError(); bool result = CheckGLError();
if (!result && buf)
{
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
buf = nullptr;
}
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
return buf; return buf;
} }
void RenderDevice::UnmapPBO(Texture* texture) bool RenderDevice::UnmapPBO(Texture* texture)
{ {
if (!mContextIsCurrent) Context->MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint pbo = texture->GetPBO(); GLint pbo = texture->GetPBO();
@ -551,35 +551,43 @@ void RenderDevice::UnmapPBO(Texture* texture)
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindTexture(GL_TEXTURE_2D, texture->GetTexture()); glBindTexture(GL_TEXTURE_2D, texture->GetTexture());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->GetWidth(), texture->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->GetWidth(), texture->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
mNeedApply = true; mNeedApply = true;
mTexturesChanged = true; mTexturesChanged = true;
return result;
} }
void RenderDevice::InvalidateTexture(Texture* texture) bool RenderDevice::InvalidateTexture(Texture* texture)
{ {
if (texture->IsTextureCreated()) if (texture->IsTextureCreated())
{ {
if (!mContextIsCurrent) Context->MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
texture->Invalidate(); texture->Invalidate();
CheckGLError(); bool result = CheckGLError();
if (!mContextIsCurrent) Context->ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
mNeedApply = true; mNeedApply = true;
mTexturesChanged = true; mTexturesChanged = true;
return result;
}
else
{
return true;
} }
} }
bool RenderDevice::CheckGLError() bool RenderDevice::CheckGLError()
{ {
// on Windows, "no context" is a GL_INVALID_OPERATION error if (!Context->IsCurrent())
GLenum error = glGetError();
if (error != GL_NO_ERROR && Context->IsCurrent())
{ {
SetError("OpenGL error: %d", error); SetError("Unexpected current OpenGL context");
return true;
} }
GLenum error = glGetError();
if (error == GL_NO_ERROR)
return true;
SetError("OpenGL error: %d", error);
return false; return false;
} }
@ -587,16 +595,18 @@ void RenderDevice::SetError(const char* fmt, ...)
{ {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
mLastError[sizeof(mLastError) - 1] = 0; mSetErrorBuffer[0] = 0;
_vsnprintf(mLastError, sizeof(mLastError)-1, fmt, va); mSetErrorBuffer[sizeof(mSetErrorBuffer) - 1] = 0;
_vsnprintf(mSetErrorBuffer, sizeof(mSetErrorBuffer)-1, fmt, va);
va_end(va); va_end(va);
mLastError = mSetErrorBuffer;
} }
const char* RenderDevice::GetError() const char* RenderDevice::GetError()
{ {
memcpy(mReturnError, mLastError, sizeof(mReturnError)); mReturnError.swap(mLastError);
mLastError[0] = 0; mLastError.clear();
return mReturnError; return mReturnError.c_str();
} }
Shader* RenderDevice::GetActiveShader() Shader* RenderDevice::GetActiveShader()
@ -630,44 +640,43 @@ void RenderDevice::SetUniform(UniformName name, const void* values, int count)
} }
} }
void RenderDevice::ApplyChanges() bool RenderDevice::ApplyChanges()
{ {
if (mShaderChanged) if (mShaderChanged && !ApplyShader()) return false;
ApplyShader(); if (mVertexBufferChanged && !ApplyVertexBuffer()) return false;
if (mVertexBufferChanged) if (mIndexBufferChanged && !ApplyIndexBuffer()) return false;
ApplyVertexBuffer(); if (mUniformsChanged && !ApplyUniforms()) return false;
if (mIndexBufferChanged) if (mTexturesChanged && !ApplyTextures()) return false;
ApplyIndexBuffer(); if (mRasterizerStateChanged && !ApplyRasterizerState()) return false;
if (mUniformsChanged) if (mBlendStateChanged && !ApplyBlendState()) return false;
ApplyUniforms(); if (mDepthStateChanged && !ApplyDepthState()) return false;
if (mTexturesChanged)
ApplyTextures();
if (mRasterizerStateChanged)
ApplyRasterizerState();
if (mBlendStateChanged)
ApplyBlendState();
if (mDepthStateChanged)
ApplyDepthState();
mNeedApply = false; mNeedApply = false;
return true;
} }
void RenderDevice::ApplyShader() bool RenderDevice::ApplyViewport()
{
glViewport(0, 0, mViewportWidth, mViewportHeight);
return CheckGLError();
}
bool RenderDevice::ApplyShader()
{ {
Shader* curShader = GetActiveShader(); Shader* curShader = GetActiveShader();
if (!curShader->CheckCompile(this)) if (!curShader->CheckCompile(this))
{ {
SetError("Failed to bind shader:\r\n%s", curShader->GetCompileError().c_str()); SetError("Failed to bind shader:\r\n%s", curShader->GetCompileError().c_str());
return; return false;
} }
curShader->Bind(); curShader->Bind();
mShaderChanged = false; mShaderChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyRasterizerState() bool RenderDevice::ApplyRasterizerState()
{ {
if (mCullMode == Cull::None) if (mCullMode == Cull::None)
{ {
@ -684,10 +693,10 @@ void RenderDevice::ApplyRasterizerState()
mRasterizerStateChanged = false; mRasterizerStateChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyBlendState() bool RenderDevice::ApplyBlendState()
{ {
if (mAlphaBlend) if (mAlphaBlend)
{ {
@ -705,10 +714,10 @@ void RenderDevice::ApplyBlendState()
mBlendStateChanged = false; mBlendStateChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyDepthState() bool RenderDevice::ApplyDepthState()
{ {
if (mDepthTest) if (mDepthTest)
{ {
@ -723,10 +732,10 @@ void RenderDevice::ApplyDepthState()
mDepthStateChanged = false; mDepthStateChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyIndexBuffer() bool RenderDevice::ApplyIndexBuffer()
{ {
if (mIndexBuffer) if (mIndexBuffer)
{ {
@ -739,17 +748,17 @@ void RenderDevice::ApplyIndexBuffer()
mIndexBufferChanged = false; mIndexBufferChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyVertexBuffer() bool RenderDevice::ApplyVertexBuffer()
{ {
if (mVertexBuffer != -1) if (mVertexBuffer != -1)
glBindVertexArray(mSharedVertexBuffers[mVertexBuffer]->GetVAO()); glBindVertexArray(mSharedVertexBuffers[mVertexBuffer]->GetVAO());
mVertexBufferChanged = false; mVertexBufferChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::DeclareUniform(UniformName name, const char* glslname, UniformType type) void RenderDevice::DeclareUniform(UniformName name, const char* glslname, UniformType type)
@ -762,7 +771,7 @@ void RenderDevice::DeclareUniform(UniformName name, const char* glslname, Unifor
mUniformData.resize(mUniformData.size() + (type == UniformType::Matrix ? 16 : 4)); mUniformData.resize(mUniformData.size() + (type == UniformType::Matrix ? 16 : 4));
} }
void RenderDevice::ApplyUniforms() bool RenderDevice::ApplyUniforms()
{ {
Shader* shader = GetActiveShader(); Shader* shader = GetActiveShader();
auto& locations = shader->UniformLocations; auto& locations = shader->UniformLocations;
@ -789,10 +798,10 @@ void RenderDevice::ApplyUniforms()
mUniformsChanged = false; mUniformsChanged = false;
CheckGLError(); return CheckGLError();
} }
void RenderDevice::ApplyTextures() bool RenderDevice::ApplyTextures()
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
if (mTextureUnit.Tex) if (mTextureUnit.Tex)
@ -827,7 +836,7 @@ void RenderDevice::ApplyTextures()
mTexturesChanged = false; mTexturesChanged = false;
CheckGLError(); return CheckGLError();
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -944,69 +953,69 @@ void RenderDevice_SetSamplerState(RenderDevice* device, TextureAddress address)
device->SetSamplerState(address); device->SetSamplerState(address);
} }
void RenderDevice_Draw(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount) bool RenderDevice_Draw(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount)
{ {
device->Draw(type, startIndex, primitiveCount); return device->Draw(type, startIndex, primitiveCount);
} }
void RenderDevice_DrawIndexed(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount) bool RenderDevice_DrawIndexed(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount)
{ {
device->DrawIndexed(type, startIndex, primitiveCount); return device->DrawIndexed(type, startIndex, primitiveCount);
} }
void RenderDevice_DrawData(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount, const void* data) bool RenderDevice_DrawData(RenderDevice* device, PrimitiveType type, int startIndex, int primitiveCount, const void* data)
{ {
device->DrawData(type, startIndex, primitiveCount, data); return device->DrawData(type, startIndex, primitiveCount, data);
} }
void RenderDevice_StartRendering(RenderDevice* device, bool clear, int backcolor, Texture* target, bool usedepthbuffer) bool RenderDevice_StartRendering(RenderDevice* device, bool clear, int backcolor, Texture* target, bool usedepthbuffer)
{ {
device->StartRendering(clear, backcolor, target, usedepthbuffer); return device->StartRendering(clear, backcolor, target, usedepthbuffer);
} }
void RenderDevice_FinishRendering(RenderDevice* device) bool RenderDevice_FinishRendering(RenderDevice* device)
{ {
device->FinishRendering(); return device->FinishRendering();
} }
void RenderDevice_Present(RenderDevice* device) bool RenderDevice_Present(RenderDevice* device)
{ {
device->Present(); return device->Present();
} }
void RenderDevice_ClearTexture(RenderDevice* device, int backcolor, Texture* texture) bool RenderDevice_ClearTexture(RenderDevice* device, int backcolor, Texture* texture)
{ {
device->ClearTexture(backcolor, texture); return device->ClearTexture(backcolor, texture);
} }
void RenderDevice_CopyTexture(RenderDevice* device, Texture* dst, CubeMapFace face) bool RenderDevice_CopyTexture(RenderDevice* device, Texture* dst, CubeMapFace face)
{ {
device->CopyTexture(dst, face); return device->CopyTexture(dst, face);
} }
void RenderDevice_SetVertexBufferData(RenderDevice* device, VertexBuffer* buffer, void* data, int64_t size, VertexFormat format) bool RenderDevice_SetVertexBufferData(RenderDevice* device, VertexBuffer* buffer, void* data, int64_t size, VertexFormat format)
{ {
device->SetVertexBufferData(buffer, data, size, format); return device->SetVertexBufferData(buffer, data, size, format);
} }
void RenderDevice_SetVertexBufferSubdata(RenderDevice* device, VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) bool RenderDevice_SetVertexBufferSubdata(RenderDevice* device, VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size)
{ {
device->SetVertexBufferSubdata(buffer, destOffset, data, size); return device->SetVertexBufferSubdata(buffer, destOffset, data, size);
} }
void RenderDevice_SetIndexBufferData(RenderDevice* device, IndexBuffer* buffer, void* data, int64_t size) bool RenderDevice_SetIndexBufferData(RenderDevice* device, IndexBuffer* buffer, void* data, int64_t size)
{ {
device->SetIndexBufferData(buffer, data, size); return device->SetIndexBufferData(buffer, data, size);
} }
void RenderDevice_SetPixels(RenderDevice* device, Texture* texture, const void* data) bool RenderDevice_SetPixels(RenderDevice* device, Texture* texture, const void* data)
{ {
device->SetPixels(texture, data); return device->SetPixels(texture, data);
} }
void RenderDevice_SetCubePixels(RenderDevice* device, Texture* texture, CubeMapFace face, const void* data) bool RenderDevice_SetCubePixels(RenderDevice* device, Texture* texture, CubeMapFace face, const void* data)
{ {
device->SetCubePixels(texture, face, data); return device->SetCubePixels(texture, face, data);
} }
void* RenderDevice_MapPBO(RenderDevice* device, Texture* texture) void* RenderDevice_MapPBO(RenderDevice* device, Texture* texture)
@ -1014,9 +1023,9 @@ void* RenderDevice_MapPBO(RenderDevice* device, Texture* texture)
return device->MapPBO(texture); return device->MapPBO(texture);
} }
void RenderDevice_UnmapPBO(RenderDevice* device, Texture* texture) bool RenderDevice_UnmapPBO(RenderDevice* device, Texture* texture)
{ {
device->UnmapPBO(texture); return device->UnmapPBO(texture);
} }
#ifdef NO_SSE #ifdef NO_SSE

View file

@ -99,36 +99,36 @@ public:
void SetTexture(Texture* texture); void SetTexture(Texture* texture);
void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy); void SetSamplerFilter(TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy);
void SetSamplerState(TextureAddress address); void SetSamplerState(TextureAddress address);
void Draw(PrimitiveType type, int startIndex, int primitiveCount); bool Draw(PrimitiveType type, int startIndex, int primitiveCount);
void DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount); bool DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount);
void DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data); bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data);
void StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer); bool StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer);
void FinishRendering(); bool FinishRendering();
void Present(); bool Present();
void ClearTexture(int backcolor, Texture* texture); bool ClearTexture(int backcolor, Texture* texture);
void CopyTexture(Texture* dst, CubeMapFace face); bool CopyTexture(Texture* dst, CubeMapFace face);
void SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format); bool SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format);
void SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size); bool SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size);
void SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size); bool SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size);
void SetPixels(Texture* texture, const void* data); bool SetPixels(Texture* texture, const void* data);
void SetCubePixels(Texture* texture, CubeMapFace face, const void* data); bool SetCubePixels(Texture* texture, CubeMapFace face, const void* data);
void* MapPBO(Texture* texture); void* MapPBO(Texture* texture);
void UnmapPBO(Texture* texture); bool UnmapPBO(Texture* texture);
void InvalidateTexture(Texture* texture); bool InvalidateTexture(Texture* texture);
void ApplyViewport(); bool ApplyViewport();
void ApplyChanges(); bool ApplyChanges();
void ApplyVertexBuffer(); bool ApplyVertexBuffer();
void ApplyIndexBuffer(); bool ApplyIndexBuffer();
void ApplyShader(); bool ApplyShader();
void ApplyUniforms(); bool ApplyUniforms();
void ApplyTextures(); bool ApplyTextures();
void ApplyRasterizerState(); bool ApplyRasterizerState();
void ApplyBlendState(); bool ApplyBlendState();
void ApplyDepthState(); bool ApplyDepthState();
bool CheckGLError(); bool CheckGLError();
void SetError(const char* fmt, ...); void SetError(const char* fmt, ...);
@ -225,8 +225,9 @@ public:
bool mContextIsCurrent = false; bool mContextIsCurrent = false;
char mLastError[4096]; std::string mLastError;
char mReturnError[4096]; std::string mReturnError;
char mSetErrorBuffer[4096];
int mViewportWidth = 0; int mViewportWidth = 0;
int mViewportHeight = 0; int mViewportHeight = 0;