kevink's picture

Create uniform shader blocks

Hi everybody,

I´m new to opentk and I try using uniform blocks in the GLControl.
The question is also on stackoverflow. But it is still not working.

I try to rewrite an example of the "OpenGL Shading Language Cookbook".
The source can be found here:

File: scenebasic_uniformblock.cpp

Compiling and linking is successfull.

My source in the initializing function looks now:

// Get the index of the uniform block			
var blockIndex = GL.GetUniformBlockIndex(programId, "BlobSettings");
// Store data within the buffer at the appropriate offsets
var blockBuffer = new BlobSettings
	OuterColor = new Vector4(1.0f, 0.0f, 0.0f, 0.0f),
	InnerColor = new Vector4(1.0f, 1.0f, 0.75f, 1.0f),
	InnerRadius = 0.25f,
	OuterRadius = 0.45f
 // Create the buffer object and copy the data
int uboHandle;
GL.GenBuffers(1, out uboHandle);
GL.BindBuffer(BufferTarget.UniformBuffer, uboHandle);
	ref blockBuffer, BufferUsageHint.DynamicDraw);			
// Bind the buffer object to the uniform block
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 1, uboHandle);
// We don't need this if we specify the binding within the shader
GL.UniformBlockBinding(programId, blockIndex, 0);				
// Clear Color
// Create buffer objects
var vertexBufferObjectHandles = new int[2];
GL.GenBuffers(2, vertexBufferObjectHandles);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjectHandles[0]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(_vertdata.Length * sizeof(float)), _vertdata, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjectHandles[1]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(_tcData.Length * sizeof(float)), _tcData, BufferUsageHint.StaticDraw);
// Create VAO
GL.GenVertexArrays(1, out _vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjectHandles[0]);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjectHandles[1]);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 0, 0);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

The BlobSettings Type is a struct of:

public struct BlobSettings
	public Vector4 InnerColor;
	public Vector4 OuterColor;
	public float InnerRadius;
	public float OuterRadius;
	public static readonly int Size = BlittableValueType<BlobSettings>.Stride;

And the paint Method:

// Clear Color Buffer and Depth Buffer
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);

The full source of my projekt can be found:
Full Source of Project

All I got is a black Screen. If I change the Fragment shader to

FragColor = mix(innerC, outerC, smoothstep(0.25, 0.45, dist));

I got a working Image.

So I think there is a Problem with setting the uniform block data.

Does anyone know where the problem is?

Thank you very much!


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

I'll take a look into this as soon as I get some time.

kevink's picture

That would be very nice. Thank you very much.

the Fiddler's picture

I am having some trouble getting this project to work on my system.

First thing I tried was to replace OpenTK.dll with a debug version. This uncovered an OpenGL error at GL.UseProgram, so I added some code to check for compile/link status of the shaders.

            GL.GetShader(vertexShaderId, ShaderParameter.CompileStatus, out status);
            if (status == 0)
                throw new Exception(
            GL.GetShader(fragmentShaderId, ShaderParameter.CompileStatus, out status);
            if (status == 0)
                throw new Exception(
            GL.GetProgram(programId, GetProgramParameterName.LinkStatus, out status);
            if (status == 0)
                throw new Exception(

On my system, it appears that the fragment shader is failing to compile: explicit uniform location requires OpenGL 4.3, so you need to bump your shader to #version 430.

My system only supports OpenGL 4.1, so I removed the explicit location. However, the fragment shader still fails to compile for me, but with no error message this time.

I would suggest the following:

  • Use a debug version of OpenTK.dll for testing. This will throw an exception as soon as an OpenGL error is detected, which is very helpful during development.
  • Run your shaders through the reference GLSL compiler to ensure they are correct.
  • Use layout(std140, binding = 1) to specify the binding location for the uniform block.
  • Try layout(std430) to see if it makes a difference. (From my reading of the spec, std140 should match the default C# packing rules, but I might be wrong.)

I'll try to see if I have any system with better OpenGL support to test on.

maxwills's picture

Where can I find a "debug version of OpenTK.dll". I've seen this advice a couple of times. Sounds great, but I have no idea where to get that dll.

the Fiddler's picture

You can use OpenTK.sln to compile a debug build of OpenTK.dll. Additional instructions here:

You can download the source code from The source is also included in the installation package from sourceforge.

kevink's picture


sorry I extracted this project from a bigger one.

After setting the shader sources I forgot to compile the shaders:

So adding this



result in no shader errors.

The current source can be found here:

"Use layout(std140, binding = 1) to specify the binding location for the uniform block."
I get a System.AccessViolationException.

"Try layout(std430) to see if it makes a difference. (From my reading of the spec, std140 should match the default C# packing rules, but I might be wrong.)"
I get a ERROR: 0:12: '' : layout std430 is only allowed for buffer

Tomorrow I will test the code on another machine. Then I can say it has something to do with my GPU.

kevink's picture

On an nvidia quadro 2000 I cant it also get working.

Same issues.