glTexImage2D 不起作用,但将 FragColor 设置为 vec4(1.0, 0, 0, 1.0) 会给我红色图像

Posted

技术标签:

【中文标题】glTexImage2D 不起作用,但将 FragColor 设置为 vec4(1.0, 0, 0, 1.0) 会给我红色图像【英文标题】:glTexImage2D won't work, but setting FragColor to vec4(1.0, 0, 0, 1.0) gives me red image 【发布时间】:2019-09-17 04:44:32 【问题描述】:

我正在尝试使用来自 OpenGL 的纹理单元将图像写入屏幕。如您所见,我在 tex Sampler2D 中写入了 0,因为我使用的是第 0 个纹理单元。我还将顶点和纹理作为矩形。我检查了 gl 错误,没有。我还将 FragColor 更改为vec4(1.0, 0, 0, 1.0);,我确实看到了红色图像,这意味着我的坐标是正确的。

这是我的代码:

    static unsigned char * d = new unsigned char[640*360*4];

    const GLfloat vertices_textures[20] = 
    //vertices            //positions
    -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
    1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
    1.0f, 1.0f, 0.0f, 1.0f, 0.0f;

    if (this->firstRun)
        
            int i;
            for (i = 0; i < 640*360*4; ++i)
            
                d[i] = 255;
            

            program = std::make_unique<Program>();
            Shader vertexShader(ShaderType::Vertex);
            vertexShader.load_from_string(vertexShaderSource);

            program->attach_shader(vertexShader);

            Shader fragmentShader(ShaderType::Fragment);
            fragmentShader.load_from_string(fragmentShaderSource);
            program->attach_shader(fragmentShader);

            program->link();

            vextexInLocation = glGetAttribLocation(program->get_id(), "aPos");

            textureInLocation = glGetAttribLocation(program->get_id(), "aTexCoord");

            glGenVertexArrays(1, &vertexArrayObject);

            glBindVertexArray(vertexArrayObject);

            glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_textures), vertices_textures, GL_STATIC_DRAW);

            glVertexAttribPointer(vextexInLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)0);
            glEnableVertexAttribArray(vextexInLocation);

            glVertexAttribPointer(textureInLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat)));
            glEnableVertexAttribArray(textureInLocation);


            glActiveTexture(GL_TEXTURE0);
            texLocation = glGetUniformLocation(program->get_id(), "tex");

            program->use();

            glGenTextures(1, &texture_id);

            glBindTexture(GL_TEXTURE_2D, texture_id);

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 640, 360, 0,  GL_RED, GL_UNSIGNED_BYTE, d);

            firstRun = false;
        

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glUniform1i(texLocation, 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture_id);
        glBindVertexArray(vertexArrayObject);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

这是我的着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

void main()

    gl_Position = vec4(aPos, 1.0);
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;
uniform sampler2D tex;

void main()

    FragColor = texture(tex, TexCoord);

【问题讨论】:

【参考方案1】:

您无法“看到”图像,因为纹理不是完整的 mipmap。

见OpenGL 4.6 API Compatibility Profile Specification; 8.17 Texture Completeness; page 306

如果使用纹理应用纹理所需的所有纹理图像和纹理参数都被一致定义,则称纹理是完整的

...除非满足以下任何条件,否则纹理是完整的:

缩小过滤器需要 mipmap(既不是 NEAREST 也不是 LINEAR),并且纹理不是完整的 mipmap。

GL_TEXTURE_MIN_FILTER 的初始值为GL_NEAREST_MIPMAP_LINEAR。如果您不更改它并且不创建 mipmap,则纹理不是“完整的”并且不会“显示”。见glTexParameter

将缩小过滤器设置为GL_NEARESTGL_LINEAR

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

或者通过glGenerateMipmap(GL_TEXTURE_2D)生成mipmap来解决问题。

【讨论】:

对不起,我没有正确解释。仅当我执行FragColor = vec4(1.0,0,0,1.0); 时,图像才会显示为红色。如果我按照上面的代码进行操作,图像是黑色的,我什么也看不到。我应该看到我的代码是红色的,或者你的代码是白色的,但我没有看到它们中的任何一个 @GuerlandoOCs glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) 解决问题 我试过了,没用。可以看到我做的代码的修改 @GuerlandoOCs 对不起,我的错,复制/粘贴问题。当然是GL_TEXTURE_MIN_FILTER 而不是GL_TEXTURE_MAG_FILTER

以上是关于glTexImage2D 不起作用,但将 FragColor 设置为 vec4(1.0, 0, 0, 1.0) 会给我红色图像的主要内容,如果未能解决你的问题,请参考以下文章

ng-selected 不起作用,但将选项修改为 selected="selected",使用 ng-repeat

对符号 glTexImage2D 的未定义引用

Android view.setid(View.generateViewId()) 不起作用。它找不到附加到的视图

颜色在开始示例opengl中不起作用

Microsoft TTS SaveToWaveFileAsync 功能不起作用

CORS 中间件在 nodeJS 中不起作用