Edge detection shader (Passing 3 vertex positions to the shader program)

31 Views Asked by At

I've been trying to render the effect of having triangle faces in one solid colour, and their edges another, ideally I wanted a soft glow of a different colour on the edges. I looked around for some shader source code and the ones I found all want all three vertex positions of the triangle in order to calculate where the edge is. I just can't seem to get it right, at best the entire triangle is either the solid colour or the highlight colour, and not being able to cout the values of the variables to see if the right data was passed to them makes things even harder. So, a bit of a two fold question, my main question: Can someone point me to a way of implementing a shader (or maybe some other technique) which will highlight the edges of triangles, or add a soft glow to the outline of the triangle? (My triangles are stored in a vectorglm::vec3 and use a int array to index which 3 vertices for each triangle). And as a side question, is there a way to pass the entire triangle into the shader (all 3 vertices), or at least pass each vertex along with the positions of the other two, and make that work somehow?

Here's my initBuffers and render functions:

void initBuffers() {
    // Generate buffers
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &IBO);
    glGenBuffers(1, &colorVBO);

    // Bind and upload vertex data
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

    // Bind and upload index data
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, cubeIndex.size() * sizeof(int), cubeIndex.data(), GL_STATIC_DRAW);

    // Bind and upload color data
    glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
    glBufferData(GL_ARRAY_BUFFER, colours.size() * sizeof(glm::vec3), colours.data(), GL_STATIC_DRAW);
    glUseProgram(shaderProgram);
    cubeWVPLocation = glGetUniformLocation(shaderProgram, "cubeWVP");


    // Create and bind buffer for the floor vertices
    glGenBuffers(1, &floorVBO);
    glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * floorVertices.size(), floorVertices.data(), GL_STATIC_DRAW);
    glUseProgram(outlineShaderProgram);

    floorWVPLocation = glGetUniformLocation(outlineShaderProgram, "floorWVP");

}


void render() {

    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);

    // Render the cubes with the existing shader
    glUniformMatrix4fv(cubeWVPLocation, 1, GL_FALSE, glm::value_ptr(projMatrix));


    // Enable vertex attributes
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // Bind VBO and set up vertex attribute pointers
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    // Bind colorVBO and set up color attribute pointers
    glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    // Bind IBO for index data
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);


    //glFrontFace(GL_CCW);

    // Draw the cube
    glDrawElements(GL_TRIANGLES, cubeIndex.size(), GL_UNSIGNED_INT, nullptr);

    // Disable vertex attributes
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    glUseProgram(outlineShaderProgram);

    glUniformMatrix4fv(floorWVPLocation, 1, GL_FALSE, glm::value_ptr(projMatrix));


    // Position attribute for the floor vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, floorVBO);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);

    // Draw the floor outlines using GL_LINES
    glDrawArrays(GL_LINES, 0, floorVertices.size());

    glDisableVertexAttribArray(0);


    glutPostRedisplay();
    glutSwapBuffers();
}

0

There are 0 best solutions below