Longs Peak Program Objects

I think having a default-shader would be a nice thing. It makes life easier to get started.

However, this default shader could be supplied by a glu-function (eg. gluBindDefaultShader () …). It could be a simple shader, that just transforms vertices and passes color and texture-coordinates to a fragment shader, which then does a simple texture-fetch and modulates it with the color. I think more is not needed, but it would be nice to have such a basic shader, just to be able to get an app up and running fast. By putting this functionality into a glu-function, one would keep the core clean.

Jan.

which then does a simple texture-fetch and modulates it with the color
I see it rather this way: gluBindSimpleShader( red, green, blue, alpha, texture); - binds shader and/or sets uniform values for it. Texture is optional. That would certainly shorten the learning curve for those new to OpenGL. Otherwise they would have to learn basics of shader programming just to make ‘Hello world’ application.
As for me, even if such function existed I wouldn’t use it. I just don’t like to link addtional library just to use a functon of two from it. But that’s just me. Others might like it.

The layered mode is what was originally proposed for this fixed-function emulation - a full OpenGL2.0 implementation layered on top of the new API.
How much you can mix (or if at all) between layered mode and LongsPeak is another matter.
It’s like the old situation with how much you mix Performer and OpenGL…Performer being analogous to layered mode - the high level makes assumptions that it’s in total control of the low level states.

The layered mode is what was originally proposed for this fixed-function emulation - a full OpenGL2.0 implementation layered on top of the new API.
But should beginner learn OpenGL 2.0 first and then move to Longs Peak or start his adventure with the new object/state model?
First option means long learning curve with unnecessary stage. Second option means long learning curve because shaders are required. Unless glu helps a bit.

Good point.

One could have a layered mode to implement OpenGL 2.1 on top of LP, just for convenience, so that people’s old programs still compile and run.

But for beginners, i would rather have a good utility library, that provides many helper-functions (immediate mode, default shaders, easy texture creation, extension loading(?), glTransform, glRotate, camera-matrix creation, default state-objects, …) and would thus allow to get into OpenGL fast and easy. Many of these functions might be useful for advanced users, too (i still use gluPerspective and gluBuild2DMipmaps as a fallback).

That’s was the idea behind glu 15 years ago and it was a really good one.

Jan.

I find it hard to think of this new API without thinking about the layered mode/utility library alongside it. If people know that there will be 2 distinct layers, one with a standardised bare minimum to communicate with the hardware, the other with a standardised bare minimum to get a prototype application up and running layered on top of the low-level API, then I’m sure we’ll hear more sensible suggestions.
For me, the IHV’s should decide what functionality needs exposing (they know their hardware best), and then work with the developer community to discuss how that functionality should be exposed (they’re the ones who’ll have to use the API).
At the moment it seems like people are trying to dictate high level functionality is put into the low level core where it does not belong.

There is an honorable mention of a new GLU like layer in the newsletter, but few clues as to what it might look like.

To be honest, I hadn’t really stopped to think of not being able to dive straight into drawing in the new model. Although it does sound as if there’s the possibility of having both 2.1 and LP drawables current at once (or something to that effect). This seems like the best of both worlds.

Cheers

Edit: correction.

Although it does sound as if there’s the possibility of having both 2.1 and LP contexts current at once (or something to that effect).
They will be separate contexts. They may both be bound to the same drawable (although only one context may be current at any time within a single thread). Thus you can render parts of the scene with legacy code and other parts with new code, and it should all mix and match - you just need to bind the appropriate context when switching between GL2 and LP.

Thanks, Michael. Drawable is what I meant :wink:

So to rephrase, we can bind a legacy context, render to a common drawable (shared with a LP context), then bind a LP context, then render again to the same shared drawable?

This seems like just the ticket. The only potential caveat that I can see is the cost of the context switch; but if it’s this or no compatibility at all, I’ll take this.

Cheers

Originally posted by Flavious:
How would uniform updates fit into this scenario? I suppose we’d need to update the uniforms for each program (vs or fs) independently, or together once used in a list? Of course currently we have our uniforms applied to these stages together as a group, so I’m a bit curious as to how this plays out in the proposal.
Your question is actually more complex than it first seems…

In OpenGL 2.x to update a uniform you bind the program object, and call glUniform.

With the advent of glUsePrograms there can be multiple bound at once, does the glUniform call affect all that are currently bound?

Or does glUniform take a program object handle for the specific one (vs, gs, fs) you want to modify? (which would require validation of the program object handle on each glUniform call, the very thing glUseProgram was designed to avoid)

Or is there a new glEditProgram to select which program the glUniform call affects?

With the advent of glUsePrograms there can be multiple bound at once, does the glUniform call affect all that are currently bound?
You’re not thinking in terms of the full Longs Peak experience.

Under LP, there is no “glUniform” call anymore. Well, not to a program. The equivalent call takes a buffer object that was created for the purpose of holding uniform data. So it might look like:

