diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.cpp index dc6a28b9b..dd9b84f31 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.cpp @@ -17,6 +17,8 @@ #include "driver_opengl.h" #include "driver_opengl_uniform_buffer.h" +#include + #include namespace NL3D { @@ -32,6 +34,71 @@ const char *GLSLHeaderUniformBuffer = "#define NL_USER_PIXEL_PROGRAM_BIND " NL_MACRO_TO_STR(NL_USER_PIXEL_PROGRAM_BIND) "\n" "#define NL_USER_MATERIAL_BIND " NL_MACRO_TO_STR(NL_USER_MATERIAL_BIND) "\n"; +static const char *s_UniformBufferBindDefine[] = { + "NL_BUILTIN_CAMERA_BIND", + "NL_BUILTIN_MODEL_BIND", + "NL_BUILTIN_MATERIAL_BIND", + "NL_USER_ENV_BIND", + "NL_USER_VERTEX_PROGRAM_BIND", + "NL_USER_GEOMETRY_PROGRAM_BIND", + "NL_USER_PIXEL_PROGRAM_BIND", + "NL_USER_MATERIAL_BIND", +}; + +static const char *s_UniformBufferName[] = { + "BuiltinCamera", + "BuiltinModel", + "BuiltinMaterial", + "UserEnv", + "UserLocal", // Yes, there can only be one per stage here, as these are bound to the stage + "UserLocal", + "UserLocal", + "UserMaterial", +}; + +static const char *s_TypeKeyword[] = { + "float", // float + "vec2", // CVector2D + "vec3", + "vec4", // CVector + "int", // sint32 + "ivec2", + "ivec3", + "ivec3", + "unsigned int", // uint32 + "uvec2", + "uvec3", + "uvec4", + "bool", + "bvec2", + "bvec3", + "bvec4", + "mat2", + "mat3", + "mat4", // CMatrix + "mat2x3", + "mat2x4", + "mat3x2", + "mat3x4", + "mat4x2", + "mat4x3", +}; + +void generateUniformBufferGLSL(std::stringstream &ss, const CUniformBufferFormat &ubf, sint binding) +{ + ss << "layout(std140, binding = " << s_UniformBufferBindDefine[binding] << ") uniform " << s_UniformBufferName[binding] << "\n"; + ss << "{\n"; + for (sint i = 0; i < ubf.size(); ++i) + { + const CUniformBufferFormat::CEntry &entry = ubf.get(i); + ss << "\t" << s_TypeKeyword[entry.Type] << " " << NLMISC::CStringMapper::unmap(entry.Name); + if (entry.Count != 1) + ss << "[" << entry.Count << "]"; + ss << ";\n"; + } + ss << "}\n"; +} + } // NLDRIVERGL3 } // NL3D diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.h b/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.h index 9b3ffb33c..a44e7c7b0 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_uniform_buffer.h @@ -23,6 +23,10 @@ namespace NL3D { namespace NLDRIVERGL3 { // NOTE: It is completely safe to reorder these indices. +// When changing, update: +// - GLSLHeaderUniformBuffer +// - s_UniformBufferBindDefine +// - s_UniformBufferBindName // Always use the defines. #define NL_BUILTIN_CAMERA_BIND 0 // Builtin uniform buffer bound by driver, set by camera transformation #define NL_BUILTIN_MODEL_BIND 1 // Builtin uniform buffer bound by driver, set by model transformation @@ -46,6 +50,10 @@ namespace NL3D { class CUniformBufferFormat { public: + // When changing, update + // - s_TypeAlignment + // - s_TypeSize + // - NL3D::NLDRIVERGL3::s_TypeKeyword enum TType { Float, // float @@ -82,13 +90,13 @@ public: sint Offset; sint Count; - inline sint stride() + inline sint stride() const { return Count == 1 ? s_TypeSize[Type] : ((s_TypeSize[Type] + 15) & ~0xF); } - inline sint size() + inline sint size() const { return stride() * Count; } @@ -114,11 +122,12 @@ public: entry.Type = type; entry.Offset = alignOffset; entry.Count = count; - return baseOffset; + return alignOffset; } - inline const CEntry *get() { return &m_Entries[0]; } - inline size_t size() { return m_Entries.size(); } + inline const CEntry &get(sint i) const { return m_Entries[i]; } + inline size_t size() const { return m_Entries.size(); } + inline void clear() { m_Entries.clear(); } private: static const sint s_TypeAlignment[];