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

时间:2019-01-08 14:55:42

标签: c++ opengl textures

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

可疑:函数glEnableVertexAttribArray()glVertexAttribPointer()的问题

对于VertexBuffer和IndexBuffer构造函数,它们分别采用大小,数据和索引,数据

//不能张贴图片,没有足够的声誉(很抱歉)

Texture.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 个答案:

答案 0 :(得分:0)

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

  

...当数组从顶点属性的缓冲区对象中获取时,顶点缓冲区的偏移量设置被用作基本机器单位中的偏移量。 / strong>该缓冲区数据存储区中第一个元素。


进一步,纹理坐标混乱了。更改为:

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