PDA

View Full Version : Color Array bound to Vertexs instead of Elements?



Jeffg
03-16-2010, 12:23 PM
I'm trying to draw some lines using a VBO. I create a vertex array of the points. I create a color array that specifies the color of the lines. I then create an element array that defines the lines based on the vertex count.

Problem is that the color array is binding to vertex positions, not the element array. So instead of the first and second color in my array applying to the color of the first line, it's being applied to the first and second vertex. If my first line is vertex 0 and vertex 5, it should pull the first color from the array, not take a gradient from vertex 0 and 5. So I want to bind the 0/1 color to element 0/1, not vertex 0/1.

Help! Thanks, Jeff
P.S. Any obvious performance tips with such code would also be appreciated. :-)

Below is some code, which is a Processing.org sketch.


import processing.opengl.*;
import javax.media.opengl.*;
import com.sun.opengl.util.*;
import java.nio.*;

PGraphicsOpenGL pgl;
GL gl;
int[] elements_vbo = new int[1];
int[] positions_vbo = new int[1];
int[] colors_vbo = new int[1];

void setup() {
size( 400, 400, OPENGL );

pgl = (PGraphicsOpenGL) g;
gl = pgl.gl;

//Vertexs - 6 vertexes, 3 floats xyz
FloatBuffer pos = BufferUtil.newFloatBuffer( 6 * 3 );
pos.put( 100 );
pos.put( 50 );
pos.put( 0 );
pos.put( 100 );
pos.put( 300 );
pos.put( 0 );
pos.put( 200 );
pos.put( 50 );
pos.put( 0 );
pos.put( 200 );
pos.put( 300 );
pos.put( 0 );
pos.put( 300 );
pos.put( 50 );
pos.put( 0 );
pos.put( 300 );
pos.put( 300 );
pos.put( 0 );
pos.rewind();

//Elements - 4 lines, 2 vertexs
IntBuffer el = BufferUtil.newIntBuffer( 4 * 2 );
el.put( 0 );
el.put( 1 );
el.put( 2 );
el.put( 3 );
el.put( 4 );
el.put( 5 );
el.put( 0 );
el.put( 5 );
el.rewind();

//Colors - 4 lines, 2 colors (one for each vertex - correct?), 4 floats rgba
FloatBuffer col = BufferUtil.newFloatBuffer( 4 * 2 * 4 );
col.put( 1.0 ); //first line should be RED (1,0,0,1) * 2
col.put( 0.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 1.0 );
col.put( 0.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 0.0 ); //second line should be GREEN (0,1,0,1) * 2
col.put( 1.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 0.0 ); //third line should be BLUE (0,0,1,1) * 2
col.put( 0.0 );
col.put( 1.0 );
col.put( 1.0 );
col.put( 0.0 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 1.0 );
col.put( 1.0 ); //forth line should be ORANGE (1,.5,0,1) * 2
col.put( 0.5 );
col.put( 0.0 );
col.put( 1.0 );
col.put( 1.0 );
col.put( 0.5 );
col.put( 0.0 );
col.put( 1.0 );
col.rewind();

pgl.beginGL();

gl.glGenBuffers( 1, positions_vbo, 0 );
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, positions_vbo[0] );
gl.glBufferData( GL.GL_ARRAY_BUFFER, 6 * 3 * BufferUtil.SIZEOF_FLOAT, pos, GL.GL_STATIC_DRAW );
pos = null;

gl.glGenBuffers( 1, elements_vbo, 0 );
gl.glBindBuffer( GL.GL_ELEMENT_ARRAY_BUFFER, elements_vbo[0] );
gl.glBufferData( GL.GL_ELEMENT_ARRAY_BUFFER, 4 * 2 * BufferUtil.SIZEOF_INT, el, GL.GL_STATIC_DRAW );
el = null;

gl.glGenBuffers( 1, colors_vbo, 0 );
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, colors_vbo[0] );
gl.glBufferData( GL.GL_ARRAY_BUFFER, 4 * 2 * 4 * BufferUtil.SIZEOF_FLOAT, col, GL.GL_STATIC_DRAW );
col = null;

pgl.endGL();

}

void draw() {
pgl.beginGL();
gl.glLineWidth(10.0);
gl.glEnable (gl.GL_LINE_SMOOTH);
gl.glEnableClientState(GL.GL_COLOR_ARRAY);
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, colors_vbo[0] );
gl.glColorPointer(4,GL.GL_FLOAT,0,0);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, positions_vbo[0] );
gl.glVertexPointer(3,GL.GL_FLOAT,0,0);
gl.glBindBuffer( GL.GL_ELEMENT_ARRAY_BUFFER, elements_vbo[0] );
gl.glDrawElements( GL.GL_LINES, 4 * 2, GL.GL_UNSIGNED_INT, 0 );
gl.glBindBuffer( gl.GL_ARRAY_BUFFER, 0);
gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL.GL_COLOR_ARRAY);
gl.glDisable (gl.GL_LINE_SMOOTH);
pgl.endGL();
}

void stop()
{
gl.glDeleteBuffers( 1, positions_vbo, 0 );
gl.glDeleteBuffers( 1, colors_vbo, 0 );
gl.glDeleteBuffers( 1, elements_vbo, 0 );
}

Alfonse Reinheart
03-16-2010, 12:41 PM
So instead of the first and second color in my array applying to the color of the first line, it's being applied to the first and second vertex.

That's how vertex arrays work; each array attribute shares the same index. See here (http://www.opengl.org/wiki_132/index.php?title=Vertex_Specification&action=edit&s ection=1) for more details.

Jeffg
03-16-2010, 12:47 PM
Yes, but I want the colors to apply to the first and second vertex as defined in the element array, not the vertex array. The vertex array is just a collection of points. The mode and shape is in the element array. I could save a lot of space in my project and make it much more efficient if I could use the elements (using tens of thousands of lines as well as using those vertex data for texture mapping), but I need to bind the color to the element (line). Is there any way to get around this or should I not use elements (using glDrawArray instead)?

Jeffg
03-17-2010, 06:00 PM
I understand now.. Thanks for your help. :-)