c++ glReadPixels()读取错误值

omvjsjqw  于 2023-03-10  发布在  其他
关注(0)|答案(2)|浏览(183)

现在,我正在尝试读回传送到OpenGL纹理的数据。2但是,我没有收到正确的结果。3我哪里出错了?

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const int SCR_WIDTH = 600;
const int SCR_HEIGHT = 600;
int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    int texSize = 2;
    const int Size = texSize*texSize*4;
    float *data = new float[Size];
    float *result = new float[Size];
    for(int i=0;i<Size;i++){
        data[i] = i + 1.0;
    }
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    glEnable(GL_TEXTURE_2D);
    GLuint fbo;
    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_FRAMEBUFFER,fbo);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    GLuint text;
    glGenTextures(1,&text);
    glBindTexture(GL_TEXTURE_2D,text);

    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D,
                    GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

    glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, texSize, texSize, 0,GL_RGBA,GL_FLOAT,data);
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,text, 0);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glReadPixels(0, 0, texSize, texSize,GL_RGBA,GL_FLOAT,result);
    std::cout<<"Data before roundtrip:\n";
    for (int i=0; i<texSize*texSize*4; i++)
        std::cout<<"\n"<<data[i];
    std::cout<<"\nData after roundtrip:\n";
    for (int i=0; i<texSize*texSize*4; i++)
        std::cout<<"\n"<<result[i];
    // clean up
    free(data);
    free(result);
    glDeleteFramebuffers (1,&fbo);
    glDeleteTextures (1,&text);
    glfwTerminate();
    return 0;

}

结果如下:

Data before roundtrip:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Data after roundtrip:

1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1

这不是我期望的结果。我期望数据和结果都是相同的
我已经在网上查过了,但仍然没有结果或解释。

f87krz0w

f87krz0w1#

glReadPixels没有读取错误的值,如果是这样的话我会很惊讶的。
您期望返回的值与传递给glTexImage2D的值相同,这是一种误解,因为GL会将客户端内存中的数据解包并根据指定的类型转换为内部格式(请参见:8.4.4像素矩形的传输)。
简而言之,如果你的数据类型是GL_FLOAT,那么你的数组中的值必须在[0.0f , 1.0f]范围内,否则所有小于或大于[0.0f , 1.0f]的值都会被钳位在这个范围内。因为你的值大于1.0f,钳位确实会发生,因此这些值会被解释为1.0f,这就是你从glReadPixels得到的值。
因此,您可以将每个分量除以255.0f,或者使用整数类型之一,例如GL_UNSIGNED_BYTE

3bygqnnd

3bygqnnd2#

帧缓冲区纹理的内部格式是GL_RGBA,这种格式只能存储范围[0.0,1.0]内的值。注意,glTexImage2D的第7和第8个参数(GL_RGBAGL_FLOAT)只指定源数据的格式,但不是数据存储的内部格式。您必须使用已调整大小的内部格式之一(请参见glTexImage2D)。例如GL_RGBA32F
glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, texSize, texSize, 0,GL_RGBA,GL_FLOAT,data);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, texSize, texSize, 0,GL_RGBA, GL_FLOAT, data);

相关问题