mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-29 23:22:32 +00:00
Improved error reporting
This commit is contained in:
parent
7f09dd2aec
commit
502b641967
8 changed files with 979 additions and 819 deletions
|
@ -29,6 +29,11 @@ using System.Reflection;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.Rendering
|
namespace CodeImp.DoomBuilder.Rendering
|
||||||
{
|
{
|
||||||
|
public class RenderDeviceException : Exception
|
||||||
|
{
|
||||||
|
public RenderDeviceException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
public class RenderDevice : IDisposable
|
public class RenderDevice : IDisposable
|
||||||
{
|
{
|
||||||
public RenderDevice(RenderTargetControl rendertarget)
|
public RenderDevice(RenderTargetControl rendertarget)
|
||||||
|
@ -59,6 +64,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
public bool Disposed { get { return Handle == IntPtr.Zero; } }
|
||||||
|
|
||||||
|
private void CheckAndThrow()
|
||||||
|
{
|
||||||
|
string err = Marshal.PtrToStringAnsi(RenderDevice_GetError(Handle));
|
||||||
|
if (err != "")
|
||||||
|
throw new RenderDeviceException(err);
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (!Disposed)
|
if (!Disposed)
|
||||||
|
@ -71,36 +83,43 @@ 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)
|
||||||
|
@ -111,173 +130,207 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
matrix.M31, matrix.M32, matrix.M33, matrix.M34,
|
matrix.M31, matrix.M32, matrix.M33, matrix.M34,
|
||||||
matrix.M41, matrix.M42, matrix.M43, matrix.M44
|
matrix.M41, matrix.M42, matrix.M43, matrix.M44
|
||||||
}, 16);
|
}, 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)
|
||||||
{
|
{
|
||||||
SetSamplerState(address, address, address);
|
SetSamplerState(address, address, address);
|
||||||
|
CheckAndThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSamplerState(TextureAddress addressU, TextureAddress addressV, TextureAddress addressW)
|
public void SetSamplerState(TextureAddress addressU, TextureAddress addressV, TextureAddress addressW)
|
||||||
{
|
{
|
||||||
RenderDevice_SetSamplerState(Handle, addressU, addressV, addressW);
|
RenderDevice_SetSamplerState(Handle, addressU, addressV, addressW);
|
||||||
|
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);
|
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);
|
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);
|
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);
|
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);
|
RenderDevice_StartRendering(Handle, clear, backcolor.ToArgb(), target.Handle, usedepthbuffer);
|
||||||
|
CheckAndThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinishRendering()
|
public void FinishRendering()
|
||||||
{
|
{
|
||||||
RenderDevice_FinishRendering(Handle);
|
RenderDevice_FinishRendering(Handle);
|
||||||
|
CheckAndThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present()
|
public void Present()
|
||||||
{
|
{
|
||||||
RenderDevice_Present(Handle);
|
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);
|
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);
|
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>());
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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)
|
||||||
|
@ -290,6 +343,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
RenderDevice_SetPixels(Handle, texture.Handle, bmpdata.Scan0);
|
RenderDevice_SetPixels(Handle, texture.Handle, bmpdata.Scan0);
|
||||||
|
|
||||||
bitmap.UnlockBits(bmpdata);
|
bitmap.UnlockBits(bmpdata);
|
||||||
|
CheckAndThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPixels(CubeTexture texture, CubeMapFace face, System.Drawing.Bitmap bitmap)
|
public void SetPixels(CubeTexture texture, CubeMapFace face, System.Drawing.Bitmap bitmap)
|
||||||
|
@ -302,6 +356,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
RenderDevice_SetCubePixels(Handle, texture.Handle, face, bmpdata.Scan0);
|
RenderDevice_SetCubePixels(Handle, texture.Handle, face, bmpdata.Scan0);
|
||||||
|
|
||||||
bitmap.UnlockBits(bmpdata);
|
bitmap.UnlockBits(bmpdata);
|
||||||
|
CheckAndThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RegisterResource(IRenderResource res)
|
internal void RegisterResource(IRenderResource res)
|
||||||
|
@ -350,10 +405,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
static extern void RenderDevice_Delete(IntPtr handle);
|
static extern void RenderDevice_Delete(IntPtr handle);
|
||||||
|
|
||||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr RenderDevice_SetShader(IntPtr hwnd, ShaderName name);
|
static extern IntPtr RenderDevice_GetError(IntPtr handle);
|
||||||
|
|
||||||
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr RenderDevice_SetUniform(IntPtr hwnd, UniformName name, float[] data, int count);
|
static extern IntPtr RenderDevice_SetShader(IntPtr handle, ShaderName name);
|
||||||
|
|
||||||
|
[DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr RenderDevice_SetUniform(IntPtr handle, UniformName name, float[] 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);
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "ShaderManager.h"
|
#include "ShaderManager.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
RenderDevice::RenderDevice(void* disp, void* window)
|
RenderDevice::RenderDevice(void* disp, void* window)
|
||||||
{
|
{
|
||||||
memset(mUniforms, 0, sizeof(mUniforms));
|
memset(mUniforms, 0, sizeof(mUniforms));
|
||||||
|
memset(mLastError, 0, sizeof(mLastError));
|
||||||
|
memset(mReturnError, 0, sizeof(mReturnError));
|
||||||
|
|
||||||
Context = IOpenGLContext::Create(disp, window);
|
Context = IOpenGLContext::Create(disp, window);
|
||||||
if (Context)
|
if (Context)
|
||||||
|
@ -25,7 +28,7 @@ RenderDevice::RenderDevice(void* disp, void* window)
|
||||||
|
|
||||||
mShaderManager = std::make_unique<ShaderManager>();
|
mShaderManager = std::make_unique<ShaderManager>();
|
||||||
|
|
||||||
CheckError();
|
CheckGLError();
|
||||||
Context->ClearCurrent();
|
Context->ClearCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +273,16 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target->GetFramebuffer(usedepthbuffer));
|
GLuint framebuffer = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
framebuffer = target->GetFramebuffer(usedepthbuffer);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{
|
||||||
|
SetError("Error setting render target: %s", e.what());
|
||||||
|
}
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
mViewportWidth = target->GetWidth();
|
mViewportWidth = target->GetWidth();
|
||||||
mViewportHeight = target->GetHeight();
|
mViewportHeight = target->GetHeight();
|
||||||
ApplyViewport();
|
ApplyViewport();
|
||||||
|
@ -310,7 +322,7 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
|
||||||
|
|
||||||
void RenderDevice::FinishRendering()
|
void RenderDevice::FinishRendering()
|
||||||
{
|
{
|
||||||
CheckError();
|
CheckGLError();
|
||||||
Context->ClearCurrent();
|
Context->ClearCurrent();
|
||||||
mContextIsCurrent = false;
|
mContextIsCurrent = false;
|
||||||
}
|
}
|
||||||
|
@ -408,11 +420,27 @@ void RenderDevice::InvalidateTexture(Texture* texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDevice::CheckError()
|
void RenderDevice::CheckGLError()
|
||||||
{
|
{
|
||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
if (error != GL_NO_ERROR)
|
||||||
throw std::runtime_error("OpenGL error!");
|
SetError("OpenGL error: %d", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderDevice::SetError(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
mLastError[sizeof(mLastError) - 1] = 0;
|
||||||
|
_vsnprintf(mLastError, sizeof(mLastError)-1, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* RenderDevice::GetError()
|
||||||
|
{
|
||||||
|
memcpy(mReturnError, mLastError, sizeof(mReturnError));
|
||||||
|
mLastError[0] = 0;
|
||||||
|
return mReturnError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* RenderDevice::GetActiveShader()
|
Shader* RenderDevice::GetActiveShader()
|
||||||
|
@ -492,7 +520,14 @@ void RenderDevice::ApplyChanges()
|
||||||
|
|
||||||
void RenderDevice::ApplyShader()
|
void RenderDevice::ApplyShader()
|
||||||
{
|
{
|
||||||
GetActiveShader()->Bind();
|
Shader* curShader = GetActiveShader();
|
||||||
|
if (!curShader->CheckCompile())
|
||||||
|
{
|
||||||
|
SetError("Failed to bind shader:\r\n%s", curShader->GetCompileError().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
curShader->Bind();
|
||||||
mShaderChanged = false;
|
mShaderChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,6 +687,11 @@ void RenderDevice_Delete(RenderDevice* device)
|
||||||
delete device;
|
delete device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* RenderDevice_GetError(RenderDevice* device)
|
||||||
|
{
|
||||||
|
return device->GetError();
|
||||||
|
}
|
||||||
|
|
||||||
void RenderDevice_SetShader(RenderDevice* device, ShaderName name)
|
void RenderDevice_SetShader(RenderDevice* device, ShaderName name)
|
||||||
{
|
{
|
||||||
device->SetShader(name);
|
device->SetShader(name);
|
||||||
|
|
|
@ -126,7 +126,9 @@ public:
|
||||||
void ApplyBlendState();
|
void ApplyBlendState();
|
||||||
void ApplyDepthState();
|
void ApplyDepthState();
|
||||||
|
|
||||||
void CheckError();
|
void CheckGLError();
|
||||||
|
void SetError(const char* fmt, ...);
|
||||||
|
const char* GetError();
|
||||||
|
|
||||||
Shader* GetActiveShader();
|
Shader* GetActiveShader();
|
||||||
|
|
||||||
|
@ -186,6 +188,9 @@ public:
|
||||||
|
|
||||||
bool mContextIsCurrent = false;
|
bool mContextIsCurrent = false;
|
||||||
|
|
||||||
|
char mLastError[4096];
|
||||||
|
char mReturnError[4096];
|
||||||
|
|
||||||
int mViewportWidth = 0;
|
int mViewportWidth = 0;
|
||||||
int mViewportHeight = 0;
|
int mViewportHeight = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,31 +4,54 @@
|
||||||
#include "RenderDevice.h"
|
#include "RenderDevice.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
void Shader::Setup(const std::string& vertexShader, const std::string& fragmentShader, bool alphatest)
|
void Shader::Setup(const std::string& identifier, const std::string& vertexShader, const std::string& fragmentShader, bool alphatest)
|
||||||
{
|
{
|
||||||
|
mIdentifier = identifier;
|
||||||
mVertexText = vertexShader;
|
mVertexText = vertexShader;
|
||||||
mFragmentText = fragmentShader;
|
mFragmentText = fragmentShader;
|
||||||
mAlphatest = alphatest;
|
mAlphatest = alphatest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::Bind()
|
bool Shader::CheckCompile()
|
||||||
{
|
{
|
||||||
bool firstCall = !mProgramBuilt;
|
bool firstCall = !mProgramBuilt;
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
mProgramBuilt = true;
|
mProgramBuilt = true;
|
||||||
CreateProgram();
|
CreateProgram();
|
||||||
|
glUseProgram(mProgram);
|
||||||
|
glUniform1i(glGetUniformLocation(mProgram, "texture1"), 0);
|
||||||
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mProgram)
|
return !mErrors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Shader::GetCompileError()
|
||||||
|
{
|
||||||
|
std::string lines = "Error compiling ";
|
||||||
|
if (!mVertexShader)
|
||||||
|
lines += "vertex ";
|
||||||
|
else if (!mFragmentShader)
|
||||||
|
lines += "fragment ";
|
||||||
|
lines += "shader \"" + mIdentifier + "\":\r\n";
|
||||||
|
for (auto c : mErrors)
|
||||||
|
{
|
||||||
|
if (c == '\r')
|
||||||
|
continue;
|
||||||
|
if (c == '\n')
|
||||||
|
lines += "\r\n";
|
||||||
|
else lines += c;
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::Bind()
|
||||||
|
{
|
||||||
|
if (!mProgram || !mProgramBuilt || mErrors.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glUseProgram(mProgram);
|
glUseProgram(mProgram);
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
glUniform1i(glGetUniformLocation(mProgram, "texture1"), 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::CreateProgram()
|
void Shader::CreateProgram()
|
||||||
|
|
|
@ -11,15 +11,20 @@ public:
|
||||||
Shader() = default;
|
Shader() = default;
|
||||||
void ReleaseResources();
|
void ReleaseResources();
|
||||||
|
|
||||||
void Setup(const std::string& vertexShader, const std::string& fragmentShader, bool alphatest);
|
void Setup(const std::string& identifier, const std::string& vertexShader, const std::string& fragmentShader, bool alphatest);
|
||||||
|
bool CheckCompile();
|
||||||
void Bind();
|
void Bind();
|
||||||
|
|
||||||
|
std::string GetIdentifier();
|
||||||
|
std::string GetCompileError();
|
||||||
|
|
||||||
GLuint UniformLocations[(int)UniformName::NumUniforms] = { 0 };
|
GLuint UniformLocations[(int)UniformName::NumUniforms] = { 0 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateProgram();
|
void CreateProgram();
|
||||||
GLuint CompileShader(const std::string& code, GLenum type);
|
GLuint CompileShader(const std::string& code, GLenum type);
|
||||||
|
|
||||||
|
std::string mIdentifier;
|
||||||
std::string mVertexText;
|
std::string mVertexText;
|
||||||
std::string mFragmentText;
|
std::string mFragmentText;
|
||||||
bool mAlphatest = false;
|
bool mAlphatest = false;
|
||||||
|
|
|
@ -37,14 +37,42 @@ static const ShaderPair ShaderSources[(int)ShaderName::count] = {
|
||||||
{ world3D_vs_lightpass, world3D_ps_lightpass }
|
{ world3D_vs_lightpass, world3D_ps_lightpass }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const std::string ShaderNames[(int)ShaderName::count] = {
|
||||||
|
"display2d_fsaa",
|
||||||
|
"display2d_normal",
|
||||||
|
"display2d_fullbright",
|
||||||
|
"things2d_thing",
|
||||||
|
"things2d_sprite",
|
||||||
|
"things2d_fill",
|
||||||
|
"plotter",
|
||||||
|
"world3d_main",
|
||||||
|
"world3d_fullbright",
|
||||||
|
"world3d_main_highlight",
|
||||||
|
"world3d_fullbright_highlight",
|
||||||
|
"world3d_main_vertexcolor",
|
||||||
|
"world3d_skybox",
|
||||||
|
"world3d_main_highlight_vertexcolor",
|
||||||
|
"world3d_p7",
|
||||||
|
"world3d_main_fog",
|
||||||
|
"world3d_p9",
|
||||||
|
"world3d_main_highlight_fog",
|
||||||
|
"world3d_p11",
|
||||||
|
"world3d_main_fog_vertexcolor",
|
||||||
|
"world3d_p13",
|
||||||
|
"world3d_main_highlight_fog_vertexcolor",
|
||||||
|
"world3d_vertex_color",
|
||||||
|
"world3d_constant_color",
|
||||||
|
"world3d_lightpass",
|
||||||
|
};
|
||||||
|
|
||||||
ShaderManager::ShaderManager()
|
ShaderManager::ShaderManager()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)ShaderName::count; i++)
|
for (int i = 0; i < (int)ShaderName::count; i++)
|
||||||
{
|
{
|
||||||
if (ShaderSources[i].vs && ShaderSources[i].ps)
|
if (ShaderSources[i].vs && ShaderSources[i].ps)
|
||||||
{
|
{
|
||||||
Shaders[i].Setup(ShaderSources[i].vs, ShaderSources[i].ps, false);
|
Shaders[i].Setup(ShaderNames[i], ShaderSources[i].vs, ShaderSources[i].ps, false);
|
||||||
AlphaTestShaders[i].Setup(ShaderSources[i].vs, ShaderSources[i].ps, true);
|
AlphaTestShaders[i].Setup(ShaderNames[i], ShaderSources[i].vs, ShaderSources[i].ps, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ EXPORTS
|
||||||
|
|
||||||
RenderDevice_New
|
RenderDevice_New
|
||||||
RenderDevice_Delete
|
RenderDevice_Delete
|
||||||
|
RenderDevice_GetError
|
||||||
RenderDevice_SetShader
|
RenderDevice_SetShader
|
||||||
RenderDevice_SetUniform
|
RenderDevice_SetUniform
|
||||||
RenderDevice_SetVertexBuffer
|
RenderDevice_SetVertexBuffer
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue