How to write data to uniform-blocks

Hello everyone,

i’d like to use uniform-blocks to transfer two independent sets of parameters to my shader, but i never did this before. I found a tutorial / example, where a uniform-buffer-object is used. So the data for a block is transferred at once but for me it would be better, if i could access single elements. Something like (pseudocode):


GLuint bLocation, uLocation;
glGetUniformBlockLocation(GLuint progamIndex, char *blockName, GLuint &bLocation); 
glGetUniformSubLocation(GLuint progamIndex, GLuint bLocation, char *itemName, GLuint &uLocation); 
glUniform1f (uLocation, value);

Is there anything like this??

Best,
Frank

The entire point of uniform blocks is to allow users to directly manage the uniform data used by a shader. Such an interface would work against that.

I mean sure, you could implement functions of that sort (though they would have to write data to the buffer object), but it’d be really slow (in part due to the need to write data to the buffer object more or less piecemeal).

No. The only way to modify uniforms stored in a UBO is to modify the corresponding buffer. To figure out the variable’s offset in the buffer, you either need to use the [var]std140[/var] layout (in which case the offset is determined by the structure of the interface block) or query the offset with glGetActiveUniforms() or glGetProgramResource().

The simplest approach is to use the [var]std140[/var] layout and define a C structure type with the same layout (you may need to insert explicit padding elements, as [var]std140[/var] has stricter alignment requirements than most C ABIs). Then you can map the UBO, cast the pointer to the structure type, and write to structure fields via the pointer.

Okay, here i’ve a more theoretical question: what means “slow”? This is something where i was thinking about several times “en passent”…

My program uses a self-written script-language for almost everything. Once i have to rewrite the interpreter, because it is buggy an - hmmm - “slow”. Today i would porgram it completly different, but currently it’s performes hundreds of strcmp()-calls per executed script-line, which means possibly near 100.000 per frame. Under this there are various glGetUniformLocation()-calls etc. (some around 50-100 per frame).

On my old notebook i really reached the limit, of what is possible, but on this one, that i have now, i can render a particle-simulation with one million particles. Speed-problems i’ve, when i use system elements, like a file-opening-window, to select a texture for loading, or if a larger part of the ui-window is updated.
Also compiling a shader might be a problem (unfortunately here the new notebook is much(!) slower - possibly the nvidia-driver spends more time on optimisation)

Concerning OpenGL i often read things that have to do with speed, so that each OpenGL-call costs time and that especially legacy-pipeline-calls might do this. If i now try to compare all these things in mind, that are done until one frame appers on my screen, i’ve absolutly no idea, how much performance they need. Month ago i i.e. red an article about the internal basics of GPU-access - so that there are several levels of “depth”, it has to pass until my call gets to the GPU. Therefore i consider my script-language as something like only one additional level and i don’t really wonder that it’s obviously fast enogh so far.
I would expect, that rendering more but smaller (less vertices then my particle-test) objects will sometimes lead the CPU to the limit, because the higher number of script-language-calls, but currently i’m far away of this (CPU-load around 15-20%). So, reprogramming my interpreter is not the thing that has currently high priority, but there i could save lots of time.

What i want to have is a “consistent interface”, so that the my scripts and openGL work together, even if it costs a bit time.

So, finally:
I want to combine shader-programs, openGL-calls an user-interface definition in ONE well readable script-language. But on the other hand i surely don’t want to waste too much performance. As far as i can see the bottleneck is my interpreter, but i’m not sure if i read about that something “is slow” - especially if you consider all the overhead of the OS and the drivers.

So my question from the beginning: What means “slow”? This is no joke. I don’t even have an idea how to scale / compare??

Best,
Frank

The simplest approach is to use the std140 layout and define a C structure type with the same layout…

Hmmmm…

I never understood / used “std140 layout” (or std420).

To explain my idea before i try to understand it (also because - as you know possibly - i’ve a complex working application, that i improve step by step, so i dont want to implement things that lead me to dead ends): I have (no, i’m near to have) a shader, that renders several object with specific enviournment-settings. Each of the objects have the same standard “dataset”: a texture, a VAO and some parameters concerning their material. So, the individual object-definitions are independent of the enviournment-settings and - a bit like in the old fixed-pipeline - rendered each after changing the material-parameters, while the shader itself and the enviournment-settings are kept.

The problem is now that my script-langage (i think you know about), can’t really manage arrays. In fact it mostly uses only single GLfloat and char*. This is not really a problem. Things like getting a value from a fader and transfereing it as uniform to a shader doesn’t need much more, but it is done sequecially fader-value by fader-value and faders are placed in panels, that have names.

So it’s obviuos that a term like PanelName.FaderName or structs like:


uniform SurfaceSettings {
  sampler2D Texture;
  float bumpFactor;
  float reflectionFactor;
  [...]
} PanelName;

…would be good. But with my interpreter i need to access them value by value. Is this possible with std14-layout and how best would be a code-example…

Best,
Frank

First, unless you’re using bindless textures (which you may be; you didn’t say), you can’t put a sampler in a uniform block.

Second, it’s not clear why these things need to be uniform blocks rather than just uniform variables. The general reason to use a block is that you want to be able to put the data for a specific object’s uniforms into a buffer object and set that buffer to define the value of those uniforms. To have that data be stored and managed separately from any particular program object.

It’s not clear what you gain from using a uniform block. Especially if you’re writing your rendering engine in your own interpreted scripting language.

Is this possible with std14-layout and how best would be a code-example…

OpenGL is a low-level API (kinda), so it’s meant to be worked with in a low-level way. Most uses of buffer objects are designed expecting that you are using C, C++ or a similar low-level language. Specifically, one where you can deal directly with memory. The API essentially expects that you can create a struct in your language of choice, set values in that, and then copy the bytes into the buffer object. Or that you can map the buffer, cast the pointer to the struct, and manipulate the values in the buffer directly through that pointer.

If you’re working in some other language, one without access to low-level memory in that way, then you need to build an abstraction around it that suits your needs. OpenGL isn’t going to provide one for you.

If you’re working in some other language, one without access to low-level memory in that way, then you need to build an abstraction around it that suits your needs. OpenGL isn’t going to provide one for you.

This is the point where i should rewrite my whole program. One and a half year ago i began to write a new interpreter, with complex memory-managent which allowed it, to store data en block in the heep. But i did not continue it, because i had to learn more about how OpenGL stores data. Now in between, i think i know enough to have a second try, but before summer i won’t find the time to do this. So i have to live with it as it is currently which means, that i have to write a class that can build an ubo-data-array if i want to implement this - not only some additional code-lines…

By the way: The idea with the interpreter comes from that if you add an additional function to a shader-program (like i.e. a glare-effect), you may also want to have additional controls on the UI. So in my program shaders and ui-controls belong together. So the main idea was, to store the shader-program and the definition for the UI-controls that it uses in one text-file (which also needed basic math and string-operations for names, sizes etc.). This is where my interpreter is used for at first.
After a while it angered me, that i had to write a lot of things two times in my text-files. Especially many declarations appeared once in the shader-string and once for my script-language. So i started to get rid of this redundant things. Therefore now uniform-variables (that appear on both sides), are not notated inside of the shader-string anymore. If a variable (that can also be a UI-control) is defined as uniform in my script, the interpreter adds it to the shader-program and takes care that, the their values are transmitted to the shader before calculating a frame.

I’ll mark this thread a solved. If i have problems with the mentioned class, i’ll open a new one…

Thank you,
Frank


EDIT: Is there any “solved” button? I don’t find it?

No, I don’t think we have that addon installed. So as you did, just follow-up with the conclusion you reached.