0

currently, I am trying to read back the data I transfer to texture in OpenGL. However, I do not receive the correct result. Where do I wrong?

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


}

Here is the result:

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

This is not the result I expected. I expected both data and result are the same

I have looked it up on the internet but still no result or explanation for this.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Minh Le
  • 1
  • 1

2 Answers2

0

glReadPixels does not read the wrong values, i would be surprised if that would be the case.

You expect the returned values to be the same as those you passed to glTexImage2D and that is a misconception, because the data in your client memory gets unpacked by GL and converted to the internal format based on the specified type (see: 8.4.4 Transfer of Pixel Rectangles).

In short, if your data type is GL_FLOAT, then the values in your data array have to be in the range [0.0f , 1.0f], otherwise every value below and beyond gets clamped to this range. Since your values are above 1.0f, clamping does occur and therefore the values will be interpreted as 1.0f and that is the value you get from glReadPixels.

So, either you divide each component by 255.0f or use one of the integer types, e.g. GL_UNSIGNED_BYTE.

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
0

The internal format of the framebuffer texture is GL_RGBA, this format can only store values in range [0.0, 1.0]. Note, the 7th and 8th argument of glTexImage2D (GL_RGBA, GL_FLOAT) just specify the format of the source data, but not the internal format of the data store. You have to use one of the sized internal formats (see glTexImage2D). e.g. 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);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174