Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use different texture for specific triangles in VBO

I have 9 quads made of triangles, like this:

enter image description here

I'm using VBO to store data about them - their position and textures coordinates.

My question is - is it possible to make the quad 5 to have a different texture than the rest of quads by using only one VBO and shader? :

enter image description here

Green color represents texture 1 and yellow - texture 2.

So far I got:

GLfloat vertices[] = { 
    // Positions
    0.0f, 0.0f,
    ...

    // Texture coordinates
    0.0f, 0.0f, 
    ...
};

I'm creating VBO by using that vertices[] array, and then I'm binding my first texture m_texture1 (I also have access to the second one - m_texture2) and calling shader:

glBindTexture(GL_TEXTURE_2D, m_texture1);

glUseProgram(program);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vboId);          // for vertex coordinates
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);                                      // Vertices
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(GLfloat)*108));           // Texture
glDrawArrays(GL_TRIANGLES, 0, 108);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glUseProgram(0);

My vertex shader:

#version 330

layout (location = 0) in vec4 position;
layout (location = 1) in vec2 texcoord;

out vec2 Texcoord;

void main()
{
    gl_Position = position;
    Texcoord = texcoord;
}

And fragment shader:

#version 330

in vec2 Texcoord;

out vec4 outputColor;

uniform sampler2D tex;

void main()
{
    outputColor = texture(tex, Texcoord) * vec4(1.0,1.0,1.0,1.0);
}

So basically I'm using here only that one texture, because I have no idea how could I use the second one.

like image 438
Piotr Chojnacki Avatar asked Mar 02 '13 11:03

Piotr Chojnacki


1 Answers

You can do this using different texture image units and setting their values to uniform sampler2D tex.

You would have to call glActiveTexture and set texture image unit (GL_TEXTURE0), bind your green texture, then set active texture to GL_TEXTURE1 and bind your yellow texture. This way your green texture will have texture image unit id 0 and yellow 1.

You would have to split your drawing calls into two: one for green quads and other for yellow. You will have to set which texture to use by setting your uniform sampler2D tex using glUniform1i for each call. And finally call glDrawArrays for a subset of triangles in your VBO indicating green or yellow ones you are drawing in a current call.

Also you might consider using a texture atlas if all you need to draw is a picture in your example. In that case you would have a single texture mapped in a single call.

like image 149
Kimi Avatar answered Oct 13 '22 14:10

Kimi