Adding barycentric coordinates to an vboMesh


#1

Hello, I have read this http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/ and I want to implement that technique.

This is my ofApp.cpp code:

#include "ofApp.h"
#include "MeshHelper.hpp"

//--------------------------------------------------------------
void ofApp::setup(){
    shader.load("shaders_gl3/passthruogh.vert", "shaders_gl3/textureWithLambert.frag", "");
    MeshHelper::addBarycentricCoordinates(cube.mesh, shader);

}

//--------------------------------------------------------------
void ofApp::draw(){
    cam.begin();
    shader.begin();
    cube.draw();
    shader.end();
    cam.end();
}

This is my MeshHelper:

#pragma once
#include "ofMain.h"

class MeshHelper{
public:

    static void addBarycentricCoordinates(ofVboMesh &mesh, ofShader &shader){
        int nVertices = mesh.getVertices().size();
        int nTriangles = nVertices / 3; // number of triangles
        int n = nVertices*3;
        int nFloats = 9;
        float barycentric[n]; // each vertex has 3 floats

        // for each triangle in the geometry, add the barycentric coordinates
        for (int i = 0; i < nTriangles; i++) {
            barycentric[i*nFloats] = 1.f;
            barycentric[i*nFloats+1] = 0.f;
            barycentric[i*nFloats+2] = 0.f;
            barycentric[i*nFloats+3] = 0.f;
            barycentric[i*nFloats+4] = 1.f;
            barycentric[i*nFloats+5] = 0.f;
            barycentric[i*nFloats+6] = 0.f;
            barycentric[i*nFloats+7] = 0.f;
            barycentric[i*nFloats+8] = 1.;
        }

        int baryLoc = shader.getAttributeLocation("barycentric");
        mesh.getVbo().setAttributeData(baryLoc, &barycentric[0], 1, nVertices*3, GL_STATIC_DRAW);
    };
};

The strange thing is that if I log the mesh.getVbo() after setting the “baricentric” attribute, the customAttribute property of the VBO is empty. What am I doing wrong?


#2

Ok, now I have the attributes in the VBO. I am trying to debug the attributes values, simply using its value as color for a triangle. This is my mesh helper

#pragma once
#include "ofMain.h"

class MeshHelper{
public:

    static void addBarycentricCoordinates(ofVboMesh &mesh, ofShader &shader){
        int nVertices = mesh.getVertices().size();
        int nTriangles = nVertices / 3; // number of triangles
        int n = nVertices*3;
        int nFloats = 9;
        float barycentric[n]; // each vertex has 3 floats

        // for each triangle in the geometry, add the barycentric coordinates
        for (int i = 0; i < nTriangles; i++) {
            barycentric[i*nFloats] = 1.f;
            barycentric[i*nFloats+1] = 0.f;
            barycentric[i*nFloats+2] = 0.f;
            barycentric[i*nFloats+3] = 0.f;
            barycentric[i*nFloats+4] = 1.f;
            barycentric[i*nFloats+5] = 0.f;
            barycentric[i*nFloats+6] = 0.f;
            barycentric[i*nFloats+7] = 0.f;
            barycentric[i*nFloats+8] = 1.;
        }


        int bariLoc = shader.getAttributeLocation("baryCoord");
        mesh.getVbo().setAttributeData(bariLoc, barycentric, 3,
                                       nVertices*3, GL_STATIC_DRAW, sizeof(float));
    };
};
  

This is how I am creating a simple triangle in the setup method

    shader.load("shaders_gl3/passthruogh.vert", "shaders_gl3/final.frag", "");
    mesh.addVertex(glm::vec3(-100,0,0));
    mesh.addVertex(glm::vec3(100,0,0));
    mesh.addVertex(glm::vec3(0,100,0));

    MeshHelper::addBarycentricCoordinates(mesh, shader, true);

This is the vertex shader:

#version 150

uniform mat4 modelViewProjectionMatrix;

in vec4 position;
in vec4 normal;
in vec3 baryCoord;
out vec3 vBC;

void main() {
    vBC = baryCoord;
    gl_Position = modelViewProjectionMatrix * position;
}

And this is the fragment shader:

in vec3 vBC;
out vec4 fragColor;

void main(){
    fragColor = vec4(vBC, 1.0);
}

I should see a triangle with a red vertex, a blue vertex and a green vertex. But the last one is black instead of green.

43
For sure I am not packing the attributes correctly when I call setAttributeData. Any hints?


#3

The problem was in the stride.
I was doing:

        mesh.getVbo().setAttributeData(bariLoc, &barycentric[0], 3,
                                    nVertices*3, GL_STATIC_DRAW, sizeof(float));

but of course the stride is the size of a float times the number of floats for each vertex:

mesh.getVbo().setAttributeData(bariLoc, &barycentric[0], 3,
                             nVertices*3, GL_STATIC_DRAW, sizeof(float)*3);