2
\$\begingroup\$

I'm building a shader program to render a simple bitmap font in GLSL.

My programming environment is C# so I'm using OpenTK to encapsulate OpenGL 4.0, but the syntax is very similar to any examples in C and C++.

My issue is that I'm trying to pass an array of integers to the fragment shader, but whenever I do, all the array elements end up being zero. The integers should range between 0 and 255 and I've checked the values before and after sending them. It's infuriating.

Currently I'm binding my program, then attempting to send the int[] array to the shader using the following instructions:

int[] ints = new int[] { 33, 34, 35, 36, 37, 38, 39, 40 };
GL.UseProgram(programLocation);
GL.Uniform1(arrayLocation, ints.Length, ints);

My fragment shader takes the array and uses a couple of functions to determine which part of the quad to place which characters. I've tested these functions with static numbers and arrays I build manually in the shader and they work just as I'd expect them to. For some reason the syntax above simply doesn't actually end up sending any data - all elements evaluate to 0.

In my shader, the array is denoted and used like this:

uniform int characters[8];
....
gl_FragColor = texture2D(bitmapFontTex, GetBitmapFontStart(characters[0...8etc]));

The rest of my code seems to work when tested in isolation - it only falls apart when it comes together, and the above code blocks are where it comes together. Have I made some silly rookie mistake, or is there something more screwy happening? Any help greatly appreciated.

\$\endgroup\$
  • \$\begingroup\$ I'm not familiar with OpenTK. Make sure you use a correct function to set the uniform and also check if arrayLocation is right \$\endgroup\$ – Russoul Jul 25 '16 at 19:50
  • \$\begingroup\$ Well, all of my location data is correct so far as I've seen in testing - and I can set each element of the array separately using "characters[0...8]" as the uniform name - I just can't set the whole array at once. Besides that, if I set them all separately, then iterate over the array, technically I'm not accessing the same uniform because "characters[0]" has its own location, as does "characters[1]" and so on. This is all giving me a headache. \$\endgroup\$ – Mavichist Jul 26 '16 at 4:33
  • \$\begingroup\$ Does OpenTK have an glUniform1iv() method? I've never done anything with it before but syntax-wise this would be the one you need. \$\endgroup\$ – cozmic Jul 26 '16 at 5:46
  • \$\begingroup\$ @cozmic In OpenTK, all of the glUniform1 methods are encapsulated into a single overloaded method. Their invocations change but they carry the same name. I'll have a look, but as far as I know this is the only one: i.imgur.com/GFIk6OD.png \$\endgroup\$ – Mavichist Jul 26 '16 at 11:19
1
\$\begingroup\$

Looks like you are using the wrong function, need to use uniform1i instead.

https://www.opengl.org/sdk/docs/man/html/glUniform.xhtml

glUniform1i and glUniform1iv are the only two functions that may be used to load uniform variables defined as sampler types. Loading samplers with any other function will result in a GL_INVALID_OPERATION error.

If count is greater than 1 and the indicated uniform variable is not an array, a GL_INVALID_OPERATION error is generated and the specified uniform variable will remain unchanged.

Other than the preceding exceptions, if the type and size of the uniform variable as defined in the shader do not match the type and size specified in the name of the command used to load its value, a GL_INVALID_OPERATION error will be generated and the specified uniform variable will remain unchanged.

If location is a value other than -1 and it does not represent a valid uniform variable location in the current program object, an error will be generated, and no changes will be made to the uniform variable storage of the current program object. If location is equal to -1, the data passed in will be silently ignored and the specified uniform variable will not be changed.

\$\endgroup\$
  • \$\begingroup\$ Thanks for taking the time to answer.This is one of the few points where the OpenTK and OpenGL method calls differ slightly. In OpenTK, all glUniform1x calls are wrapped into one overloaded method that can take various types (such as float and int). They looks something like this i.imgur.com/GFIk6OD.png . \$\endgroup\$ – Mavichist Jul 26 '16 at 10:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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