Tuesday, September 19, 2017

How to Process Mouse Events in a 3D Scene, Part 2

2. Modify the vertex and fragment shaders

The shaders must be modified to write the object ID to the new color buffer.  Given an existing vertex shader, it must be modified with the lines:

flat out unsigned int ObjectID;
uniform unsigned int inObjectID;
void main()
{

    ObjectID = inObjectID;
    // etc.
}


This declares a new uniform providing the object id to the vertex shader from the program, and passing it on to the fragment shader.  Similarly, the fragment shader must be modified like this:

flat in unsigned int ObjectID;
out unsigned int outObjectID;
void main()
{
    outObjectID = ObjectID;
    // etc.

}

Similarly, the first two lines here declare an input variable from the vertex shader, and an output variable that is bound to a framebuffer attachment.

The flat modifier simply means that the value is not interpolated across vertices, and is required to use an integer type in this way.

Before linking the shader program, you must bind the outObjectID out variable of the fragment shader to the proper framebuffer attachment.  The second argument to the following function specifies which color attachment to bind the out variable to.  Here, we want to bind to GL_COLOR_ATTACHMENT1.

glBindFragDataLocation(shaderProgram, 1, "outObjectID");

Additionally, when drawing the scene, before drawing each object you must send its unique ID to the graphics card, updating the uniform.

GLuint objectIDUniform = glGetUniformLocation(shaderProgram, "inObjectID");
 
glUniform1ui(objectIDUniform, object.id);

The first line gets a handle to the shader uniform, and the second line sets its value to the object's unique ID.  A good time to update the objectID uniform might be right before or after you update the model matrix with the object's position in world space.

Intro
Part 1
Part 3

No comments:

Post a Comment