簡體   English   中英

OpenGL 紋理顯示為黑色

[英]OpenGL texture displaying as black

我第一次將 OpenGL 與 GLFW、GLEW 和 GLM 一起使用。 我或多或少地遵循了一個教程,但也轉移了注意力以專注於我目前感興趣的方面。

目前,我正在嘗試將像素繪制到紋理,然后將其作為全屏四邊形顯示在屏幕上。 但是,紋理始終顯示為黑色,我不確定哪里出錯了。

在這里初始化紋理(以及全屏四邊形):

int InitializeRenderTarget(GameManager* gameManager)
{
    // Vertex Array Object
    GLuint vertexArrayID;
    glGenVertexArrays(1, &vertexArrayID);
    glBindVertexArray(vertexArrayID);

    programID = LoadShaders("Source/Graphics/SimpleVertexShader.vert", "Source/Graphics/RenderTextureFragmentShader.frag");

    // The texture we're going to render to
    glGenTextures(1, &renderedTexture);
    glBindTexture(GL_TEXTURE_2D, renderedTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
        gameManager->GRID_SIZE, gameManager->GRID_SIZE,
        0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    glGenerateMipmap(GL_TEXTURE_2D);

    // The fullscreen quad's FBO
    static const GLfloat g_quad_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f, //0.0f, 0.0f,
         1.0f, -1.0f, 0.0f, //1.0f, 0.0f,
        -1.0f,  1.0f, 0.0f, //0.0f, 1.0f,
        -1.0f,  1.0f, 0.0f, //0.0f, 1.0f,
         1.0f, -1.0f, 0.0f, //1.0f, 0.0f,
         1.0f,  1.0f, 0.0f, //1.0f, 1.0f
    };

    glGenBuffers(1, &quad_vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);

    texID = glGetUniformLocation(programID, "renderedTexture");

    glEnable(GL_TEXTURE_2D);

    return 0;
}

在此處繪制紋理:

void RenderToTexture(GameManager* gameManager)
{
    glBindTexture(GL_TEXTURE_2D, renderedTexture);

    float* particleColors = gameManager->getParticleColors();
    glTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
        gameManager->GRID_SIZE, gameManager->GRID_SIZE,
        0, GL_RGB, GL_FLOAT, (GLvoid*)particleColors);
    glGenerateMipmap(GL_TEXTURE_2D);
    
    // Poor filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

在此處繪制到屏幕:

void RenderToScreen()
{
    // Render to the screen
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    // Render on the whole framebuffer, complete from the lower left corner to the upper right
    glViewport(100, 100, screenWidth-200, screenHeight-200);

    // Clear the screen
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Use our shader
    glUseProgram(programID);

    // Bind our texture in Texture Unit 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, renderedTexture);
    // Set our "renderedTexture" sampler to use Texture Unit 0
    glUniform1i(texID, 0);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,  // stride
        (void*)0            // array buffer offset
    );

    // Draw the triangles !
    glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles

    glDisableVertexAttribArray(0);

    // Swap buffers
    glfwSwapBuffers(window);
    glfwPollEvents();
}

主循環:

int main(void)
{
    if (InitializeWindow() != 0) {
        fprintf(stderr, "Failed to open GLFW window.\n");
        getchar();
        glfwTerminate();
        return -1;
    }
    
    GameManager* gameManager = gameManager->getInstance();

    if (InitializeRenderTarget(gameManager) != 0) {
        fprintf(stderr, "Failed to initialize render target.\n");
        getchar();
        glfwTerminate();
        return -1;
    }

    do {
        gameManager->Update();
        RenderToTexture(gameManager);
        RenderToScreen();
    } // Check if the ESC key was pressed or the window was closed
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);

    CleanUp();

    return 0;
}

頂點着色器:

#version 460 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

void main(){
    gl_Position =  vec4(vertexPosition_modelspace, 1);
    UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
}

最后是片段着色器:

#version 460 core

in vec2 UV;

out vec4 color;

uniform sampler2D renderedTexture;

void main(){
    color = texture(renderedTexture, UV);
    //color = vec4(UV.x, UV.y, 0, 1);
}

我相當確定我正在將四邊形正確地繪制到屏幕上,因為我在片段着色器中使用注釋掉的線來制作漂亮的彩色漸變效果。 但是,我可能沒有正確綁定紋理。

我確認particleColors數組確實包含正確的浮點值。 我嘗試將所有紅色設置為1.0f 1.0f並將所有值設置為255.0f (以防萬一)。

我嘗試添加如下行:

glEnable(GL_TEXTURE_2D);

glGenerateMipmap(GL_TEXTURE_2D);

// Poor filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

基於我看到的其他一些帖子,但我還沒有看到任何明顯的效果。

我還嘗試更改頂點和片段着色器計算和使用 UV 的方式,但這只會讓事情變得更糟,因為此時甚至不會出現漸變效果。

希望你能弄清楚我錯過了什么。 感謝您的任何幫助。

您使用的glTexSubImage2D完全錯誤。 第二個和第三個 arguments 是偏移量,第四個和第五個 arguments 是大小:

glTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gameManager->GRID_SIZE, gameManager->GRID_SIZE, 0, GL_RGB, GL_FLOAT, (GLvoid*)particleColors);

glTexSubImage2D(
    GL_TEXTURE_2D, 0, 
    0, 0, gameManager->GRID_SIZE, gameManager->GRID_SIZE,
    GL_RGB, GL_FLOAT, (GLvoid*)particleColors);

glEnable(GL_TEXTURE_2D); 僅在使用固定的 function 管道且沒有着色器程序時才有意義。

我想通了。 Rabbid76 的修正是重要的第一步。

之后我用我的像素陣列玩了一些,在把它變小后發現我的紋理底部確實有一條小像素線。 更多的探索,我發現我實際上填錯了我的像素數據。 在我的循環中修復我的邏輯錯誤,正確地填充了紋理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM