Sign in to follow this  
EvilNando

1 VBO - multiple textures?

Recommended Posts

[quote]how to bind different textures[/quote]
First you select a texture unit
[font="Arial"]glActiveTexture(GL_TEXTURE0);[/font]
then bind a texture
glBindTexture

then select another texture unit
[font="Arial"]glActiveTexture(GL_TEXTURE1);

then bind a texture
[/font] glBindTexture


From http://opengl.org/wiki/Texture_Binding

Share this post


Link to post
Share on other sites
my problem is that how does my VBO knows which texture to use when I call glDrawArray do I need to store something like a texture id on the VBO as well? I have no idea honestly

Share this post


Link to post
Share on other sites
[quote name='EvilNando' timestamp='1307160761' post='4819308']
my problem is that how does my VBO knows which texture to use when I call glDrawArray do I need to store something like a texture id on the VBO as well? I have no idea honestly
[/quote]

Hi there,

if your VBO contains objects which require different textures, just bind them to different texture units (as shown in the first reply you got). After you did that, you have to setup multitexturing in such a way that the objects select the right textures. For example:

You bind "a.png" -> GL_TEXTURE0, "b.png" -> GL_TEXTURE1, etc. Now setup all (!) your models in the VBO to work with multitexturing. For each object you then setup which GL_TEXTURE to use accordingly. Objects in the VBO which use 'a.png' must only use GL_TEXTURE0 input for multitexturing and disregard whatever is bound to any other texture unit (using 'b.png' works the same way). Have a look at the OpenGL documentation for multitexturing on how to achieve that exactly.

If at all possible, you should probably merge your textures. If its only a few textures with (almost) the same size, its not really hard to do this. If you have a very large number of textures you will probably have to do it, as (depending on your hardware) you only have a limited number of texture units. There's praised code from John Ratcliff for automatically generating texture atlases (although for a batch of small textures that I tried, the program always crashed. I therefore rewrote the whole thing from scratch yesterday, so if your interested in code just write me a message).

- Michael.

[i]PS: I just thought about how you would have to change the way the multi texturing combines the textures when switching between objects in the VBO. Anyone knows what the impact of that is? I've only limited knowledge about how the graphics accelerator's hardware layout works, but wouldn't the impact be the same (or comparable) to a regular texture switch?[/i]

Share this post


Link to post
Share on other sites
o wow yeah I was thinking of just doing that

is it just me or the old opengl is way better for 2d stuff?


Ill try to arrange my textures and see if I can at least merge some stuff but it really is not ideal for my and my artist to keep track of things from a single texture :S

Share this post


Link to post
Share on other sites
If you want to select a texture, it depends if you are using the old GL or if you are using shaders. You didn't mention it so if you are using old GL, then you use Texture Combiners.
The one with GL_INTERPOLATE is what you want.
[url="http://www.opengl.org/wiki/Texture_Combiners"]http://www.opengl.or...xture_Combiners[/url]

If you are using shaders, you would do this in your fragment shader
[code]
#version 110
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform float Select; //Set to 0.0 or 1.0

varying vec2 TexCoord0;

void main()
{
vec4 texel0, texel1;

texel0 = texture2D(Texture0, TexCoord0);
texel1 = texture2D(Texture1, TexCoord0);
gl_FragColor = mix(texel0, texel1, Select);
}
[/code]

if you want to do more textures, then modify the code as you wish.

Share this post


Link to post
Share on other sites
[code]
uniform sampler2DArray Texture;
uniform float Select;

varying vec2 TexCoord0;

void main()
{
gl_FragColor = texture2DArray(Texture, vec3(TexCoord0, Select));
}
[/code]

Share this post


Link to post
Share on other sites
[quote name='EvilNando' timestamp='1307166555' post='4819323']
o wow yeah I was thinking of just doing that

is it just me or the old opengl is way better for 2d stuff?


Ill try to arrange my textures and see if I can at least merge some stuff but it really is not ideal for my and my artist to keep track of things from a single texture :S
[/quote]


Well it's not that you are forced to use a texture atlas. If you're interested in performance its already a good start to minimize things like texture switches by sorting the contents of your VBO. You can also issue draw calls which only render a certain subset of your VBO. I think it was something like glDrawElements, but better look into the documentation for that.

- Michael.

Share this post


Link to post
Share on other sites
[quote name='Michael N.' timestamp='1307272278' post='4819707']
[quote name='EvilNando' timestamp='1307166555' post='4819323']
o wow yeah I was thinking of just doing that

is it just me or the old opengl is way better for 2d stuff?


Ill try to arrange my textures and see if I can at least merge some stuff but it really is not ideal for my and my artist to keep track of things from a single texture :S
[/quote]


Well it's not that you are forced to use a texture atlas. If you're interested in performance its already a good start to minimize things like texture switches by sorting the contents of your VBO. You can also issue draw calls which only render a certain subset of your VBO. I think it was something like glDrawElements, but better look into the documentation for that.

- Michael.
[/quote]

You can use any render function to render a subset of a VBO. There are perhaps 15 render functions.

Share this post


Link to post
Share on other sites
[quote name='Yann L' timestamp='1307236729' post='4819605']
[code]
uniform sampler2DArray Texture;
uniform float Select;

varying vec2 TexCoord0;

void main()
{
gl_FragColor = texture2DArray(Texture, vec3(TexCoord0, Select));
}
[/code]
[/quote]

Im interested in knowing more on how to use this approach

should I add the corresponding "Select" value to my buffer object then? can you give any more guidance on how should I implement this at the code level?

thank you

Share this post


Link to post
Share on other sites
[quote name='EvilNando' timestamp='1307402246' post='4820293']
Im interested in knowing more on how to use this approach

should I add the corresponding "Select" value to my buffer object then? can you give any more guidance on how should I implement this at the code level?
[/quote]
It's actually not really that useful, at least not with the Select being a uniform. If you have to issue multiple draw calls (which you do, for setting the uniform), then you could just as well sort by texture and switch a standard sampler2D uniform. My snippet is much more useful if you have to switch textures per pixel or per-primitive. The Select variable would then be either calculated in the pixel shader or supplied as a varying through vertex attributes. The latter method allows the drawing of a mesh with many different textures using only a single draw call. It doesn't have to be faster though, since although you gain on draw call overhead, you can easily thrash the GPU texture caches, unless you presort the mesh faces per material.

Share this post


Link to post
Share on other sites
Hidden
Okay I think Im gonna sort my draw calls by texture and then just render subsets of the vbo

the only problem (I can think of) is that I will lose a way to arrange what goes in front or back of my scene

Any ideas on how to solve this?

Share this post


Link to post
[quote name='Yann L' timestamp='1307403265' post='4820300']
[quote name='EvilNando' timestamp='1307402246' post='4820293']
Im interested in knowing more on how to use this approach

should I add the corresponding "Select" value to my buffer object then? can you give any more guidance on how should I implement this at the code level?
[/quote]
It's actually not really that useful, at least not with the Select being a uniform. If you have to issue multiple draw calls (which you do, for setting the uniform), then you could just as well sort by texture and switch a standard sampler2D uniform. My snippet is much more useful if you have to switch textures per pixel or per-primitive. The Select variable would then be either calculated in the pixel shader or supplied as a varying through vertex attributes. The latter method allows the drawing of a mesh with many different textures using only a single draw call. It doesn't have to be faster though, since although you gain on draw call overhead, you can easily thrash the GPU texture caches, unless you presort the mesh faces per material.
[/quote]

can u provide an brief example on how to pass the select variable inside a vertex attribute array?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this