- moved ShaderUniforms to hwrenderer/ .

This commit is contained in:
Christoph Oelckers 2018-06-12 22:08:31 +02:00
parent f166624eb2
commit cb5caa757b
2 changed files with 121 additions and 116 deletions

View file

@ -1,123 +1,9 @@
#pragma once #pragma once
#include "hwrenderer/data/uniformbuffer.h" #include "gl_load/gl_system.h"
#include "v_video.h"
#include "gl/data/gl_uniformbuffer.h"
#include "gl_shader.h" #include "gl_shader.h"
#include "hwrenderer/data/shaderuniforms.h"
enum class UniformType
{
Int,
UInt,
Float,
Vec2,
Vec3,
Vec4,
IVec2,
IVec3,
IVec4,
UVec2,
UVec3,
UVec4,
Mat4
};
class UniformFieldDesc
{
public:
UniformFieldDesc() { }
UniformFieldDesc(const char *name, UniformType type, std::size_t offset) : Name(name), Type(type), Offset(offset) { }
const char *Name;
UniformType Type;
std::size_t Offset;
};
template<typename T, int bindingpoint>
class ShaderUniforms
{
public:
ShaderUniforms()
{
memset(&Values, 0, sizeof(Values));
}
~ShaderUniforms()
{
if (mBuffer != nullptr)
delete mBuffer;
}
int BindingPoint() const
{
return bindingpoint;
}
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
{
mFields = fields;
FString decl;
decl.Format("layout(%s) uniform %s\n{\n", screen->GetUniformLayoutString(bindingpoint).GetChars(), name);
for (const auto &field : fields)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
}
decl += "};\n";
return decl;
}
void Init()
{
if (mBuffer == nullptr)
mBuffer = screen->CreateUniformBuffer(sizeof(T));
}
void Set(bool bind = true)
{
if (mBuffer != nullptr)
mBuffer->SetData(&Values);
// Let's hope this can be done better when things have moved further ahead.
// This really is not the best place to add something that depends on API behavior.
if (bind) mBuffer->Bind(bindingpoint);
}
T *operator->() { return &Values; }
const T *operator->() const { return &Values; }
T Values;
private:
ShaderUniforms(const ShaderUniforms &) = delete;
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
const char *GetTypeStr(UniformType type)
{
switch (type)
{
default:
case UniformType::Int: return "int";
case UniformType::UInt: return "uint";
case UniformType::Float: return "float";
case UniformType::Vec2: return "vec2";
case UniformType::Vec3: return "vec3";
case UniformType::Vec4: return "vec4";
case UniformType::IVec2: return "ivec2";
case UniformType::IVec3: return "ivec3";
case UniformType::IVec4: return "ivec4";
case UniformType::UVec2: return "uvec2";
case UniformType::UVec3: return "uvec3";
case UniformType::UVec4: return "uvec4";
case UniformType::Mat4: return "mat4";
}
}
IUniformBuffer *mBuffer = nullptr;
std::vector<UniformFieldDesc> mFields;
};
class FShaderProgram class FShaderProgram
{ {

View file

@ -0,0 +1,119 @@
#pragma once
#include <vector>
#include "hwrenderer/data/uniformbuffer.h"
#include "v_video.h"
enum class UniformType
{
Int,
UInt,
Float,
Vec2,
Vec3,
Vec4,
IVec2,
IVec3,
IVec4,
UVec2,
UVec3,
UVec4,
Mat4
};
class UniformFieldDesc
{
public:
UniformFieldDesc() { }
UniformFieldDesc(const char *name, UniformType type, std::size_t offset) : Name(name), Type(type), Offset(offset) { }
const char *Name;
UniformType Type;
std::size_t Offset;
};
template<typename T, int bindingpoint>
class ShaderUniforms
{
public:
ShaderUniforms()
{
memset(&Values, 0, sizeof(Values));
}
~ShaderUniforms()
{
if (mBuffer != nullptr)
delete mBuffer;
}
int BindingPoint() const
{
return bindingpoint;
}
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
{
mFields = fields;
FString decl;
decl.Format("layout(%s) uniform %s\n{\n", screen->GetUniformLayoutString(bindingpoint).GetChars(), name);
for (const auto &field : fields)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
}
decl += "};\n";
return decl;
}
void Init()
{
if (mBuffer == nullptr)
mBuffer = screen->CreateUniformBuffer(sizeof(T));
}
void Set(bool bind = true)
{
if (mBuffer != nullptr)
mBuffer->SetData(&Values);
// Let's hope this can be done better when things have moved further ahead.
// This really is not the best place to add something that depends on API behavior.
if (bind) mBuffer->Bind(bindingpoint);
}
T *operator->() { return &Values; }
const T *operator->() const { return &Values; }
T Values;
private:
ShaderUniforms(const ShaderUniforms &) = delete;
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
const char *GetTypeStr(UniformType type)
{
switch (type)
{
default:
case UniformType::Int: return "int";
case UniformType::UInt: return "uint";
case UniformType::Float: return "float";
case UniformType::Vec2: return "vec2";
case UniformType::Vec3: return "vec3";
case UniformType::Vec4: return "vec4";
case UniformType::IVec2: return "ivec2";
case UniformType::IVec3: return "ivec3";
case UniformType::IVec4: return "ivec4";
case UniformType::UVec2: return "uvec2";
case UniformType::UVec3: return "uvec3";
case UniformType::UVec4: return "uvec4";
case UniformType::Mat4: return "mat4";
}
}
IUniformBuffer *mBuffer = nullptr;
std::vector<UniformFieldDesc> mFields;
};