无法在OpenGL

时间:2017-11-03 04:51:59

标签: opengl textures

所以我在OpenGL中对纹理应用纹理时遇到了一些麻烦。我的解决方案看起来很高很低,但在很多小时的研究中都找不到解决方案。

我希望另一双眼睛能够捕捉到我的代码中的错误。

当我在着色器中设置颜色时,一切都很有效,但如果我尝试将纹理传递给它,我就会得到

  • 一个完全不可见的网格,如果加载的图像具有透明度或
  • 均匀着色的网格,似乎是我图像中实际颜色的混合(在没有透明度的图像的情况下)。

下面的代码绘制了一个简单的正方形,并且(应该)对其应用纹理。

Image Loader:

void Texture::loadTexture(const char* _filename)
{
    char fn[255] = "assets/textures/";
    strcat(fn, _filename);

    std::cout << fn << std::endl;

    FREE_IMAGE_FORMAT format = FreeImage_GetFileType(fn, 0);
    FIBITMAP* bitmap = FreeImage_Load(format, fn);
    FIBITMAP* bitmap32 = nullptr;

    unsigned int bitsPerPixel =  FreeImage_GetBPP(bitmap);
    std::cout << "Image BPP: " << bitsPerPixel << std::endl;

    int imageWidth  = FreeImage_GetWidth(bitmap);
    int imageHeight = FreeImage_GetHeight(bitmap);
    std::cout << "Image size: " << imageWidth << " x " << imageHeight << std::endl;

    if (bitsPerPixel != 32)
        bitmap32 = FreeImage_ConvertTo32Bits(bitmap);
    else
        bitmap32 = bitmap;

    BYTE* textureData = FreeImage_GetBits(bitmap32);

    //for(int i = 0; i < imageWidth * imageHeight * 4; i += 4) {
    //   std::cout << (int)textureData[i] << ", " << (int)textureData[i+1] << ", " << (int)textureData[i+2] << ", " << (int)textureData[i+3] << std::endl;
    //}

    glBindTexture(GL_TEXTURE_2D, m_ID);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)textureData);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    FreeImage_Unload(bitmap);

    if (bitsPerPixel != 32)
        FreeImage_Unload(bitmap32);

}

通过以可读格式输出图像数据,我确认图像文件已加载并且数据正确无误。结果如预期。

我的主循环:

int main()
{

const std::vector<sun::Vertex> vertices = {
        sun::Vertex(sun::Vector3f(-4.0f, 4.0f, 0.0f), sun::Vector2f(0.0f, 1.0f)),
        sun::Vertex(sun::Vector3f(4.0f, 4.0f, 0.0f), sun::Vector2f(1.0f, 1.0f)),
        sun::Vertex(sun::Vector3f(-4.0f, -4.0f, 0.0f), sun::Vector2f(0.0f, 0.0f)),
        sun::Vertex(sun::Vector3f(4.0f, -4.0f, 0.0f), sun::Vector2f(1.0f, 0.0f))
};

const std::vector<unsigned int> indices = {0, 1, 2, 1, 3, 2};

sun::Window window("My Game", 1280, 800);
sun::Shader shader("basic.vs", "basic.fs");
sun::Mesh mesh;
sun::Transform transform;
sun::Texture texture;

transform.setProjection(70.0f, window.getWidth(), window.getHeight(), 1.0f, -1000.0f);

mesh.addVertices(vertices, indices);
texture.loadTexture("test2.png");

shader.addUniform("transform");
shader.bind();

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

// Start the main loop
while (!window.closeWindow()) {

    // Render
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.3f, 0.8f, 1.0f, 1.0f);

    transform.setTranslation(0.0f, 0.0f, 10.0f);

    shader.setUniform("transform", transform.getProjectedTransformation());

    texture.bind(); // { glBindTexture(GL_TEXTURE_2D, m_ID); }
    glEnable(GL_TEXTURE_2D);

    mesh.draw(); // See below for details.

    glDisable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    window.update();

}

return 1;
}

mesh.draw()方法:

void Mesh::draw()
{
    //std::cout << m_Index << std::endl;
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)sizeof(Vector3f));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
    glDrawElements(GL_TRIANGLES, m_SizeIndices, GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);
}

最后,我的Vertex和Fragment着色器分别为:

#version 330 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;

uniform mat4 transform;

out vec2 coords;

void main()
{
    gl_Position = transform * vec4(position, 1.0f);
    coords = texCoord;
}

#version 330 core

in vec2 coord;

uniform sampler2D sampler;

void main()
{
    gl_FragColor = texture2D(sampler, coord.xy);//vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

作为补充信息,在初始化期间设置/启用以下OpenGL参数:

void Window::init()
{
    // Set viewport size
    glfwGetFramebufferSize(m_Window, &m_Width, &m_Height);
    glViewport(0, 0, m_Width, m_Height);

    // Set vsync
    glfwSwapInterval(0);

    // Set face culling and depth test.
    glFrontFace(GL_CW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    // Enable 2D textures
    glEnable(GL_TEXTURE_2D);

    // Enable gamma correction
    glEnable(GL_FRAMEBUFFER_SRGB);
}

非常感谢任何帮助。

谢谢!

1 个答案:

答案 0 :(得分:1)

Annnnd我发现了我的问题。这表明,长时间盯着自己的代码会让你错过最明显的事情。

问题出在我的着色器上。顶点着色器正在输出

vec2 coords

但片段着色器正在等待

vec2 coord

一旦我改变了变量名称以匹配,我就得到了我的纹理。