2017-10-29 105 views
0

我对我的场景中的“加载”或绑定单独对象的不同纹理有点困惑。为每个对象绑定不同的纹理

这是我设置纹理的方式(从加载的硬盘和结合纹理):

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

现在如预期,我可以载入我的纹理和它们之间的“开关”!

+0

什么样的问题是,你的记忆力不是无限的,所以当然会有一个限度。 –

+0

答案:这是不可能的。 textue单元的数量取决于硬件。 'GLint否; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&no)'。 – Rabbid76

+0

我能想象的唯一事情是['ARB_bindless_texture'](https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_bindless_texture.txt) - 请参阅[Bindless Texture](https://www.khronos .ORG/OpenGL的/维基/ Bindless_Texture)。但我认为这不是标准的一部分,也不是每个硬件都支持的。 – Rabbid76

回答

3

怎么可能在开始时加载理论上无限的物体的每个纹理,然后在它们之间进行“切换”?

通过只创建几个纹理对象,并绑定它们,当你想使用它们。纹理单位与此无关。

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

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

+0

我编辑我的文章 –

相关问题