Johnny Pauling
Johnny Pauling

Reputation: 13407

openGL shader: two object and one line to connect them

I'm using shaders and the programmable pipeline, I need to connect two meshes with a line (maybe colored) but I just have the model matrices of these two objects. The line should start at the center of these objects so I assume the object-coords of the two points should be:

start point: 0,0,0
end point: 0,0,0

to connect the two objects I assume I'll have to multiply these points in the shader by their respective object's model matrix. And then multiply everything by the view matrix (this is common to the two objects). And eventually by the projection matrix.

I've always used shaders with vertex arrays, how would I pass two different vertices to a shader? Should I use uniforms for them too? And what function should I use to draw the line since both glDrawElements and glDrawArrays require a data array?

Upvotes: 0

Views: 2386

Answers (1)

torbjoernwh
torbjoernwh

Reputation: 445

The most straightforward method would be to create a VBO containing the worldspace points of all the lines you wish to draw with GL_LINES.

The easiest is to use glDrawArrays. If you have extreme amounts of object pairs that need lines between (10.000s+) then it might make sense to store all the points in a VBO, and then use a IBO (index buffer) to say what points in the VBO are connected by a line.

The line vertices would still have to be transformed by the view matrix.

Here's an example: GLuint vao, vbo;

// generate and bind the vao
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// generate and bind the buffer object
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

struct Point{ 
    float x,y,z; 
    Point(float x,float y,float z) 
                    : x(x), y(y), z(z) 
    {} 
};

// create two points needed for a line. For more lines, just add another point-pair
std::vector<Point> vertexData;
vertexData.push_back( Point(-0.5, 0.f, 0.f) );
vertexData.push_back( Point(+0.5, 0.f, 0.f) );

// fill with data
size_t numVerts = vertexData.size();
glBufferData(GL_ARRAY_BUFFER, sizeof(Point)*numVerts, &vertexData[0], GL_STATIC_DRAW);

// set up generic attrib pointers
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, numVerts*sizeof(Point), (char*)0 + 0*sizeof(GLfloat));

// "unbind" vao
glBindVertexArray(0);

// In your render-loop:
glBindVertexArray(vao);
glDrawArrays(GL_LINES, 0, numVerts);

If you need to add more point-pairs during runtime, update the std::vector, bind the VBO and call glBufferData.

Upvotes: 2

Related Questions