PDA

View Full Version : acessing texture units without naming them



Jochen
01-25-2006, 01:45 PM
Hi everyone,

I am trying to access the different texture units by index, rather than by naming them using glUniform1iARB. Is that possible yet ? That would be a great improvement of GLSL.

Cheers
Jochen

P.S. Here is a quote I found about the same problem:

quote:
--------------------------------------------------------------------------------
Originally posted by Plasma8:
Maybe a set of predefined sampler uniforms. Like gl_Texture0, gl_Texture1...

Its a bit annoying to have to send down a uniform when you know you just want whats in the second texture unit.

This way shaders are also more portable, the program dosen't need to know the name for the uniforms.
--------------------------------------------------------------------------------

V-man
01-25-2006, 04:24 PM
I am trying to access the different texture units by indexThat's not indexing. That's just naming.
Indexing is this

gl_Texture[x] where x is an integer.

I'm assuming you want x to be a uniform which should be ok for todays hw but compilers have to be adjusted.

If you want x to be a variable in the shader..... oh boy!


This way shaders are also more portableProtable between what?

Jochen
01-25-2006, 07:49 PM
Thx for your reply. Let me reword my question. I normally do the following:

> uniform sampler2D Texture;

and then get a value from the texture using

> vec4 colour = texture2D(Texture, gl_TexCoord[0].xy);

Everything works fine if I bind the name "Texture" using

> GLint lLocation = glGetUniformLocationARB(mProgram, "Texture");
> glUniform1iARB(lLocation, 0 or 1 or...);

What I really want to do is skip binding the sampler name to a texture. I am looking for an inbuild variable where I can just sample a texture unit by its index. i.e.

> uniform sampler2D Texture : TEXUNIT0;

as you can do in Cg. I have a large scene with different textures in different objects and I want to skip binding each to the name "Texture", but instead rely on them being bound to a particular texture unit.

On another note, I am also wondering if there is a way to print out values from a shader program, so that I can do some old-fashioned debugging. I don't really expect that to be possible but maybe someone knows a way.

Cheers
Jochen

def
01-26-2006, 04:07 AM
Originally posted by Jochen:

What I really want to do is skip binding the sampler name to a texture. I am looking for an inbuild variable where I can just sample a texture unit by its index. i.e.

> uniform sampler2D Texture : TEXUNIT0;
That is exactly what you are doing. You are just assigning the texture unit number to the sampler, and you only need to do that once when setting up the shader.


On another note, I am also wondering if there is a way to print out values from a shader program, so that I can do some old-fashioned debugging. I don't really expect that to be possible but maybe someone knows a way. I am afraid that will not be possible. Take a look at GLIntercept for debugging your shaders.

V-man
01-26-2006, 05:37 AM
What I really want to do is skip binding the sampler name to a texture. I am looking for an inbuild variable where I can just sample a texture unit by its index.In that case, this is basically what you need

texel = texture2D(0, texcoord.xy);

> uniform sampler2D Texture : TEXUNIT0;

It's a valid suggestion, but I think it's useless if you do things right.
Are you binding every time you render something?
Keep in mind that these are uniforms.

What I could use is global uniforms (for all shaders). This avoids having to update a uniform for each shader I have.


Take a look at GLIntercept for debugging your shaders.How does it help in debugging shaders?

I had saved this link
http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=11;t=000751

def
01-26-2006, 06:49 AM
Well, maybe one shouldn't call it debugging, but neither is printing from inside shaders.
Since you can change your shaders mit GLIntercept while your app is running, I think it is helpfull in "playing around" with different code.

Jochen
01-26-2006, 10:31 AM
>> It's a valid suggestion, but I think it's
>> useless if you do things right.
>> Are you binding every time you render something?
>> Keep in mind that these are uniforms.

Yes, I am binding every time I render, and I am trying to avoid that. I am building a graphics engine that is based on a scene tree architecture. You can basically use a tree view to organize shaders and objects hierarchically. I am relying on the structure of the tree to define the scope of shaders and textures. Everything below a shader node, for example, is being rendered using that shader. I think in my case it makes sense to define texture access according to the position in the tree, which ultimately corresponds to the texture unit. The texture coordinates can be accessed in an array, so why not the textures themselves ? Anyways, I think I have just come up with a solution.

What do you mean by "Keep in mind they are uniforms" ? Are those calls expensive ?

Cheers
Jochen

V-man
01-26-2006, 02:49 PM
My main point was that a uniform doesn't change unless you change it so why call glUniform needlessly?

What I do is group objects in sequence, so if 5 objects are using the same shader, they get rendered in sequence and this avoids call to glUseProgram. It comes down to what you are doing except I don't rebind tex units.
Also, I don't upload uniforms that stay constant.


The texture coordinates can be accessed in an array, so why not the textures themselvesYou can do this

uniform sampler2D MyTextures[5];

You aren't forced to use gl_TexCoord[] either. You can have your own varying.
You can have your own attributes as well with generic attributes.

Jochen
01-26-2006, 03:47 PM
Thx

uniform sampler2D MyTextures[5];

will do the trick. I didn't know you could bind arrays. Do you know the proper function call of the top of your head ?

I am also trying to group objects and textures under a single program. I am allowing users to define the structure themselves using a tree view. I will let this thread know once I am ready to demo the app. I have worked on it for
four years now. It includes Pyhton and Petri Nets
as well.

Cheers
Jochen

Zulfiqar Malik
01-27-2006, 02:03 AM
I agree that such a feature useless a lot of the times but can be really helpful if you want to rid urself of knowing the name of the uniform. Basically, something similar to setting register values where say t0 contains the texture bound to stage0, t1 to stage 1 and so on. It can help decouple shaders and the C++ application but that can be remedied using a good material system where most (if not every) detail lies within a material script which can be edited and compiled on the fly. Unfortunately such a system does not exist, even Direct3D and CG fx scripts are mostly ... useless.

V-man
01-27-2006, 01:12 PM
Originally posted by Jochen:
Do you know the proper function call of the top of your head ?
You probably know by now.
A uniform is a uniform, so the call is the same

glGetUniformLocation or glGetUniformLocationARB

and to upload, I think it would be
glUniform1fv(location, 5, your_array);

I don't quite remember it, but I think if you want to refresh element 1 and 2, you can do
glUniform1fv(location+1, 2, &your_array[1]);

sqrt[-1]
01-27-2006, 04:19 PM
Originally posted by V-man:
I don't quite remember it, but I think if you want to refresh element 1 and 2, you can do
glUniform1fv(location+1, 2, &your_array[1]);Ack, don't do this. It may work on current drivers buf if you want to work with the standards call:

GLint array1 = glGetUniformLocation("myarray[1]");
GLint array2 = glGetUniformLocation("myarray[2]");

Then use the offsets to set single values. The reason for this is there is nothing in the spec that states that a implementation has to use consecutive offsets for arrays.

However, doing

GLint arrayOffset = glGetUniformLocation("myarray");

Then uploading 5 values at once is valid.

David Spilling
02-01-2006, 03:21 AM
With regards to "printing out" values from shaders, I've found the following useful. It's done by Mike Weiblen, of 3Dlabs, and set in an OpenSceneGraph context, but the basic shader and idea are portable.

http://mew.cx/drawtext/drawtext.html

David