在 OpenGL 中绑定多个纹理无法正常工作
binding multiple texture in OpenGL does not work correctly
我厌倦了绑定多个纹理
当我有 2 个或更多纹理时,我有一些奇怪的东西,它们相互叠加
使用 GPU 时出现此问题:NVIDIA GeForce RTX 3070 笔记本电脑 GPU/PCIe/SSE2
和 openGL 版本 4.6 是这样的:
但使用 GPU 时:AMD Radeon(TM) 图形非常好像这样
main.cpp
shaderProgram.bind();
const int NUMBER_OF_TEXTURE = textures.size();
auto sample = new int[NUMBER_OF_TEXTURE];
for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
sample[i] = i;
shaderProgram.setUniform1iv("u_Textuers", NUMBER_OF_TEXTURE, sample);
delete[] sample;
while (!glfwWindowShouldClose(window))
{
processInput(window);
Renderer::clear();
shaderProgram.bind();
for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
{
textures[i].Bind(i);
}
render.draw(shaderProgram);
GLCall(glBindTexture(GL_TEXTURE_2D, 0))
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwPollEvents();
}
Texture.cpp
Texture::Texture(const FxrDataStructures::Image& image)
:m_RendererID(0), m_LocalBuffer(nullptr),
m_Width(0), m_Height(0), m_BPP(0)
{
GLCall(glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID));
GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
// set the texture wrapping/filtering options (on the currently bound texture object)
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE))
m_Width = image.getWidth();
m_Height = image.getHeight();
m_BPP = image.getBitDepth();
cv::Mat mat = image.img;
cv::flip(mat, mat, 0);
m_LocalBuffer = mat.ptr();
if (m_LocalBuffer)
{
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer))
//GLCall(glGenerateMipmap(GL_TEXTURE_2D))
}
else
{
LOG_DEBUG("Failed to load texture ");
}
GLCall(glBindTexture(GL_TEXTURE_2D, 0))
}
void Texture::Bind(unsigned int slot) const
{
GLCall(glBindTextureUnit(slot, m_RendererID))
}
片段着色器
in float IndexMaterial;
uniform sampler2D u_Textuers[32];
void main()
{
float diff;
const int index = int(IndexMaterial);
FragColor = vec4(texture(u_Textuers[index], TexCoord));
}
我想说这与 int-to-float 转换有关。貌似NVIDIA GPU在插值IndexMaterial时加入了一点随机噪声,而AMD GPU则没有。
尝试对 IndexMaterial 使用平面着色。这将导致 GPU 使用来自一个顶点的值,而不是在顶点之间进行插值:
flat in float IndexMaterial;
参见:"flat" qualifier in glsl?
您也可以将 IndexMaterial 从 float 更改为 int,因为它没有充分的理由成为 float。
我厌倦了绑定多个纹理 当我有 2 个或更多纹理时,我有一些奇怪的东西,它们相互叠加
使用 GPU 时出现此问题:NVIDIA GeForce RTX 3070 笔记本电脑 GPU/PCIe/SSE2
和 openGL 版本 4.6 是这样的:
但使用 GPU 时:AMD Radeon(TM) 图形非常好像这样
main.cpp
shaderProgram.bind();
const int NUMBER_OF_TEXTURE = textures.size();
auto sample = new int[NUMBER_OF_TEXTURE];
for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
sample[i] = i;
shaderProgram.setUniform1iv("u_Textuers", NUMBER_OF_TEXTURE, sample);
delete[] sample;
while (!glfwWindowShouldClose(window))
{
processInput(window);
Renderer::clear();
shaderProgram.bind();
for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
{
textures[i].Bind(i);
}
render.draw(shaderProgram);
GLCall(glBindTexture(GL_TEXTURE_2D, 0))
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwPollEvents();
}
Texture.cpp
Texture::Texture(const FxrDataStructures::Image& image)
:m_RendererID(0), m_LocalBuffer(nullptr),
m_Width(0), m_Height(0), m_BPP(0)
{
GLCall(glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID));
GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));
// set the texture wrapping/filtering options (on the currently bound texture object)
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE))
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE))
m_Width = image.getWidth();
m_Height = image.getHeight();
m_BPP = image.getBitDepth();
cv::Mat mat = image.img;
cv::flip(mat, mat, 0);
m_LocalBuffer = mat.ptr();
if (m_LocalBuffer)
{
GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer))
//GLCall(glGenerateMipmap(GL_TEXTURE_2D))
}
else
{
LOG_DEBUG("Failed to load texture ");
}
GLCall(glBindTexture(GL_TEXTURE_2D, 0))
}
void Texture::Bind(unsigned int slot) const
{
GLCall(glBindTextureUnit(slot, m_RendererID))
}
片段着色器
in float IndexMaterial;
uniform sampler2D u_Textuers[32];
void main()
{
float diff;
const int index = int(IndexMaterial);
FragColor = vec4(texture(u_Textuers[index], TexCoord));
}
我想说这与 int-to-float 转换有关。貌似NVIDIA GPU在插值IndexMaterial时加入了一点随机噪声,而AMD GPU则没有。
尝试对 IndexMaterial 使用平面着色。这将导致 GPU 使用来自一个顶点的值,而不是在顶点之间进行插值:
flat in float IndexMaterial;
参见:"flat" qualifier in glsl?
您也可以将 IndexMaterial 从 float 更改为 int,因为它没有充分的理由成为 float。