为每个物体绑定不同的纹理
Bind different textures for each object
我对 "loading" 或为场景中的不同对象绑定不同纹理感到有点困惑。
这是我设置纹理的方式(从硬盘加载纹理并绑定):
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
的 class。
我有 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);
现在我可以按预期加载我的纹理和 "switch"!
How is it possible to load every texture for theoretically infinite objects at the beginning and then just "switching" between them?
只需创建几个 纹理对象 ,并在需要时绑定它们。纹理单位与此无关。
// 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
是什么,但它看起来像 class 的某个成员变量。但是,您没有显示您的代码片段属于哪个 classes,因此很难猜测您到底在做什么。在我看来,您似乎只有一个 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
这当然需要一个使用两种纹理的着色器,如何组合它们(或将它们用于不同类型的数据)完全取决于您。
我对 "loading" 或为场景中的不同对象绑定不同纹理感到有点困惑。
这是我设置纹理的方式(从硬盘加载纹理并绑定):
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
的 class。
我有 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);
现在我可以按预期加载我的纹理和 "switch"!
How is it possible to load every texture for theoretically infinite objects at the beginning and then just "switching" between them?
只需创建几个 纹理对象 ,并在需要时绑定它们。纹理单位与此无关。
// 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
是什么,但它看起来像 class 的某个成员变量。但是,您没有显示您的代码片段属于哪个 classes,因此很难猜测您到底在做什么。在我看来,您似乎只有一个 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
这当然需要一个使用两种纹理的着色器,如何组合它们(或将它们用于不同类型的数据)完全取决于您。