繁体   English   中英

为每个对象绑定不同的纹理

[英]Bind different textures for each object

我对场景中的单独对象“加载”或绑定不同的纹理感到有些困惑。

这是设置纹理的方式(从硬盘驱动器加载纹理并进行绑定):

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

该函数属于一个称为Rectangle的类。

我有VAO,VBO和纹理对象的成员变量:

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

因此,每个Rectangle实例都有一个纹理对象m_Tex

每当我在用于绘制框架的主函数中绘制对象时,都使用这种方式:

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

问题:我的所有对象(假设我有3个Rectangle实例)都使用相同的纹理,尽管它们在绘制之前都绑定了自己的纹理对象。 这是为什么?

编辑:好的,我的错! 我忘了像这样在setTexture函数中生成纹理对象:

glGenTextures(1, &m_TEX);

现在,我可以加载纹理并按预期在它们之间“切换”!

如何在开始时为理论上无限的对象加载每个纹理,然后仅在它们之间“切换”?

通过仅创建几个纹理对象 ,并在要使用它们时进行绑定。 纹理单元与此无关。

// 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

目前尚不清楚代码中的m_TEX是什么,但它看起来像是类的某些成员变量。 但是,您不会显示您的代码片段属于哪些类,因此很难猜测您到底在做什么。 在我看来,您似乎只有一个m_TEX变量,这意味着您只能记住一个纹理对象名称,因此可以重复使用同一纹理。 即,您的加载器代码不会生成新的纹理对象,而只是重新使用m_TEX

纹理单元可用于多纹理 ,以便能够多于一个纹理在同一时间 (单个绘图调用期间意思)结合:

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

当然,这将需要使用两种纹理的着色器,如何组合它们(或将它们用于不同类型的数据)完全取决于您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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