2017-04-08 95 views
-1

我正在使用OpenGL 4.3,並試圖繪製一個我想應用此紋理的四元組(即「紋理/ dickbutt.png」)。紋理有654x654尺寸。當使用加載了freeimage的紋理時,OpenGL四分顯示爲黑色

dickbutt

但指令每一個可能的組合總是使我有一個黑色的質感,有時與右下角的一些文物。

black quad artefacts close-up

下面是其中抽籤發生的主要功能的代碼。

void Run() { 
    shader::factory::CompileShaderFile("shaders/test.vert", GL_VERTEX_SHADER); 
    shader::factory::CompileShaderFile("shaders/test.frag", GL_FRAGMENT_SHADER); 
    GLuint m_shaderProgram = shader::factory::CreateProgram(); 

    // Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = { 
    -0.5f, -0.5f, 0.0f, 
    0.5f, -0.5f, 0.0f, 
    0.5f, 0.5f, 0.0f, 
    -0.5f, 0.5f, 0.0f 
    }; 

GLfloat texcoords[] = { 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 1.0f 
    }; 

    GLuint VBO, VAO; 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 

    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    // Position attribute 
    glEnableVertexAttribArray(0); 
    glBindVertexBuffer(0, VBO, 0, 3*sizeof(GL_FLOAT)); 
    glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); 
    glVertexAttribBinding(0, 0); 

    GLuint texVBO; 
    glGenBuffers(1, &texVBO); 
    glBindBuffer(GL_ARRAY_BUFFER, texVBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(1); 
    glBindVertexBuffer(1, texVBO, 0, 2 * sizeof(GL_FLOAT)); 
    glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 0); 
    glVertexAttribBinding(1, 1); 

    glBindVertexArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 


    GLuint m_textureID = 
    texture::factory::Create2DTexture("textures/dickbutt.png"); 

    shader::module::RegisterUniform("mytexture", m_shaderProgram); 

    while (!graphic_context->PollWindowClosedEvent()) { 
    double dt = timer::chrono::GetTimeElapsedInSeconds(); 

    glActiveTexture(GL_TEXTURE0); 
    shader::module::Use(m_shaderProgram); 
    glUniform1i(shader::module::GetUniformLocation("mytexture", m_shaderProgram), 0); 
    glBindTexture(GL_TEXTURE_2D, m_textureID); 

    glBindVertexArray(VAO); 
    glDrawArrays(GL_QUADS, 0, 4); 
    glBindVertexArray(0); 

    // Next line renders the XYZ axes in separated shader program, commenting it out changes nothing in the texture display. 
    scene::Render(); 

    graphic_context->Update(); 
    timer::chrono::Update(); 
    } 
} 

這裏是紋理::工廠的代碼,其中圖像加載和OpenGL緩衝區創建和設置。

GLuint Create2DTexture(const std::string& a_sFileName) { 
    GLsizei wWidth, wHeight; 
    unsigned char *wImage = nullptr; 
    void *wBitMapHandle = nullptr; 

    if (!LoadImage(a_sFileName, wImage, wWidth, wHeight, wBitMapHandle)) { 
    std::cerr << "texture_factory::Create2DTexture -> Loading image failed. " << std::endl 
     << "Returning 0xFFFFFFFF..." << std::endl; 
    return 0xFFFFFFFF; 
    } 

    // Generate texture 
    GLuint wTexture; 
    glGenTextures(1, &wTexture); 
    // Create texture 
    glBindTexture(GL_TEXTURE_2D, wTexture); 

    glTexImage2D(
    GL_TEXTURE_2D, // 2D texture target 
    0,    // Base mipmap level 
    GL_RGBA,   // RGBA color components 
    wWidth, wHeight, // Dimensions 
    0,    // Must be 0... 
    GL_RGBA,   // Pixel data format 
    GL_UNSIGNED_BYTE, // Depends on what the LoadImage function return type 
    wImage);   // Loaded image 

    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_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   

    // Commenting-out the next line make the artefacts appear on the quad 
    // glGenerateMipmap(GL_TEXTURE_2D); 

    // Free image 
    FreeImage(wBitMapHandle); 
    //glBindTexture(GL_TEXTURE_2D, 0); 

    return wTexture; 
} 

