-1

I'm using OpenGL shader and trying to print the color values.

So, I used glReadPixels function. It is working with GL_UNSIGNED_BYTE but not with GL_FLOAT.

Is there anything else should I do?

This is my code.

void settingFrameBuffers()
{
    glGenFramebuffers(NUM_FBO, fbo);
    glGenTextures(NUM_FBO, tex);

    for (int i = 0; i < NUM_FBO; i++)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
        glBindTexture(GL_TEXTURE_2D, tex[i]);

        if (i == 0) glActiveTexture(GL_TEXTURE0);
        else if (i == 1) glActiveTexture(GL_TEXTURE1);
        else if (i == 2) glActiveTexture(GL_TEXTURE2);
        else if (i == 3) glActiveTexture(GL_TEXTURE3);
        else if (i == 4) glActiveTexture(GL_TEXTURE4);
        else if (i == 5) glActiveTexture(GL_TEXTURE5);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[i], 0);

        GLuint dbo;
        glGenRenderbuffers(1, &dbo);
        glBindRenderbuffer(GL_RENDERBUFFER, dbo);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dbo);

        glDrawBuffer(GL_COLOR_ATTACHMENT0);
    }
}

void printWholeMassToConsole()
{
    GLfloat* data =new GLfloat[4 * width*height];

    glBindFramebuffer(GL_FRAMEBUFFER, fbo[otFb]);
    //glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, data);
    glReadnPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, sizeof(data), data);

    float sumR = 0;
    float sumG = 0;
    float sumB = 0;

    for (int i = 0; i < 4 * width*height; i += 4)
    {
        if (i > 0) break;
        sumR += data[i];
        sumG += data[i + 1];
        sumB += data[i + 2];
    }

    float sum = sumR + sumG + sumB;

    float possibleDiff = 3.0*width*height*0.5;
    //if (abs(wholeMass - sum) <= possibleDiff) cout << "O - ";
    //else cout << "X - ";
    printf("mass : %d\t %d\t %d\t %d\n", sum, sumR, sumG, sumB);

    free(data);
}

This is the first shader.

// vertex shader
#version 450

in vec4 position;
in vec2 texCoord;

out vec2 fragTexCoord;

void main()
{
    gl_Position = position;
    fragTexCoord = texCoord;
}

// fragment shader
#version 450

in vec2 fragTexCoord;

out vec4 FragColor;

void main()
{
    FragColor = vec4(0.5, 0.0, 0.0, 1.0);
}

This is the second shader.

// vertex shader
#version 450

in vec4 position;
in vec2 texCoord;

out vec2 fragTexCoord;

void main()
{
    gl_Position = position;
    fragTexCoord = texCoord;
}

// fragment shader
#version 450

in vec2 fragTexCoord;

uniform sampler2D tex;

out vec4 FragColor;

void main()
{
    FragColor = texture(tex, fragTexCoord);
}

It draws something on otFb framebuffer through the first shader and then otFb texture is mapped on the main framebuffer.

When I use glReadPixels with GL_FLOAT, the program is terminated by itself, when glReadnPixels with GL_FLOAT, the program print garbage values.

I used so many times to search, but I could not find the solutions.

Or is there any different way that I can try?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
hando
  • 1
  • 4
    Side note: When you allocate memory with new[], then you have to free it with delete[] instead of free(). – BDL May 25 '18 at 11:22
  • Thanks, I forgot that changing the allocating method alloc to new[]. – hando May 25 '18 at 11:30
  • 3
    `sizeof(data)` is not the size of the dynamically allocated memory. It is the size of `GLfloat*`. The size of the allocated memory in bytes would be `sizeof(GLfloat)*4*widht*height`. – Rabbid76 May 25 '18 at 11:45
  • 1
    Oh... There was a mistake. I used %d instead of %f for printf.... – hando May 27 '18 at 07:46

1 Answers1

-1

Try changing the first parameter of the framebuffer binding function call(the second line of code in your printWholeMassToConsole function) i.e.:

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[otFb]);

Hope it works.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Alex Dinu
  • 1
  • 1
  • 2
    That won't change anything. Calling [`glBindFramebuffer`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindFramebuffer.xhtml) with target set to `GL_FRAMEBUFFER` binds framebuffer to both the read and draw framebuffer targets – Rabbid76 May 26 '18 at 17:31