简体   繁体   English

OpenGL 纹理显示为黑色

[英]OpenGL texture displaying as black

I am using OpenGL for the first time with GLFW, GLEW, and GLM.我第一次将 OpenGL 与 GLFW、GLEW 和 GLM 一起使用。 I've been more or less following a tutorial but also diverted in order to focus on the aspects I'm interested in at the moment.我或多或少地遵循了一个教程,但也转移了注意力以专注于我目前感兴趣的方面。

Currently, I'm trying to draw pixels to a texture and then display that on the screen as a fullscreen quad.目前,我正在尝试将像素绘制到纹理,然后将其作为全屏四边形显示在屏幕上。 However, the texture is always displaying as black and I'm unsure where I went wrong.但是,纹理始终显示为黑色,我不确定哪里出错了。

Initializing the texture here (as well as the fullscreen quad):在这里初始化纹理(以及全屏四边形):

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

Drawing onto the texture here:在此处绘制纹理:

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

Drawing to screen here:在此处绘制到屏幕:

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

The main loop:主循环:

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

Vertex shader:顶点着色器:

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

and finally fragment shader:最后是片段着色器:

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

I'm fairly certain that I am drawing the quad to the screen correctly as I used the commented out line in the fragment shader to make a nice colorful gradient effect.我相当确定我正在将四边形正确地绘制到屏幕上,因为我在片段着色器中使用注释掉的线来制作漂亮的彩色渐变效果。 However, I might not be binding the texture correctly.但是,我可能没有正确绑定纹理。

I confirmed that the particleColors array does contain float values correctly.我确认particleColors数组确实包含正确的浮点值。 I've tried setting all the reds to 1.0f , and all the values to 1.0f , as well as all values to 255.0f (just in case).我尝试将所有红色设置为1.0f 1.0f并将所有值设置为255.0f (以防万一)。

I tried adding lines like:我尝试添加如下行:

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

based on some other posts I saw but I have yet to see any visible effect.基于我看到的其他一些帖子,但我还没有看到任何明显的效果。

I also tried changing how the vertex and fragment shader were calculating and using the UVs but that only made things worse as the gradient effect wouldn't even appear at that point.我还尝试更改顶点和片段着色器计算和使用 UV 的方式,但这只会让事情变得更糟,因为此时甚至不会出现渐变效果。

Hopefully you can figure out what I've missed.希望你能弄清楚我错过了什么。 Thank you for any help.感谢您的任何帮助。

You're using glTexSubImage2D completely wrong.您使用的glTexSubImage2D完全错误。 The 2nd and 3rd arguments are the offsets and the 4th and 5th arguments are the size:第二个和第三个 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); only has meaning when using the fixed function pipeline and no shader program.仅在使用固定的 function 管道且没有着色器程序时才有意义。

I have figured it out.我想通了。 The correction by Rabbid76, was a big first step. Rabbid76 的修正是重要的第一步。

Afterwards I played some with my pixel array, and after making it smaller found that I did have a small line of pixels at the bottom of my texture.之后我用我的像素阵列玩了一些,在把它变小后发现我的纹理底部确实有一条小像素线。 More poking around and I found I had actually filled my pixel data wrong.更多的探索,我发现我实际上填错了我的像素数据。 Fixing my logic in error in my loop filled the texture properly.在我的循环中修复我的逻辑错误,正确地填充了纹理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM