2. Once this is set up, it is time to place your models in the world. For sake of brevity, I will create a very simple model of a cube, that is coloured. To do this, we load up a VBO with the vertex data, another with colour data per vertex, and an indices buffer (one that tells OpenGL how to go through the vertices drawing the different faces).
- A cube has 8 vertices, each interleaved with is own colour, and i’ll place them around the origin at first
float[] vertexAttributesData=new float[] {
// front
-1f, -1f, 1f, 1f, 0f, 0f,
1f, -1f, 1f, 0f, 1f, 0f,
1f, 1f, 1f, 0f, 0f, 1f,
-1f, 1f, 1f, 1f, 1f, 1f,
// back
-1f, -1f, -1f, 1f, 0f, 0f,
1f, -1f, -1f, 0f, 1f, 0f,
1f, 1f, -1f, 0f, 0f, 1f,
-1f, 1f, -1f, 1f, 1f, 1f,};
- A cube has 6 faces, each created from 2 triangles, each again, created from 3 vertices. So, the indices matrix comes out like the following
int[] indecesData=new int[] {
// front
0, 1, 2, 2, 3, 0,
// top
1, 5, 6, 6, 2, 1,
// back
7, 6, 5, 5, 4, 7,
// bottom
4, 0, 3, 3, 7, 4,
// left
4, 5, 1, 1, 0, 4,
// right
3, 2, 6, 6, 7, 3};
- Next up, we setup the Vertex Shader & the Fragment Shader to transform the cube vertices and colour to the screen
[list][li]The Vertex Shader: does no real transformation at this point, and so just produces the output by applying the ModelViewProjection Matrix to the coordinates and hence, turns out as follows:
[/list]
#version 120
attribute vec3 coords;
attribute vec3 color;
varying vec3 fragmentColor;
void main(void) {
gl_Position=gl_ModelViewProjectionMatrix*vec4(coords,1.0);
fragmentColor=color;
}
-
The Fragment Shader: Also here does not do much, and hence just outputs the colours as specified in the model matrix, which makes it turn out to be simply
#version 120
varying vec3 fragmentColor;
void main(void) {
gl_FragColor=vec4(fragmentColor.x,fragmentColor.y,fragmentColor.z,1.0);
}
[list]
[/li]
- Finally, the Drawing process of the cube is a simple passing in of arguments to the shaders and drawing according to the indices[/list]
public void draw() {
// bind vertex data array
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexAttributesBuffer);
// pass in info to vertex shader
int dataOffset=0;
glEnableVertexAttribArray(coordsAttributeIndex);
glVertexAttribPointer(coordsAttributeIndex, numAxisPerVertex, GL_FLOAT, false, stride, 0);
dataOffset+=numAxisPerVertex*bytesPerFloat;
glEnableVertexAttribArray(colorAttributeIndex);
glVertexAttribPointer(colorAttributeIndex, numColoursPerVertex, GL_FLOAT, false, stride, dataOffset);
dataOffset+=numColoursPerVertex*bytesPerFloat;
// draw the vertices using the indices
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndicesBuffer);
glDrawElements(GL_TRIANGLES, numIndeces, GL_UNSIGNED_INT, 0);
// unbind the buffers & attribute arrays
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDisableVertexAttribArray(colorAttributeIndex);
}
[list]- FINALLY we can actually run and GET something drawn on the screen. What we get is the front face of the cube filling up the entire screen, because we placed the square vertices from -1 to 1, which fills up our entire area
[/list]