Reputation: 6029
I have an Android app using OpenGL ES 2.0. I need to draw 10 lines from an array each of which are described by a start point and an end point. So there are 10 lines = 20 points = 60 floats values. None of the points are connected so each pair of points in the array is unrelated to the others, hence I draw with GL_LINES.
I draw them by putting the values into a float buffer and calling some helper code like this:
public void drawLines(FloatBuffer vertexBuffer, float lineWidth,
int numPoints, float colour[]) {
GLES20.glLineWidth(lineWidth);
drawShape(vertexBuffer, GLES20.GL_LINES, numPoints, colour);
}
protected void drawShape(FloatBuffer vertexBuffer, int drawType,
int numPoints, float colour[]) {
// ... set shader ...
GLES20.glDrawArrays(drawType, 0, numPoints);
}
The drawLines takes the float buffer (60 floats), a linewidth, the number of points (20) and a 4 float colour value array. I haven't shown the shader setting code but it basically exposes the colour variable to uniform uColour value.
The fragment shader that picks up uColour just plugs it straight into the output.
/* Fragment */
precision mediump float;
uniform vec4 uColour;
uniform float uTime;
void main() {
gl_FragColor = uColour;
}
The vertex shader:
uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
void main() {
gl_Position = uMVPMatrix * vPosition;
}
But now I want to do something different. I want every line in my buffer to have a different colour. The colours are a function of the position of the line in the array. I want to shade the beginning line white, the last dark gray and lines between a gradation between the two, e.g. #ffffff, #eeeeee, #dddddd etc.
I could obviously just draw each line individually plugging a new value into uColour each time but that is inefficient. I don't want to call GL 10 times when I could call it once and modify the value in a shader each time around.
Perhaps I could declare a uniform value called uVertexCount in my vertex shader? Prior to the draw I set uVertexCount to 0 and for each time the vertex shader is called I increment this value. The fragment shader could determine the line index by looking at uVertexCount. It could then interpolate a value for the colour between some start and end value or some other means. But this depends if every line or point is considered a primitive or the whole array of lines is a single primitive.
Is this feasible? I don't know how many times the vertex shader is called per fragment shader. Are the calls interleaved in a way such as this to make it viable, i.e. vertex 0, vertex 1, x * fragment, vertex 2, vertex 3, x * fragment etc.
Does anyone know of some reasonable sample code that might demonstrate the concept or point me to some other way of doing something similar?
Upvotes: 6
Views: 6988
Reputation: 1149
Add color information into your Vertexbuffer (Floatbuffer) and use the attribute in your shader.
Example vertexbuffer:
uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
attribute vec3 vColor;
varying vec3 color;
void main() {
gl_Position = uMVPMatrix * vPosition;
color = vColor;
}
Example fragmentshader:
precision mediump float;
varying vec3 color;
void main() {
gl_FragColor = color;
}
Upvotes: 6