clean VBO

This commit is contained in:
Martin Pernollet 2015-04-11 22:16:18 +02:00
parent fb6d50d476
commit f70e383209
2 changed files with 233 additions and 201 deletions

View File

@ -15,109 +15,45 @@ import org.jzy3d.maths.Coord3d;
import org.jzy3d.plot3d.primitives.vbo.buffers.FloatVBO;
import org.jzy3d.plot3d.primitives.vbo.drawable.DrawableVBO;
public abstract class VBOBuilder implements IGLLoader<DrawableVBO>{
/**
* The {@link VBOBuilder} is responsible for sizing a {@link FloatVBO}, filling
* it with vertex coordinates and colors properties, and and configure a
* {@link DrawableVBO} with filled buffer.
*
* The builder will be called via method {@link load()} once GL context is ready
* to store geometry in GPU for the given DrawableVBO instance. This is where
* builder actually draw the object by setting coordinates, colors, and rendering parameters.
*
*
* A {@link Quality} setting can be given to configure GL properties of the drawable:
* <ul>
* <li>
* <li>
* <li>
* </ul>
*
*
*
* @author Martin Pernollet
*
*/
public abstract class VBOBuilder implements IGLLoader<DrawableVBO> {
protected void fillWithCollection(DrawableVBO drawable, Collection<Coord3d> coordinates, ColorMapper colors, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) {
drawable.setHasColorBuffer(colors != null);
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>having normals defined (default to false)
* <li>number of dimensions (default to 3)
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasNormal, boolean hasColor, int n, int dimension) {
int geometrySize = computeGeometrySize(drawable);
int verticeBufferSize = computeVerticeBufferSize(drawable.getGeometry(), n, dimension, geometrySize, hasNormal, hasColor);
int indexBufferSize = computeIndexBufferSize(n, geometrySize, hasColor);
System.out.println(indexBufferSize + " " + verticeBufferSize);
FloatVBO vbo = new FloatVBO(verticeBufferSize, indexBufferSize);
return vbo;
}
private int computeIndexBufferSize(int n, int geometrySize, boolean hasColor) {
//if(hasColor)
return n * geometrySize;
}
protected int geometryTypeToMultiplier(int geometrySize) {
if(geometrySize==GL.GL_POINTS){
return 1;
} else if(geometrySize==GL.GL_LINES){
return 2;
} else if(geometrySize==GL.GL_TRIANGLES){
return 3;
}
return 1;
}
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>having normals defined (default to false)
* <li>3 dimensions
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasNormal, boolean hasColor, int n) {
return initFloatVBO(drawable, hasNormal, hasColor, n, 3);
}
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>no normals defined
* <li>3 dimensions
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasColor, int n) {
return initFloatVBO(drawable, false, hasColor, n, 3);
}
/* */
protected int computeVerticeBufferSize(int type, int n, int dim, int geometrySize, boolean hasNormal, boolean hasColor) {
if(type==GL.GL_LINES){
if(hasColor){
return n * (dim *2 * 2) * geometrySize;// *2 points for lines, *2 for having a color
int size = 0;
for (Coord3d c : coordinates) {
indices.put(size++);
putCoord(vertices, c);
bounds.add(c);
if (colors != null) {
putColor(vertices, colors.getColor(c));
}
else{
return n * (dim *2) * geometrySize;// *2 lines
}
}
else{
if (hasColor) {
return n * (dim * 2) * geometrySize;// *2 colors
}
if (hasNormal) {
return n * (dim * 2) * geometrySize;// *2 normals
}
return n * dim * geometrySize;
}
}
protected int computeGeometrySize(DrawableVBO drawable) {
if (drawable.getGeometry() == GL.GL_POINTS) {
return 1;
}
if (drawable.getGeometry() == GL.GL_LINES) {
return 2;
}
else if (drawable.getGeometry() == GL.GL_TRIANGLES) {
return 3;
}
return 2;
vertices.rewind();
indices.rewind();
}
/* */
protected void fillWithCollection(DrawableVBO drawable, List<Coord3d> coordinates, FloatVBO vbo) {
fillWithCollection(drawable, coordinates, vbo.getVertices(), vbo.getIndices(), vbo.getBounds());
}
@ -130,72 +66,49 @@ public abstract class VBOBuilder implements IGLLoader<DrawableVBO>{
fillWithCollection(drawable, coordinates, null, vertices, indices, bounds);
}
protected void fillWithCollection(DrawableVBO drawable, Collection<Coord3d> coordinates, ColorMapper colors, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) {
/* */
protected void fillWithRandomBar(int n, DrawableVBO drawable, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds, ColorMapper colors) {
drawable.setHasColorBuffer(colors != null);
int size = 0;
for (Coord3d c : coordinates) {
indices.put(size++);
putCoord(vertices, c);
bounds.add(c);
for (int i = 0; i < n; i++) {
if (colors != null) {
putColor(vertices, colors.getColor(c));
}
}
vertices.rewind();
indices.rewind();
}
/* */
protected void fillWithRandomBar(int n, DrawableVBO drawable, FloatVBO vbo, ColorMapper colors) {
fillWithRandomBar(n, drawable, vbo.getVertices(), vbo.getIndices(), vbo.getBounds(), colors);
}
protected void fillWithRandomBar(int n, DrawableVBO drawable, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds, ColorMapper colors) {
drawable.setHasColorBuffer(colors!=null);
int size = 0;
for (int i=0; i<n; i++) {
float z = (float)Math.random()*100;
float y = (float)Math.random()*1;
float z = (float) Math.random() * 100;
float y = (float) Math.random() * 1;
indices.put(size++);
Coord3d c1 = new Coord3d(i, 0, 0);
putCoord(vertices, c1);
putColor(vertices, Color.RED);
bounds.add(c1);
indices.put(size++);
Coord3d c2 = new Coord3d(i, y, z);
putCoord(vertices, c2);
putColor(vertices, Color.RED);
bounds.add(c2);
/*if(colors!=null){
putColor(vertices, colors.getColor(c1));
putColor(vertices, colors.getColor(c2));
}*/
}
vertices.rewind();
indices.rewind();
}
protected void fillWithRandomBar(int n, DrawableVBO drawable, FloatVBO vbo, ColorMapper colors) {
fillWithRandomBar(n, drawable, vbo.getVertices(), vbo.getIndices(), vbo.getBounds(), colors);
}
/* */
protected void putBar(FloatVBO vbo, int size, float x, float y, float z, Color color) {
Coord3d c1 = new Coord3d(x, 0, 0);
Coord3d c2 = new Coord3d(x, y, z);
putPoint(vbo, size++, color, c1);
putPoint(vbo, size++, color, c2);
}
protected void putPoint(FloatVBO vbo, int id, Color color, Coord3d coord) {
// System.out.println("putPpoint "+ id);
// System.out.println("putPpoint "+ id);
vbo.getIndices().put(id);
putCoord(vbo, coord);
putColor(vbo, color);
@ -226,5 +139,103 @@ public abstract class VBOBuilder implements IGLLoader<DrawableVBO>{
vertices.put(color.b);
}
/* */
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>having normals defined (default to false)
* <li>number of dimensions (default to 3)
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasNormal, boolean hasColor, int n, int dimension) {
int geometrySize = computeGeometrySize(drawable);
int verticeBufferSize = computeVerticeBufferSize(drawable.getGeometry(), n, dimension, geometrySize, hasNormal, hasColor);
int indexBufferSize = computeIndexBufferSize(n, geometrySize, hasColor);
System.out.println(indexBufferSize + " " + verticeBufferSize);
FloatVBO vbo = new FloatVBO(verticeBufferSize, indexBufferSize);
return vbo;
}
private int computeIndexBufferSize(int n, int geometrySize, boolean hasColor) {
// if(hasColor)
return n * geometrySize;
}
protected int geometryTypeToMultiplier(int geometrySize) {
if (geometrySize == GL.GL_POINTS) {
return 1;
} else if (geometrySize == GL.GL_LINES) {
return 2;
} else if (geometrySize == GL.GL_TRIANGLES) {
return 3;
}
return 1;
}
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>having normals defined (default to false)
* <li>3 dimensions
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasNormal, boolean hasColor, int n) {
return initFloatVBO(drawable, hasNormal, hasColor, n, 3);
}
/**
* Setup buffers dimensions according to various parameters:
* <ul>
* <li>target drawable representation type (point, line, etc),
* <li>having color per vertex or not,
* <li>no normals defined
* <li>3 dimensions
* </ul>
*
*/
protected FloatVBO initFloatVBO(DrawableVBO drawable, boolean hasColor, int n) {
return initFloatVBO(drawable, false, hasColor, n, 3);
}
/* */
protected int computeVerticeBufferSize(int type, int n, int dim, int geometrySize, boolean hasNormal, boolean hasColor) {
if (type == GL.GL_LINES) {
if (hasColor) {
return n * (dim * 2 * 2) * geometrySize;// *2 points for lines,
// *2 for having a color
} else {
return n * (dim * 2) * geometrySize;// *2 lines
}
} else {
if (hasColor) {
return n * (dim * 2) * geometrySize;// *2 colors
}
if (hasNormal) {
return n * (dim * 2) * geometrySize;// *2 normals
}
return n * dim * geometrySize;
}
}
protected int computeGeometrySize(DrawableVBO drawable) {
if (drawable.getGeometry() == GL.GL_POINTS) {
return 1;
}
if (drawable.getGeometry() == GL.GL_LINES) {
return 2;
} else if (drawable.getGeometry() == GL.GL_TRIANGLES) {
return 3;
}
return 2;
}
}

View File

@ -48,7 +48,8 @@ import com.jogamp.common.nio.Buffers;
public class DrawableVBO extends AbstractDrawable implements IGLBindedResource {
protected int geometry = GL.GL_TRIANGLES;
protected float width = 1;
protected Quality quality = Quality.Nicest;
protected int colorChannelNumber = 3;
public DrawableVBO(IGLLoader<DrawableVBO> loader) {
@ -92,79 +93,33 @@ public class DrawableVBO extends AbstractDrawable implements IGLBindedResource {
this.width = width;
}
static Quality quality = Quality.Nicest;
public Quality getQuality() {
return quality;
}
public void setQuality(Quality quality) {
this.quality = quality;
}
protected void doDrawElements(GL gl) {
if (gl.isGL2()) {
doBindGL2(gl);
gl.getGL2().glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer);
gl.getGL2().glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
if (hasColorBuffer) {
// int bo = 6 * Buffers.SIZEOF_FLOAT;
int p = 3 * Buffers.SIZEOF_FLOAT;
gl.getGL2().glEnableClientState(GL2.GL_COLOR_ARRAY);
gl.getGL2().glColorPointer(colorChannelNumber, GL.GL_FLOAT, byteOffset, p);
}
// enable
gl.getGL2().glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
//gl.getGL2().glPointSize(width);
// gl.getGL2().glPointWidth(4);
if(geometry==GL.GL_POINTS){
gl.getGL2().glPointSize(width);
} else if(geometry==GL.GL_LINES){
gl.getGL2().glLineWidth(width);
}
if (quality.isSmoothPolygon()) {
gl.glEnable(GL2GL3.GL_POLYGON_SMOOTH);
gl.glHint(GL2GL3.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST);
} else
gl.glDisable(GL2GL3.GL_POLYGON_SMOOTH);
if (quality.isSmoothLine()) {
gl.glEnable(GL.GL_LINE_SMOOTH);
gl.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST);
} else
gl.glDisable(GL.GL_LINE_SMOOTH);
if (quality.isSmoothPoint()) {
gl.glEnable(GL2ES1.GL_POINT_SMOOTH);
gl.glHint(GL2ES1.GL_POINT_SMOOTH_HINT, GL.GL_NICEST);
// gl.glDisable(GL2.GL_BLEND);
// gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_NICEST);
} else
gl.glDisable(GL2ES1.GL_POINT_SMOOTH);
// draw
gl.getGL2().glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
//gl.getGL2().glDrawElements
doBindGL2(gl);
// disable
gl.getGL2().glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
if (hasColorBuffer) {
gl.getGL2().glDisableClientState(GL2.GL_COLOR_ARRAY);
}
pointers(gl);
color(gl);
enable(gl);
applyWidth(gl);
applyQuality(gl);
applyVertices(gl);
disable(gl);
disableColor(gl);
} else {
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
GLES2CompatUtils.glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer);
GLES2CompatUtils.glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
GLES2CompatUtils.glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
@ -172,13 +127,79 @@ static Quality quality = Quality.Nicest;
}
}
private void disableColor(GL gl) {
if (hasColorBuffer) {
gl.getGL2().glDisableClientState(GL2.GL_COLOR_ARRAY);
}
}
private void pointers(GL gl) {
gl.getGL2().glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer);
gl.getGL2().glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
}
private void color(GL gl) {
if (hasColorBuffer) {
// int bo = 6 * Buffers.SIZEOF_FLOAT;
int p = 3 * Buffers.SIZEOF_FLOAT;
gl.getGL2().glEnableClientState(GL2.GL_COLOR_ARRAY);
gl.getGL2().glColorPointer(colorChannelNumber, GL.GL_FLOAT, byteOffset, p);
}
}
private void enable(GL gl) {
gl.getGL2().glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
}
private void disable(GL gl) {
gl.getGL2().glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
}
private void applyVertices(GL gl) {
gl.getGL2().glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
doBindGL2(gl);
}
private void applyWidth(GL gl) {
if(geometry==GL.GL_POINTS){
gl.getGL2().glPointSize(width);
} else if(geometry==GL.GL_LINES){
gl.getGL2().glLineWidth(width);
}
}
private void applyQuality(GL gl) {
if (quality.isSmoothPolygon()) {
gl.glEnable(GL2GL3.GL_POLYGON_SMOOTH);
gl.glHint(GL2GL3.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST);
} else
gl.glDisable(GL2GL3.GL_POLYGON_SMOOTH);
if (quality.isSmoothLine()) {
gl.glEnable(GL.GL_LINE_SMOOTH);
gl.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST);
} else
gl.glDisable(GL.GL_LINE_SMOOTH);
if (quality.isSmoothPoint()) {
gl.glEnable(GL2ES1.GL_POINT_SMOOTH);
gl.glHint(GL2ES1.GL_POINT_SMOOTH_HINT, GL.GL_NICEST);
// gl.glDisable(GL2.GL_BLEND);
// gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_NICEST);
} else
gl.glDisable(GL2ES1.GL_POINT_SMOOTH);
}
protected void doBindGL2(GL gl) {
gl.getGL2().glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
gl.getGL2().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
}
/**
* rotate around Z axis
* Returns a {@link Rotator} that can let the VBO turn around Z axis centered at X=0,Y=0.
* Must be started by {@link Rotator.start()} if not started explicitely.
*/
public Rotator rotator(boolean start) {
final Rotate r = new Rotate(25, new Coord3d(0, 0, 1));