Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Ok,

First of all, if just use uniforms everthing works like it should. Switching to uniform blocks nothing goes, as all values look like 0.0. I tested this with various if-then-else stuff within the vertex shader and modifying the output color.

According to CodeXL 1.3(here the data is listed as VBO, but I think this is only cosmetic), GL.BindBuffer with GL.MapBuffer, or GL.GetBufferSubData there is really the proper data within my ubo but nonetheless the uniform block in the shader contains 0.0 only.

workflow:

    //Create UBO 
    BufferUBOName = new int[2];
    GL.GenBuffers(2, BufferUBOName); // Generate the buffer
    BufferIndex = 0;

    GL.BindBuffer(BufferTarget.UniformBuffer, BufferUBOName[0]); // Bind the buffer for writing
    GL.BufferData(BufferTarget.UniformBuffer, (IntPtr)uboWorldData.SizeInBytes, IntPtr.Zero, BufferUsageHint.StreamDraw);  // Request the memory to be allocated
    GL.BindBufferRange(BufferRangeTarget.UniformBuffer, BufferIndex, BufferUBOName[0], IntPtr.Zero, (IntPtr)uboWorldData.SizeInBytes); // Bind the created Uniform Buffer to the Buffer Index

Creating and linking the shaders works fine and gives the following ouput :

GL   4.3
GLSL 4.30
Shader: basic_fs ok
Shader: basic_vs ok
ShaderProgram :hexgrid [ basic_vs, basic_fs ]
    Active Uniform Block : UboWorld
      Size         : 144
      BlockBinding : 1
      BufferPoint  : 0
        Name : UboWorld.time
          Type[n] : Float [4]
          Offset  : 0
        Name : UboWorld.screenwidth
          Type[n] : Int [4]
          Offset  : 4
        Name : UboWorld.screenheight
          Type[n] : Int [4]
          Offset  : 8
        Name : UboWorld.promat
          Type[n] : FloatMat4 [64]
          Offset  : 16
          matrix stride: 16
        Name : UboWorld.mvpmat
          Type[n] : FloatMat4 [64]
          Offset  : 80
          matrix stride: 16

    // Done after successful program linking
    uniformBlockIndices["ubodata"] = GL.GetUniformBlockIndex(shaderprog.Handle, "UboWorld"); // Gets the uniform variable Location
    if (uniformBlockIndices["ubodata"] != -1)
        GL.UniformBlockBinding(shaderprog.Handle, uniformBlockIndices["ubodata"], BufferUBOName[0]);

Then VBO / VAO are created and working fine, incl. drawing elements.

On UpdateFrame the UBO data will be processed like:

    GL.BindBuffer(BufferTarget.UniformBuffer, BufferUBOName[0]);
    GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, (IntPtr)uboWorldData.SizeInBytes, ref uboWorld);

The offsets are taken from the information after program linking and reading the various values for the UniformBlockActiveUniforms. I skip the output here as the struct should reflect it properly.

    [StructLayout(LayoutKind.Explicit)]
    struct uboWorldData
    {
        [FieldOffset(0)]
        public float time;
        [FieldOffset(4)]
        public Int32 screenwidth;
        [FieldOffset(8)]
        public Int32 screenheight;
        [FieldOffset(16)]
        public Matrix4 projectionMatrix;
        [FieldOffset(80)]
        public Matrix4 modelviewMatrix;

        public static readonly int SizeInBytes = 144;
    };

Vertex shader for testing:

    #version 400    
    in vec3 in_position;
    in vec3 in_normal;    
    out vec3 normal;
    out vec3 colortime;
    out vec3 colortimeubo;

    // These uniforms work
    uniform mat4 mvpmat; 
    uniform mat4 promat;
    uniform float time;

    // This compiles fine. But always 0.0
    layout(std140) uniform UboWorld {
        float time;
        int screenwidth;
        int screenheight;
        mat4 promat;
        mat4 mvpmat;
    } w;

    const float pi = 3.1415;

    void main()
    {
      // This uses the UNIFORM FLOAT
      colortime = vec3(abs(sin(time * 360.0 * pi / 180.0)), 0.3, 0.3);
      // Here the uniform UboWorld
      colortimeubo = vec3(abs(sin(w.time * 360.0 * pi / 180.0)), 0.3, 0.3);

      normal = (mvpmat * vec4(in_normal, 0)).xyz;  
      gl_Position = promat * mvpmat * vec4(in_position, 1);  
    }

Any hints why w.time and also w.mvpmat or w.promat are always zero filled ???

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Here you are binding the buffer to the index BufferIndex:

GL.BindBufferRange(BufferRangeTarget.UniformBuffer, BufferIndex,
                   BufferUBOName[0], IntPtr.Zero, 
                   (IntPtr)uboWorldData.SizeInBytes);

The problem probably lies in the following line:

GL.UniformBlockBinding(shaderprog.Handle, uniformBlockIndices["ubodata"],
                       BufferUBOName[0]);

Which should be:

GL.UniformBlockBinding(shaderprog.Handle, uniformBlockIndices["ubodata"], BufferIndex);
share|improve this answer
    
GL.BindBufferRange(BufferRangeTarget.UniformBuffer, BufferIndex, BufferUBOName[0], IntPtr.Zero, (IntPtr)uboWorldData.SizeInBytes); // Bind the created Uniform Buffer to the Buffer Index –  OpenGL Beginner Mar 8 at 23:31
    
I don't follow... –  Fault Mar 8 at 23:38
    
In my question I use GL.BindBufferRange with BufferIndex = 0 and I tried changing the GL.UniformBlockBinding. But the result is still no active value in w.time. (Sorry for first answer. Copy&Pasted and accidentially press commit) –  OpenGL Beginner Mar 8 at 23:39
    
Are you padding your data? It shouldn't affect the value for w.time, but it's worth mentioning that the std140 layout means all values in your uniform block will be padded to a multiple of vec4. –  Fault Mar 8 at 23:54
    
Yes, like described above I use a struct with Explicit layout and setting the offsets regarding to the values in the shaderprogram retrieved with GL.GetActiveUniforms and ActiveUniformParameter.UniformOffset. BTW using the BufferIndex=0 GL.GetError() returns InvalidOperation during GL.UniformBlockBinding, whereas uniformBlockIndices["ubodata"] returns NoError. –  OpenGL Beginner Mar 9 at 0:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.