-1

I am trying to use a frame buffer for object picking and trying to use stbi_write_png to see what i'm rendering as this frame buffer is not going to be rendered to the screen. I want to use unsigned ints to determine the object id. This is the frame buffer definition, I do check if the frame buffer is valid.

glGenFramebuffers(1, &frameBufferObject);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);

glGenTextures(1, &frameBufferTexture);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, width, height, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexture, 0);

This is the render to the frame buffer and then save the image

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferObject);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderScene();
unsigned int* pixelData = new unsigned int[width * height * 3];
glReadPixels(0, 0, width, height, GL_RGB_INTEGER, GL_UNSIGNED_INT, pixelData);
unsigned char* pngData = new unsigned char[width * height * 3];
for (u64 i = 0; i < width * height; i++) {
    pngData[i * 3] = pixelData[i*3] & 0xff;
    pngData[i * 3 + 1] = pixelData[i * 3 + 1] & 0xff;
    pngData[i * 3 + 2] = pixelData[i * 3 + 2] & 0xff;
}
stbi_write_png(path, width, height, 3, data, 0)
delete[] pixelData;
delete[] pngData;

Render Scene is this

bindShader();
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projection);
glUniformMatrix4fv(viewLocation, 1, GL_FALSE, view);
glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_POINTS, 0, amountObjects);

Vertex Shader

#version 330 core
layout(location=0)in vec3 location;

uniform mat4 projection;
uniform mat4 view;

mat4 getTranslationModel(vec3 loc){
    mat4 toRet=mat4(1.f);//Init to identity matrix
    toRet[3]=vec4(loc,1.0);//Set the translation params
    return toRet;
}

void main(){
    mat4 model=getTranslationModel(location);
    gl_Position=projection*view*model*vec4(0,0,0,1);
}

Geometry Shader

#version 330 core
layout(points) in;
layout(triangle_strip, max_vertices=4) out;

const vec4 halfX=vec4(0.75,0,0,0);
const vec4 halfY=vec4(0,0.75,0,0);

void main(){
    vec4 loc=gl_in[0].gl_Position;
    //Top Left
    gl_Position=loc-halfX+halfY;
    EmitVertex();
    //Bottom Left
    gl_Position=loc-halfX-halfY;
    EmitVertex();
    //Top Right
    gl_Position=loc+halfX+halfY;
    EmitVertex();
    //Bottom Right
    gl_Position=loc+halfX-halfY;
    EmitVertex();
    EndPrimitive();
}

Fragment Shader

#version 330 core
layout(location=0)out uvec3 FragColour;

void main(){
    FragColour=uvec3(255,0,0);
}

When the image is created, it's just a black image. The goal is to see a red square as if I can see the red square, I can easily replace that number with an object id.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
BackSpace7777777
  • 159
  • 3
  • 13

1 Answers1

-1

I think you have a bad format parameter.

(Have you tried testing glGetError() after every line? Seems tedious, but it sometimes it's the only way to find problems.)

According to the online doco the format argument only specifies pixel layout, not pixel component size, so should be GL_RGB.

https://registry.khronos.org/OpenGL-Refpages/gl4/html/glReadPixels.xhtml

Hugh Fisher
  • 2,321
  • 13
  • 8