Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7778243
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T18:20:58+00:00 2026-06-01T18:20:58+00:00

I am trying to implement object picking by packing the vao id to RGBA

  • 0

I am trying to implement object picking by packing the vao id to RGBA and render with it to an off-screen buffer which I then try to read with a buffer object.

I am rendering to an off-screen buffer by creating a texture and a z-buffer RenderBuffer Object then attaching them to a FrameBuffer object as such:

/* create a framebuffer object */ 
glGenFramebuffers(1, &fbo);     
/* attach the texture and the render buffer to the frame buffer */ 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 

/* generate a texture id */ 
glGenTextures(1, &tex); 
/* bind the texture */ 
glBindTexture(GL_TEXTURE_2D, tex); 
/* create the texture in the GPU */ 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WINDOW_SIZE_X, WINDOW_SIZE_Y 
    , 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 

/* set texture parameters */ 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

/* unbind the texture */ 
glBindTexture(GL_TEXTURE_2D, 0); 

/* create a renderbuffer object for the depth buffer */ 
glGenRenderbuffers(1, &rbo); 
/* bind the texture */ 
glBindRenderbuffer(GL_RENDERBUFFER, rbo); 
/* create the render buffer in the GPU */ 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT 
    , WINDOW_SIZE_X, WINDOW_SIZE_Y); 

/* unbind the render buffer */ 
glBindRenderbuffer(GL_RENDERBUFFER, 0);


/* attach the texture and the render buffer to the frame buffer */ 
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT 
    , GL_RENDERBUFFER, rbo); 

// check the frame buffer 
if (glCheckFramebufferStatus( 
    GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::cout << "Framebuffer status not complete" << '\n';
}
/* handle an error : frame buffer incomplete */ 
/* return to the default frame buffer */ 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

I also generate a pixel buffer object to read from the FrameBuffer after rendering is complete:

    /* generate the pixel buffer object */ 
glGenBuffers(1,&pbo);     
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); 
glBufferData(GL_PIXEL_PACK_BUFFER, WINDOW_SIZE_X * WINDOW_SIZE_Y * 4, nullptr, GL_STREAM_READ); 
/* to avoid weird behaviour the first frame the data is loaded */ 
glReadPixels(0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y, GL_BGRA, GL_UNSIGNED_BYTE, 0);     

Then in my render loop i bind it and render to that off-screen FrameBuffer:

    GLubyte red, green, blue, alpha; 

/* bind the frame buffer */ 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 

/* clear the frame buffer */ 
glClearColor(0,0,0,0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

/* select the shader program */ 
glUseProgram(pickProgram); 
/* set the object color */ 

/*alpha = house.vaoId & 0xFF; 
blue = (house.vaoId >> 8) & 0xFF; 
green = (house.vaoId >> 16) & 0xFF; 
red = (house.vaoId >> 24) & 0xFF; */

GLuint objectId = 5;
alpha = objectId & 0xFF; 
blue  = (objectId >> 8) & 0xFF; 
green = (objectId >> 16) & 0xFF; 
red   = (objectId >> 24) & 0xFF; 

//Upload the packed RGBA values to the shader   
glUniform4f(baseColorUniformLocation, red, green ,blue, alpha);     

    //prepare to draw the object
pvm = projectionMatrix*viewMatrix*house.modelMatrix;
glUniformMatrix4fv(offScreenMatrixUniformLocation, 1, GL_FALSE, glm::value_ptr(pvm));

/* draw the object*/ 
glBindVertexArray(house.getVaoId());
glDrawRangeElements(GL_TRIANGLES,0,42,42,GL_UNSIGNED_SHORT,NULL);
glBindVertexArray(0);

//check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer Error" << '\n';
}

GLuint temp;
    //get the object id from the read pixels
temp = get_object_id(); <--- this function is explained later


/* return to the default frame buffer */
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

The fragment shader that renders to the offscreen buffer is very simple:

#version 420
uniform vec4 BaseColor; 
layout(location=0) out vec4 fragColor;

void main() 
{ 
 fragColor = BaseColor; 
} 

This is the function called during the off-screen rendering to extract the packaged RGBA from the framebuffer:

GLuint Engine::get_object_id() 
{ 
static int frame_event = 0; 
GLuint object_id; 
int x, y; 
GLuint red, green, blue, alpha, pixel_index; 
//GLuint read_pbo, map_pbo;
GLubyte* ptr; 

/* read one pixel buffer */ 
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_a); 
/* map the other pixel buffer */  
    ///////////////////// NOTE :5th argument, BGRA or RGBA, doesn't make a difference right?
glReadPixels(0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y, GL_BGRA, GL_UNSIGNED_BYTE, 0);
ptr = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE); 
/* get the mouse coordinates */ 
/* OpenGL has the {0,0} at the down-left corner of the screen */ 
glfwGetMousePos(&x, &y); 
y = WINDOW_SIZE_Y - y; 
object_id = -1; 
if (x >= 0 && x < WINDOW_SIZE_X && y >= 0 && y < WINDOW_SIZE_Y){ 
//////////////////////////////////////////
    //I have to admit I don't understand what he does here
///////////////////////////////////////////
    pixel_index = (x + y * WINDOW_SIZE_X) * 4; 
    blue = ptr[pixel_index]; 
    green = ptr[pixel_index + 1]; 
    red = ptr[pixel_index + 2]; 
    alpha = ptr[pixel_index + 3]; 

object_id = alpha +(red << 24) + (green << 16) + (blue << 8);
} 
glUnmapBuffer(GL_PIXEL_PACK_BUFFER); 
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 
return object_id; 
} 

The problem is that this final bit of code that is supposed to read the pixels from the off-screen Framebuffer and give me the vao_id, has the following weird behavior:

If ANY of the 4 bytes packed into the RGBA (sent via the shader) is anything other than 0 that byte comes out as 0xFF at the other end.

So if I send

00000000 00000000 00000000 00000001 

I will get

00000000 00000000 00000000 11111111 

Or if I send

00000000 00010000 00000000 00000000 

I will get

00000000 11111111 00000000 00000000 

…when I read the pixels with get_object_id().

If I bind the texture and render it to a quad on my normal FrameBuffer the colors that I pass to the off-screen rendering come out correct on the quad. But the pixels read by the get_object_id() make every byte sent in rounded up to 255 (0xFF). So my guess is there’s a problem with that final function.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T18:20:59+00:00Added an answer on June 1, 2026 at 6:20 pm

    The fragment shader outputs values in a [0, 1] range which are remapped to [0, 255] when written to the frame buffer. glUniform4f accepts floating point values and you need to send your id’s as [0, 1] values instead of [0, 255] values:

    glUniform4f(baseColorUniformLocation, red / 255.0f, green / 255.0f...);   
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to implement a search method, which returns a index of a object
I am trying to implement a JSON-RPC solution, using a server connector object which
I am trying to implement an ajax view to create an object and then
I am trying to implement the Visitor Pattern for an object structure which has
I am wrestling with trying to implement a simple object-oriented like system in Tcl
I've been trying to implement a simple component-based game object architecture using Objective-C, much
I'm trying to implement a comet style, long polling connection using an XMLHttpResponse object.
I'm trying to implement a singleton class, that holds a com object inside it.
I have an object with a readonly property that I am trying to implement
Trying to implement simple error handling without adding buku try / except statements to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.