c++ - Understanding GLSL Uniform Buffer Block Alignment -
i'm having trouble understanding std140 layout glsl uniform buffer objects. i'm under impression in following uniform block, int begin @ offset 0 , matrix begin @ offset 16. following uniform giving me bad matrix, apparent because nothing draws on-screen.
layout (std140) uniform camera { int rendermode; mat4 projection; } camera;
the point of rendermode
tells me uniform update code doesn't work.
i have following code (homegrown) me along. code makes open gl calls in c++ application. code inside class called uniformbufferobject
.
#define updateexdata(o, s, d) glbindbuffer(gl_uniform_buffer, _uboid); \ glbuffersubdata(gl_uniform_buffer, o, s, d); \ glbindbuffer(gl_uniform_buffer, 0); int alignment(int offset, int alignment) { int leftover = offset % alignment; if (leftover > 0) { return offset + (alignment - leftover); } else { return offset; } } template<typename t, typename... args> void updateex(int offset, const std::vector<t>& data, args&... args) { auto mysize = sizeof(t) * data.size(); int myalignment = alignment(offset, 16); // fixed vectors of vec4 updateexdata(myalignment, mysize, data.data()); updateex(myalignment + mysize, args...); } template<typename... args> void updateex(int offset, int& data, args&... args) { auto mysize = sizeof(int); int myalignment = alignment(offset, mysize); // assume 4 byte alignment ints updateexdata(myalignment, mysize, &data); updateex(myalignment + mysize, args...); } template<typename... args> void updateex(int offset, const glm::mat4& data, args&... args) { auto mysize = sizeof(glm::mat4); int myalignment = alignment(offset, 16); // assume 16-byte alignment mat4 updateexdata(myalignment, mysize, &data); updateex(myalignment + mysize, args...); }
the line of code initiates update follows. m
integer. cam
glm::mat4. purpose of piece update camera in shaders.
cameraubo->updateex(0, m, cam);
if flip uniform around such matrix first, , update call above cameraubo->updateex(0, cam, m)
, matrix updates rendermode no longer works.
i have no idea what's wrong , confuses me gl_uniform_block_data_size returns beyond 80 expect. different values, above 1000, across 5 shaders it's in.
i have uniform appears work perfectly, , has same size across 2 shaders in appears in.
struct towerlight { vec4 position; vec4 color; }; layout(std140) uniform towers { int lightcount; towerlight lights[maxlights]; };
with following code. count
integer , lights
std::vector<struct_of_2_vec4>
.
ubo->updateex(0, towercount, lights);
[edit]
this might bug in video card driver. have radeon 6870. if use default uniform block layout or drop shader version 430 440, block size of 80 across shaders.
this page explains how alignment works http://learnopengl.com/#!advanced-opengl/advanced-glsl
layout (std140) uniform exampleblock { // // base alignment // aligned offset float value; // 4 // 0 vec3 vector; // 16 // 16 (must multiple of 16 4->16) mat4 matrix; // 16 // 32 (column 0) // 16 // 48 (column 1) // 16 // 64 (column 2) // 16 // 80 (column 3) float values[3]; // 16 // 96 (values[0]) // 16 // 112 (values[1]) // 16 // 128 (values[2]) bool boolean; // 4 // 144 int integer; // 4 // 148 };
Comments
Post a Comment