glUniformfv(bufferObject, "glLightDir", direction, 3);

This is just a guess, but it’s gathered from several pages worth of thread discussion.

The buffer object would be created from a program object. Thus BO would be compatible with the program object, and would contain only names that the program object used. Attempting to set program object uniforms that the program didn’t actually specify would produce an error.

A program can have multiple such buffer objects, with the layouts defined by the program (and probably named in some way?). Further, multiple programs with compatible buffer object layouts (all containing the same uniform definitions) can use the same buffer object. Creating such buffer objects may actually be an external process that does not require any particular program object, but that’s going on old data (from discussions months ago) and may not be consistent with the current Longs Peak version.

So, when you want to render with a program, you bind the program and bind to that program its associated uniform buffer objects. You bind to certain slots in those UBOs samplers and texture images as well.

Now, as for multiple programs for different stages, it works as it expects, except that the buffer objects do not cross-connect. If you want the uniform named “glLTPMatrix” to be available in both the vertex and fragment program, you have to bind separate (or possibly the same, but you need two binds) buffer objects that contain that uniform. That’s the price of having separate program objects.

If you used only one program object, then the stages would share uniform data were reasonable. IE, where the different stages refer to the same uniform name.

Better make that:

glUniformfv(programObject, ...);

One of the things Long Peaks gets rid of is the whole “bind to edit” thing :wink:

Actually I prefer Korval’s suggestion. One weeknes with GLSL IMHO is, that semantically same uniforms have to be set separately for each program. It would be so much nicer to have a unified uniform block feature…

True. Now that you mention it, setting a uniform is not really something that should belong to a program :stuck_out_tongue: . It’s not really editing the program, it’s just a state that’s associated with programs (currently, propably it should not be).

This makes me wonder, will there still be individually settable uniforms? If yes, what object will this state be associated with? The program object? An extra object? Globally?

Uniform blocks in buffer objects make a lot of sense for things like lighting parameters or matrices (that is, the global environment).

But how will we set “parameter” uniforms like material properties? What about sampler uniforms? I doubt we’ll be able to store texture object handles in buffer objects :wink:

But how will we set “parameter” uniforms like material properties?
A “material” property is just another uniform. I don’t understand what is special about this.

What about sampler uniforms?

I doubt we’ll be able to store texture object handles in buffer objects
Why not?

Or, more importantly, once you can store uniforms in buffer objects, why would you ever want to store them in the program objects themselves (or anywhere else)? Rare is the shader texture that is specific to the nature of shader itself (maybe a look-up table) as opposed to the particular use of the shader (which character it is, etc). And for those, you just have a UBO specifically for those uniforms.

I think Overmind is right, most state is totally unrelated to the specific program object being used.

The classic example being a model using multiple materials on different meshes in the model, some of them requiring different program objects, to update a uniform for rendering this particular instance of the model it must be set in all the program objects referenced by this model.

Can anyone think of a good example of state that is per program object, rather than per rendered model?

The concept of a uniform buffer certainly allows the same uniform set to be supplied to multiple program objects used on a single model, which should solve this previous weakness of program objects.

Can anyone think of a good example of state that is per program object, rather than per rendered model?
A lookup table.

Originally posted by Korval:
[quote]Can anyone think of a good example of state that is per program object, rather than per rendered model?
A lookup table.
[/QUOTE]A fine example indeed! :slight_smile:

Thanks, was having no luck thinking of such a thing :slight_smile:

This however means that ideally you want to have a bit of per-program state (lookup tables) AND per-model state (light source information, etc).

Why not?
Because the texture is an OpenGL object handle, and I doubt the GPU could interpret this without help by the driver.

glUniformo(bufferObject, “texture0”, samplerObject);
Are you sure that’s the way buffer objects are manipulated? I was under the impression buffer objects are just some arbitrary lump of memory. That’s what makes storing uniforms in buffer objects so interesting.

The call you posted looks more like a manipulation of some black-box object encapsulating the uniform state. This kind of object would of course make sense in addition to normal buffer objects :wink:

A “material” property is just another uniform. I don’t understand what is special about this.
The difference is the granularity at which I want to update it. I have three different granularities in my engine:

  • per program state (e.g. lookup tables)
  • per material state (textures, colors, …)
  • per object state (lights, matrices, …)

Are you sure that’s the way buffer objects are manipulated? I was under the impression buffer objects are just some arbitrary lump of memory. That’s what makes storing uniforms in buffer objects so interesting.
If you’re going to store uniforms in a buffer object, then this is how you have to do it. It gives the driver its required flexibility (specifically in not telling you how it’s laying out the uniforms), while allowing the user to quickly switch banks of uniforms without making a bunch of calls.

  • per program state (e.g. lookup tables)
  • per material state (textures, colors, …)
  • per object state (lights, matrices, …)
    Then use 3 separate buffer objects. Problem solved.