OpenGL - 纹理显示不正确(夹紧?)

Posted

技术标签:

【中文标题】OpenGL - 纹理显示不正确(夹紧?)【英文标题】:OpenGL - Texture not displaying properly (clamping?) 【发布时间】:2019-01-08 14:55:41 【问题描述】:

我刚开始学习 OpenGL 中的纹理并遇到了这个问题:

怀疑:函数 glEnableVertexAttribArray()glVertexAttribPointer() 有问题

对于 VertexBuffer 和 IndexBuffer 构造函数,它们分别接受大小、数据和索引、数据

// 不能发布图片,没有足够的声誉(sry)

纹理.cpp

Texture::Texture(const std::string & filepath)
    : m_RendererID(0), m_Filepath(filepath), m_ImageBuffer(nullptr), 
    m_Width(0), m_Height(0), m_BPP(0)

stbi_set_flip_vertically_on_load(true);
m_ImageBuffer = stbi_load(filepath.c_str(), &m_Width, &m_Height, &m_BPP, 4);

if (m_ImageBuffer == NULL)
    std::cout << "Unable to open file : " << m_Filepath << "!";

glGenTextures(1, &m_RendererID);
glBindTexture(GL_TEXTURE_2D, m_RendererID);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_ImageBuffer);
glBindTexture(GL_TEXTURE_2D, 0);

if (m_ImageBuffer)
    stbi_image_free(m_ImageBuffer);

main.cpp

float positions[] =

    // positions //texCoords
     0.5f,  0.5f, 0.0f, 0.0f,
    -0.5f,  0.5f, 1.0f, 0.0f,
    -0.5f, -0.5f, 0.0f, 1.0f,
     0.5f, -0.5f, 1.0f, 1.0f
;

unsigned int indices[] =

    0, 1, 2,
    2, 3, 0
;

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

VertexBuffer vb(4 * 4 * sizeof(float), positions);

IndexBuffer ib(6, indices);

Shader shader("res/shaders/basic.shader");
shader.Bind();
shader.SetUniform4f("u_Color", 0.0f, 0.0f, 1.0f, 1.0f);

Texture texture("res/textures/pepe.jpg");
texture.Bind();
shader.SetUniform1i("u_Texture", 0);

Renderer renderer;

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);

while (!glfwWindowShouldClose(window))

    renderer.Clear();

    renderer.Draw(ib, shader);

    glfwSwapBuffers(window);

    glfwPollEvents();

【问题讨论】:

【参考方案1】:

glVertexAttribPointer的最后一个参数是数组中第一个通用顶点属性的第一个分量的偏移量。纹理坐标的此参数设置不正确:

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (void*)(2*sizeof(float)));

见OpenGL 4.6 API Compatibility Profile Specification; 10.3.9 Vertex Arrays in Buffer Objects; page 409

...当数组来自顶点属性的缓冲区对象时,[...]为顶点缓冲区设置的偏移量[...]用作基本机器单位中的偏移量 该缓冲区数据存储中的第一个元素。


进一步混淆了纹理坐标。将其更改为:

float positions[] =

    // positions //texCoords
    0.5f,  0.5f, 1.0f, 0.0f,
   -0.5f,  0.5f, 0.0f, 0.0f,
   -0.5f, -0.5f, 0.0f, 1.0f,
    0.5f, -0.5f, 1.0f, 1.0f
;

【讨论】:

感谢您的回答。它现在看起来有点“好”了,但是纹理看起来好像是在两个三角形上镜像。 @XtraTerrestrialCoder 更改纹理坐标。请参阅答案的扩展。 像魅力一样工作。如果你不介意,你能告诉我我的坐标有什么问题吗?谢谢 @XtraTerrestrialCoder 交换了第一个和第二个顶点属性的 u 坐标。

以上是关于OpenGL - 纹理显示不正确(夹紧?)的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 2D纹理无法正确显示c ++

QT和OpenGL如何正确集成并显示纹理

纹理未正确显示 - 可能坐标是错误的 OpenGL、C++

编译c ++项目/ Open GL时出现纹理错误

OpenGL - 纹理加载不正确

在所有代码都正确的情况下,OpenGL加载不了纹理的原因之一(不易发现)