From 28406cf1a7a2ceec02b128e49a9ea3d386b98875 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 21 Dec 2019 02:14:42 +0100 Subject: [PATCH] Declare the uniform variables in C# --- Source/Core/Rendering/RenderDevice.cs | 71 +++++++++++++++++++++------ Source/Native/RenderDevice.cpp | 45 +++++++---------- Source/Native/RenderDevice.h | 42 ++++------------ Source/Native/Shader.cpp | 13 +++-- Source/Native/Shader.h | 5 +- Source/Native/exports.def | 1 + 6 files changed, 94 insertions(+), 83 deletions(-) diff --git a/Source/Core/Rendering/RenderDevice.cs b/Source/Core/Rendering/RenderDevice.cs index 115f1a20..8df6911f 100755 --- a/Source/Core/Rendering/RenderDevice.cs +++ b/Source/Core/Rendering/RenderDevice.cs @@ -41,18 +41,30 @@ namespace CodeImp.DoomBuilder.Rendering { public RenderDevice(RenderTargetControl rendertarget) { - // Grab the X11 Display handle by abusing reflection to access internal classes in the mono implementation. - // That's par for the course for everything in Linux, so yeah.. - IntPtr display = IntPtr.Zero; - Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); - if (xplatui != null) - { - display = (IntPtr)xplatui.GetField("DisplayHandle", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - } - - Handle = RenderDevice_New(display, rendertarget.Handle); - if (Handle == IntPtr.Zero) - throw new Exception("RenderDevice_New failed"); + RenderTarget = rendertarget; + + CreateDevice(); + + DeclareUniform(UniformName.rendersettings, "rendersettings", UniformType.Vec4); + DeclareUniform(UniformName.projection, "projection", UniformType.Mat4); + DeclareUniform(UniformName.desaturation, "desaturation", UniformType.Float); + DeclareUniform(UniformName.highlightcolor, "highlightcolor", UniformType.Vec4); + DeclareUniform(UniformName.view, "view", UniformType.Mat4); + DeclareUniform(UniformName.world, "world", UniformType.Mat4); + DeclareUniform(UniformName.modelnormal, "modelnormal", UniformType.Mat4); + DeclareUniform(UniformName.FillColor, "FillColor", UniformType.Vec4); + DeclareUniform(UniformName.vertexColor, "vertexColor", UniformType.Vec4); + DeclareUniform(UniformName.stencilColor, "stencilColor", UniformType.Vec4); + DeclareUniform(UniformName.lightPosAndRadius, "lightPosAndRadius", UniformType.Vec4); + DeclareUniform(UniformName.lightOrientation, "lightOrientation", UniformType.Vec3); + DeclareUniform(UniformName.light2Radius, "light2Radius", UniformType.Vec2); + DeclareUniform(UniformName.lightColor, "lightColor", UniformType.Vec4); + DeclareUniform(UniformName.ignoreNormals, "ignoreNormals", UniformType.Float); + DeclareUniform(UniformName.spotLight, "spotLight", UniformType.Float); + DeclareUniform(UniformName.campos, "campos", UniformType.Vec4); + DeclareUniform(UniformName.texturefactor, "texturefactor", UniformType.Vec4); + DeclareUniform(UniformName.fogsettings, "fogsettings", UniformType.Vec4); + DeclareUniform(UniformName.fogcolor, "fogcolor", UniformType.Vec4); DeclareShader(ShaderName.display2d_fsaa, "display2d.vp", "display2d_fsaa.fp"); DeclareShader(ShaderName.display2d_normal, "display2d.vp", "display2d_normal.fp"); @@ -76,8 +88,6 @@ namespace CodeImp.DoomBuilder.Rendering DeclareShader(ShaderName.world3d_constant_color, "world3d_customvertexcolor.vp", "world3d_constant_color.fp"); DeclareShader(ShaderName.world3d_lightpass, "world3d_lightpass.vp", "world3d_lightpass.fp"); - RenderTarget = rendertarget; - SetupSettings(); } @@ -86,6 +96,22 @@ namespace CodeImp.DoomBuilder.Rendering Dispose(); } + void CreateDevice() + { + // Grab the X11 Display handle by abusing reflection to access internal classes in the mono implementation. + // That's par for the course for everything in Linux, so yeah.. + IntPtr display = IntPtr.Zero; + Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); + if (xplatui != null) + { + display = (IntPtr)xplatui.GetField("DisplayHandle", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + } + + Handle = RenderDevice_New(display, RenderTarget.Handle); + if (Handle == IntPtr.Zero) + throw new Exception("RenderDevice_New failed"); + } + public bool Disposed { get { return Handle == IntPtr.Zero; } } void ThrowIfFailed(bool result) @@ -103,6 +129,11 @@ namespace CodeImp.DoomBuilder.Rendering } } + public void DeclareUniform(UniformName name, string variablename, UniformType type) + { + RenderDevice_DeclareUniform(Handle, name, variablename, type); + } + public void DeclareShader(ShaderName name, string vertResourceName, string fragResourceName) { RenderDevice_DeclareShader(Handle, name, name.ToString(), GetResourceText(vertResourceName), GetResourceText(fragResourceName)); @@ -425,6 +456,9 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl)] static extern void RenderDevice_Delete(IntPtr handle); + [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + static extern void RenderDevice_DeclareUniform(IntPtr handle, UniformName name, string variablename, UniformType type); + [DllImport("BuilderNative", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] static extern void RenderDevice_DeclareShader(IntPtr handle, ShaderName index, string name, string vertexShader, string fragShader); @@ -601,6 +635,15 @@ namespace CodeImp.DoomBuilder.Rendering world3d_lightpass } + public enum UniformType : int + { + Vec4, + Vec3, + Vec2, + Float, + Mat4 + } + public enum UniformName : int { rendersettings, diff --git a/Source/Native/RenderDevice.cpp b/Source/Native/RenderDevice.cpp index 8a9878ce..370aaf1b 100644 --- a/Source/Native/RenderDevice.cpp +++ b/Source/Native/RenderDevice.cpp @@ -28,27 +28,6 @@ static void APIENTRY GLLogCallback(GLenum source, GLenum type, GLuint id, RenderDevice::RenderDevice(void* disp, void* window) { - DeclareUniform(UniformName::projection, "projection", UniformType::Matrix); - DeclareUniform(UniformName::view, "view", UniformType::Matrix); - DeclareUniform(UniformName::world, "world", UniformType::Matrix); - DeclareUniform(UniformName::modelnormal, "modelnormal", UniformType::Matrix); - DeclareUniform(UniformName::rendersettings, "rendersettings", UniformType::Vec4f); - DeclareUniform(UniformName::highlightcolor, "highlightcolor", UniformType::Vec4f); - DeclareUniform(UniformName::FillColor, "fillColor", UniformType::Vec4f); - DeclareUniform(UniformName::vertexColor, "vertexColor", UniformType::Vec4f); - DeclareUniform(UniformName::stencilColor, "stencilColor", UniformType::Vec4f); - DeclareUniform(UniformName::lightPosAndRadius, "lightPosAndRadius", UniformType::Vec4f); - DeclareUniform(UniformName::lightColor, "lightColor", UniformType::Vec4f); - DeclareUniform(UniformName::campos, "campos", UniformType::Vec4f); - DeclareUniform(UniformName::texturefactor, "texturefactor", UniformType::Vec4f); - DeclareUniform(UniformName::fogsettings, "fogsettings", UniformType::Vec4f); - DeclareUniform(UniformName::fogcolor, "fogcolor", UniformType::Vec4f); - DeclareUniform(UniformName::lightOrientation, "lightOrientation", UniformType::Vec3f); - DeclareUniform(UniformName::light2Radius, "light2Radius", UniformType::Vec2f); - DeclareUniform(UniformName::desaturation, "desaturation", UniformType::Float); - DeclareUniform(UniformName::ignoreNormals, "ignoreNormals", UniformType::Float); - DeclareUniform(UniformName::spotLight, "spotLight", UniformType::Float); - Context = IOpenGLContext::Create(disp, window); if (Context) { @@ -760,23 +739,28 @@ bool RenderDevice::ApplyVertexBuffer() void RenderDevice::DeclareUniform(UniformName name, const char* glslname, UniformType type) { - UniformInfo& info = mUniformInfo[(int)name]; + size_t index = (size_t)name; + if (mUniformInfo.size() <= index) + mUniformInfo.resize(index + 1); + + UniformInfo& info = mUniformInfo[index]; info.Name = glslname; info.Type = type; info.Offset = (int)mUniformData.size(); - mUniformData.resize(mUniformData.size() + (type == UniformType::Matrix ? 16 : 4)); + mUniformData.resize(mUniformData.size() + (type == UniformType::Mat4 ? 16 : 4)); } bool RenderDevice::ApplyUniforms() { Shader* shader = GetActiveShader(); - auto& locations = shader->UniformLocations; - auto& lastupdates = shader->UniformLastUpdates; + GLuint* locations = shader->UniformLocations.data(); + int* lastupdates = shader->UniformLastUpdates.data(); - for (int i = 0; i < (int)UniformName::NumUniforms; i++) + int count = (int)mUniformInfo.size(); + for (int i = 0; i < count; i++) { - if (lastupdates[i] != mUniformInfo[i].LastUpdate) + if (lastupdates[i] != mUniformInfo.data()[i].LastUpdate) { float* data = mUniformData.data() + mUniformInfo[i].Offset; GLuint location = locations[i]; @@ -787,7 +771,7 @@ bool RenderDevice::ApplyUniforms() case UniformType::Vec3f: glUniform3fv(location, 1, data); break; case UniformType::Vec2f: glUniform2fv(location, 1, data); break; case UniformType::Float: glUniform1fv(location, 1, data); break; - case UniformType::Matrix: glUniformMatrix4fv(location, 1, GL_FALSE, data); break; + case UniformType::Mat4: glUniformMatrix4fv(location, 1, GL_FALSE, data); break; } lastupdates[i] = mUniformInfo[i].LastUpdate; } @@ -865,6 +849,11 @@ const char* RenderDevice_GetError(RenderDevice* device) return device->GetError(); } +void RenderDevice_DeclareUniform(RenderDevice* device, UniformName name, const char* variablename, UniformType type) +{ + device->DeclareUniform(name, variablename, type); +} + void RenderDevice_DeclareShader(RenderDevice* device, ShaderName index, const char* name, const char* vertexshader, const char* fragmentshader) { device->DeclareShader(index, name, vertexshader, fragmentshader); diff --git a/Source/Native/RenderDevice.h b/Source/Native/RenderDevice.h index 20e587fb..db6402e2 100644 --- a/Source/Native/RenderDevice.h +++ b/Source/Native/RenderDevice.h @@ -21,31 +21,16 @@ enum class ShaderFlags : int { None, Debug }; enum class PrimitiveType : int { LineList, TriangleList, TriangleStrip }; enum class TextureFilter : int { None, Point, Linear, Anisotropic }; +typedef int UniformName; typedef int ShaderName; -enum class UniformName : int +enum class UniformType : int { - rendersettings, - projection, - desaturation, - highlightcolor, - view, - world, - modelnormal, - FillColor, - vertexColor, - stencilColor, - lightPosAndRadius, - lightOrientation, - light2Radius, - lightColor, - ignoreNormals, - spotLight, - campos, - texturefactor, - fogsettings, - fogcolor, - NumUniforms + Vec4f, + Vec3f, + Vec2f, + Float, + Mat4 }; class RenderDevice @@ -54,6 +39,7 @@ public: RenderDevice(void* disp, void* window); ~RenderDevice(); + void DeclareUniform(UniformName name, const char* glslname, UniformType type); void DeclareShader(ShaderName index, const char* name, const char* vertexshader, const char* fragmentshader); void SetShader(ShaderName name); void SetUniform(UniformName name, const void* values, int count); @@ -150,8 +136,6 @@ public: std::unique_ptr mShaderManager; ShaderName mShaderName = {}; - enum class UniformType { Matrix, Vec4f, Vec3f, Vec2f, Float }; - struct UniformInfo { std::string Name; @@ -160,17 +144,9 @@ public: int LastUpdate = 0; }; - UniformInfo mUniformInfo[(int)UniformName::NumUniforms]; + std::vector mUniformInfo; std::vector mUniformData; - void DeclareUniform(UniformName name, const char* glslname, UniformType type); - - union UniformEntry - { - float valuef; - int32_t valuei; - }; - GLuint mStreamVertexBuffer = 0; GLuint mStreamVAO = 0; diff --git a/Source/Native/Shader.cpp b/Source/Native/Shader.cpp index 3b5f61f2..c178c2db 100644 --- a/Source/Native/Shader.cpp +++ b/Source/Native/Shader.cpp @@ -104,12 +104,15 @@ void Shader::CreateProgram(RenderDevice* device) return; } - for (int i = 0; i < (int)UniformName::NumUniforms; i++) + UniformLastUpdates.resize(device->mUniformInfo.size()); + UniformLocations.resize(device->mUniformInfo.size(), (GLuint)-1); + + int count = (int)UniformLocations.size(); + for (int i = 0; i < count; i++) { - if (!device->mUniformInfo[i].Name.empty()) - UniformLocations[i] = glGetUniformLocation(mProgram, device->mUniformInfo[i].Name.c_str()); - else - UniformLocations[i] = (GLuint)-1; + const auto& name = device->mUniformInfo[i].Name; + if (!name.empty()) + UniformLocations[i] = glGetUniformLocation(mProgram, name.c_str()); } } diff --git a/Source/Native/Shader.h b/Source/Native/Shader.h index c4b8da20..1c72b893 100644 --- a/Source/Native/Shader.h +++ b/Source/Native/Shader.h @@ -14,11 +14,10 @@ public: bool CheckCompile(RenderDevice *device); void Bind(); - std::string GetIdentifier(); std::string GetCompileError(); - int UniformLastUpdates[(int)UniformName::NumUniforms] = { 0 }; - GLuint UniformLocations[(int)UniformName::NumUniforms] = { 0 }; + std::vector UniformLastUpdates; + std::vector UniformLocations; private: void CreateProgram(RenderDevice* device); diff --git a/Source/Native/exports.def b/Source/Native/exports.def index 972311d6..40a8c28b 100644 --- a/Source/Native/exports.def +++ b/Source/Native/exports.def @@ -4,6 +4,7 @@ EXPORTS RenderDevice_New RenderDevice_Delete RenderDevice_GetError + RenderDevice_DeclareUniform RenderDevice_DeclareShader RenderDevice_SetShader RenderDevice_SetUniform