Skip to main content
GameDev.net gamedev.net
🔒 Locked

1 VBO - multiple textures?

Started by EvilNando Jun 3, 2011 at 10:58 PM 11 replies 8.6k views
Original Post
EvilNando
EvilNando
I would like to know how to bind different textures for rendering my objects which all of them are stored in a single VBO without merging my textures
V-man
V-man
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
EvilNando
EvilNando
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
MichaelNett
MichaelNett

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


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.

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?
EvilNando
EvilNando
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
V-man
V-man
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.
http://www.opengl.or...xture_Combiners

If you are using shaders, you would do this in your fragment shader

#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);
}


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

uniform sampler2DArray Texture;
uniform float Select;

varying vec2 TexCoord0;

void main()
{
gl_FragColor = texture2DArray(Texture, vec3(TexCoord0, Select));
}
MichaelNett
MichaelNett

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



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.

V-man
V-man

[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



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.
EvilNando
EvilNando


uniform sampler2DArray Texture;
uniform float Select;

varying vec2 TexCoord0;

void main()
{
gl_FragColor = texture2DArray(Texture, vec3(TexCoord0, Select));
}



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
Yann L
Yann L

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?

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.
EvilNando
EvilNando

[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?

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?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.