简体   繁体   中英

Bind different textures for each object

I am a bit confused about "loading" or binding different textures for seperate objects in my scene.

This is the way I set the texture (loading the texture from harddrive and binding):

setTexture ( const std::string& t_filename )
{
int width, height, nrChannels;

glBindTexture( GL_TEXTURE_2D, m_TEX );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

unsigned char* image = stbi_load( t_filename.c_str(), &width, &height, &nrChannels, 0 );

if ( image )
{
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image );
    glGenerateMipmap( GL_TEXTURE_2D );
}
else
{
    throw std::string( "Texture could not get loaded. Abort" );
}
stbi_image_free( image );

glBindTexture( GL_TEXTURE_2D, 0 );
}

The function belongs to a class called Rectangle .

I have member variables for the VAO, VBO and the texture object:

GLuint m_VAO{ 0 };
GLuint m_VBO{ 0 };
GLuint m_VEBO{ 0 };
GLuint m_TEX{ 0 };

So every instance of Rectangle has one texture object m_Tex .

Everytime I draw my object in the main function for drawing the frame I use this way:

glBindVertexArray( m_VAO );
glBindTexture( GL_TEXTURE_2D, m_TEX );
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr );
glBindVertexArray( 0 );

The problem: All of my objects (let's say I have 3 Rectangle instances) use the same texture although all of them bind there own texture object before drawing. Why is that?

Edit: Okay my fault! I forgot to generate the texture object in my setTexture function like that:

glGenTextures(1, &m_TEX);

Now I can load my textures and "switch" between them as expected!

How is it possible to load every texture for theoretically infinite objects at the beginning and then just "switching" between them?

By just creating several texture objects , and binding them when you want to use them. Texture units have nothing to do with that.

// at init time
GLuint texA, texB;

// create texture A
glGenTextures(1, &texA);
glBindTexture(GL_TEXTURE_2D, texA);
glTexParameter(...); glTexImage(...);

// create texture B
glGenTextures(1, &texB);
glBindTexture(GL_TEXTURE_2D, texB);
glTexParameter(...); glTexImage(...);


// at draw time
glBindTexture(GL_TEXTURE_2D, texA);
glDraw*(...); // draw with texture A
glDraw*(...); // still draw with texture A

glBindTexture(GL_TEXTURE_2D, texB);
glDraw*(...); // now draw with texture B

It is not clear what m_TEX in your code is, but it looks like some member variable of a class. However, you do not show which classes your code fragments belong to, so it is hard to guess what exactly you're doing. To me, it looks like you only have a single m_TEX variable, meaning you are able to remember only one texture object name, and hence re-use the same texture over and over again. Ie, your loader code does not generate a new texture object, but just re-uses m_TEX .

Texture units are for multitexturing , to be able to bind more than one texture at the same time (meaning during a single draw call):

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texA);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texB);
glDraw*(...)  // draw with both texA and texB

This will of course require a shader which makes use of both textures, and how to combine them (or use them for different kinds of data) is totally up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM