Opengl 将非零uint转换为255的着色器

Opengl 将非零uint转换为255的着色器,opengl,Opengl,我试图通过单击实现多边形选择,首先将三角形ID绘制到屏幕外帧缓冲区,然后通过glReadPixels读取单击位置的像素值。我将ID作为无符号整数传递给每个顶点(我从apitrace确认缓冲区是正确的),并在片段着色器中将其作为uvec4输出。我将帧缓冲区设置为RGBA8UI纹理(也确认了apitrace中的单位是正确的)。没有opengl错误,还检查了帧缓冲区是否完整 问题在于,ID所在的输出图像的值始终为255。三角形覆盖的区域根据glClear值进行修改,但它们不是(id,0,0,0),而是

我试图通过单击实现多边形选择,首先将三角形ID绘制到屏幕外帧缓冲区,然后通过glReadPixels读取单击位置的像素值。我将ID作为无符号整数传递给每个顶点(我从apitrace确认缓冲区是正确的),并在片段着色器中将其作为uvec4输出。我将帧缓冲区设置为RGBA8UI纹理(也确认了apitrace中的单位是正确的)。没有opengl错误,还检查了帧缓冲区是否完整

问题在于,ID所在的输出图像的值始终为255。三角形覆盖的区域根据glClear值进行修改,但它们不是(id,0,0,0),而是始终是(255,0,0,0)。ID为0的除外。似乎在着色器中的某个位置,如果ID不是0,则ID将转换为255。这是下面代码的预期行为吗?我做错什么了吗

顶点缓冲区:

x (float), y (float), z (float), tx (float), ty (float), id (unsigned int)
顶点着色器:

#version 330 core

// Input
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in uint id;

// Output (Varying)
out vec2 v_texCoord;
flat out uint v_id;

// Uniform
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;

void main()
{
    v_texCoord = texCoord;
    v_id = id;
    gl_Position = u_projection * u_view * u_model * vec4(position, 1.0);
}
片段着色器:

#version 330 core

// Input (Varying)
in vec2 v_texCoord;
flat in uint v_id;

// Output
layout(location = 0) out uvec4 color;

void main()
{
    color = uvec4(v_id, 0, 0, 0);
}
GL_版本是3.3.0 NVIDIA 419.35,我昨天更新了驱动程序

--编辑--

我因缺乏信息而被否决,因此我创建了一个单独的项目,仅显示了我的上述观点以及以下代码的其余部分:

#include <glad/glad.h> // Must be included before GLFW header
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>

const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 800;

int main()
{
    // glfw: initialize and configure
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // glfw window creation
    GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // glad: load all OpenGL function pointers
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    std::cout << glGetString(GL_VERSION) << std::endl;


    // Vertex and fragment shaders
    GLuint shader = glCreateProgram();
    {
        GLint isSuccess = false;
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

        // Vertex shader
        {
            const GLchar* vertexShaderSource =
                "#version 330 core\n"
                "layout(location = 0) in vec2 position;\n"
                "layout(location = 1) in uint id;\n"
                "flat out uint v_id;\n"
                "void main() {v_id = id; gl_Position = vec4(position.x, position.y, 0.0, 1.0);}\n";
            glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
            glCompileShader(vertexShader);
            glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isSuccess);
            std::cout << "Vertex shader compile status: " << isSuccess << std::endl;
        }

        // Fragment shader
        {
            const GLchar* fragmentShaderSource =
                "#version 330 core\n"
                "layout(location = 0) out uvec4 color;\n"
                "flat in uint v_id;\n"
                "void main() {color = uvec4(v_id, 0, 0, 0);}\n";
            glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
            glCompileShader(fragmentShader);
            glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isSuccess);
            std::cout << "Fragment shader compile status: " << isSuccess << std::endl;
        }

        glAttachShader(shader, vertexShader);
        glAttachShader(shader, fragmentShader);
        glLinkProgram(shader);
        glGetProgramiv(shader, GL_LINK_STATUS, &isSuccess);
        std::cout << "Shader link status: " << isSuccess << std::endl;

        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    }

    // Vertex Buffer
    GLuint vertexBuffer;
    {
        glGenBuffers(1, &vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        GLfloat data[] = {
            //  x      y     id
            -1.0f,  0.0f,  0.0f,
            -1.0f, -1.0f,  0.0f,
             0.0f, -1.0f,  0.0f,
             0.0f,  1.0f,  0.0f,
             0.0f,  0.0f,  0.0f,
             1.0f,  0.0f,  0.0f
        };
        GLuint* data2 = ((GLuint *)data);
        data2[2] = 0;
        data2[5] = 0;
        data2[8] = 0;
        data2[11] = 1;
        data2[14] = 1;
        data2[17] = 1;
        std::cout << "Size of GLuint: " << sizeof(GLuint) << std::endl;
        std::cout << "Size of GLfloat: " << sizeof(GLfloat) << std::endl;
        std::cout << "Size of vertex buffer: " << sizeof(data) << std::endl;
        glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    // Vertex Array
    GLuint vertexArray;
    {
        glGenVertexArrays(1, &vertexArray);
        glBindVertexArray(vertexArray);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 1, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }

    // Texture for framebuffer
    GLuint texture;
    glGenTextures(1, &texture);
    {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);

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

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, nullptr);

        glBindTexture(GL_TEXTURE_2D, 0);
    }

    // Framebuffer
    GLuint framebuffer;
    {
        GLenum completenessStatus;
        glGenFramebuffers(1, &framebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        std::cout << "Framebuffer status: " << (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) << std::endl;
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    // Clear
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    GLenum error = glGetError();
    std::cout << "No error: " << (error == GL_NO_ERROR) << std::endl;

    // Draw
    while (!glfwWindowShouldClose(window))
    {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);

        glClear(GL_COLOR_BUFFER_BIT);

        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        {
            glDisable(GL_DITHER);
            glClear(GL_COLOR_BUFFER_BIT);

            glUseProgram(shader);
            glBindVertexArray(vertexArray);
            glActiveTexture(GL_TEXTURE0);

            glDrawArrays(GL_TRIANGLES, 0, 6);
            glEnable(GL_DITHER);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteProgram(shader);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteVertexArrays(1, &vertexArray);
    glDeleteFramebuffers(1, &framebuffer);
    glDeleteTextures(1, &texture);

    return 0;
}
帧缓冲区是RGBA8UI:

顶点是正确的:

ID为0的三角形按预期颜色为(0,0,0,0):

三角形外的区域为(255、255、255、255)如预期(glClearColor为白色):

ID为1的三角形的颜色为(255,0,0,0)。它应该是(1,0,0,0):

ID>1时也会出现同样的问题。为什么会这样?如何使其颜色为(ID,0,0,0),如片段着色器中所示?

在定义uint ID中的顶点属性
的通用顶点属性数据数组时,必须使用(聚焦于


当顶点属性数据由
glvertexattributepointer
定义时,它们将转换为浮点值

VertexAttribI*
命令指定有符号或无符号定点值 分别存储为有符号或无符号整数的。这些值称为纯整数

所有其他
VertexAttrib*
命令指定直接转换为内部浮点表示形式的值


如何为属性
id
指定通用顶点属性数据数组?我通过添加完整代码更新了问题<代码>glvertexattributepointer(1,1,GL_UNSIGNED_INT,GL_FALSE,3*sizeof(GLfloat),(void*)(2*sizeof(GLfloat))
是我指定ID属性的方式
GlvertexAttributePointer
->
GlvertexAttributeInter
(关注
I
)-谢谢,这已经修复了它。
3.3.0 NVIDIA 419.35
Vertex shader compile status: 1
Fragment shader compile status: 1
Shader link status: 1
Size of GLuint: 4
Size of GLfloat: 4
Size of vertex buffer: 72
Framebuffer status: 1
No error: 1