Declare the uniform variables in C#

This commit is contained in:
Magnus Norddahl 2019-12-21 02:14:42 +01:00
parent a21edf78da
commit 28406cf1a7
6 changed files with 94 additions and 83 deletions

View file

@ -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,

View file

@ -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);

View file

@ -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<ShaderManager> 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<UniformInfo> mUniformInfo;
std::vector<float> mUniformData;
void DeclareUniform(UniformName name, const char* glslname, UniformType type);
union UniformEntry
{
float valuef;
int32_t valuei;
};
GLuint mStreamVertexBuffer = 0;
GLuint mStreamVAO = 0;

View file

@ -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());
}
}

View file

@ -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<int> UniformLastUpdates;
std::vector<GLuint> UniformLocations;
private:
void CreateProgram(RenderDevice* device);

View file

@ -4,6 +4,7 @@ EXPORTS
RenderDevice_New
RenderDevice_Delete
RenderDevice_GetError
RenderDevice_DeclareUniform
RenderDevice_DeclareShader
RenderDevice_SetShader
RenderDevice_SetUniform