From f70e383209c34a4992c0b6bbb98ce8c437013b0d Mon Sep 17 00:00:00 2001 From: Martin Pernollet Date: Sat, 11 Apr 2015 22:16:18 +0200 Subject: [PATCH] clean VBO --- .../primitives/vbo/builders/VBOBuilder.java | 285 +++++++++--------- .../primitives/vbo/drawable/DrawableVBO.java | 149 +++++---- 2 files changed, 233 insertions(+), 201 deletions(-) diff --git a/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/builders/VBOBuilder.java b/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/builders/VBOBuilder.java index a895bc86..d507f69f 100644 --- a/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/builders/VBOBuilder.java +++ b/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/builders/VBOBuilder.java @@ -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{ +/** + * 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: + * + * + * + * + * @author Martin Pernollet + * + */ +public abstract class VBOBuilder implements IGLLoader { + protected void fillWithCollection(DrawableVBO drawable, Collection coordinates, ColorMapper colors, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) { + drawable.setHasColorBuffer(colors != null); - /** - * Setup buffers dimensions according to various parameters: - *
    - *
  • target drawable representation type (point, line, etc), - *
  • having color per vertex or not, - *
  • having normals defined (default to false) - *
  • number of dimensions (default to 3) - *
- * - */ - 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: - *
    - *
  • target drawable representation type (point, line, etc), - *
  • having color per vertex or not, - *
  • having normals defined (default to false) - *
  • 3 dimensions - *
- * - */ - - 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: - *
    - *
  • target drawable representation type (point, line, etc), - *
  • having color per vertex or not, - *
  • no normals defined - *
  • 3 dimensions - *
- * - */ - 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 coordinates, FloatVBO vbo) { fillWithCollection(drawable, coordinates, vbo.getVertices(), vbo.getIndices(), vbo.getBounds()); } @@ -130,72 +66,49 @@ public abstract class VBOBuilder implements IGLLoader{ fillWithCollection(drawable, coordinates, null, vertices, indices, bounds); } - protected void fillWithCollection(DrawableVBO drawable, Collection 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{ vertices.put(color.b); } - + /* */ + + /** + * Setup buffers dimensions according to various parameters: + *
    + *
  • target drawable representation type (point, line, etc), + *
  • having color per vertex or not, + *
  • having normals defined (default to false) + *
  • number of dimensions (default to 3) + *
+ * + */ + 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: + *
    + *
  • target drawable representation type (point, line, etc), + *
  • having color per vertex or not, + *
  • having normals defined (default to false) + *
  • 3 dimensions + *
+ * + */ + + 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: + *
    + *
  • target drawable representation type (point, line, etc), + *
  • having color per vertex or not, + *
  • no normals defined + *
  • 3 dimensions + *
+ * + */ + 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; + } + } \ No newline at end of file diff --git a/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/drawable/DrawableVBO.java b/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/drawable/DrawableVBO.java index ebecfa96..7393b577 100644 --- a/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/drawable/DrawableVBO.java +++ b/jzy3d-api/src/api/org/jzy3d/plot3d/primitives/vbo/drawable/DrawableVBO.java @@ -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 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));