的的LoadImage函數

bool LoadImage(const std::string& a_sFileName, 
    unsigned char *a_pImage, 
    GLsizei& a_rWidth, 
    GLsizei& a_rHeight, 
    void *a_pBitmapHandle) { 
    const char *wFilename = a_sFileName.c_str(); 
    //image format 
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; 
    //pointer to the image, once loaded 
    FIBITMAP *dib(0); 
    //pointer to the image data 
    BYTE* bits(0); 
    //image width and height 
    unsigned int width(0), height(0); 

    //check the file signature and deduce its format 
    fif = FreeImage_GetFileType(wFilename, 0); 
    //if still unknown, try to guess the file format from the file extension 
    if (fif == FIF_UNKNOWN) 
    fif = FreeImage_GetFIFFromFilename(wFilename); 
    //if still unkown, return failure 
    if (fif == FIF_UNKNOWN) 
    return false; 

    //check that the plugin has reading capabilities and load the file 
    if (FreeImage_FIFSupportsReading(fif)) 
    dib = FreeImage_Load(fif, wFilename); 
    //if the image failed to load, return failure 
    if (!dib) 
    return false; 

    //retrieve the image data 
    bits = FreeImage_GetBits(dib); 
    //get the image width and height 
    width = FreeImage_GetWidth(dib); 
    height = FreeImage_GetHeight(dib); 
    //if somehow one of these failed (they shouldn't), return failure 
    if ((bits == 0) || (width == 0) || (height == 0)) 
    return false; 

    a_pImage = bits; 
    a_rWidth = width; 
    a_rHeight = height; 
    a_pBitmapHandle = dib; 

    return true; 
} 

和相關頂點/斷枝着色器代碼分別

// test.vert 
#version 430 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec2 texcoord; 

layout (std140, binding = 0) uniform CameraInfo { 
    mat4 ProjectionView; 
    vec3 eye; 
}; 

out vec2 tex_coord; 

void main() 
{ 
    vec4 vertex = vec4(position,1.0); 
    gl_Position = ProjectionView*vertex; 
    tex_coord = vec2(texcoord.x, 1.0 - texcoord.y); 
} 

//test.frag 
#version 430 

out vec4 color; 

in vec2 tex_coord; 

// Texture samplers 
uniform sampler2D mytexture; 

void main() 
{ 
    //color = vec4(1.0f,0.0f,0.0f,1.0f); // Prints red quad 
    color = texture2D(mytexture, tex_coord); 
} 

我比較了教程,代碼數十次,對SO和工作實例其他職位,但我找不到我做錯了什麼。

回答

2

您已經通過a_rWidtha_rHeight作爲參考。您必須同樣爲a_pImagea_pBitmapHandle這樣做。

這一切都歸結爲,爲什麼是這樣的:

int a = 1; 
test(a); 
printf("%d\n", a); 

打印1,而不是2鑑於test()這樣定義:

void test(int a) { 
    a = 2; 
} 

因此您需要更改​​這樣的:

bool LoadImage(
    const std::string &a_sFileName, 
    unsigned char **a_pImage, 
    GLsizei &a_rWidth, 
    GLsizei &a_rHeight, 
    void **a_pBitmapHandle) { 

    [...] 

    *a_pImage = bits; 
    a_rWidth = width; 
    a_rHeight = height; 
    *a_pBitmapHandle = dib; 

並調用它像這樣:

LoadImage(a_sFileName, &wImage, wWidth, wHeight, &wBitMapHandle) 

另外注意的FreeImage圖像解碼成BGR/BGRA格式。所以你必須使用GL_BGRA而不是GL_RGBA

+0

天啊,你完全正確!注意:糾正後,我有一個訪問衝突異常,由glTexImage2D引起,我必須使用FreeImage_ConvertTo32Bits來修復,並使用正確的參數(如GL_BGRA)。你讓我的一週感謝你! – lordjohncena

+2

正在考慮是否需要'FreeImage_ConvertTo32Bits'。道具給你找出答案。無論如何,不​​客氣! :) – Vallentin