aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/curve/OutlineShape.java408
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/curve/Region.java166
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/curve/RegionFactory.java51
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java70
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java55
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java256
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java155
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java324
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/Font.java34
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/AABBox.java475
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Outline.java258
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Triangle.java84
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Vertex.java62
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java278
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/math/Quaternion.java668
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/math/VectorUtil.java466
-rw-r--r--src/jogl/classes/com/jogamp/graph/package.html33
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java61
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/FBObject.java133
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java20
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java248
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java203
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java257
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLDataArrayHandler.java41
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java14
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java54
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Locator.java77
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java29
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java60
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java55
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java193
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java931
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java33
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java195
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java67
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java92
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java10
41 files changed, 3846 insertions, 2859 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
index 827717aa5..724380f4a 100755
--- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
@@ -50,13 +50,13 @@ import com.jogamp.graph.curve.tess.CDTriangulator2D;
* <br><br>
* Example to creating an Outline Shape:
* <pre>
- addVertex(...)
- addVertex(...)
- addVertex(...)
- addEnptyOutline()
- addVertex(...)
- addVertex(...)
- addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ addEnptyOutline()
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
* </pre>
*
* The above will create two outlines each with three vertices. By adding these two outlines to
@@ -72,10 +72,10 @@ import com.jogamp.graph.curve.tess.CDTriangulator2D;
*
* <br>Example: <br>
* <pre>
- addVertex(0,0, true);
- addVertex(0,1, false);
- addVertex(1,1, false);
- addVertex(1,0, true);
+ addVertex(0,0, true);
+ addVertex(0,1, false);
+ addVertex(1,1, false);
+ addVertex(1,0, true);
* </pre>
*
* The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
@@ -83,8 +83,8 @@ import com.jogamp.graph.curve.tess.CDTriangulator2D;
*
* <i>Implementation Notes:</i><br>
* <ul>
- * <li> The first vertex of any outline belonging to the shape should be on-curve</li>
- * <li> Intersections between off-curved parts of the outline is not handled</li>
+ * <li> The first vertex of any outline belonging to the shape should be on-curve</li>
+ * <li> Intersections between off-curved parts of the outline is not handled</li>
* </ul>
*
* @see Outline
@@ -92,216 +92,216 @@ import com.jogamp.graph.curve.tess.CDTriangulator2D;
*/
public class OutlineShape {
- public static final int QUADRATIC_NURBS = 10;
- private final Vertex.Factory<? extends Vertex> vertexFactory;
+ public static final int QUADRATIC_NURBS = 10;
+ private final Vertex.Factory<? extends Vertex> vertexFactory;
- /** The list of {@link Outline}s that are part of this
- * outline shape.
- */
- private ArrayList<Outline> outlines = new ArrayList<Outline>(3);
+ /** The list of {@link Outline}s that are part of this
+ * outline shape.
+ */
+ private ArrayList<Outline> outlines = new ArrayList<Outline>(3);
- /** Create a new Outline based Shape
- */
- public OutlineShape(Vertex.Factory<? extends Vertex> factory) {
- vertexFactory = factory;
- outlines.add(new Outline());
- }
+ /** Create a new Outline based Shape
+ */
+ public OutlineShape(Vertex.Factory<? extends Vertex> factory) {
+ vertexFactory = factory;
+ outlines.add(new Outline());
+ }
- /** Returns the associated vertex factory of this outline shape
- * @return Vertex.Factory object
- */
- public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; }
+ /** Returns the associated vertex factory of this outline shape
+ * @return Vertex.Factory object
+ */
+ public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; }
- /** Add a new empty {@link Outline}
- * to the shape, this new outline will
- * be placed at the end of the outline list.
- *
- * After a call to this function all new vertices added
- * will belong to the new outline
- */
- public void addEmptyOutline(){
- outlines.add(new Outline());
- }
+ /** Add a new empty {@link Outline}
+ * to the shape, this new outline will
+ * be placed at the end of the outline list.
+ *
+ * After a call to this function all new vertices added
+ * will belong to the new outline
+ */
+ public void addEmptyOutline(){
+ outlines.add(new Outline());
+ }
- /** Adds an {@link Outline} to the OutlineShape object
- * if last outline of the shape is empty, it will replace
- * that last Outline with the new one. If outline is empty,
- * it will do nothing.
- * @param outline an Outline object
- */
- public void addOutline(Outline outline){
- if(outline.isEmpty()){
- return;
- }
- if(getLastOutline().isEmpty()){
- outlines.remove(getLastOutline());
- }
- outlines.add(outline);
- }
+ /** Adds an {@link Outline} to the OutlineShape object
+ * if last outline of the shape is empty, it will replace
+ * that last Outline with the new one. If outline is empty,
+ * it will do nothing.
+ * @param outline an Outline object
+ */
+ public void addOutline(Outline outline){
+ if(outline.isEmpty()){
+ return;
+ }
+ if(getLastOutline().isEmpty()){
+ outlines.remove(getLastOutline());
+ }
+ outlines.add(outline);
+ }
- /** Adds a vertex to the last open outline in the
- * shape.
- * @param v the vertex to be added to the OutlineShape
- */
- public final void addVertex(Vertex v){
- getLastOutline().addVertex(v);
- }
+ /** Adds a vertex to the last open outline in the
+ * shape.
+ * @param v the vertex to be added to the OutlineShape
+ */
+ public final void addVertex(Vertex v){
+ getLastOutline().addVertex(v);
+ }
- /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex. The 2D vertex will be represented as Z=0.
- *
- * @param x the x coordinate
- * @param y the y coordniate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, boolean onCurve) {
- getLastOutline().addVertex(vertexFactory, x, y, onCurve);
- }
+ /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex. The 2D vertex will be represented as Z=0.
+ *
+ * @param x the x coordinate
+ * @param y the y coordniate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, boolean onCurve) {
+ getLastOutline().addVertex(vertexFactory, x, y, onCurve);
+ }
- /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex.
- * @param x the x coordinate
- * @param y the y coordniate
- * @param z the z coordniate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, float z, boolean onCurve) {
- getLastOutline().addVertex(vertexFactory, x, y, z, onCurve);
- }
+ /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex.
+ * @param x the x coordinate
+ * @param y the y coordniate
+ * @param z the z coordniate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, float z, boolean onCurve) {
+ getLastOutline().addVertex(vertexFactory, x, y, z, onCurve);
+ }
- /** Add a vertex to the last outline by passing a float array and specifying the
- * offset and length in which. The attributes of the vertex are located.
- * The attributes should be continuous (stride = 0).
- * Attributes which value are not set (when length less than 3)
- * are set implicitly to zero.
- * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
- * @param offset the offset in the buffer to the x coordinate
- * @param length the number of attributes to pick from the buffer (maximum 3)
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
- getLastOutline().addVertex(vertexFactory, coordsBuffer, offset, length, onCurve);
- }
+ /** Add a vertex to the last outline by passing a float array and specifying the
+ * offset and length in which. The attributes of the vertex are located.
+ * The attributes should be continuous (stride = 0).
+ * Attributes which value are not set (when length less than 3)
+ * are set implicitly to zero.
+ * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
+ * @param offset the offset in the buffer to the x coordinate
+ * @param length the number of attributes to pick from the buffer (maximum 3)
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
+ getLastOutline().addVertex(vertexFactory, coordsBuffer, offset, length, onCurve);
+ }
- /** Closes the last outline in the shape
- * if last vertex is not equal to first vertex.
- * A new temp vertex is added at the end which
- * is equal to the first.
- */
- public void closeLastOutline(){
- getLastOutline().setClosed(true);
- }
+ /** Closes the last outline in the shape
+ * if last vertex is not equal to first vertex.
+ * A new temp vertex is added at the end which
+ * is equal to the first.
+ */
+ public void closeLastOutline(){
+ getLastOutline().setClosed(true);
+ }
- /** Get the last added outline to the list
- * of outlines that define the shape
- * @return the last outline
- */
- public final Outline getLastOutline(){
- return outlines.get(outlines.size()-1);
- }
- /** Make sure that the outlines represent
- * the specified destinationType, if not
- * transform outlines to destination type.
- * @param destinationType The curve type needed
- */
- public void transformOutlines(int destinationType){
- if(destinationType == QUADRATIC_NURBS){
- transformOutlinesQuadratic();
- }
- }
+ /** Get the last added outline to the list
+ * of outlines that define the shape
+ * @return the last outline
+ */
+ public final Outline getLastOutline(){
+ return outlines.get(outlines.size()-1);
+ }
+ /** Make sure that the outlines represent
+ * the specified destinationType, if not
+ * transform outlines to destination type.
+ * @param destinationType The curve type needed
+ */
+ public void transformOutlines(int destinationType){
+ if(destinationType == QUADRATIC_NURBS){
+ transformOutlinesQuadratic();
+ }
+ }
- private void transformOutlinesQuadratic(){
- ArrayList<Outline> newOutlines = new ArrayList<Outline>(3);
+ private void transformOutlinesQuadratic(){
+ ArrayList<Outline> newOutlines = new ArrayList<Outline>(3);
- /**loop over the outlines and make sure no
- * adj off-curve vertices
- */
- for(Outline outline:outlines){
- Outline newOutline = new Outline();
+ /**loop over the outlines and make sure no
+ * adj off-curve vertices
+ */
+ for(Outline outline:outlines){
+ Outline newOutline = new Outline();
- ArrayList<Vertex> vertices = outline.getVertices();
- int size =vertices.size()-1;
- for(int i=0;i<size;i++){
- Vertex currentVertex = vertices.get(i);
- Vertex nextVertex = vertices.get((i+1)%size);
- if(!(currentVertex.isOnCurve()) && !(nextVertex.isOnCurve())) {
- newOutline.addVertex(currentVertex);
+ ArrayList<Vertex> vertices = outline.getVertices();
+ int size =vertices.size()-1;
+ for(int i=0;i<size;i++){
+ Vertex currentVertex = vertices.get(i);
+ Vertex nextVertex = vertices.get((i+1)%size);
+ if(!(currentVertex.isOnCurve()) && !(nextVertex.isOnCurve())) {
+ newOutline.addVertex(currentVertex);
- float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), nextVertex.getCoord());
- newOutline.addVertex(vertexFactory, newCoords, 0, 3, true);
- }
- else {
- newOutline.addVertex(currentVertex);
- }
- }
- newOutlines.add(newOutline);
- }
- outlines = newOutlines;
- }
+ float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), nextVertex.getCoord());
+ newOutline.addVertex(vertexFactory, newCoords, 0, 3, true);
+ }
+ else {
+ newOutline.addVertex(currentVertex);
+ }
+ }
+ newOutlines.add(newOutline);
+ }
+ outlines = newOutlines;
+ }
- private void generateVertexIds(){
- int maxVertexId = 0;
- for(Outline outline:outlines){
- ArrayList<Vertex> vertices = outline.getVertices();
- for(Vertex vert:vertices){
- vert.setId(maxVertexId);
- maxVertexId++;
- }
- }
- }
+ private void generateVertexIds(){
+ int maxVertexId = 0;
+ for(Outline outline:outlines){
+ ArrayList<Vertex> vertices = outline.getVertices();
+ for(Vertex vert:vertices){
+ vert.setId(maxVertexId);
+ maxVertexId++;
+ }
+ }
+ }
- /** @return the list of vertices associated with the
- * {@code Outline} list of this object
- */
- public ArrayList<Vertex> getVertices(){
- ArrayList<Vertex> vertices = new ArrayList<Vertex>();
- for(Outline polyline:outlines){
- vertices.addAll(polyline.getVertices());
- }
- return vertices;
- }
+ /** @return the list of vertices associated with the
+ * {@code Outline} list of this object
+ */
+ public ArrayList<Vertex> getVertices(){
+ ArrayList<Vertex> vertices = new ArrayList<Vertex>();
+ for(Outline polyline:outlines){
+ vertices.addAll(polyline.getVertices());
+ }
+ return vertices;
+ }
- /** Triangulate the outline shape generating a list of triangles
- * @return an arraylist of triangles representing the filled region
- * which is produced by the combination of the outlines
- */
- public ArrayList<Triangle> triangulate(){
- return triangulate(0.5f);
- }
+ /** Triangulate the outline shape generating a list of triangles
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
+ */
+ public ArrayList<Triangle> triangulate(){
+ return triangulate(0.5f);
+ }
- /**Triangulate the {@link OutlineShape} generating a list of triangles
- * @param sharpness defines the curvature strength around the off-curve vertices.
- * defaults to 0.5f
- * @return an arraylist of triangles representing the filled region
- * which is produced by the combination of the outlines
- */
- public ArrayList<Triangle> triangulate(float sharpness){
- if(outlines.size() == 0){
- return null;
- }
- sortOutlines();
- generateVertexIds();
-
- CDTriangulator2D triangulator2d = new CDTriangulator2D(sharpness);
- for(int index = 0; index< outlines.size();index++){
- Outline outline = outlines.get(index);
- triangulator2d.addCurve(outline);
- }
-
- ArrayList<Triangle> triangles = triangulator2d.generateTriangulation();
- triangulator2d.reset();
+ /**Triangulate the {@link OutlineShape} generating a list of triangles
+ * @param sharpness defines the curvature strength around the off-curve vertices.
+ * defaults to 0.5f
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
+ */
+ public ArrayList<Triangle> triangulate(float sharpness){
+ if(outlines.size() == 0){
+ return null;
+ }
+ sortOutlines();
+ generateVertexIds();
+
+ CDTriangulator2D triangulator2d = new CDTriangulator2D(sharpness);
+ for(int index = 0; index< outlines.size();index++){
+ Outline outline = outlines.get(index);
+ triangulator2d.addCurve(outline);
+ }
+
+ ArrayList<Triangle> triangles = triangulator2d.generateTriangulation();
+ triangulator2d.reset();
- return triangles;
- }
+ return triangles;
+ }
- /** Sort the outlines from large
- * to small depending on the AABox
- */
- private void sortOutlines() {
- Collections.sort(outlines);
- Collections.reverse(outlines);
- }
+ /** Sort the outlines from large
+ * to small depending on the AABox
+ */
+ private void sortOutlines() {
+ Collections.sort(outlines);
+ Collections.reverse(outlines);
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java
index 051cb1c38..eb88b787c 100755
--- a/src/jogl/classes/com/jogamp/graph/curve/Region.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java
@@ -29,6 +29,12 @@ package com.jogamp.graph.curve;
import java.util.ArrayList;
+import javax.media.opengl.GL2ES2;
+
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.geom.AABBox;
+import jogamp.opengl.Debug;
+
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.opengl.util.PMVMatrix;
@@ -44,85 +50,83 @@ import com.jogamp.opengl.util.PMVMatrix;
* @see RegionFactory, OutlineShape
*/
public interface Region {
- /** The vertices index in an OGL object
- */
- public static int VERTEX_ATTR_IDX = 0;
-
- /** The Texture Coord index in an OGL object
- */
- public static int TEXCOORD_ATTR_IDX = 1;
-
- /** single pass rendering, fast, but AA might not be perfect */
- public static int SINGLE_PASS = 1;
-
- /** two pass rendering, slower and more resource hungry (FBO), but AA is perfect */
- public static int TWO_PASS = 2;
-
- /** Updates a graph region by updating the ogl related
- * objects for use in rendering. if called for the first time
- * it initialize the objects.
- */
- public void update();
-
- /** Renders the associated OGL objects specifying
- * current width/hight of window for multi pass rendering
- * of the region.
- * @param matrix current {@link PMVMatrix}.
- * @param vp_width current screen width
- * @param vp_height current screen height
- * @param width texture width for mp rendering
- *
- * @see update()
- */
- public void render(PMVMatrix matrix, int vp_width, int vp_height, int width);
-
- /** Adds a list of {@link Triangle} objects to the Region
- * These triangles are to be binded to OGL objects
- * on the next call to {@code update}
- * @param tris an arraylist of triangle objects
- *
- * @see update()
- */
- public void addTriangles(ArrayList<Triangle> tris);
-
- /** Get the current number of vertices associated
- * with this region. This number is not necessary equal to
- * the OGL binded number of vertices.
- * @return vertices count
- *
- * @see isDirty()
- */
- public int getNumVertices();
-
- /** Adds a list of {@link Vertex} objects to the Region
- * These vertices are to be binded to OGL objects
- * on the next call to {@code update}
- * @param verts an arraylist of vertex objects
- *
- * @see update()
- */
- public void addVertices(ArrayList<Vertex> verts);
-
- /** Check if this region is dirty. A region is marked dirty
- * when new Vertices, Triangles, and or Lines are added after a
- * call to update()
- * @return true if region is Dirty, false otherwise
- *
- * @see update();
- */
- public boolean isDirty();
-
- /** Delete and clean the associated OGL
- * objects
- */
- public void destroy();
-
- public boolean isFlipped();
-
- /** Set if the y coordinate of the region should be flipped
- * {@code y=-y} used mainly for fonts since they use opposite vertex
- * as origion
- * @param flipped flag if the coordinate is flipped defaults to false.
- */
- public void setFlipped(boolean flipped);
+ public static final boolean DEBUG = Debug.debug("graph.curve");
+ public static final boolean DEBUG_INSTANCE = false;
+
+ /** single pass rendering, fast, but AA might not be perfect */
+ public static int SINGLE_PASS = 1;
+
+ /** two pass rendering, slower and more resource hungry (FBO), but AA is perfect */
+ public static int TWO_PASS = 2;
+ public static int TWO_PASS_DEFAULT_TEXTURE_UNIT = 0;
+
+ /** Updates a graph region by updating the ogl related
+ * objects for use in rendering. if called for the first time
+ * it initialize the objects.
+ */
+ public void update(GL2ES2 gl);
+
+ /** Renders the associated OGL objects specifying
+ * current width/hight of window for multi pass rendering
+ * of the region.
+ * @param matrix current {@link PMVMatrix}.
+ * @param vp_width current screen width
+ * @param vp_height current screen height
+ * @param width texture width for mp rendering
+ *
+ * @see update()
+ */
+ public void render(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int width);
+
+ /** Adds a list of {@link Triangle} objects to the Region
+ * These triangles are to be binded to OGL objects
+ * on the next call to {@code update}
+ * @param tris an arraylist of triangle objects
+ *
+ * @see update()
+ */
+ public void addTriangles(ArrayList<Triangle> tris);
+
+ /** Get the current number of vertices associated
+ * with this region. This number is not necessary equal to
+ * the OGL binded number of vertices.
+ * @return vertices count
+ *
+ * @see isDirty()
+ */
+ public int getNumVertices();
+
+ /** Adds a list of {@link Vertex} objects to the Region
+ * These vertices are to be binded to OGL objects
+ * on the next call to {@code update}
+ * @param verts an arraylist of vertex objects
+ *
+ * @see update()
+ */
+ public void addVertices(ArrayList<Vertex> verts);
+
+ /** Check if this region is dirty. A region is marked dirty
+ * when new Vertices, Triangles, and or Lines are added after a
+ * call to update()
+ * @return true if region is Dirty, false otherwise
+ *
+ * @see update();
+ */
+ public boolean isDirty();
+
+ /** Delete and clean the associated OGL
+ * objects
+ */
+ public void destroy(GL2ES2 gl, RenderState rs);
+
+ public AABBox getBounds();
+
+ public boolean isFlipped();
+
+ /** Set if the y coordinate of the region should be flipped
+ * {@code y=-y} used mainly for fonts since they use opposite vertex
+ * as origion
+ * @param flipped flag if the coordinate is flipped defaults to false.
+ */
+ public void setFlipped(boolean flipped);
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/RegionFactory.java b/src/jogl/classes/com/jogamp/graph/curve/RegionFactory.java
index d3b978b8a..23b318e8a 100755
--- a/src/jogl/classes/com/jogamp/graph/curve/RegionFactory.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/RegionFactory.java
@@ -27,36 +27,43 @@
*/
package com.jogamp.graph.curve;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
-import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.graph.curve.opengl.RenderState;
import jogamp.graph.curve.opengl.VBORegionSPES2;
import jogamp.graph.curve.opengl.VBORegion2PES2;
-
/** RegionFactory to create a Context specific Region implementation.
*
* @see Region
*/
public class RegionFactory {
-
- /**Create a Region based on the GLContext attached
- * @param context the current {@link GLContext}
- * @param st the {@link ShaderState} object
- * @param type can be one of Region.SINGLE_PASS or Region.TWO_PASS
- * @return region
- */
- public static Region create(GLContext context, ShaderState st, int type){
- if( !context.isGL2ES2() ) {
- throw new GLException("At least a GL2ES2 GL context is required. Given: " + context);
- }
- if( Region.TWO_PASS == type ){
- return new VBORegion2PES2(context, st);
- }
- else{
- return new VBORegionSPES2(context);
- }
- }
+
+ /**
+ * Create a Region using the passed curren GL object.
+ *
+ * <p> In case {@link Region#TWO_PASS} is being requested the default texture unit
+ * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.</p>
+ * @param rs TODO
+ * @param type can be one of {@link Region#SINGLE_PASS} or {@link Region#TWO_PASS}
+ *
+ * @return region
+ */
+ public static Region create(RenderState rs, int type) {
+ if( Region.TWO_PASS == type ){
+ return new VBORegion2PES2(rs, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT);
+ }
+ else{
+ return new VBORegionSPES2(rs);
+ }
+ }
+
+ public static Region createSinglePass(RenderState rs) {
+ return new VBORegionSPES2(rs);
+ }
+
+ public static Region createTwoPass(RenderState rs, int textureUnit) {
+ return new VBORegion2PES2(rs, textureUnit);
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
index c6e03cad6..69fdd5c4a 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.graph.curve.opengl;
import java.util.ArrayList;
@@ -13,15 +40,18 @@ import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
public abstract class RegionRenderer extends Renderer {
-
- /** Create a Hardware accelerated Curve Region Renderer
+
+ /**
+ * Create a Hardware accelerated Text Renderer.
+ * @param rs the used {@link RenderState}
+ * @param renderType either {@link com.jogamp.graph.curve.Region#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#TWO_PASS}
*/
- public static RegionRenderer create(Vertex.Factory<? extends Vertex> factory, int type) {
- return new jogamp.graph.curve.opengl.RegionRendererImpl01(factory, type);
+ public static RegionRenderer create(RenderState rs, int type) {
+ return new jogamp.graph.curve.opengl.RegionRendererImpl01(rs, type);
}
- public RegionRenderer(Vertex.Factory<? extends Vertex> factory, int type) {
- super(factory, type);
+ protected RegionRenderer(RenderState rs, int type) {
+ super(rs, type);
}
/** Render an array of {@link OutlineShape}s combined in one region
@@ -45,52 +75,50 @@ public abstract class RegionRenderer extends Renderer {
protected HashMap<Integer, Region> regions = new HashMap<Integer, Region>();
- public void flushCache() {
+ public void flushCache(GL2ES2 gl) {
Iterator<Region> iterator = regions.values().iterator();
while(iterator.hasNext()){
Region region = iterator.next();
- region.destroy();
+ region.destroy(gl, rs);
}
regions.clear();
}
@Override
protected void disposeImpl(GL2ES2 gl) {
- flushCache();
+ // fluchCache(gl) already called
}
- /** Create an ogl {@link Region} defining this {@link OutlineShape}
- * @param sharpness parameter for Region generation
+ /**
+ * Create an ogl {@link Region} defining this {@link OutlineShape}
* @return the resulting Region.
*/
- protected Region createRegion(GL2ES2 gl, OutlineShape outlineShape, float sharpness) {
- Region region = RegionFactory.create(gl.getContext(), st, renderType);
+ protected Region createRegion(GL2ES2 gl, OutlineShape outlineShape) {
+ Region region = RegionFactory.create(rs, renderType);
outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
-
- ArrayList<Triangle> triangles = (ArrayList<Triangle>) outlineShape.triangulate(sharpness);
+ ArrayList<Triangle> triangles = (ArrayList<Triangle>) outlineShape.triangulate(rs.getSharpness().floatValue());
ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices();
region.addVertices(vertices);
region.addTriangles(triangles);
- region.update();
+ region.update(gl);
return region;
}
/** Create an ogl {@link Region} defining the list of {@link OutlineShape}.
* Combining the Shapes into single buffers.
- * @param sharpness parameter for Region generation
* @return the resulting Region inclusive the generated region
*/
- protected Region createRegion(GL2ES2 gl, OutlineShape[] outlineShapes, float sharpness) {
- Region region = RegionFactory.create(gl.getContext(), st, renderType);
+ protected Region createRegion(GL2ES2 gl, OutlineShape[] outlineShapes) {
+ Region region = RegionFactory.create(rs, renderType);
int numVertices = region.getNumVertices();
for(OutlineShape outlineShape:outlineShapes){
outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
- ArrayList<Triangle> triangles = outlineShape.triangulate(sharpness);
+ ArrayList<Triangle> triangles = outlineShape.triangulate(rs.getSharpness().floatValue());
region.addTriangles(triangles);
ArrayList<Vertex> vertices = outlineShape.getVertices();
@@ -100,7 +128,7 @@ public abstract class RegionRenderer extends Renderer {
region.addVertices(vertices);
}
- region.update();
+ region.update(gl);
return region;
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
new file mode 100644
index 000000000..84323f6e5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.graph.curve.opengl;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLUniformData;
+
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public interface RenderState {
+
+ void destroy(GL2ES2 gl);
+
+ ShaderState getShaderState();
+ Vertex.Factory<? extends Vertex> getPointFactory();
+ PMVMatrix pmvMatrix();
+ GLUniformData getPMVMatrix();
+ GLUniformData getSharpness();
+ GLUniformData getAlpha();
+ GLUniformData getColorStatic();
+ GLUniformData getStrength();
+
+ RenderState attachTo(GL2ES2 gl);
+ boolean detachFrom(GL2ES2 gl);
+
+ StringBuilder toString(StringBuilder sb);
+ String toString();
+}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
index 57eeb016f..35022f769 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
@@ -1,39 +1,75 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.graph.curve.opengl;
+import java.nio.FloatBuffer;
+
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
-import jogamp.opengl.Debug;
+import jogamp.graph.curve.opengl.RenderStateImpl;
+import com.jogamp.graph.curve.Region;
import com.jogamp.graph.geom.Vertex;
-import com.jogamp.graph.geom.opengl.SVertex;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderState;
public abstract class Renderer {
- protected static final boolean DEBUG = Debug.debug("CurveRenderer");
+ protected static final boolean DEBUG = Region.DEBUG;
+ protected static final boolean DEBUG_INSTANCE = Region.DEBUG_INSTANCE;
+
+ public static RenderState createRenderState(ShaderState st, Vertex.Factory<? extends Vertex> pointFactory, PMVMatrix pmvMatrix) {
+ return new RenderStateImpl(st, pointFactory, pmvMatrix);
+ }
- protected abstract boolean initImpl(GL2ES2 gl);
+ public static RenderState createRenderState(ShaderState st, Vertex.Factory<? extends Vertex> pointFactory) {
+ return new RenderStateImpl(st, pointFactory);
+ }
+
+ /**
+ * Implementation shall load, compile and link the shader program and leave it active.
+ * @param gl
+ * @return
+ */
+ protected abstract boolean initShaderProgram(GL2ES2 gl);
protected abstract void disposeImpl(GL2ES2 gl);
/**
* Flushes all cached data
+ * @see #destroy(GL2ES2)
*/
- public abstract void flushCache();
+ public abstract void flushCache(GL2ES2 gl);
+
+ protected final RenderState rs;
+ public final int renderType;
- public abstract float getAlpha();
-
- public abstract void setAlpha(GL2ES2 gl, float alpha_t);
-
- public abstract void setColor(GL2ES2 gl, float r, float g, float b);
-
- protected final Vertex.Factory<? extends Vertex> pointFactory;
- protected ShaderState st = new ShaderState();
- protected PMVMatrix pmvMatrix = new PMVMatrix();
- protected GLUniformData mgl_PMVMatrix;
- protected int renderType;
protected int vp_width = 0;
protected int vp_height = 0;
@@ -41,16 +77,15 @@ public abstract class Renderer {
private boolean initialized = false;
/**
- *
- * @param factory
+ * @param rs the used {@link RenderState}
* @param renderType either {@link com.jogamp.graph.curve.Region#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#TWO_PASS}
*/
- protected Renderer(Vertex.Factory<? extends Vertex> factory, int renderType) {
+ protected Renderer(RenderState rs, int renderType) {
+ this.rs = rs;
this.renderType = renderType;
- this.pointFactory = (null != factory) ? factory : SVertex.factory();
}
- public Vertex.Factory<? extends Vertex> getFactory() { return pointFactory; }
+ public Vertex.Factory<? extends Vertex> getFactory() { return rs.getPointFactory(); }
public final boolean isInitialized() { return initialized; }
@@ -62,10 +97,12 @@ public abstract class Renderer {
public final int getHeight() { return vp_height; }
/**
- * Initialize shaders and bindings for GPU based rendering.
- * Leaves the renderer enabled, ie ShaderState on.
+ * Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext.
*
- * @param gl the current GL state
+ * Leaves the renderer enabled, ie ShaderState.
+ *
+ * @param gl referencing the current GLContext to which the ShaderState is bound to
+ *
* @return true if succeeded, false otherwise
*/
public boolean init(GL2ES2 gl) {
@@ -86,85 +123,176 @@ public abstract class Renderer {
System.err.println("TextRendererImpl01: VBO Supported = " + isVBOSupported());
}
- initialized = initImpl(gl);
+ if(!vboSupported){
+ return false;
+ }
+
+ rs.attachTo(gl);
+
+ gl.glEnable(GL2ES2.GL_BLEND);
+ gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); // FIXME: alpha blending stage ?
+
+ initialized = initShaderProgram(gl);
+ if(!initialized) {
+ return false;
+ }
+
+ if(!rs.getShaderState().uniform(gl, rs.getPMVMatrix())) {
+ if(DEBUG){
+ System.err.println("Error setting PMVMatrix in shader: "+rs.getShaderState());
+ }
+ return false;
+ }
+
+ if(!rs.getShaderState().uniform(gl, rs.getSharpness())) {
+ if(DEBUG){
+ System.err.println("Error setting sharpness in shader: "+rs.getShaderState());
+ }
+ return false;
+ }
+
+ if(!rs.getShaderState().uniform(gl, rs.getAlpha())) {
+ if(DEBUG){
+ System.err.println("Error setting global alpha in shader: "+rs.getShaderState());
+ }
+ return false;
+ }
+
+ if(!rs.getShaderState().uniform(gl, rs.getColorStatic())) {
+ if(DEBUG){
+ System.err.println("Error setting global color in shader: "+rs.getShaderState());
+ }
+ return false;
+ }
+
+ if(!rs.getShaderState().uniform(gl, rs.getStrength())) {
+ System.err.println("Error setting antialias strength in shader: "+rs.getShaderState());
+ }
+
return initialized;
}
- public void dispose(GL2ES2 gl) {
+ public void destroy(GL2ES2 gl) {
if(!initialized){
- if(DEBUG) {
+ if(DEBUG_INSTANCE) {
System.err.println("TextRenderer: Not initialized!");
}
return;
}
+ rs.getShaderState().useProgram(gl, false);
+ flushCache(gl);
disposeImpl(gl);
- st.destroy(gl);
- flushCache();
+ rs.destroy(gl);
initialized = false;
}
- public final ShaderState getShaderState() { return st; }
+ public final RenderState getRenderState() { return rs; }
+ public final ShaderState getShaderState() { return rs.getShaderState(); }
public final void enable(GL2ES2 gl, boolean enable) {
- st.glUseProgram(gl, enable);
+ rs.getShaderState().useProgram(gl, enable);
}
- public final PMVMatrix getMatrix() { return pmvMatrix; }
+ public float getSharpness() {
+ return rs.getSharpness().floatValue();
+ }
+
+ public void setSharpness(GL2ES2 gl, float v) {
+ rs.getSharpness().setData(v);
+ if(null != gl && rs.getShaderState().inUse()) {
+ rs.getShaderState().uniform(gl, rs.getSharpness());
+ }
+ }
- public void rotate(GL2ES2 gl, float angle, float x, float y, float z) {
- pmvMatrix.glRotatef(angle, x, y, z);
- if(initialized && null != gl && st.inUse()) {
- st.glUniform(gl, mgl_PMVMatrix);
+ public float getStrength() {
+ return rs.getStrength().floatValue();
+ }
+
+ public void setStrength(GL2ES2 gl, float v) {
+ rs.getStrength().setData(v);
+ if(null != gl && rs.getShaderState().inUse()) {
+ rs.getShaderState().uniform(gl, rs.getStrength());
}
}
+
+ public float getAlpha() {
+ return rs.getAlpha().floatValue();
+ }
- public void translate(GL2ES2 gl, float x, float y, float z) {
- pmvMatrix.glTranslatef(x, y, z);
- if(initialized && null != gl && st.inUse()) {
- st.glUniform(gl, mgl_PMVMatrix);
+ public void setAlpha(GL2ES2 gl, float alpha_t) {
+ rs.getAlpha().setData(alpha_t);
+ if(null != gl && rs.getShaderState().inUse()) {
+ rs.getShaderState().uniform(gl, rs.getAlpha());
}
+
}
- public void resetModelview(GL2ES2 gl) {
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
- if(initialized && null != gl && st.inUse()) {
- st.glUniform(gl, mgl_PMVMatrix);
+ public void getColorStatic(GL2ES2 gl, float[] rgb) {
+ FloatBuffer fb = (FloatBuffer) rs.getColorStatic().getBuffer();
+ rgb[0] = fb.get(0);
+ rgb[1] = fb.get(1);
+ rgb[2] = fb.get(2);
+ }
+
+ public void setColorStatic(GL2ES2 gl, float r, float g, float b){
+ FloatBuffer fb = (FloatBuffer) rs.getColorStatic().getBuffer();
+ fb.put(0, r);
+ fb.put(1, g);
+ fb.put(2, b);
+ if(null != gl && rs.getShaderState().inUse()) {
+ rs.getShaderState().uniform(gl, rs.getColorStatic());
}
}
+
+ public final PMVMatrix getMatrix() { return rs.pmvMatrix(); }
+
+ public void rotate(GL2ES2 gl, float angle, float x, float y, float z) {
+ rs.pmvMatrix().glRotatef(angle, x, y, z);
+ updateMatrix(gl);
+ }
+
+ public void translate(GL2ES2 gl, float x, float y, float z) {
+ rs.pmvMatrix().glTranslatef(x, y, z);
+ updateMatrix(gl);
+ }
+
+ public void scale(GL2ES2 gl, float x, float y, float z) {
+ rs.pmvMatrix().glScalef(x, y, z);
+ updateMatrix(gl);
+ }
+
+ public void resetModelview(GL2ES2 gl) {
+ rs.pmvMatrix().glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ rs.pmvMatrix().glLoadIdentity();
+ updateMatrix(gl);
+ }
public void updateMatrix(GL2ES2 gl) {
- if(initialized && null != gl && st.inUse()) {
- st.glUniform(gl, mgl_PMVMatrix);
+ if(initialized && null != gl && rs.getShaderState().inUse()) {
+ rs.getShaderState().uniform(gl, rs.getPMVMatrix());
}
}
public boolean reshapePerspective(GL2ES2 gl, float angle, int width, int height, float near, float far) {
this.vp_width = width;
this.vp_height = height;
- float ratio = (float)width/(float)height;
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.gluPerspective(angle, ratio, near, far);
-
- if(initialized && null != gl) {
- st.glUniform(gl, mgl_PMVMatrix);
- }
-
+ final float ratio = (float)width/(float)height;
+ final PMVMatrix p = rs.pmvMatrix();
+ p.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ p.glLoadIdentity();
+ p.gluPerspective(angle, ratio, near, far);
+ updateMatrix(gl);
return true;
}
public boolean reshapeOrtho(GL2ES2 gl, int width, int height, float near, float far) {
this.vp_width = width;
this.vp_height = height;
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glOrthof(0, width, 0, height, near, far);
-
- if(initialized && null != gl) {
- st.glUniform(gl, mgl_PMVMatrix);
- }
-
+ final PMVMatrix p = rs.pmvMatrix();
+ p.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ p.glLoadIdentity();
+ p.glOrthof(0, width, 0, height, near, far);
+ updateMatrix(gl);
return true;
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
index 45f78fc23..deaa1dfad 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
@@ -1,9 +1,37 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package com.jogamp.graph.curve.opengl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import jogamp.graph.curve.text.GlyphString;
@@ -12,21 +40,21 @@ import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
import com.jogamp.graph.font.Font;
-import com.jogamp.graph.geom.Vertex;
public abstract class TextRenderer extends Renderer {
-
/**
* Create a Hardware accelerated Text Renderer.
- * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory.
+ * @param rs the used {@link RenderState}
+ * @param renderType either {@link com.jogamp.graph.curve.Region#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#TWO_PASS}
*/
- public static TextRenderer create(Vertex.Factory<? extends Vertex> factory, int type) {
- return new jogamp.graph.curve.opengl.TextRendererImpl01(factory, type);
+ public static TextRenderer create(RenderState rs, int type) {
+ return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, type);
}
- protected TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) {
- super(factory, type);
+ protected TextRenderer(RenderState rs, int type) {
+ super(rs, type);
}
+
/** Render the String in 3D space wrt to the font provided at the position provided
* the outlines will be generated, if not yet generated
@@ -46,27 +74,29 @@ public abstract class TextRenderer extends Renderer {
* @param font {@link Font} to be used
* @param size font size
* @param str {@link String} to be created
- * @param sharpness parameter for Region generation of the resulting GlyphString
* @return the resulting GlyphString inclusive the generated region
*/
- protected GlyphString createString(GL2ES2 gl, Font font, int size, String str, float sharpness) {
- AffineTransform affineTransform = new AffineTransform(pointFactory);
+ public GlyphString createString(GL2ES2 gl, Font font, int size, String str) {
+ if(DEBUG_INSTANCE) {
+ System.err.println("createString: "+getCacheSize()+"/"+getCacheLimit()+" - "+Font.NAME_UNIQUNAME + " - " + str + " - " + size);
+ }
+ AffineTransform affineTransform = new AffineTransform(rs.getPointFactory());
Path2D[] paths = new Path2D[str.length()];
((FontInt)font).getOutline(str, size, affineTransform, paths);
- GlyphString glyphString = new GlyphString(pointFactory, font.getName(Font.NAME_UNIQUNAME), str);
- glyphString.createfromFontPath(paths, affineTransform);
- glyphString.generateRegion(gl.getContext(), sharpness, st, renderType);
+ GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str);
+ glyphString.createfromFontPath(rs.getPointFactory(), paths, affineTransform);
+ glyphString.generateRegion(gl, rs, renderType);
return glyphString;
}
- public void flushCache() {
+ public void flushCache(GL2ES2 gl) {
Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
while(iterator.hasNext()){
GlyphString glyphString = iterator.next();
- glyphString.destroy();
+ glyphString.destroy(gl, rs);
}
stringCacheMap.clear();
stringCacheArray.clear();
@@ -74,35 +104,90 @@ public abstract class TextRenderer extends Renderer {
@Override
protected void disposeImpl(GL2ES2 gl) {
- flushCache();
+ // fluchCache(gl) already called
}
- public final void setCacheMaxSize(int newSize ) { stringCacheMaxSize = newSize; validateCache(0); }
- public final int getCacheMaxSize() { return stringCacheMaxSize; }
+ /**
+ * <p>Sets the cache limit for reusing GlyphString's and their Region.
+ * Default is {@link #DEFAULT_CACHE_LIMIT}, -1 unlimited, 0 turns cache off, >0 limited </p>
+ *
+ * <p>The cache will be validate when the next string rendering happens.</p>
+ *
+ * @param newLimit new cache size
+ *
+ * @see #DEFAULT_CACHE_LIMIT
+ */
+ public final void setCacheLimit(int newLimit ) { stringCacheLimit = newLimit; }
+
+ /**
+ * Sets the cache limit, see {@link #setCacheLimit(int)} and validates the cache.
+ *
+ * @see #setCacheLimit(int)
+ *
+ * @param gl current GL used to remove cached objects if required
+ * @param newLimit new cache size
+ */
+ public final void setCacheLimit(GL2ES2 gl, int newLimit ) { stringCacheLimit = newLimit; validateCache(gl, 0); }
+
+ /**
+ * @return the current cache limit
+ */
+ public final int getCacheLimit() { return stringCacheLimit; }
+
+ /**
+ * @return the current utilized cache size, <= {@link #getCacheLimit()}
+ */
public final int getCacheSize() { return stringCacheArray.size(); }
- protected void validateCache(int space) {
- while ( getCacheSize() + space > getCacheMaxSize() ) {
- String key = stringCacheArray.remove(0);
- stringCacheMap.remove(key);
+ protected final void validateCache(GL2ES2 gl, int space) {
+ if ( getCacheLimit() > 0 ) {
+ while ( getCacheSize() + space > getCacheLimit() ) {
+ removeCachedGlyphString(gl, 0);
+ }
}
}
- protected GlyphString getCachedGlyphString(Font font, String str, int fontSize) {
- final String key = font.getName(Font.NAME_UNIQUNAME) + "." + str.hashCode() + "." + fontSize;
- return stringCacheMap.get(key);
+ protected final GlyphString getCachedGlyphString(Font font, String str, int fontSize) {
+ return stringCacheMap.get(getKey(font, str, fontSize));
}
- protected void addCachedGlyphString(Font font, String str, int fontSize, GlyphString glyphString) {
- final String key = font.getName(Font.NAME_UNIQUNAME) + "." + str.hashCode() + "." + fontSize;
- validateCache(1);
- stringCacheMap.put(key, glyphString);
- stringCacheArray.add(stringCacheArray.size(), key);
+ protected final void addCachedGlyphString(GL2ES2 gl, Font font, String str, int fontSize, GlyphString glyphString) {
+ if ( 0 != getCacheLimit() ) {
+ final String key = getKey(font, str, fontSize);
+ GlyphString oldGlyphString = stringCacheMap.put(key, glyphString);
+ if ( null == oldGlyphString ) {
+ // new entry ..
+ validateCache(gl, 1);
+ stringCacheArray.add(stringCacheArray.size(), key);
+ } /// else overwrite is nop ..
+ }
+ }
+
+ protected final void removeCachedGlyphString(GL2ES2 gl, Font font, String str, int fontSize) {
+ final String key = getKey(font, str, fontSize);
+ GlyphString glyphString = stringCacheMap.remove(key);
+ if(null != glyphString) {
+ glyphString.destroy(gl, rs);
+ }
+ stringCacheArray.remove(key);
+ }
+
+ protected final void removeCachedGlyphString(GL2ES2 gl, int idx) {
+ final String key = stringCacheArray.remove(idx);
+ final GlyphString glyphString = stringCacheMap.remove(key);
+ if(null != glyphString) {
+ glyphString.destroy(gl, rs);
+ }
+ }
+
+ protected final String getKey(Font font, String str, int fontSize) {
+ return font.getName(Font.NAME_UNIQUNAME) + "." + str.hashCode() + "." + fontSize;
}
- // Cache is adding at the end of the array
- public static final int DEFAULT_CACHE_SIZE = 32;
- private HashMap<String, GlyphString> stringCacheMap = new HashMap<String, GlyphString>(DEFAULT_CACHE_SIZE);
- private ArrayList<String> stringCacheArray = new ArrayList<String>(DEFAULT_CACHE_SIZE);
- private int stringCacheMaxSize = DEFAULT_CACHE_SIZE; // -1 unlimited, 0 off, >0 limited
+ /** Default cache limit, see {@link #setCacheLimit(int)} */
+ public static final int DEFAULT_CACHE_LIMIT = 256;
+
+ private HashMap<String, GlyphString> stringCacheMap = new HashMap<String, GlyphString>(DEFAULT_CACHE_LIMIT);
+ private ArrayList<String> stringCacheArray = new ArrayList<String>(DEFAULT_CACHE_LIMIT);
+ private int stringCacheLimit = DEFAULT_CACHE_LIMIT;
} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java
index a2e4ca50f..42eebf7a8 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java
@@ -48,169 +48,169 @@ import jogamp.opengl.Debug;
*/
public class CDTriangulator2D {
- protected static final boolean DEBUG = Debug.debug("Triangulation");
-
- private float sharpness = 0.5f;
- private ArrayList<Loop> loops;
- private ArrayList<Vertex> vertices;
-
- private ArrayList<Triangle> triangles;
- private int maxTriID = 0;
+ protected static final boolean DEBUG = Debug.debug("Triangulation");
+
+ private float sharpness = 0.5f;
+ private ArrayList<Loop> loops;
+ private ArrayList<Vertex> vertices;
+
+ private ArrayList<Triangle> triangles;
+ private int maxTriID = 0;
-
- public CDTriangulator2D() {
- this(0.5f);
- }
-
- /** Constructor for a new Delaunay triangulator
- * @param curveSharpness the curvature around
- * the off-curve vertices
- */
- public CDTriangulator2D(float curveSharpness) {
- this.sharpness = curveSharpness;
- reset();
- }
-
- /** Reset the triangulation to initial state
- * Clearing cached data
- */
- public void reset() {
- maxTriID = 0;
- vertices = new ArrayList<Vertex>();
- triangles = new ArrayList<Triangle>(3);
- loops = new ArrayList<Loop>();
- }
-
- /** Add a curve to the list of profiles provided
- * @param polyline a bounding {@link Outline}
- */
- public void addCurve(Outline polyline){
- Loop loop = null;
-
- if(!loops.isEmpty()){
- loop = getContainerLoop(polyline);
- }
-
- if(loop == null) {
- GraphOutline outline = new GraphOutline(polyline);
- GraphOutline innerPoly = extractBoundaryTriangles(outline, false);
- vertices.addAll(polyline.getVertices());
- loop = new Loop(innerPoly, VectorUtil.CCW);
- loops.add(loop);
- }
- else {
- GraphOutline outline = new GraphOutline(polyline);
- GraphOutline innerPoly = extractBoundaryTriangles(outline, true);
- vertices.addAll(innerPoly.getPoints());
- loop.addConstraintCurve(innerPoly);
- }
- }
-
- /** Generate the triangulation of the provided
- * List of {@link Outline}s
- */
- public ArrayList<Triangle> generateTriangulation(){
- for(int i=0;i<loops.size();i++) {
- Loop loop = loops.get(i);
- int numTries = 0;
- int size = loop.computeLoopSize();
- while(!loop.isSimplex()){
- Triangle tri = null;
- if(numTries > size){
- tri = loop.cut(false);
- }
- else{
- tri = loop.cut(true);
- }
- numTries++;
+
+ public CDTriangulator2D() {
+ this(0.5f);
+ }
+
+ /** Constructor for a new Delaunay triangulator
+ * @param curveSharpness the curvature around
+ * the off-curve vertices
+ */
+ public CDTriangulator2D(float curveSharpness) {
+ this.sharpness = curveSharpness;
+ reset();
+ }
+
+ /** Reset the triangulation to initial state
+ * Clearing cached data
+ */
+ public void reset() {
+ maxTriID = 0;
+ vertices = new ArrayList<Vertex>();
+ triangles = new ArrayList<Triangle>(3);
+ loops = new ArrayList<Loop>();
+ }
+
+ /** Add a curve to the list of profiles provided
+ * @param polyline a bounding {@link Outline}
+ */
+ public void addCurve(Outline polyline){
+ Loop loop = null;
+
+ if(!loops.isEmpty()){
+ loop = getContainerLoop(polyline);
+ }
+
+ if(loop == null) {
+ GraphOutline outline = new GraphOutline(polyline);
+ GraphOutline innerPoly = extractBoundaryTriangles(outline, false);
+ vertices.addAll(polyline.getVertices());
+ loop = new Loop(innerPoly, VectorUtil.CCW);
+ loops.add(loop);
+ }
+ else {
+ GraphOutline outline = new GraphOutline(polyline);
+ GraphOutline innerPoly = extractBoundaryTriangles(outline, true);
+ vertices.addAll(innerPoly.getPoints());
+ loop.addConstraintCurve(innerPoly);
+ }
+ }
+
+ /** Generate the triangulation of the provided
+ * List of {@link Outline}s
+ */
+ public ArrayList<Triangle> generateTriangulation(){
+ for(int i=0;i<loops.size();i++) {
+ Loop loop = loops.get(i);
+ int numTries = 0;
+ int size = loop.computeLoopSize();
+ while(!loop.isSimplex()){
+ Triangle tri = null;
+ if(numTries > size){
+ tri = loop.cut(false);
+ }
+ else{
+ tri = loop.cut(true);
+ }
+ numTries++;
- if(tri != null) {
- numTries = 0;
- size--;
- tri.setId(maxTriID++);
- triangles.add(tri);
- if(DEBUG){
- System.err.println(tri);
- }
- }
- if(numTries > size*2){
- if(DEBUG){
- System.err.println("Triangulation not complete!");
- }
- break;
- }
- }
- Triangle tri = loop.cut(true);
- if(tri != null)
- triangles.add(tri);
- }
- return triangles;
- }
+ if(tri != null) {
+ numTries = 0;
+ size--;
+ tri.setId(maxTriID++);
+ triangles.add(tri);
+ if(DEBUG){
+ System.err.println(tri);
+ }
+ }
+ if(numTries > size*2){
+ if(DEBUG){
+ System.err.println("Triangulation not complete!");
+ }
+ break;
+ }
+ }
+ Triangle tri = loop.cut(true);
+ if(tri != null)
+ triangles.add(tri);
+ }
+ return triangles;
+ }
- private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole){
- GraphOutline innerOutline = new GraphOutline();
- ArrayList<GraphVertex> outVertices = outline.getGraphPoint();
- int size = outVertices.size();
- for(int i=0; i < size; i++) {
- GraphVertex currentVertex = outVertices.get(i);
- GraphVertex gv0 = outVertices.get((i+size-1)%size);
- GraphVertex gv2 = outVertices.get((i+1)%size);
- GraphVertex gv1 = currentVertex;
-
- if(!currentVertex.getPoint().isOnCurve()) {
- Vertex v0 = gv0.getPoint().clone();
- Vertex v2 = gv2.getPoint().clone();
- Vertex v1 = gv1.getPoint().clone();
-
- gv0.setBoundaryContained(true);
- gv1.setBoundaryContained(true);
- gv2.setBoundaryContained(true);
-
- Triangle t= null;
- boolean holeLike = false;
- if(VectorUtil.ccw(v0,v1,v2)){
- t = new Triangle(v0, v1, v2);
- }
- else {
- holeLike = true;
- t = new Triangle(v2, v1, v0);
- }
- t.setId(maxTriID++);
- triangles.add(t);
- if(DEBUG){
- System.err.println(t);
- }
- if(hole || holeLike) {
- v0.setTexCoord(0, -0.1f);
- v2.setTexCoord(1, -0.1f);
- v1.setTexCoord(0.5f, -1*sharpness -0.1f);
- innerOutline.addVertex(currentVertex);
- }
- else {
- v0.setTexCoord(0, 0.1f);
- v2.setTexCoord(1, 0.1f);
- v1.setTexCoord(0.5f, sharpness+0.1f);
- }
- }
- else {
- if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){
- currentVertex.setBoundaryContained(true);
- }
- innerOutline.addVertex(currentVertex);
- }
- }
- return innerOutline;
- }
-
- private Loop getContainerLoop(Outline polyline){
- ArrayList<Vertex> vertices = polyline.getVertices();
- for(Vertex vert: vertices){
- for (Loop loop:loops){
- if(loop.checkInside(vert)){
- return loop;
- }
- }
- }
- return null;
- }
+ private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole){
+ GraphOutline innerOutline = new GraphOutline();
+ ArrayList<GraphVertex> outVertices = outline.getGraphPoint();
+ int size = outVertices.size();
+ for(int i=0; i < size; i++) {
+ GraphVertex currentVertex = outVertices.get(i);
+ GraphVertex gv0 = outVertices.get((i+size-1)%size);
+ GraphVertex gv2 = outVertices.get((i+1)%size);
+ GraphVertex gv1 = currentVertex;
+
+ if(!currentVertex.getPoint().isOnCurve()) {
+ Vertex v0 = gv0.getPoint().clone();
+ Vertex v2 = gv2.getPoint().clone();
+ Vertex v1 = gv1.getPoint().clone();
+
+ gv0.setBoundaryContained(true);
+ gv1.setBoundaryContained(true);
+ gv2.setBoundaryContained(true);
+
+ Triangle t= null;
+ boolean holeLike = false;
+ if(VectorUtil.ccw(v0,v1,v2)){
+ t = new Triangle(v0, v1, v2);
+ }
+ else {
+ holeLike = true;
+ t = new Triangle(v2, v1, v0);
+ }
+ t.setId(maxTriID++);
+ triangles.add(t);
+ if(DEBUG){
+ System.err.println(t);
+ }
+ if(hole || holeLike) {
+ v0.setTexCoord(0, -0.1f);
+ v2.setTexCoord(1, -0.1f);
+ v1.setTexCoord(0.5f, -1*sharpness -0.1f);
+ innerOutline.addVertex(currentVertex);
+ }
+ else {
+ v0.setTexCoord(0, 0.1f);
+ v2.setTexCoord(1, 0.1f);
+ v1.setTexCoord(0.5f, sharpness+0.1f);
+ }
+ }
+ else {
+ if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){
+ currentVertex.setBoundaryContained(true);
+ }
+ innerOutline.addVertex(currentVertex);
+ }
+ }
+ return innerOutline;
+ }
+
+ private Loop getContainerLoop(Outline polyline){
+ ArrayList<Vertex> vertices = polyline.getVertices();
+ for(Vertex vert: vertices){
+ for (Loop loop:loops){
+ if(loop.checkInside(vert)){
+ return loop;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java
index d8c30c61b..1010d4f1a 100644
--- a/src/jogl/classes/com/jogamp/graph/font/Font.java
+++ b/src/jogl/classes/com/jogamp/graph/font/Font.java
@@ -52,27 +52,27 @@ public interface Font {
public static final int NAME_DESIGNER = 9;
- /**
- * Metrics for font
- *
- * Depending on the font's direction, horizontal or vertical,
- * the following tables shall be used:
- *
- * Vertical http://developer.apple.com/fonts/TTRefMan/RM06/Chap6vhea.html
+ /**
+ * Metrics for font
+ *
+ * Depending on the font's direction, horizontal or vertical,
+ * the following tables shall be used:
+ *
+ * Vertical http://developer.apple.com/fonts/TTRefMan/RM06/Chap6vhea.html
* Horizontal http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html
- */
+ */
public interface Metrics {
- float getAscent(float pixelSize);
- float getDescent(float pixelSize);
- float getLineGap(float pixelSize);
- float getMaxExtend(float pixelSize);
- float getScale(float pixelSize);
- AABBox getBBox(float pixelSize);
+ float getAscent(float pixelSize);
+ float getDescent(float pixelSize);
+ float getLineGap(float pixelSize);
+ float getMaxExtend(float pixelSize);
+ float getScale(float pixelSize);
+ AABBox getBBox(float pixelSize);
}
- /**
- * Glyph for font
- */
+ /**
+ * Glyph for font
+ */
public interface Glyph {
public Font getFont();
public char getSymbol();
diff --git a/src/jogl/classes/com/jogamp/graph/geom/AABBox.java b/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
index 8cd06329e..7051e9110 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/AABBox.java
@@ -36,176 +36,181 @@ import com.jogamp.graph.math.VectorUtil;
*
*/
public class AABBox {
- private float[] low = {Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE};
- private float[] high = {-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE};
- private float[] center = new float[3];
+ private float[] low = new float[3];
+ private float[] high = new float[3];
+ private float[] center = new float[3];
- /** Create a Axis Aligned bounding box (AABBox)
- * where the low and and high MAX float Values.
- */
- public AABBox() {}
+ /** Create a Axis Aligned bounding box (AABBox)
+ * where the low and and high MAX float Values.
+ */
+ public AABBox() {
+ reset();
+ }
- /** Create an AABBox specifying the coordinates
- * of the low and high
- * @param lx min x-coordinate
- * @param ly min y-coordnate
- * @param lz min z-coordinate
- * @param hx max x-coordinate
- * @param hy max y-coordinate
- * @param hz max z-coordinate
- */
- public AABBox(float lx, float ly, float lz,
- float hx, float hy, float hz)
- {
- setLow(lx, ly, lz);
- setHigh(hx, hy, hz);
+ /** Create an AABBox specifying the coordinates
+ * of the low and high
+ * @param lx min x-coordinate
+ * @param ly min y-coordnate
+ * @param lz min z-coordinate
+ * @param hx max x-coordinate
+ * @param hy max y-coordinate
+ * @param hz max z-coordinate
+ */
+ public AABBox(float lx, float ly, float lz,
+ float hx, float hy, float hz)
+ {
+ reset();
+ resize(lx, ly, lz);
+ resize(hx, hy, hz);
- computeCenter();
- }
-
- /** Create a AABBox defining the low and high
- * @param low min xyz-coordinates
- * @param high max xyz-coordinates
- */
- public AABBox(float[] low, float[] high)
- {
- this.low = low;
- this.high = high;
+ computeCenter();
+ }
+
+ /** Create a AABBox defining the low and high
+ * @param low min xyz-coordinates
+ * @param high max xyz-coordinates
+ */
+ public AABBox(float[] low, float[] high) {
+ reset();
+ resize(low[0],low[1],low[2]);
+ resize(high[0],high[1],high[2]);
- computeCenter();
- }
-
- /** Get the max xyz-coordinates
- * @return a float array containing the max xyz coordinates
- */
- public float[] getHigh()
- {
- return high;
- }
-
- private void setHigh(float hx, float hy, float hz)
- {
- this.high[0] = hx;
- this.high[1] = hy;
- this.high[2] = hz;
- }
-
- /** Get the min xyz-coordinates
- * @return a float array containing the min xyz coordinates
- */
- public float[] getLow()
- {
- return low;
- }
-
- private void setLow(float lx, float ly, float lz)
- {
- this.low[0] = lx;
- this.low[1] = ly;
- this.low[2] = lz;
- }
+ computeCenter();
+ }
+
+ /** resets this box to the inverse low/high, allowing the next {@link #resize(float, float, float)} command to hit. */
+ public void reset() {
+ setLow(Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE);
+ setHigh(-1*Float.MAX_VALUE,-1*Float.MAX_VALUE,-1*Float.MAX_VALUE);
+ center[0] = 0f;
+ center[1] = 0f;
+ center[2] = 0f;
+ }
+
+ /** Get the max xyz-coordinates
+ * @return a float array containing the max xyz coordinates
+ */
+ public float[] getHigh() {
+ return high;
+ }
+
+ private void setHigh(float hx, float hy, float hz) {
+ this.high[0] = hx;
+ this.high[1] = hy;
+ this.high[2] = hz;
+ }
+
+ /** Get the min xyz-coordinates
+ * @return a float array containing the min xyz coordinates
+ */
+ public float[] getLow() {
+ return low;
+ }
+
+ private void setLow(float lx, float ly, float lz) {
+ this.low[0] = lx;
+ this.low[1] = ly;
+ this.low[2] = lz;
+ }
- /** Resize the AABBox to encapsulate another AABox
- * @param newBox AABBox to be encapsulated in
- */
- public void resize(AABBox newBox)
- {
- float[] newLow = newBox.getLow();
- float[] newHigh = newBox.getHigh();
+ /** Resize the AABBox to encapsulate another AABox
+ * @param newBox AABBox to be encapsulated in
+ */
+ public void resize(AABBox newBox) {
+ float[] newLow = newBox.getLow();
+ float[] newHigh = newBox.getHigh();
- /** test low */
- if (newLow[0] < low[0])
- low[0] = newLow[0];
- if (newLow[1] < low[1])
- low[1] = newLow[1];
- if (newLow[2] < low[2])
- low[2] = newLow[2];
+ /** test low */
+ if (newLow[0] < low[0])
+ low[0] = newLow[0];
+ if (newLow[1] < low[1])
+ low[1] = newLow[1];
+ if (newLow[2] < low[2])
+ low[2] = newLow[2];
- /** test high */
- if (newHigh[0] > high[0])
- high[0] = newHigh[0];
- if (newHigh[1] > high[1])
- high[1] = newHigh[1];
- if (newHigh[2] > high[2])
- high[2] = newHigh[2];
+ /** test high */
+ if (newHigh[0] > high[0])
+ high[0] = newHigh[0];
+ if (newHigh[1] > high[1])
+ high[1] = newHigh[1];
+ if (newHigh[2] > high[2])
+ high[2] = newHigh[2];
- computeCenter();
- }
+ computeCenter();
+ }
- private void computeCenter()
- {
- center[0] = (high[0] + low[0])/2;
- center[1] = (high[1] + low[1])/2;
- center[2] = (high[2] + low[2])/2;
- }
+ private void computeCenter() {
+ center[0] = (high[0] + low[0])/2;
+ center[1] = (high[1] + low[1])/2;
+ center[2] = (high[2] + low[2])/2;
+ }
- /** Resize the AABBox to encapsulate the passed
- * xyz-coordinates.
- * @param x x-axis coordinate value
- * @param y y-axis coordinate value
- * @param z z-axis coordinate value
- */
- public void resize(float x, float y, float z)
- {
- /** test low */
- if (x < low[0])
- low[0] = x;
- if (y < low[1])
- low[1] = y;
- if (z < low[2])
- low[2] = z;
+ /** Resize the AABBox to encapsulate the passed
+ * xyz-coordinates.
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @param z z-axis coordinate value
+ */
+ public void resize(float x, float y, float z) {
+ /** test low */
+ if (x < low[0])
+ low[0] = x;
+ if (y < low[1])
+ low[1] = y;
+ if (z < low[2])
+ low[2] = z;
- /** test high */
- if (x > high[0])
- high[0] = x;
- if (y > high[1])
- high[1] = y;
- if (z > high[2])
- high[2] = z;
-
- computeCenter();
- }
+ /** test high */
+ if (x > high[0])
+ high[0] = x;
+ if (y > high[1])
+ high[1] = y;
+ if (z > high[2])
+ high[2] = z;
+
+ computeCenter();
+ }
- /** Check if the x & y coordinates are bounded/contained
- * by this AABBox
- * @param x x-axis coordinate value
- * @param y y-axis coordinate value
- * @return true if x belong to (low.x, high.x) and
- * y belong to (low.y, high.y)
- */
- public boolean contains(float x, float y){
- if(x<low[0] || x>high[0]){
- return false;
- }
- if(y<low[1]|| y>high[1]){
- return false;
- }
- return true;
- }
-
- /** Check if the xyz coordinates are bounded/contained
- * by this AABBox.
- * @param x x-axis coordinate value
- * @param y y-axis coordinate value
- * @param z z-axis coordinate value
- * @return true if x belong to (low.x, high.x) and
- * y belong to (low.y, high.y) and z belong to (low.z, high.z)
- */
- public boolean contains(float x, float y, float z){
- if(x<low[0] || x>high[0]){
- return false;
- }
- if(y<low[1]|| y>high[1]){
- return false;
- }
- if(z<low[2] || z>high[2]){
- return false;
- }
- return true;
- }
-
+ /** Check if the x & y coordinates are bounded/contained
+ * by this AABBox
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @return true if x belong to (low.x, high.x) and
+ * y belong to (low.y, high.y)
+ */
+ public boolean contains(float x, float y) {
+ if(x<low[0] || x>high[0]){
+ return false;
+ }
+ if(y<low[1]|| y>high[1]){
+ return false;
+ }
+ return true;
+ }
+
+ /** Check if the xyz coordinates are bounded/contained
+ * by this AABBox.
+ * @param x x-axis coordinate value
+ * @param y y-axis coordinate value
+ * @param z z-axis coordinate value
+ * @return true if x belong to (low.x, high.x) and
+ * y belong to (low.y, high.y) and z belong to (low.z, high.z)
+ */
+ public boolean contains(float x, float y, float z) {
+ if(x<low[0] || x>high[0]){
+ return false;
+ }
+ if(y<low[1]|| y>high[1]){
+ return false;
+ }
+ if(z<low[2] || z>high[2]){
+ return false;
+ }
+ return true;
+ }
+
/** Check if there is a common region between this AABBox and the passed
- * 2D region irrespective of z range
+ * 2D region irrespective of z range
* @param x lower left x-coord
* @param y lower left y-coord
* @param w width
@@ -213,87 +218,87 @@ public class AABBox {
* @return true if this AABBox might have a common region with this 2D region
*/
public boolean intersects(float x, float y, float w, float h) {
- if (w <= 0 || h <= 0) {
- return false;
- }
-
- final float _w = getWidth();
- final float _h = getHeight();
- if (_w <= 0 || _h <= 0) {
- return false;
- }
-
- final float x0 = getMinX();
- final float y0 = getMinY();
- return (x + w > x0 &&
- y + h > y0 &&
- x < x0 + _w &&
- y < y0 + _h);
+ if (w <= 0 || h <= 0) {
+ return false;
+ }
+
+ final float _w = getWidth();
+ final float _h = getHeight();
+ if (_w <= 0 || _h <= 0) {
+ return false;
+ }
+
+ final float x0 = getMinX();
+ final float y0 = getMinY();
+ return (x + w > x0 &&
+ y + h > y0 &&
+ x < x0 + _w &&
+ y < y0 + _h);
}
-
- /** Get the size of the Box where the size is represented by the
- * length of the vector between low and high.
- * @return a float representing the size of the AABBox
- */
- public float getSize(){
- return VectorUtil.computeLength(low, high);
- }
+
+ /** Get the size of the Box where the size is represented by the
+ * length of the vector between low and high.
+ * @return a float representing the size of the AABBox
+ */
+ public float getSize() {
+ return VectorUtil.computeLength(low, high);
+ }
- /**Get the Center of the AABBox
- * @return the xyz-coordinates of the center of the AABBox
- */
- public float[] getCenter() {
- return center;
- }
+ /**Get the Center of the AABBox
+ * @return the xyz-coordinates of the center of the AABBox
+ */
+ public float[] getCenter() {
+ return center;
+ }
- /** Scale the AABBox by a constant
- * @param size a constant float value
- */
- public void scale(float size) {
- float[] diffH = new float[3];
- diffH[0] = high[0] - center[0];
- diffH[1] = high[1] - center[1];
- diffH[2] = high[2] - center[2];
-
- diffH = VectorUtil.scale(diffH, size);
-
- float[] diffL = new float[3];
- diffL[0] = low[0] - center[0];
- diffL[1] = low[1] - center[1];
- diffL[2] = low[2] - center[2];
-
- diffL = VectorUtil.scale(diffL, size);
-
- high = VectorUtil.vectorAdd(center, diffH);
- low = VectorUtil.vectorAdd(center, diffL);
- }
+ /** Scale the AABBox by a constant
+ * @param size a constant float value
+ */
+ public void scale(float size) {
+ float[] diffH = new float[3];
+ diffH[0] = high[0] - center[0];
+ diffH[1] = high[1] - center[1];
+ diffH[2] = high[2] - center[2];
+
+ diffH = VectorUtil.scale(diffH, size);
+
+ float[] diffL = new float[3];
+ diffL[0] = low[0] - center[0];
+ diffL[1] = low[1] - center[1];
+ diffL[2] = low[2] - center[2];
+
+ diffL = VectorUtil.scale(diffL, size);
+
+ high = VectorUtil.vectorAdd(center, diffH);
+ low = VectorUtil.vectorAdd(center, diffL);
+ }
- public float getMinX() {
- return low[0];
- }
-
- public float getMinY() {
- return low[1];
- }
-
- public float getWidth(){
- return high[0] - low[0];
- }
-
- public float getHeight() {
- return high[1] - low[1];
- }
-
- public float getDepth() {
- return high[2] - low[2];
- }
- public AABBox clone(){
- return new AABBox(this.low, this.high);
- }
-
- public String toString() {
- return "[ "+low[0]+"/"+low[1]+"/"+low[1]+" .. "+high[0]+"/"+high[0]+"/"+high[0]+", ctr "+
- center[0]+"/"+center[1]+"/"+center[1]+" ]";
- }
+ public float getMinX() {
+ return low[0];
+ }
+
+ public float getMinY() {
+ return low[1];
+ }
+
+ public float getWidth(){
+ return high[0] - low[0];
+ }
+
+ public float getHeight() {
+ return high[1] - low[1];
+ }
+
+ public float getDepth() {
+ return high[2] - low[2];
+ }
+ public AABBox clone() {
+ return new AABBox(this.low, this.high);
+ }
+
+ public String toString() {
+ return "[ "+low[0]+"/"+low[1]+"/"+low[1]+" .. "+high[0]+"/"+high[0]+"/"+high[0]+", ctr "+
+ center[0]+"/"+center[1]+"/"+center[1]+" ]";
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
index a805adf6c..315be002f 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
@@ -44,133 +44,133 @@ import com.jogamp.graph.math.VectorUtil;
* @see OutlineShape, Region
*/
public class Outline implements Comparable<Outline> {
-
- private ArrayList<Vertex> vertices = new ArrayList<Vertex>(3);
- private boolean closed = false;
- private AABBox box = new AABBox();
-
- /**Create an outline defined by control vertices.
- * An outline can contain off Curve vertices which define curved
- * regions in the outline.
- */
- public Outline(){
-
- }
-
- /** Add a vertex to the outline. The {@link Vertex} is added at the
- * end of the outline loop/strip.
- * @param vertex Vertex to be added
- */
- public final void addVertex(Vertex vertex) {
- vertices.add(vertex);
- box.resize(vertex.getX(), vertex.getY(), vertex.getZ());
- }
-
- /** Add a {@link Vertex} by specifying its 2D attributes to the outline.
- * The {@link Vertex} is added at the
- * end of the outline loop/strip.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param x the x coordinate
- * @param y the y coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, boolean onCurve) {
- addVertex(factory, x, y, 0f, onCurve);
- }
-
- /** Add a {@link Vertex} by specifying its 3D attributes to the outline.
- * The {@link Vertex} is added at the
- * end of the outline loop/strip.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param x the x coordinate
- * @param y the y coordinate
- * @param z the z coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, float z, boolean onCurve) {
- Vertex v = factory.create(x, y, z);
- v.setOnCurve(onCurve);
- addVertex(v);
- }
-
- /** Add a vertex to the outline by passing a float array and specifying the
- * offset and length in which. The attributes of the vertex are located.
- * The attributes should be continuous (stride = 0).
- * Attributes which value are not set (when length less than 3)
- * are set implicitly to zero.
- * @param factory a {@link Factory} to get the required Vertex impl
- * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
- * @param offset the offset in the buffer to the x coordinate
- * @param length the number of attributes to pick from the buffer (maximum 3)
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(Vertex.Factory<? extends Vertex> factory, float[] coordsBuffer, int offset, int length, boolean onCurve) {
- Vertex v = factory.create(coordsBuffer, offset, length);
- v.setOnCurve(onCurve);
- addVertex(v);
- }
-
- public Vertex getVertex(int index){
- return vertices.get(index);
- }
-
- public boolean isEmpty(){
- return (vertices.size() == 0);
- }
- public Vertex getLastVertex(){
- if(isEmpty()){
- return null;
- }
- return vertices.get(vertices.size()-1);
- }
-
- public ArrayList<Vertex> getVertices() {
- return vertices;
- }
- public void setVertices(ArrayList<Vertex> vertices) {
- this.vertices = vertices;
- }
- public AABBox getBox() {
- return box;
- }
- public boolean isClosed() {
- return closed;
- }
-
- /** define if this outline is closed or not.
- * if set to closed, checks if the last vertex is
- * equal to the first vertex. If not Equal adds a
- * vertex at the end to the list.
- * @param closed
- */
- public void setClosed(boolean closed) {
- this.closed = closed;
- if(closed){
- Vertex first = vertices.get(0);
- Vertex last = getLastVertex();
- if(!VectorUtil.checkEquality(first.getCoord(), last.getCoord())){
- Vertex v = first.clone();
- vertices.add(v);
- }
- }
- }
-
- /** Compare two outlines with Bounding Box area
- * as criteria.
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- public int compareTo(Outline outline) {
- float size = box.getSize();
- float newSize = outline.getBox().getSize();
- if(size < newSize){
- return -1;
- }
- else if(size > newSize){
- return 1;
- }
- return 0;
- }
+
+ private ArrayList<Vertex> vertices = new ArrayList<Vertex>(3);
+ private boolean closed = false;
+ private AABBox box = new AABBox();
+
+ /**Create an outline defined by control vertices.
+ * An outline can contain off Curve vertices which define curved
+ * regions in the outline.
+ */
+ public Outline(){
+
+ }
+
+ /** Add a vertex to the outline. The {@link Vertex} is added at the
+ * end of the outline loop/strip.
+ * @param vertex Vertex to be added
+ */
+ public final void addVertex(Vertex vertex) {
+ vertices.add(vertex);
+ box.resize(vertex.getX(), vertex.getY(), vertex.getZ());
+ }
+
+ /** Add a {@link Vertex} by specifying its 2D attributes to the outline.
+ * The {@link Vertex} is added at the
+ * end of the outline loop/strip.
+ * @param factory a {@link Factory} to get the required Vertex impl
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, boolean onCurve) {
+ addVertex(factory, x, y, 0f, onCurve);
+ }
+
+ /** Add a {@link Vertex} by specifying its 3D attributes to the outline.
+ * The {@link Vertex} is added at the
+ * end of the outline loop/strip.
+ * @param factory a {@link Factory} to get the required Vertex impl
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z coordinate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(Vertex.Factory<? extends Vertex> factory, float x, float y, float z, boolean onCurve) {
+ Vertex v = factory.create(x, y, z);
+ v.setOnCurve(onCurve);
+ addVertex(v);
+ }
+
+ /** Add a vertex to the outline by passing a float array and specifying the
+ * offset and length in which. The attributes of the vertex are located.
+ * The attributes should be continuous (stride = 0).
+ * Attributes which value are not set (when length less than 3)
+ * are set implicitly to zero.
+ * @param factory a {@link Factory} to get the required Vertex impl
+ * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
+ * @param offset the offset in the buffer to the x coordinate
+ * @param length the number of attributes to pick from the buffer (maximum 3)
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(Vertex.Factory<? extends Vertex> factory, float[] coordsBuffer, int offset, int length, boolean onCurve) {
+ Vertex v = factory.create(coordsBuffer, offset, length);
+ v.setOnCurve(onCurve);
+ addVertex(v);
+ }
+
+ public Vertex getVertex(int index){
+ return vertices.get(index);
+ }
+
+ public boolean isEmpty(){
+ return (vertices.size() == 0);
+ }
+ public Vertex getLastVertex(){
+ if(isEmpty()){
+ return null;
+ }
+ return vertices.get(vertices.size()-1);
+ }
+
+ public ArrayList<Vertex> getVertices() {
+ return vertices;
+ }
+ public void setVertices(ArrayList<Vertex> vertices) {
+ this.vertices = vertices;
+ }
+ public AABBox getBox() {
+ return box;
+ }
+ public boolean isClosed() {
+ return closed;
+ }
+
+ /** define if this outline is closed or not.
+ * if set to closed, checks if the last vertex is
+ * equal to the first vertex. If not Equal adds a
+ * vertex at the end to the list.
+ * @param closed
+ */
+ public void setClosed(boolean closed) {
+ this.closed = closed;
+ if(closed){
+ Vertex first = vertices.get(0);
+ Vertex last = getLastVertex();
+ if(!VectorUtil.checkEquality(first.getCoord(), last.getCoord())){
+ Vertex v = first.clone();
+ vertices.add(v);
+ }
+ }
+ }
+
+ /** Compare two outlines with Bounding Box area
+ * as criteria.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Outline outline) {
+ float size = box.getSize();
+ float newSize = outline.getBox().getSize();
+ if(size < newSize){
+ return -1;
+ }
+ else if(size > newSize){
+ return 1;
+ }
+ return 0;
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java
index d13e8ddb1..fb34de221 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java
@@ -28,52 +28,52 @@
package com.jogamp.graph.geom;
public class Triangle {
- private int id = Integer.MAX_VALUE;
- final private Vertex[] vertices;
- private boolean[] boundaryEdges = new boolean[3];
- private boolean[] boundaryVertices = null;
+ private int id = Integer.MAX_VALUE;
+ final private Vertex[] vertices;
+ private boolean[] boundaryEdges = new boolean[3];
+ private boolean[] boundaryVertices = null;
- public Triangle(Vertex ... v123){
- vertices = v123;
- }
+ public Triangle(Vertex ... v123){
+ vertices = v123;
+ }
- public int getId() {
- return id;
- }
+ public int getId() {
+ return id;
+ }
- public void setId(int id) {
- this.id = id;
- }
+ public void setId(int id) {
+ this.id = id;
+ }
- public Vertex[] getVertices() {
- return vertices;
- }
-
- public boolean isEdgesBoundary() {
- return boundaryEdges[0] || boundaryEdges[1] || boundaryEdges[2];
- }
-
- public boolean isVerticesBoundary() {
- return boundaryVertices[0] || boundaryVertices[1] || boundaryVertices[2];
- }
+ public Vertex[] getVertices() {
+ return vertices;
+ }
+
+ public boolean isEdgesBoundary() {
+ return boundaryEdges[0] || boundaryEdges[1] || boundaryEdges[2];
+ }
+
+ public boolean isVerticesBoundary() {
+ return boundaryVertices[0] || boundaryVertices[1] || boundaryVertices[2];
+ }
- public void setEdgesBoundary(boolean[] boundary) {
- this.boundaryEdges = boundary;
- }
-
- public boolean[] getEdgeBoundary() {
- return boundaryEdges;
- }
-
- public boolean[] getVerticesBoundary() {
- return boundaryVertices;
- }
+ public void setEdgesBoundary(boolean[] boundary) {
+ this.boundaryEdges = boundary;
+ }
+
+ public boolean[] getEdgeBoundary() {
+ return boundaryEdges;
+ }
+
+ public boolean[] getVerticesBoundary() {
+ return boundaryVertices;
+ }
- public void setVerticesBoundary(boolean[] boundaryVertices) {
- this.boundaryVertices = boundaryVertices;
- }
-
- public String toString() {
- return "Tri ID: " + id + "\n" + vertices[0] + "\n" + vertices[1] + "\n" + vertices[2];
- }
+ public void setVerticesBoundary(boolean[] boundaryVertices) {
+ this.boundaryVertices = boundaryVertices;
+ }
+
+ public String toString() {
+ return "Tri ID: " + id + "\n" + vertices[0] + "\n" + vertices[1] + "\n" + vertices[2];
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
index 0e4e5e8df..859add943 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java
@@ -32,49 +32,49 @@ package com.jogamp.graph.geom;
*/
public interface Vertex extends Comparable<Vertex>, Cloneable {
- public static interface Factory <T extends Vertex> {
- T create();
+ public static interface Factory <T extends Vertex> {
+ T create();
- T create(float x, float y);
+ T create(float x, float y);
- T create(float x, float y, float z);
+ T create(float x, float y, float z);
- T create(float[] coordsBuffer, int offset, int length);
- }
-
- void setCoord(float x, float y);
+ T create(float[] coordsBuffer, int offset, int length);
+ }
+
+ void setCoord(float x, float y);
- void setCoord(float x, float y, float z);
+ void setCoord(float x, float y, float z);
- void setCoord(float[] coordsBuffer, int offset, int length);
-
- float[] getCoord();
+ void setCoord(float[] coordsBuffer, int offset, int length);
+
+ float[] getCoord();
- void setX(float x);
+ void setX(float x);
- void setY(float y);
+ void setY(float y);
- void setZ(float z);
+ void setZ(float z);
- float getX();
+ float getX();
- float getY();
+ float getY();
- float getZ();
+ float getZ();
- boolean isOnCurve();
+ boolean isOnCurve();
- void setOnCurve(boolean onCurve);
+ void setOnCurve(boolean onCurve);
- int getId();
-
- void setId(int id);
-
- int compareTo(Vertex p);
-
- float[] getTexCoord();
-
- void setTexCoord(float s, float t);
-
- Vertex clone();
+ int getId();
+
+ void setId(int id);
+
+ int compareTo(Vertex p);
+
+ float[] getTexCoord();
+
+ void setTexCoord(float s, float t);
+
+ Vertex clone();
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java b/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
index 681067e40..6241d60df 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/opengl/SVertex.java
@@ -36,143 +36,143 @@ import com.jogamp.graph.math.VectorUtil;
*
*/
public class SVertex implements Vertex {
- private int id = Integer.MAX_VALUE;
- protected float[] coord = new float[3];
- protected boolean onCurve = true;
- private float[] texCoord = new float[2];
-
- static final Factory factory = new Factory();
-
- public static Factory factory() { return factory; }
-
- public static class Factory implements Vertex.Factory<SVertex> {
- @Override
- public SVertex create() {
- return new SVertex();
- }
-
- @Override
- public SVertex create(float x, float y) {
- return new SVertex(x, y);
- }
-
- @Override
- public SVertex create(float x, float y, float z) {
- return new SVertex(x, y, z);
- }
-
- @Override
- public SVertex create(float[] coordsBuffer, int offset, int length) {
- return new SVertex(coordsBuffer, offset, length);
- }
- }
-
- public SVertex() {
- }
-
- public SVertex(float x, float y) {
- setCoord(x, y);
- }
- public SVertex(float x, float y, float z) {
- setCoord(x, y, z);
- }
- public SVertex(float[] coordsBuffer, int offset, int length) {
- setCoord(coordsBuffer, offset, length);
- }
-
- public void setCoord(float x, float y) {
- this.coord[0] = x;
- this.coord[1] = y;
- this.coord[2] = 0f;
- }
-
- public void setCoord(float x, float y, float z) {
- this.coord[0] = x;
- this.coord[1] = y;
- this.coord[2] = z;
- }
-
- public void setCoord(float[] coordsBuffer, int offset, int length) {
- if(length > coordsBuffer.length - offset) {
- throw new IndexOutOfBoundsException("coordsBuffer too small: "+coordsBuffer.length+" - "+offset+" < "+length);
- }
- if(length > 3) {
- throw new IndexOutOfBoundsException("length too big: "+length+" > "+3);
- }
- int i=0;
- while(i<length) {
- this.coord[i++] = coordsBuffer[offset++];
- }
- }
-
- public float[] getCoord() {
- return coord;
- }
-
- public void setX(float x) {
- this.coord[0] = x;
- }
-
- public void setY(float y) {
- this.coord[1] = y;
- }
-
- public void setZ(float z) {
- this.coord[2] = z;
- }
-
- public float getX() {
- return this.coord[0];
- }
-
- public float getY() {
- return this.coord[1];
- }
-
- public float getZ() {
- return this.coord[2];
- }
-
- public boolean isOnCurve() {
- return onCurve;
- }
-
- public void setOnCurve(boolean onCurve) {
- this.onCurve = onCurve;
- }
-
- public int getId(){
- return id;
- }
-
- public void setId(int id){
- this.id = id;
- }
-
- public int compareTo(Vertex p) {
- if(VectorUtil.checkEquality(coord, p.getCoord())) {
- return 0;
- }
- return -1;
- }
-
- public float[] getTexCoord() {
- return texCoord;
- }
-
- public void setTexCoord(float s, float t) {
- this.texCoord[0] = s;
- this.texCoord[1] = t;
- }
-
- public SVertex clone(){
- SVertex v = new SVertex(this.coord, 0, 3);
- v.setOnCurve(this.onCurve);
- return v;
- }
-
- public String toString() {
- return "[ID: " + id + " X: " + coord[0]
- + " Y: " + coord[1] + " Z: " + coord[2] + "]";
- }
+ private int id = Integer.MAX_VALUE;
+ protected float[] coord = new float[3];
+ protected boolean onCurve = true;
+ private float[] texCoord = new float[2];
+
+ static final Factory factory = new Factory();
+
+ public static Factory factory() { return factory; }
+
+ public static class Factory implements Vertex.Factory<SVertex> {
+ @Override
+ public SVertex create() {
+ return new SVertex();
+ }
+
+ @Override
+ public SVertex create(float x, float y) {
+ return new SVertex(x, y);
+ }
+
+ @Override
+ public SVertex create(float x, float y, float z) {
+ return new SVertex(x, y, z);
+ }
+
+ @Override
+ public SVertex create(float[] coordsBuffer, int offset, int length) {
+ return new SVertex(coordsBuffer, offset, length);
+ }
+ }
+
+ public SVertex() {
+ }
+
+ public SVertex(float x, float y) {
+ setCoord(x, y);
+ }
+ public SVertex(float x, float y, float z) {
+ setCoord(x, y, z);
+ }
+ public SVertex(float[] coordsBuffer, int offset, int length) {
+ setCoord(coordsBuffer, offset, length);
+ }
+
+ public void setCoord(float x, float y) {
+ this.coord[0] = x;
+ this.coord[1] = y;
+ this.coord[2] = 0f;
+ }
+
+ public void setCoord(float x, float y, float z) {
+ this.coord[0] = x;
+ this.coord[1] = y;
+ this.coord[2] = z;
+ }
+
+ public void setCoord(float[] coordsBuffer, int offset, int length) {
+ if(length > coordsBuffer.length - offset) {
+ throw new IndexOutOfBoundsException("coordsBuffer too small: "+coordsBuffer.length+" - "+offset+" < "+length);
+ }
+ if(length > 3) {
+ throw new IndexOutOfBoundsException("length too big: "+length+" > "+3);
+ }
+ int i=0;
+ while(i<length) {
+ this.coord[i++] = coordsBuffer[offset++];
+ }
+ }
+
+ public float[] getCoord() {
+ return coord;
+ }
+
+ public void setX(float x) {
+ this.coord[0] = x;
+ }
+
+ public void setY(float y) {
+ this.coord[1] = y;
+ }
+
+ public void setZ(float z) {
+ this.coord[2] = z;
+ }
+
+ public float getX() {
+ return this.coord[0];
+ }
+
+ public float getY() {
+ return this.coord[1];
+ }
+
+ public float getZ() {
+ return this.coord[2];
+ }
+
+ public boolean isOnCurve() {
+ return onCurve;
+ }
+
+ public void setOnCurve(boolean onCurve) {
+ this.onCurve = onCurve;
+ }
+
+ public int getId(){
+ return id;
+ }
+
+ public void setId(int id){
+ this.id = id;
+ }
+
+ public int compareTo(Vertex p) {
+ if(VectorUtil.checkEquality(coord, p.getCoord())) {
+ return 0;
+ }
+ return -1;
+ }
+
+ public float[] getTexCoord() {
+ return texCoord;
+ }
+
+ public void setTexCoord(float s, float t) {
+ this.texCoord[0] = s;
+ this.texCoord[1] = t;
+ }
+
+ public SVertex clone(){
+ SVertex v = new SVertex(this.coord, 0, 3);
+ v.setOnCurve(this.onCurve);
+ return v;
+ }
+
+ public String toString() {
+ return "[ID: " + id + " X: " + coord[0]
+ + " Y: " + coord[1] + " Z: " + coord[2] + "]";
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/math/Quaternion.java b/src/jogl/classes/com/jogamp/graph/math/Quaternion.java
index b77a5fa08..38638dc5a 100755
--- a/src/jogl/classes/com/jogamp/graph/math/Quaternion.java
+++ b/src/jogl/classes/com/jogamp/graph/math/Quaternion.java
@@ -30,353 +30,353 @@ package com.jogamp.graph.math;
import jogamp.graph.math.MathFloat;
public class Quaternion {
- protected float x,y,z,w;
+ protected float x,y,z,w;
- public Quaternion(){
+ public Quaternion(){
- }
-
- public Quaternion(float x, float y, float z, float w) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- }
-
- /** Constructor to create a rotation based quaternion from two vectors
- * @param vector1
- * @param vector2
- */
- public Quaternion(float[] vector1, float[] vector2)
- {
- float theta = (float)MathFloat.acos(dot(vector1, vector2));
- float[] cross = cross(vector1,vector2);
- cross = normalizeVec(cross);
+ }
+
+ public Quaternion(float x, float y, float z, float w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ /** Constructor to create a rotation based quaternion from two vectors
+ * @param vector1
+ * @param vector2
+ */
+ public Quaternion(float[] vector1, float[] vector2)
+ {
+ float theta = (float)MathFloat.acos(dot(vector1, vector2));
+ float[] cross = cross(vector1,vector2);
+ cross = normalizeVec(cross);
- this.x = (float)MathFloat.sin(theta/2)*cross[0];
- this.y = (float)MathFloat.sin(theta/2)*cross[1];
- this.z = (float)MathFloat.sin(theta/2)*cross[2];
- this.w = (float)MathFloat.cos(theta/2);
- this.normalize();
- }
-
- /** Transform the rotational quaternion to axis based rotation angles
- * @return new float[4] with ,theta,Rx,Ry,Rz
- */
- public float[] toAxis()
- {
- float[] vec = new float[4];
- float scale = (float)MathFloat.sqrt(x * x + y * y + z * z);
- vec[0] =(float) MathFloat.acos(w) * 2.0f;
- vec[1] = x / scale;
- vec[2] = y / scale;
- vec[3] = z / scale;
- return vec;
- }
-
- /** Normalize a vector
- * @param vector input vector
- * @return normalized vector
- */
- private float[] normalizeVec(float[] vector)
- {
- float[] newVector = new float[3];
+ this.x = (float)MathFloat.sin(theta/2)*cross[0];
+ this.y = (float)MathFloat.sin(theta/2)*cross[1];
+ this.z = (float)MathFloat.sin(theta/2)*cross[2];
+ this.w = (float)MathFloat.cos(theta/2);
+ this.normalize();
+ }
+
+ /** Transform the rotational quaternion to axis based rotation angles
+ * @return new float[4] with ,theta,Rx,Ry,Rz
+ */
+ public float[] toAxis()
+ {
+ float[] vec = new float[4];
+ float scale = (float)MathFloat.sqrt(x * x + y * y + z * z);
+ vec[0] =(float) MathFloat.acos(w) * 2.0f;
+ vec[1] = x / scale;
+ vec[2] = y / scale;
+ vec[3] = z / scale;
+ return vec;
+ }
+
+ /** Normalize a vector
+ * @param vector input vector
+ * @return normalized vector
+ */
+ private float[] normalizeVec(float[] vector)
+ {
+ float[] newVector = new float[3];
- float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
- if(d> 0.0f)
- {
- newVector[0] = vector[0]/d;
- newVector[1] = vector[1]/d;
- newVector[2] = vector[2]/d;
- }
- return newVector;
- }
- /** compute the dot product of two points
- * @param vec1 vector 1
- * @param vec2 vector 2
- * @return the dot product as float
- */
- private float dot(float[] vec1, float[] vec2)
- {
- return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
- }
- /** cross product vec1 x vec2
- * @param vec1 vector 1
- * @param vec2 vecttor 2
- * @return the resulting vector
- */
- private float[] cross(float[] vec1, float[] vec2)
- {
- float[] out = new float[3];
+ float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
+ if(d> 0.0f)
+ {
+ newVector[0] = vector[0]/d;
+ newVector[1] = vector[1]/d;
+ newVector[2] = vector[2]/d;
+ }
+ return newVector;
+ }
+ /** compute the dot product of two points
+ * @param vec1 vector 1
+ * @param vec2 vector 2
+ * @return the dot product as float
+ */
+ private float dot(float[] vec1, float[] vec2)
+ {
+ return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
+ }
+ /** cross product vec1 x vec2
+ * @param vec1 vector 1
+ * @param vec2 vecttor 2
+ * @return the resulting vector
+ */
+ private float[] cross(float[] vec1, float[] vec2)
+ {
+ float[] out = new float[3];
- out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
- out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
- out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
+ out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
+ out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
+ out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
- return out;
- }
- public float getW() {
- return w;
- }
- public void setW(float w) {
- this.w = w;
- }
- public float getX() {
- return x;
- }
- public void setX(float x) {
- this.x = x;
- }
- public float getY() {
- return y;
- }
- public void setY(float y) {
- this.y = y;
- }
- public float getZ() {
- return z;
- }
- public void setZ(float z) {
- this.z = z;
- }
+ return out;
+ }
+ public float getW() {
+ return w;
+ }
+ public void setW(float w) {
+ this.w = w;
+ }
+ public float getX() {
+ return x;
+ }
+ public void setX(float x) {
+ this.x = x;
+ }
+ public float getY() {
+ return y;
+ }
+ public void setY(float y) {
+ this.y = y;
+ }
+ public float getZ() {
+ return z;
+ }
+ public void setZ(float z) {
+ this.z = z;
+ }
- /** Add a quaternion
- * @param q quaternion
- */
- public void add(Quaternion q)
- {
- x+=q.x;
- y+=q.y;
- z+=q.z;
- }
-
- /** Subtract a quaternion
- * @param q quaternion
- */
- public void subtract(Quaternion q)
- {
- x-=q.x;
- y-=q.y;
- z-=q.z;
- }
-
- /** Divide a quaternion by a constant
- * @param n a float to divide by
- */
- public void divide(float n)
- {
- x/=n;
- y/=n;
- z/=n;
- }
-
- /** Multiply this quaternion by
- * the param quaternion
- * @param q a quaternion to multiply with
- */
- public void mult(Quaternion q)
- {
- float w1 = w*q.w - (x*q.x + y*q.y + z*q.z);
+ /** Add a quaternion
+ * @param q quaternion
+ */
+ public void add(Quaternion q)
+ {
+ x+=q.x;
+ y+=q.y;
+ z+=q.z;
+ }
+
+ /** Subtract a quaternion
+ * @param q quaternion
+ */
+ public void subtract(Quaternion q)
+ {
+ x-=q.x;
+ y-=q.y;
+ z-=q.z;
+ }
+
+ /** Divide a quaternion by a constant
+ * @param n a float to divide by
+ */
+ public void divide(float n)
+ {
+ x/=n;
+ y/=n;
+ z/=n;
+ }
+
+ /** Multiply this quaternion by
+ * the param quaternion
+ * @param q a quaternion to multiply with
+ */
+ public void mult(Quaternion q)
+ {
+ float w1 = w*q.w - (x*q.x + y*q.y + z*q.z);
- float x1 = w*q.z + q.w*z + y*q.z - z*q.y;
- float y1 = w*q.x + q.w*x + z*q.x - x*q.z;
- float z1 = w*q.y + q.w*y + x*q.y - y*q.x;
+ float x1 = w*q.z + q.w*z + y*q.z - z*q.y;
+ float y1 = w*q.x + q.w*x + z*q.x - x*q.z;
+ float z1 = w*q.y + q.w*y + x*q.y - y*q.x;
- w = w1;
- x = x1;
- y = y1;
- z = z1;
- }
-
- /** Multiply a quaternion by a constant
- * @param n a float constant
- */
- public void mult(float n)
- {
- x*=n;
- y*=n;
- z*=n;
- }
-
- /** Normalize a quaternion required if
- * to be used as a rotational quaternion
- */
- public void normalize()
- {
- float norme = (float)MathFloat.sqrt(w*w + x*x + y*y + z*z);
- if (norme == 0.0f)
- {
- w = 1.0f;
- x = y = z = 0.0f;
- }
- else
- {
- float recip = 1.0f/norme;
+ w = w1;
+ x = x1;
+ y = y1;
+ z = z1;
+ }
+
+ /** Multiply a quaternion by a constant
+ * @param n a float constant
+ */
+ public void mult(float n)
+ {
+ x*=n;
+ y*=n;
+ z*=n;
+ }
+
+ /** Normalize a quaternion required if
+ * to be used as a rotational quaternion
+ */
+ public void normalize()
+ {
+ float norme = (float)MathFloat.sqrt(w*w + x*x + y*y + z*z);
+ if (norme == 0.0f)
+ {
+ w = 1.0f;
+ x = y = z = 0.0f;
+ }
+ else
+ {
+ float recip = 1.0f/norme;
- w *= recip;
- x *= recip;
- y *= recip;
- z *= recip;
- }
- }
-
- /** Invert the quaternion If rotational,
- * will produce a the inverse rotation
- */
- public void inverse()
- {
- float norm = w*w + x*x + y*y + z*z;
+ w *= recip;
+ x *= recip;
+ y *= recip;
+ z *= recip;
+ }
+ }
+
+ /** Invert the quaternion If rotational,
+ * will produce a the inverse rotation
+ */
+ public void inverse()
+ {
+ float norm = w*w + x*x + y*y + z*z;
- float recip = 1.0f/norm;
+ float recip = 1.0f/norm;
- w *= recip;
- x = -1*x*recip;
- y = -1*y*recip;
- z = -1*z*recip;
- }
-
- /** Transform this quaternion to a
- * 4x4 column matrix representing the rotation
- * @return new float[16] column matrix 4x4
- */
- public float[] toMatrix()
- {
- float[] matrix = new float[16];
- matrix[0] = 1.0f - 2*y*y - 2*z*z;
- matrix[1] = 2*x*y + 2*w*z;
- matrix[2] = 2*x*z - 2*w*y;
- matrix[3] = 0;
+ w *= recip;
+ x = -1*x*recip;
+ y = -1*y*recip;
+ z = -1*z*recip;
+ }
+
+ /** Transform this quaternion to a
+ * 4x4 column matrix representing the rotation
+ * @return new float[16] column matrix 4x4
+ */
+ public float[] toMatrix()
+ {
+ float[] matrix = new float[16];
+ matrix[0] = 1.0f - 2*y*y - 2*z*z;
+ matrix[1] = 2*x*y + 2*w*z;
+ matrix[2] = 2*x*z - 2*w*y;
+ matrix[3] = 0;
- matrix[4] = 2*x*y - 2*w*z;
- matrix[5] = 1.0f - 2*x*x - 2*z*z;
- matrix[6] = 2*y*z + 2*w*x;
- matrix[7] = 0;
+ matrix[4] = 2*x*y - 2*w*z;
+ matrix[5] = 1.0f - 2*x*x - 2*z*z;
+ matrix[6] = 2*y*z + 2*w*x;
+ matrix[7] = 0;
- matrix[8] = 2*x*z + 2*w*y;
- matrix[9] = 2*y*z - 2*w*x;
- matrix[10] = 1.0f - 2*x*x - 2*y*y;
- matrix[11] = 0;
+ matrix[8] = 2*x*z + 2*w*y;
+ matrix[9] = 2*y*z - 2*w*x;
+ matrix[10] = 1.0f - 2*x*x - 2*y*y;
+ matrix[11] = 0;
- matrix[12] = 0;
- matrix[13] = 0;
- matrix[14] = 0;
- matrix[15] = 1;
- return matrix;
- }
-
- /** Set this quaternion from a Sphereical interpolation
- * of two param quaternion, used mostly for rotational animation
- * @param a initial quaternion
- * @param b target quaternion
- * @param t float between 0 and 1 representing interp.
- */
- public void slerp(Quaternion a,Quaternion b, float t)
- {
- float omega, cosom, sinom, sclp, sclq;
- cosom = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
- if ((1.0f+cosom) > MathFloat.E) {
- if ((1.0f-cosom) > MathFloat.E) {
- omega = (float)MathFloat.acos(cosom);
- sinom = (float)MathFloat.sin(omega);
- sclp = (float)MathFloat.sin((1.0f-t)*omega) / sinom;
- sclq = (float)MathFloat.sin(t*omega) / sinom;
- }
- else {
- sclp = 1.0f - t;
- sclq = t;
- }
- x = sclp*a.x + sclq*b.x;
- y = sclp*a.y + sclq*b.y;
- z = sclp*a.z + sclq*b.z;
- w = sclp*a.w + sclq*b.w;
- }
- else {
- x =-a.y;
- y = a.x;
- z =-a.w;
- w = a.z;
- sclp = MathFloat.sin((1.0f-t) * MathFloat.PI * 0.5f);
- sclq = MathFloat.sin(t * MathFloat.PI * 0.5f);
- x = sclp*a.x + sclq*b.x;
- y = sclp*a.y + sclq*b.y;
- z = sclp*a.z + sclq*b.z;
- }
- }
-
- /** Check if this quaternion is empty, ie (0,0,0,1)
- * @return true if empty, false otherwise
- */
- public boolean isEmpty()
- {
- if (w==1 && x==0 && y==0 && z==0)
- return true;
- return false;
- }
-
- /** Check if this quaternion represents an identity
- * matrix, for rotation.
- * @return true if it is an identity rep., false otherwise
- */
- public boolean isIdentity()
- {
- if (w==0 && x==0 && y==0 && z==0)
- return true;
- return false;
- }
-
- /** compute the quaternion from a 3x3 column matrix
- * @param m 3x3 column matrix
- */
- public void setFromMatrix(float[] m) {
- float T= m[0] + m[4] + m[8] + 1;
- if (T>0){
- float S = 0.5f / (float)MathFloat.sqrt(T);
- w = 0.25f / S;
- x = ( m[5] - m[7]) * S;
- y = ( m[6] - m[2]) * S;
- z = ( m[1] - m[3] ) * S;
- }
- else{
- if ((m[0] > m[4])&(m[0] > m[8])) {
- float S = MathFloat.sqrt( 1.0f + m[0] - m[4] - m[8] ) * 2f; // S=4*qx
- w = (m[7] - m[5]) / S;
- x = 0.25f * S;
- y = (m[3] + m[1]) / S;
- z = (m[6] + m[2]) / S;
- }
- else if (m[4] > m[8]) {
- float S = MathFloat.sqrt( 1.0f + m[4] - m[0] - m[8] ) * 2f; // S=4*qy
- w = (m[6] - m[2]) / S;
- x = (m[3] + m[1]) / S;
- y = 0.25f * S;
- z = (m[7] + m[5]) / S;
- }
- else {
- float S = MathFloat.sqrt( 1.0f + m[8] - m[0] - m[4] ) * 2f; // S=4*qz
- w = (m[3] - m[1]) / S;
- x = (m[6] + m[2]) / S;
- y = (m[7] + m[5]) / S;
- z = 0.25f * S;
- }
- }
- }
-
- /** Check if the the 3x3 matrix (param) is in fact
- * an affine rotational matrix
- * @param m 3x3 column matrix
- * @return true if representing a rotational matrix, false otherwise
- */
- public boolean isRotationMatrix(float[] m) {
- double epsilon = 0.01; // margin to allow for rounding errors
- if (MathFloat.abs(m[0]*m[3] + m[3]*m[4] + m[6]*m[7]) > epsilon) return false;
- if (MathFloat.abs(m[0]*m[2] + m[3]*m[5] + m[6]*m[8]) > epsilon) return false;
- if (MathFloat.abs(m[1]*m[2] + m[4]*m[5] + m[7]*m[8]) > epsilon) return false;
- if (MathFloat.abs(m[0]*m[0] + m[3]*m[3] + m[6]*m[6] - 1) > epsilon) return false;
- if (MathFloat.abs(m[1]*m[1] + m[4]*m[4] + m[7]*m[7] - 1) > epsilon) return false;
- if (MathFloat.abs(m[2]*m[2] + m[5]*m[5] + m[8]*m[8] - 1) > epsilon) return false;
- return (MathFloat.abs(determinant(m)-1) < epsilon);
- }
- private float determinant(float[] m) {
- return m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[0]*m[7]*m[5] - m[3]*m[1]*m[8] - m[6]*m[4]*m[2];
- }
+ matrix[12] = 0;
+ matrix[13] = 0;
+ matrix[14] = 0;
+ matrix[15] = 1;
+ return matrix;
+ }
+
+ /** Set this quaternion from a Sphereical interpolation
+ * of two param quaternion, used mostly for rotational animation
+ * @param a initial quaternion
+ * @param b target quaternion
+ * @param t float between 0 and 1 representing interp.
+ */
+ public void slerp(Quaternion a,Quaternion b, float t)
+ {
+ float omega, cosom, sinom, sclp, sclq;
+ cosom = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
+ if ((1.0f+cosom) > MathFloat.E) {
+ if ((1.0f-cosom) > MathFloat.E) {
+ omega = (float)MathFloat.acos(cosom);
+ sinom = (float)MathFloat.sin(omega);
+ sclp = (float)MathFloat.sin((1.0f-t)*omega) / sinom;
+ sclq = (float)MathFloat.sin(t*omega) / sinom;
+ }
+ else {
+ sclp = 1.0f - t;
+ sclq = t;
+ }
+ x = sclp*a.x + sclq*b.x;
+ y = sclp*a.y + sclq*b.y;
+ z = sclp*a.z + sclq*b.z;
+ w = sclp*a.w + sclq*b.w;
+ }
+ else {
+ x =-a.y;
+ y = a.x;
+ z =-a.w;
+ w = a.z;
+ sclp = MathFloat.sin((1.0f-t) * MathFloat.PI * 0.5f);
+ sclq = MathFloat.sin(t * MathFloat.PI * 0.5f);
+ x = sclp*a.x + sclq*b.x;
+ y = sclp*a.y + sclq*b.y;
+ z = sclp*a.z + sclq*b.z;
+ }
+ }
+
+ /** Check if this quaternion is empty, ie (0,0,0,1)
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty()
+ {
+ if (w==1 && x==0 && y==0 && z==0)
+ return true;
+ return false;
+ }
+
+ /** Check if this quaternion represents an identity
+ * matrix, for rotation.
+ * @return true if it is an identity rep., false otherwise
+ */
+ public boolean isIdentity()
+ {
+ if (w==0 && x==0 && y==0 && z==0)
+ return true;
+ return false;
+ }
+
+ /** compute the quaternion from a 3x3 column matrix
+ * @param m 3x3 column matrix
+ */
+ public void setFromMatrix(float[] m) {
+ float T= m[0] + m[4] + m[8] + 1;
+ if (T>0){
+ float S = 0.5f / (float)MathFloat.sqrt(T);
+ w = 0.25f / S;
+ x = ( m[5] - m[7]) * S;
+ y = ( m[6] - m[2]) * S;
+ z = ( m[1] - m[3] ) * S;
+ }
+ else{
+ if ((m[0] > m[4])&(m[0] > m[8])) {
+ float S = MathFloat.sqrt( 1.0f + m[0] - m[4] - m[8] ) * 2f; // S=4*qx
+ w = (m[7] - m[5]) / S;
+ x = 0.25f * S;
+ y = (m[3] + m[1]) / S;
+ z = (m[6] + m[2]) / S;
+ }
+ else if (m[4] > m[8]) {
+ float S = MathFloat.sqrt( 1.0f + m[4] - m[0] - m[8] ) * 2f; // S=4*qy
+ w = (m[6] - m[2]) / S;
+ x = (m[3] + m[1]) / S;
+ y = 0.25f * S;
+ z = (m[7] + m[5]) / S;
+ }
+ else {
+ float S = MathFloat.sqrt( 1.0f + m[8] - m[0] - m[4] ) * 2f; // S=4*qz
+ w = (m[3] - m[1]) / S;
+ x = (m[6] + m[2]) / S;
+ y = (m[7] + m[5]) / S;
+ z = 0.25f * S;
+ }
+ }
+ }
+
+ /** Check if the the 3x3 matrix (param) is in fact
+ * an affine rotational matrix
+ * @param m 3x3 column matrix
+ * @return true if representing a rotational matrix, false otherwise
+ */
+ public boolean isRotationMatrix(float[] m) {
+ double epsilon = 0.01; // margin to allow for rounding errors
+ if (MathFloat.abs(m[0]*m[3] + m[3]*m[4] + m[6]*m[7]) > epsilon) return false;
+ if (MathFloat.abs(m[0]*m[2] + m[3]*m[5] + m[6]*m[8]) > epsilon) return false;
+ if (MathFloat.abs(m[1]*m[2] + m[4]*m[5] + m[7]*m[8]) > epsilon) return false;
+ if (MathFloat.abs(m[0]*m[0] + m[3]*m[3] + m[6]*m[6] - 1) > epsilon) return false;
+ if (MathFloat.abs(m[1]*m[1] + m[4]*m[4] + m[7]*m[7] - 1) > epsilon) return false;
+ if (MathFloat.abs(m[2]*m[2] + m[5]*m[5] + m[8]*m[8] - 1) > epsilon) return false;
+ return (MathFloat.abs(determinant(m)-1) < epsilon);
+ }
+ private float determinant(float[] m) {
+ return m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[0]*m[7]*m[5] - m[3]*m[1]*m[8] - m[6]*m[4]*m[2];
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java b/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
index cca9a454f..7cbb742e5 100755
--- a/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/math/VectorUtil.java
@@ -35,261 +35,261 @@ import com.jogamp.graph.geom.Vertex;
public class VectorUtil {
- public static final int CW = -1;
- public static final int CCW = 1;
- public static final int COLLINEAR = 0;
+ public static final int CW = -1;
+ public static final int CCW = 1;
+ public static final int COLLINEAR = 0;
- /** compute the dot product of two points
- * @param vec1 vector 1
- * @param vec2 vector 2
- * @return the dot product as float
- */
- public static float dot(float[] vec1, float[] vec2)
- {
- return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
- }
- /** Normalize a vector
- * @param vector input vector
- * @return normalized vector
- */
- public static float[] normalize(float[] vector)
- {
- float[] newVector = new float[3];
+ /** compute the dot product of two points
+ * @param vec1 vector 1
+ * @param vec2 vector 2
+ * @return the dot product as float
+ */
+ public static float dot(float[] vec1, float[] vec2)
+ {
+ return (vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2]);
+ }
+ /** Normalize a vector
+ * @param vector input vector
+ * @return normalized vector
+ */
+ public static float[] normalize(float[] vector)
+ {
+ float[] newVector = new float[3];
- float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
- if(d> 0.0f)
- {
- newVector[0] = vector[0]/d;
- newVector[1] = vector[1]/d;
- newVector[2] = vector[2]/d;
- }
- return newVector;
- }
+ float d = MathFloat.sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
+ if(d> 0.0f)
+ {
+ newVector[0] = vector[0]/d;
+ newVector[1] = vector[1]/d;
+ newVector[2] = vector[2]/d;
+ }
+ return newVector;
+ }
- /** Scales a vector by param
- * @param vector input vector
- * @param scale constant to scale by
- * @return scaled vector
- */
- public static float[] scale(float[] vector, float scale)
- {
- float[] newVector = new float[3];
+ /** Scales a vector by param
+ * @param vector input vector
+ * @param scale constant to scale by
+ * @return scaled vector
+ */
+ public static float[] scale(float[] vector, float scale)
+ {
+ float[] newVector = new float[3];
- newVector[0] = vector[0]*scale;
- newVector[1] = vector[1]*scale;
- newVector[2] = vector[2]*scale;
- return newVector;
- }
-
- /** Adds to vectors
- * @param v1 vector 1
- * @param v2 vector 2
- * @return v1 + v2
- */
- public static float[] vectorAdd(float[] v1, float[] v2)
- {
- float[] newVector = new float[3];
+ newVector[0] = vector[0]*scale;
+ newVector[1] = vector[1]*scale;
+ newVector[2] = vector[2]*scale;
+ return newVector;
+ }
+
+ /** Adds to vectors
+ * @param v1 vector 1
+ * @param v2 vector 2
+ * @return v1 + v2
+ */
+ public static float[] vectorAdd(float[] v1, float[] v2)
+ {
+ float[] newVector = new float[3];
- newVector[0] = v1[0] + v2[0];
- newVector[1] = v1[1] + v2[1];
- newVector[2] = v1[2] + v2[2];
- return newVector;
- }
+ newVector[0] = v1[0] + v2[0];
+ newVector[1] = v1[1] + v2[1];
+ newVector[2] = v1[2] + v2[2];
+ return newVector;
+ }
- /** cross product vec1 x vec2
- * @param vec1 vector 1
- * @param vec2 vecttor 2
- * @return the resulting vector
- */
- public static float[] cross(float[] vec1, float[] vec2)
- {
- float[] out = new float[3];
+ /** cross product vec1 x vec2
+ * @param vec1 vector 1
+ * @param vec2 vecttor 2
+ * @return the resulting vector
+ */
+ public static float[] cross(float[] vec1, float[] vec2)
+ {
+ float[] out = new float[3];
- out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
- out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
- out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
+ out[0] = vec2[2]*vec1[1] - vec2[1]*vec1[2];
+ out[1] = vec2[0]*vec1[2] - vec2[2]*vec1[0];
+ out[2] = vec2[1]*vec1[0] - vec2[0]*vec1[1];
- return out;
- }
+ return out;
+ }
- /** Column Matrix Vector multiplication
- * @param colMatrix column matrix (4x4)
- * @param vec vector(x,y,z)
- * @return result new float[3]
- */
- public static float[] colMatrixVectorMult(float[] colMatrix, float[] vec)
- {
- float[] out = new float[3];
+ /** Column Matrix Vector multiplication
+ * @param colMatrix column matrix (4x4)
+ * @param vec vector(x,y,z)
+ * @return result new float[3]
+ */
+ public static float[] colMatrixVectorMult(float[] colMatrix, float[] vec)
+ {
+ float[] out = new float[3];
- out[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12];
- out[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13];
- out[2] = vec[0]*colMatrix[2] + vec[1]*colMatrix[6] + vec[2]*colMatrix[10] + colMatrix[14];
+ out[0] = vec[0]*colMatrix[0] + vec[1]*colMatrix[4] + vec[2]*colMatrix[8] + colMatrix[12];
+ out[1] = vec[0]*colMatrix[1] + vec[1]*colMatrix[5] + vec[2]*colMatrix[9] + colMatrix[13];
+ out[2] = vec[0]*colMatrix[2] + vec[1]*colMatrix[6] + vec[2]*colMatrix[10] + colMatrix[14];
- return out;
- }
-
- /** Matrix Vector multiplication
- * @param rawMatrix column matrix (4x4)
- * @param vec vector(x,y,z)
- * @return result new float[3]
- */
- public static float[] rowMatrixVectorMult(float[] rawMatrix, float[] vec)
- {
- float[] out = new float[3];
+ return out;
+ }
+
+ /** Matrix Vector multiplication
+ * @param rawMatrix column matrix (4x4)
+ * @param vec vector(x,y,z)
+ * @return result new float[3]
+ */
+ public static float[] rowMatrixVectorMult(float[] rawMatrix, float[] vec)
+ {
+ float[] out = new float[3];
- out[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3];
- out[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7];
- out[2] = vec[0]*rawMatrix[8] + vec[1]*rawMatrix[9] + vec[2]*rawMatrix[10] + rawMatrix[11];
+ out[0] = vec[0]*rawMatrix[0] + vec[1]*rawMatrix[1] + vec[2]*rawMatrix[2] + rawMatrix[3];
+ out[1] = vec[0]*rawMatrix[4] + vec[1]*rawMatrix[5] + vec[2]*rawMatrix[6] + rawMatrix[7];
+ out[2] = vec[0]*rawMatrix[8] + vec[1]*rawMatrix[9] + vec[2]*rawMatrix[10] + rawMatrix[11];
- return out;
- }
-
- /** Calculate the midpoint of two values
- * @param p1 first value
- * @param p2 second vale
- * @return midpoint
- */
- public static float mid(float p1, float p2)
- {
- return (p1+p2)/2.0f;
- }
- /** Calculate the midpoint of two points
- * @param p1 first point
- * @param p2 second point
- * @return midpoint
- */
- public static float[] mid(float[] p1, float[] p2)
- {
- float[] midPoint = new float[3];
- midPoint[0] = (p1[0] + p2[0])/2.0f;
- midPoint[1] = (p1[1] + p2[1])/2.0f;
- midPoint[2] = (p1[2] + p2[2])/2.0f;
+ return out;
+ }
+
+ /** Calculate the midpoint of two values
+ * @param p1 first value
+ * @param p2 second vale
+ * @return midpoint
+ */
+ public static float mid(float p1, float p2)
+ {
+ return (p1+p2)/2.0f;
+ }
+ /** Calculate the midpoint of two points
+ * @param p1 first point
+ * @param p2 second point
+ * @return midpoint
+ */
+ public static float[] mid(float[] p1, float[] p2)
+ {
+ float[] midPoint = new float[3];
+ midPoint[0] = (p1[0] + p2[0])/2.0f;
+ midPoint[1] = (p1[1] + p2[1])/2.0f;
+ midPoint[2] = (p1[2] + p2[2])/2.0f;
- return midPoint;
- }
- /** Compute the norm of a vector
- * @param vec vector
- * @return vorm
- */
- public static float norm(float[] vec)
- {
- return MathFloat.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
- }
- /** Compute distance between 2 points
- * @param p0 a ref point on the line
- * @param vec vector representing the direction of the line
- * @param point the point to compute the relative distance of
- * @return distance float
- */
- public static float computeLength(float[] p0, float[] point)
- {
- float[] w = new float[]{point[0]-p0[0],point[1]-p0[1],point[2]-p0[2]};
+ return midPoint;
+ }
+ /** Compute the norm of a vector
+ * @param vec vector
+ * @return vorm
+ */
+ public static float norm(float[] vec)
+ {
+ return MathFloat.sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
+ }
+ /** Compute distance between 2 points
+ * @param p0 a ref point on the line
+ * @param vec vector representing the direction of the line
+ * @param point the point to compute the relative distance of
+ * @return distance float
+ */
+ public static float computeLength(float[] p0, float[] point)
+ {
+ float[] w = new float[]{point[0]-p0[0],point[1]-p0[1],point[2]-p0[2]};
- float distance = MathFloat.sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]);
+ float distance = MathFloat.sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]);
- return distance;
- }
+ return distance;
+ }
- /**Check equality of 2 vec3 vectors
- * @param v1 vertex 1
- * @param v2 vertex 2
- * @return
- */
- public static boolean checkEquality(float[] v1, float[] v2)
- {
- if(Float.compare(v1[0], v2[0]) == 0
- && Float.compare(v1[1] , v2[1]) == 0
- && Float.compare(v1[2], v2[2]) == 0 )
- return true;
- return false;
- }
+ /**Check equality of 2 vec3 vectors
+ * @param v1 vertex 1
+ * @param v2 vertex 2
+ * @return
+ */
+ public static boolean checkEquality(float[] v1, float[] v2)
+ {
+ if(Float.compare(v1[0], v2[0]) == 0
+ && Float.compare(v1[1] , v2[1]) == 0
+ && Float.compare(v1[2], v2[2]) == 0 )
+ return true;
+ return false;
+ }
- /** Compute the determinant of 3 vectors
- * @param a vector 1
- * @param b vector 2
- * @param c vector 3
- * @return the determinant value
- */
- public static float computeDeterminant(float[] a, float[] b, float[] c)
- {
- float area = a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[0]*b[2]*c[1] - a[1]*b[0]*c[2] - a[2]*b[1]*c[0];
- return area;
- }
+ /** Compute the determinant of 3 vectors
+ * @param a vector 1
+ * @param b vector 2
+ * @param c vector 3
+ * @return the determinant value
+ */
+ public static float computeDeterminant(float[] a, float[] b, float[] c)
+ {
+ float area = a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[0]*b[2]*c[1] - a[1]*b[0]*c[2] - a[2]*b[1]*c[0];
+ return area;
+ }
- /** Check if three vertices are colliniear
- * @param v1 vertex 1
- * @param v2 vertex 2
- * @param v3 vertex 3
- * @return true if collinear, false otherwise
- */
- public static boolean checkCollinear(float[] v1, float[] v2, float[] v3)
- {
- return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR);
- }
+ /** Check if three vertices are colliniear
+ * @param v1 vertex 1
+ * @param v2 vertex 2
+ * @param v3 vertex 3
+ * @return true if collinear, false otherwise
+ */
+ public static boolean checkCollinear(float[] v1, float[] v2, float[] v3)
+ {
+ return (computeDeterminant(v1, v2, v3) == VectorUtil.COLLINEAR);
+ }
- /** Compute Vector
- * @param v1 vertex 1
- * @param v2 vertex2 2
- * @return Vector V1V2
- */
- public static float[] computeVector(float[] v1, float[] v2)
- {
- float[] vector = new float[3];
- vector[0] = v2[0] - v1[0];
- vector[1] = v2[1] - v1[1];
- vector[2] = v2[2] - v1[2];
- return vector;
- }
+ /** Compute Vector
+ * @param v1 vertex 1
+ * @param v2 vertex2 2
+ * @return Vector V1V2
+ */
+ public static float[] computeVector(float[] v1, float[] v2)
+ {
+ float[] vector = new float[3];
+ vector[0] = v2[0] - v1[0];
+ vector[1] = v2[1] - v1[1];
+ vector[2] = v2[2] - v1[2];
+ return vector;
+ }
- /** Check if vertices in triangle circumcircle
- * @param a triangle vertex 1
- * @param b triangle vertex 2
- * @param c triangle vertex 3
- * @param d vertex in question
- * @return true if the vertex d is inside the circle defined by the
- * vertices a, b, c. from paper by Guibas and Stolfi (1985).
- */
- public static boolean inCircle(Vertex a, Vertex b, Vertex c, Vertex d){
- return (a.getX() * a.getX() + a.getY() * a.getY()) * triArea(b, c, d) -
- (b.getX() * b.getX() + b.getY() * b.getY()) * triArea(a, c, d) +
- (c.getX() * c.getX() + c.getY() * c.getY()) * triArea(a, b, d) -
- (d.getX() * d.getX() + d.getY() * d.getY()) * triArea(a, b, c) > 0;
- }
+ /** Check if vertices in triangle circumcircle
+ * @param a triangle vertex 1
+ * @param b triangle vertex 2
+ * @param c triangle vertex 3
+ * @param d vertex in question
+ * @return true if the vertex d is inside the circle defined by the
+ * vertices a, b, c. from paper by Guibas and Stolfi (1985).
+ */
+ public static boolean inCircle(Vertex a, Vertex b, Vertex c, Vertex d){
+ return (a.getX() * a.getX() + a.getY() * a.getY()) * triArea(b, c, d) -
+ (b.getX() * b.getX() + b.getY() * b.getY()) * triArea(a, c, d) +
+ (c.getX() * c.getX() + c.getY() * c.getY()) * triArea(a, b, d) -
+ (d.getX() * d.getX() + d.getY() * d.getY()) * triArea(a, b, c) > 0;
+ }
- /** Computes oriented area of a triangle
- * @param a first vertex
- * @param b second vertex
- * @param c third vertex
- * @return compute twice the area of the oriented triangle (a,b,c), the area
- * is positive if the triangle is oriented counterclockwise.
- */
- public static float triArea(Vertex a, Vertex b, Vertex c){
- return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY())*(c.getX() - a.getX());
- }
+ /** Computes oriented area of a triangle
+ * @param a first vertex
+ * @param b second vertex
+ * @param c third vertex
+ * @return compute twice the area of the oriented triangle (a,b,c), the area
+ * is positive if the triangle is oriented counterclockwise.
+ */
+ public static float triArea(Vertex a, Vertex b, Vertex c){
+ return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY())*(c.getX() - a.getX());
+ }
- /** Check if points are in ccw order
- * @param a first vertex
- * @param b second vertex
- * @param c third vertex
- * @return true if the points a,b,c are in a ccw order
- */
- public static boolean ccw(Vertex a, Vertex b, Vertex c){
- return triArea(a,b,c) > 0;
- }
+ /** Check if points are in ccw order
+ * @param a first vertex
+ * @param b second vertex
+ * @param c third vertex
+ * @return true if the points a,b,c are in a ccw order
+ */
+ public static boolean ccw(Vertex a, Vertex b, Vertex c){
+ return triArea(a,b,c) > 0;
+ }
- /** Computes the area of a list of vertices to check if ccw
- * @param vertices
- * @return positve area if ccw else negative area value
- */
- public static float area(ArrayList<Vertex> vertices) {
- int n = vertices.size();
- float area = 0.0f;
- for (int p = n - 1, q = 0; q < n; p = q++)
- {
- float[] pCoord = vertices.get(p).getCoord();
- float[] qCoord = vertices.get(q).getCoord();
- area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1];
- }
- return area;
- }
+ /** Computes the area of a list of vertices to check if ccw
+ * @param vertices
+ * @return positve area if ccw else negative area value
+ */
+ public static float area(ArrayList<Vertex> vertices) {
+ int n = vertices.size();
+ float area = 0.0f;
+ for (int p = n - 1, q = 0; q < n; p = q++)
+ {
+ float[] pCoord = vertices.get(p).getCoord();
+ float[] qCoord = vertices.get(q).getCoord();
+ area += pCoord[0] * qCoord[1] - qCoord[0] * pCoord[1];
+ }
+ return area;
+ }
}
diff --git a/src/jogl/classes/com/jogamp/graph/package.html b/src/jogl/classes/com/jogamp/graph/package.html
new file mode 100644
index 000000000..f696020ab
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/package.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>Public Graph Utility Package</title>
+</head>
+ <body>
+
+<h2>Public <i>Graph</i> Utility Package</h2>
+
+<h3>Disclaimer</h3>
+ <p>
+ The API of the namespace <i>com.jogamp.graph.**</i>
+ is experimental and subject to change until further notice.
+ </p>
+ <p>
+ It's implementation <i>jogamp.graph.**</i> may change at any time
+ as it is natural with all other API implementations.
+ </p>
+ <p>
+ We are currently refining and completing this new API and it's implementation.
+ Feel free to comment and help using our public channels.
+ </p>
+<h3>Revision History<br>
+ </h3>
+
+<ul>
+<li> Early Draft Review, April 1st 2011</li>
+</ul>
+ <br>
+ <br>
+ <br>
+</body>
+</html>
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
index 4fbd0e478..e7fbc4d58 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -125,7 +125,7 @@ public class Animator extends AnimatorBase {
class MainLoop implements Runnable {
public String toString() {
- return "[started "+isStartedImpl()+", animating "+isAnimatingImpl()+", paused "+isPausedImpl()+", frames "+getTotalFrames()+", drawable "+drawables.size()+"]";
+ return "[started "+isStartedImpl()+", animating "+isAnimatingImpl()+", paused "+isPausedImpl()+", drawable "+drawables.size()+"]";
}
public void run() {
@@ -134,11 +134,7 @@ public class Animator extends AnimatorBase {
if(DEBUG) {
System.err.println("Animator start:" + Thread.currentThread() + ": " + toString());
}
-
- startTime = System.currentTimeMillis();
- curTime = startTime;
- totalFrames = 0;
-
+ fpsCounter.resetFPSCounter();
animThread = Thread.currentThread();
setIsAnimatingSynced(false); // barrier
Animator.this.notifyAll();
@@ -161,9 +157,7 @@ public class Animator extends AnimatorBase {
if (wasPaused) {
// resume from pause -> reset counter
- startTime = System.currentTimeMillis();
- curTime = startTime;
- totalFrames = 0;
+ fpsCounter.resetFPSCounter();
if (DEBUG) {
System.err.println("Animator resume:" + Thread.currentThread() + ": " + toString());
}
@@ -269,7 +263,7 @@ public class Animator extends AnimatorBase {
if (runnable == null) {
runnable = new MainLoop();
}
- resetCounter();
+ fpsCounter.resetFPSCounter();
String threadName = Thread.currentThread().getName()+"-"+baseName;
Thread thread;
if(null==threadGroup) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index 01c2ea664..a6ba74665 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -30,7 +30,12 @@ package com.jogamp.opengl.util;
import com.jogamp.common.util.locks.RecursiveLock;
import jogamp.opengl.Debug;
+import jogamp.opengl.FPSCounterImpl;
+
+import java.io.PrintStream;
import java.util.ArrayList;
+
+import javax.media.opengl.FPSCounter;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLProfile;
@@ -61,9 +66,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
protected Thread animThread;
protected boolean ignoreExceptions;
protected boolean printExceptions;
- protected long startTime;
- protected long curTime;
- protected int totalFrames;
+ protected FPSCounterImpl fpsCounter = new FPSCounterImpl();
protected RecursiveLock stateSync = new RecursiveLock();
/** Creates a new, empty Animator. */
@@ -83,7 +86,6 @@ public abstract class AnimatorBase implements GLAnimatorControl {
baseName = baseName.concat("-"+animatorCount);
drawablesEmpty = true;
}
- resetCounter();
}
protected abstract String getBaseName(String prefix);
@@ -138,25 +140,48 @@ public abstract class AnimatorBase implements GLAnimatorControl {
lightweight widgets are continually being redrawn. */
protected void display() {
impl.display(drawables, ignoreExceptions, printExceptions);
- curTime = System.currentTimeMillis();
- totalFrames++;
+ fpsCounter.tickFPS();
+ }
+
+ public final void setUpdateFPSFrames(int frames, PrintStream out) {
+ fpsCounter.setUpdateFPSFrames(frames, out);
+ }
+
+ public final void resetFPSCounter() {
+ fpsCounter.resetFPSCounter();
}
- public long getCurrentTime() {
- return curTime;
+ public final int getUpdateFPSFrames() {
+ return fpsCounter.getUpdateFPSFrames();
+ }
+
+ public final long getFPSStartTime() {
+ return fpsCounter.getFPSStartTime();
}
- public long getDuration() {
- return curTime - startTime;
+ public final long getLastFPSUpdateTime() {
+ return fpsCounter.getLastFPSUpdateTime();
}
- public long getStartTime() {
- return startTime;
+ public final long getLastFPSPeriod() {
+ return fpsCounter.getLastFPSPeriod();
+ }
+
+ public final float getLastFPS() {
+ return fpsCounter.getLastFPS();
+ }
+
+ public final int getTotalFPSFrames() {
+ return fpsCounter.getTotalFPSFrames();
}
- public int getTotalFrames() {
- return totalFrames;
+ public final long getTotalFPSDuration() {
+ return fpsCounter.getTotalFPSDuration();
}
+
+ public final float getTotalFPS() {
+ return fpsCounter.getTotalFPS();
+ }
public final Thread getThread() {
stateSync.lock();
@@ -167,12 +192,6 @@ public abstract class AnimatorBase implements GLAnimatorControl {
}
}
- public synchronized void resetCounter() {
- startTime = System.currentTimeMillis(); // overwrite startTime to real init one
- curTime = startTime;
- totalFrames = 0;
- }
-
/** Sets a flag causing this Animator to ignore exceptions produced
while redrawing the drawables. By default this flag is set to
false, causing any exception thrown to halt the Animator. */
@@ -189,6 +208,6 @@ public abstract class AnimatorBase implements GLAnimatorControl {
}
public String toString() {
- return getClass().getName()+"[started "+isStarted()+", animating "+isAnimating()+", paused "+isPaused()+", frames "+getTotalFrames()+", drawable "+drawables.size()+"]";
+ return getClass().getName()+"[started "+isStarted()+", animating "+isAnimating()+", paused "+isPaused()+", drawable "+drawables.size()+"]";
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
index ad32b4ffe..c57d4b057 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2011 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -39,21 +40,23 @@ public class FBObject {
private int width, height;
private int fb, fbo_tex, depth_rb, stencil_rb, vStatus;
private int texInternalFormat, texDataFormat, texDataType;
-
- public static final int ATTR_DEPTH = 1 << 0;
- public static final int ATTR_STENCIL = 1 << 1;
-
+ private boolean bound;
+
public FBObject(int width, int height) {
this.width = width;
this.height = height;
this.fb = 0;
this.fbo_tex = 0;
this.depth_rb = 0;
- this.stencil_rb = 0;
+ this.stencil_rb = 0;
+ this.bound = false;
}
-
- public boolean validateStatus(GL gl) {
- /* vStatus = */ getStatus(gl);
+
+ /**
+ * @return true if the FB status is valid, otherwise false
+ * @see #getStatus()
+ */
+ public boolean isStatusValid() {
switch(vStatus) {
case GL.GL_FRAMEBUFFER_COMPLETE:
return true;
@@ -73,48 +76,40 @@ public class FBObject {
}
}
- /** @return {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1 */
+ /**
+ * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
+ * @see #validateStatus()
+ */
public int getStatus() {
return vStatus;
}
- public int getStatus(GL gl) {
- if(!gl.glIsFramebuffer(fb)) {
- vStatus = -1;
- } else {
- vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
- }
- return vStatus;
- }
-
public String getStatusString() {
return getStatusString(vStatus);
}
- public static String getStatusString(int fbStatus) {
+ public static final String getStatusString(int fbStatus) {
switch(fbStatus) {
case -1:
return "NOT A FBO";
case GL.GL_FRAMEBUFFER_COMPLETE:
return "OK";
- case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- return("GL FBO: incomplete,incomplete attachment\n");
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
return("GL FBO: Unsupported framebuffer format");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ return("GL FBO: incomplete, incomplete attachment\n");
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- return("GL FBO: incomplete,missing attachment");
+ return("GL FBO: incomplete, missing attachment");
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- return("GL FBO: incomplete,attached images must have same dimensions");
+ return("GL FBO: incomplete, attached images must have same dimensions");
case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- return("GL FBO: incomplete,attached images must have same format");
- /*
+ return("GL FBO: incomplete, attached images must have same format");
case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- return("GL FBO: incomplete,missing draw buffer");
+ return("GL FBO: incomplete, missing draw buffer");
case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- return("GL FBO: incomplete,missing read buffer");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
- return("GL FBO: incomplete, duplicate attachment");
- */
+ return("GL FBO: incomplete, missing read buffer");
+ case GL2.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ return("GL FBO: incomplete, missing multisample buffer");
case 0:
return("GL FBO: incomplete, implementation fault");
default:
@@ -154,6 +149,19 @@ public class FBObject {
return init(gl, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
}
+ private boolean checkNoError(GL gl, int err, String exceptionMessage) {
+ if(GL.GL_NO_ERROR != err) {
+ if(null != gl) {
+ destroy(gl);
+ }
+ if(null != exceptionMessage) {
+ throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+ }
+ return false;
+ }
+ return true;
+ }
+
/**
* Initializes this FBO's instance with it's texture.
*
@@ -176,6 +184,8 @@ public class FBObject {
throw new GLException("FBO already initialized (fb "+fb+", tex "+fbo_tex+")");
}
+ checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
+
texInternalFormat=textureInternalFormat;
texDataFormat=textureDataFormat;
texDataType=textureDataType;
@@ -189,24 +199,24 @@ public class FBObject {
throw new GLException("null generated framebuffer");
}
- gl.glGenTextures(1, name, 0);
- fbo_tex = name[0];
- if(fbo_tex==0) {
- throw new GLException("null generated texture");
- }
-
// bind fbo ..
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
+ checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error
if(!gl.glIsFramebuffer(fb)) {
- destroy(gl);
- System.err.println("not a framebuffer: "+ fb);
- return false;
+ checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
}
bound = true;
+ gl.glGenTextures(1, name, 0);
+ fbo_tex = name[0];
+ if(fbo_tex==0) {
+ throw new GLException("null generated texture");
+ }
gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex);
+ checkNoError(gl, gl.glGetError(), "FBObject Init.bindTex"); // throws GLException if error
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, texInternalFormat, width, height, 0,
texDataFormat, texDataType, null);
+ checkNoError(gl, gl.glGetError(), "FBObject Init.texImage2D"); // throws GLException if error
if( 0 < magFilter ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
}
@@ -225,7 +235,8 @@ public class FBObject {
GL.GL_COLOR_ATTACHMENT0,
GL.GL_TEXTURE_2D, fbo_tex, 0);
- return validateStatus(gl);
+ updateStatus(gl);
+ return isStatusValid();
}
/**
@@ -264,7 +275,8 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
GL.GL_DEPTH_ATTACHMENT,
GL.GL_RENDERBUFFER, depth_rb);
- return validateStatus(gl);
+ updateStatus(gl);
+ return isStatusValid();
}
/**
@@ -283,7 +295,6 @@ public class FBObject {
checkBound(true);
int name[] = new int[1];
gl.glGenRenderbuffers(1, name, 0);
- gl.glGenRenderbuffers(1, name, 0);
stencil_rb = name[0];
if(stencil_rb==0) {
throw new GLException("null generated stencilbuffer");
@@ -299,7 +310,8 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
GL.GL_STENCIL_ATTACHMENT,
GL.GL_RENDERBUFFER, stencil_rb);
- return validateStatus(gl);
+ updateStatus(gl);
+ return isStatusValid();
}
public void destroy(GL gl) {
@@ -331,8 +343,6 @@ public class FBObject {
}
}
- boolean bound = false;
-
private final void checkBound(boolean shallBeBound) {
if(bound != shallBeBound) {
final String s0 = shallBeBound ? "not" : "already" ;
@@ -355,16 +365,31 @@ public class FBObject {
}
public void use(GL gl) {
- if(bound) {
- unbind(gl);
- }
- gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex); // to use it ..
+ checkBound(false);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex); // use it ..
}
- public int getFBName() {
- return fb;
+ public void unuse(GL gl) {
+ checkBound(false);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
}
- public int getTextureName() {
- return fbo_tex;
+
+ public final boolean isBound() { return bound; }
+ public final int getWidth() { return width; }
+ public final int getHeight() { return height; }
+ public final int getFBName() { return fb; }
+ public final int getTextureName() { return fbo_tex; }
+ public final int getStencilBuffer() { return stencil_rb; }
+ public final int getDepthBuffer() { return depth_rb; }
+ public final String toString() {
+ return "FBO[name "+fb+", size "+width+"x"+height+", tex "+fbo_tex+", depth "+depth_rb+", stencil "+stencil_rb+"]";
}
+
+ private void updateStatus(GL gl) {
+ if(!gl.glIsFramebuffer(fb)) {
+ vStatus = -1;
+ } else {
+ vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+ }
+ }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
index fc364b67a..f7fc58160 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/FPSAnimator.java
@@ -116,9 +116,9 @@ public class FPSAnimator extends AnimatorBase {
}
private void startTask() {
- if(null != task) {
- return;
- }
+ if(null != task) {
+ return;
+ }
long delay = (long) (1000.0f / (float) fps);
task = new TimerTask() {
public void run() {
@@ -130,7 +130,7 @@ public class FPSAnimator extends AnimatorBase {
}
};
- resetCounter();
+ fpsCounter.resetFPSCounter();
shouldRun = true;
if (scheduleAtFixedRate) {
@@ -165,12 +165,12 @@ public class FPSAnimator extends AnimatorBase {
try {
shouldRun = false;
if(null != task) {
- task.cancel();
- task = null;
+ task.cancel();
+ task = null;
}
if(null != timer) {
- timer.cancel();
- timer = null;
+ timer.cancel();
+ timer = null;
}
animThread = null;
try {
@@ -190,8 +190,8 @@ public class FPSAnimator extends AnimatorBase {
try {
shouldRun = false;
if(null != task) {
- task.cancel();
- task = null;
+ task.cancel();
+ task = null;
}
animThread = null;
try {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 4586d1df5..d80d398aa 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -28,65 +28,106 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
}) != null;
/**
+ * Create a client side buffer object, using a predefined fixed function array index
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be chosen.
+ *
* @param index The GL array index
* @param name The optional custom name for the GL array index, maybe null.
* If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
* This name might be used as the shader attribute name.
* @param comps The array component number
* @param dataType The array index GL data type
- * @param normalized Wheather the data shall be normalized
+ * @param normalized Whether the data shall be normalized
+ * @param initialSize
*
* @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
- */
- public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
- int initialSize)
+ */
+ public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized, int initialSize)
throws GLException
{
- gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
GLArrayDataClient adc = new GLArrayDataClient();
GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
- adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler, 0, 0);
+ adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler, -1, -1, -1, -1);
return adc;
}
- public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer)
+ /**
+ * Create a client side buffer object, using a predefined fixed function array index
+ * and starting with a given Buffer object incl it's stride
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be chosen.
+ *
+ * @param index The GL array index
+ * @param name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer)
throws GLException
{
- gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
GLArrayDataClient adc = new GLArrayDataClient();
GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc);
- adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false, glArrayHandler, 0, 0);
+ adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false, glArrayHandler, -1, -1, -1, -1);
return adc;
}
- public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
- int initialSize)
+ /**
+ * Create a client side buffer object, using a custom GLSL array attribute name
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * @param st The ShaderState managing the state of the used shader program, vertex attributes and uniforms
+ * @param name The custom name for the GL attribute.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param initialSize
+ */
+ public static GLArrayDataClient createGLSL(ShaderState st, String name,
+ int comps, int dataType, boolean normalized, int initialSize)
throws GLException
{
- if(!gl.hasGLSL()) {
- throw new GLException("GLArrayDataClient.GLSL not supported: "+gl);
- }
- gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
-
GLArrayDataClient adc = new GLArrayDataClient();
- GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
- adc.init(name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler, 0, 0);
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(st, adc);
+ adc.init(name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler, -1, -1, -1, -1);
return adc;
}
- public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer)
+ /**
+ * Create a client side buffer object, using a custom GLSL array attribute name
+ * and starting with a given Buffer object incl it's stride
+ *
+ * @param st The ShaderState managing the state of the used shader program, vertex attributes and uniforms
+ * @param name The custom name for the GL attribute.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ */
+ public static GLArrayDataClient createGLSL(ShaderState st, String name,
+ int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer)
throws GLException
{
- if(!gl.hasGLSL()) {
- throw new GLException("GLArrayDataClient.GLSL not supported: "+gl);
- }
- gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
-
GLArrayDataClient adc = new GLArrayDataClient();
- GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc);
- adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, true, glArrayHandler, 0, 0);
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(st, adc);
+ adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, true, glArrayHandler, -1, -1, -1, -1);
return adc;
}
@@ -94,21 +135,21 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
// Data read access
//
- public final boolean isBufferWritten() { return bufferWritten; }
+ public final boolean isVBOWritten() { return bufferWritten; }
public final boolean sealed() { return sealed; }
-
- public int getBufferUsage() { return -1; }
+
+ public final boolean enabled() { return bufferEnabled; }
//
// Data and GL state modification ..
//
- public final void setBufferWritten(boolean written) { bufferWritten=written; }
+ public final void setVBOWritten(boolean written) { bufferWritten=written; }
public void destroy(GL gl) {
reset(gl);
- buffer=null;
+ super.destroy(gl);
}
public void reset(GL gl) {
@@ -116,30 +157,17 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
reset();
}
- public void seal(GL gl, boolean seal)
- {
+ public void seal(GL gl, boolean seal) {
seal(seal);
- if(sealedGL==seal) return;
- sealedGL = seal;
- if(seal) {
- init_vbo(gl);
-
- enableBuffer(gl, true);
- } else {
- enableBuffer(gl, false);
- }
+ enableBuffer(gl, seal);
}
public void enableBuffer(GL gl, boolean enable) {
- if(enableBufferAlways && enable) {
- bufferEnabled = false;
- }
- if( bufferEnabled != enable && components>0 ) {
+ if( enableBufferAlways || bufferEnabled != enable ) {
if(enable) {
checkSeal(true);
- if(null!=buffer) {
- buffer.rewind();
- }
+ // init/generate VBO name if not done yet
+ init_vbo(gl);
}
glArrayHandler.enableBuffer(gl, enable);
bufferEnabled = enable;
@@ -167,16 +195,14 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
{
if(sealed==seal) return;
sealed = seal;
+ bufferWritten=false;
if(seal) {
- bufferWritten=false;
if (null!=buffer) {
buffer.flip();
}
- } else {
- if (null!=buffer) {
- buffer.position(buffer.limit());
- buffer.limit(buffer.capacity());
- }
+ } else if (null!=buffer) {
+ buffer.position(buffer.limit());
+ buffer.limit(buffer.capacity());
}
}
@@ -202,7 +228,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
* The arguments remaining elements must be a multiple of this arrays element stride.
*/
public void put(Buffer v) {
- if ( buffer==null || sealed ) return;
+ if ( sealed ) return;
if(0!=(v.remaining() % strideL)) {
throw new GLException("Buffer length ("+v.remaining()+") is not a multiple of component-stride:\n\t"+this);
}
@@ -211,19 +237,19 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
}
public void putb(byte v) {
- if ( buffer==null || sealed ) return;
+ if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.putb(buffer, v);
}
public void puts(short v) {
- if ( buffer==null || sealed ) return;
+ if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.puts(buffer, v);
}
public void puti(int v) {
- if ( buffer==null || sealed ) return;
+ if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.puti(buffer, v);
}
@@ -233,7 +259,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
}
public void putf(float v) {
- if ( buffer==null || sealed ) return;
+ if ( sealed ) return;
growBufferIfNecessary(1);
Buffers.putf(buffer, v);
}
@@ -243,8 +269,8 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
- ", dataType "+dataType+
- ", bufferClazz "+clazz+
+ ", dataType "+componentType+
+ ", bufferClazz "+componentClazz+
", elements "+getElementNumber()+
", components "+components+
", stride "+stride+"u "+strideB+"b "+strideL+"c"+
@@ -252,7 +278,8 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
", sealed "+sealed+
", bufferEnabled "+bufferEnabled+
", bufferWritten "+bufferWritten+
- ", buffer "+buffer+
+ ", buffer "+buffer+
+ ", alive "+alive+
"]";
}
@@ -260,55 +287,58 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
protected final boolean growBufferIfNecessary(int spare) {
if(buffer==null || buffer.remaining()<spare) {
- growBuffer(initialSize);
+ growBuffer(Math.max(initialSize, spare));
return true;
}
return false;
}
- protected final void growBuffer(int additional) {
- if(sealed || 0==additional || 0==components) return;
+ protected final void growBuffer(int additional) {
+ if(!alive || sealed) {
+ throw new GLException("Invalid state: "+this);
+ }
// add the stride delta
additional += (additional/components)*(strideL-components);
- if(components>0) {
- int osize = (buffer!=null)?buffer.capacity():0;
- if(clazz==ByteBuffer.class) {
- ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newBBuffer.put((ByteBuffer)buffer);
- }
- buffer = newBBuffer;
- } else if(clazz==ShortBuffer.class) {
- ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newSBuffer.put((ShortBuffer)buffer);
- }
- buffer = newSBuffer;
- } else if(clazz==IntBuffer.class) {
- IntBuffer newIBuffer = Buffers.newDirectIntBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newIBuffer.put((IntBuffer)buffer);
- }
- buffer = newIBuffer;
- } else if(clazz==FloatBuffer.class) {
- FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newFBuffer.put((FloatBuffer)buffer);
- }
- buffer = newFBuffer;
- } else {
- throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
+ int osize = (buffer!=null)?buffer.capacity():0;
+ if(componentClazz==ByteBuffer.class) {
+ ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newBBuffer.put((ByteBuffer)buffer);
+ }
+ buffer = newBBuffer;
+ } else if(componentClazz==ShortBuffer.class) {
+ ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newSBuffer.put((ShortBuffer)buffer);
}
+ buffer = newSBuffer;
+ } else if(componentClazz==IntBuffer.class) {
+ IntBuffer newIBuffer = Buffers.newDirectIntBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newIBuffer.put((IntBuffer)buffer);
+ }
+ buffer = newIBuffer;
+ } else if(componentClazz==FloatBuffer.class) {
+ FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newFBuffer.put((FloatBuffer)buffer);
+ }
+ buffer = newFBuffer;
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+componentClazz+":\n\t"+this);
}
}
protected final void checkSeal(boolean test) throws GLException {
+ if(!alive) {
+ throw new GLException("Invalid state: "+this);
+ }
if(sealed!=test) {
if(test) {
throw new GLException("Not Sealed yet, seal first:\n\t"+this);
@@ -320,29 +350,35 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
int initialSize, boolean isVertexAttribute, GLArrayHandler handler,
- int vboName, long bufferOffset)
+ int vboName, long vboOffset, int vboUsage, int vboTarget)
throws GLException
{
super.init(name, index, comps, dataType, normalized, stride, data, isVertexAttribute,
- vboName, bufferOffset);
+ vboName, vboOffset, vboUsage, vboTarget);
this.initialSize = initialSize;
this.glArrayHandler = handler;
this.sealed=false;
- this.sealedGL=false;
this.bufferEnabled=false;
this.enableBufferAlways=false;
this.bufferWritten=false;
- if(null==buffer) {
+ if(null==buffer && initialSize>0) {
growBuffer(initialSize);
}
}
- protected void init_vbo(GL gl) {}
+ private boolean isValidated = false;
+
+ protected void init_vbo(GL gl) {
+ if(!isValidated ) {
+ isValidated = true;
+ validate(gl.getGLProfile(), true);
+ }
+ }
protected GLArrayDataClient() { }
- protected boolean sealed, sealedGL;
+ protected boolean sealed;
protected boolean bufferEnabled;
protected boolean bufferWritten;
protected boolean enableBufferAlways;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
index 0f8ed27be..0da7d1171 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
@@ -14,21 +14,18 @@ import java.nio.*;
public interface GLArrayDataEditable extends GLArrayData {
public boolean sealed();
+
+ public boolean enabled();
/**
- * The VBO buffer usage, if it's an VBO, otherwise -1
+ * Is the buffer written to the VBO ?
*/
- public int getBufferUsage();
+ public boolean isVBOWritten();
/**
- * Is the buffer written to the GPU ?
+ * Marks the buffer written to the VBO
*/
- public boolean isBufferWritten();
-
- /**
- * Marks the buffer written to the GPU
- */
- public void setBufferWritten(boolean written);
+ public void setVBOWritten(boolean written);
//
// Data and GL state modification ..
@@ -39,29 +36,27 @@ public interface GLArrayDataEditable extends GLArrayData {
public void reset(GL gl);
/**
- * If seal is true, it
- * disable write operations to the buffer.
- * Calls flip, ie limit:=position and position:=0.
- * Also enables the buffer for OpenGL, and passes the data.
- *
- * If seal is false, it
- * enable write operations continuing
- * at the buffer position, where you left off at seal(true),
- * ie position:=limit and limit:=capacity.
- * Also disables the buffer for OpenGL.
+ * Convenience method calling {@link #seal(boolean)} and {@link #enableBuffer(GL, boolean)}.
*
* @see #seal(boolean)
+ * @see #enableBuffer(GL, boolean)
+ *
*/
public void seal(GL gl, boolean seal);
/**
- * Enables/disables the buffer, which implies
- * the client state, binding the VBO
- * and transfering the data if not done yet.
+ * <p>Enables/disables the buffer,
+ * sets the client state, binds the VBO if used
+ * and transfers the data if necessary.</p>
+ *
+ * <p>The action will only be executed,
+ * if the internal enable state differs,
+ * or 'setEnableAlways' was called with 'true'.</b>
*
- * The above will only be executed,
- * if the buffer is disabled,
- * or 'setEnableAlways' was called with 'true'.
+ * <p>It is up to the user to enable/disable the array properly,
+ * ie in case of multiple data sets for the same vertex attribute (VA).
+ * Meaning in such case usage of one set while expecting another one
+ * to be used for the same VA implies decorating each usage with enable/disable.</p>
*
* @see #setEnableAlways(boolean)
*/
@@ -72,8 +67,9 @@ public interface GLArrayDataEditable extends GLArrayData {
*
* The default is 'false'
*
- * This is usefull when you mix up
- * GLArrayData usage with conventional GL array calls.
+ * This is useful when you mix up
+ * GLArrayData usage with conventional GL array calls
+ * or in case of a buggy GL VBO implementation.
*
* @see #enableBuffer(GL, boolean)
*/
@@ -86,16 +82,17 @@ public interface GLArrayDataEditable extends GLArrayData {
public void reset();
/**
- * If seal is true, it
- * disable write operations to the buffer.
- * Calls flip, ie limit:=position and position:=0.
+ * <p>If <i>seal</i> is true, it
+ * disables write operations to the buffer.
+ * Calls flip, ie limit:=position and position:=0.</p>
*
- * If seal is false, it
+ * <p>If <i>seal</i> is false, it
* enable write operations continuing
* at the buffer position, where you left off at seal(true),
- * ie position:=limit and limit:=capacity.
+ * ie position:=limit and limit:=capacity.</p>
*
- */
+ * @see #seal(boolean)
+ */
public void seal(boolean seal);
public void rewind();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
index c061e212a..23c237909 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -2,6 +2,7 @@
package com.jogamp.opengl.util;
import javax.media.opengl.*;
+
import java.nio.*;
import com.jogamp.opengl.util.glsl.*;
@@ -13,111 +14,170 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
//
/**
- * Create a VBOBuffer object, using a predefined fixed function array index
+ * Create a VBO, using a predefined fixed function array index
* and starting with a given Buffer object incl it's stride
*
* On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
* On profile ES2 the fixed function emulation will transform these calls to
* EnableVertexAttribArray and VertexAttribPointer calls,
- * and a predefined vertex attribute variable name will be choosen.
- *
+ * and a predefined vertex attribute variable name will be chosen.
+ *
* @param index The GL array index
* @param name The optional custom name for the GL array index, maybe null.
- * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
- * This name might be used as the shader attribute name.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
* @param comps The array component number
* @param dataType The array index GL data type
- * @param normalized Wheather the data shall be normalized
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
*
* @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
*/
- public static GLArrayDataServer createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer, int vboBufferUsage)
+ public static GLArrayDataServer createFixed(int index, String name, int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer, int vboUsage)
throws GLException
{
- gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
-
GLArrayDataServer ads = new GLArrayDataServer();
GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
- ads.init(gl, name, index, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
- 0, 0, vboBufferUsage);
+ ads.init(name, index, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler,
+ 0, 0, vboUsage, GL.GL_ARRAY_BUFFER);
return ads;
}
/**
- * Create a VBOBuffer object, using a predefined fixed function array index
+ * Create a VBO, using a predefined fixed function array index
* and starting with a new created Buffer object with initialSize size
*
* On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
* On profile ES2 the fixed function emulation will transform these calls to
* EnableVertexAttribArray and VertexAttribPointer calls,
- * and a predefined vertex attribute variable name will be choosen.
+ * and a predefined vertex attribute variable name will be chosen.
+ *
+ * @param index The GL array index
+ * @param name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param initialSize
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
*
* @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
*/
- public static GLArrayDataServer createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized,
- int initialSize, int vboBufferUsage)
+ public static GLArrayDataServer createFixed(int index, String name, int comps, int dataType, boolean normalized, int initialSize,
+ int vboUsage)
throws GLException
{
- gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
-
- GLArrayDataServer ads = new GLArrayDataServer();
- GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
- ads.init(gl, name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler,
- 0, 0, vboBufferUsage);
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads);
+ ads.init(name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler,
+ 0, 0, vboUsage, GL.GL_ARRAY_BUFFER);
return ads;
}
/**
- * Create a VBOBuffer object, using a custom GLSL array attribute name
+ * Create a VBO, using a custom GLSL array attribute name
* and starting with a new created Buffer object with initialSize size
- *
- * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ *
+ * @param st The ShaderState managing the state of the used shader program, vertex attributes and uniforms
+ * @param name The custom name for the GL attribute, maybe null if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param initialSize
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ */
+ public static GLArrayDataServer createGLSL(ShaderState st, String name,
+ int comps, int dataType, boolean normalized, int initialSize,
+ int vboUsage)
+ throws GLException
+ {
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(st, ads);
+ ads.init(name, -1, comps, dataType, normalized, 0, null, initialSize,
+ true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER);
+ return ads;
+ }
+
+ /**
+ * Create a VBO, using a custom GLSL array attribute name
+ * and starting with a given Buffer object incl it's stride
+ *
+ * @param st The ShaderState managing the state of the used shader program, vertex attributes and uniforms
+ * @param name The custom name for the GL attribute, maybe null if gpuBufferTarget is
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
*/
- public static GLArrayDataServer createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
- int initialSize, int vboBufferUsage)
+ public static GLArrayDataServer createGLSL(ShaderState st, String name,
+ int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer, int vboUsage)
throws GLException
{
- if(!gl.hasGLSL()) {
- throw new GLException("GLArrayDataServer.GLSL not supported: "+gl);
- }
- gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
-
GLArrayDataServer ads = new GLArrayDataServer();
- GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
- ads.init(gl, name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler,
- 0, 0, vboBufferUsage);
+ GLArrayHandler glArrayHandler = new GLSLArrayHandler(st, ads);
+ ads.init(name, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), true, glArrayHandler,
+ 0, 0, vboUsage, GL.GL_ARRAY_BUFFER);
return ads;
}
/**
- * Create a VBOBuffer object, using a custom GLSL array attribute name
- * and starting with a given Buffer object incl it's stride
- *
- * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ * Create a VBO data object for any target w/o render pipeline association, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}.
+ *
+ * Hence no index, name for a fixed function pipeline nor vertex attribute is given.
+ *
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param stride
+ * @param buffer the user define data
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, ..
+ * {@link GL#glGenBuffers(int, int[], int)
*/
- public static GLArrayDataServer createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer, int vboBufferUsage)
+ public static GLArrayDataServer createData(int comps, int dataType, int stride,
+ Buffer buffer, int vboUsage, int vboTarget)
throws GLException
{
- if(!gl.hasGLSL()) {
- throw new GLException("GLArrayDataServer.GLSL not supported: "+gl);
- }
- gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
+ GLArrayDataServer ads = new GLArrayDataServer();
+ GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads);
+ ads.init(null, -1, comps, dataType, false, stride, buffer, buffer.limit(), false, glArrayHandler,
+ 0, 0, vboUsage, vboTarget);
+ return ads;
+ }
+ /**
+ * Create a VBO data object for any target w/o render pipeline association, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}.
+ *
+ * Hence no index, name for a fixed function pipeline nor vertex attribute is given.
+ *
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param initialSize
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, ..
+ */
+ public static GLArrayDataServer createData(int comps, int dataType, int initialSize,
+ int vboUsage, int vboTarget)
+ throws GLException
+ {
GLArrayDataServer ads = new GLArrayDataServer();
- GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads);
- ads.init(gl, name, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), true, glArrayHandler,
- 0, 0, vboBufferUsage);
+ GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads);
+ ads.init(null, -1, comps, dataType, false, 0, null, initialSize, false, glArrayHandler,
+ 0, 0, vboUsage, vboTarget);
return ads;
}
+
//
// Data matters GLArrayData
//
- public int getBufferUsage() { return vboBufferUsage; }
-
//
// Data and GL state modification ..
//
@@ -141,9 +201,9 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
* switch to client side data one
* Only possible if buffer is defined.
*/
- public void setVBOUsage(boolean vboUsage) {
+ public void setVBOEnabled(boolean vboUsage) {
checkSeal(false);
- super.setVBOUsage(vboUsage);
+ super.setVBOEnabled(vboUsage);
}
public String toString() {
@@ -151,20 +211,22 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
- ", dataType "+dataType+
- ", bufferClazz "+clazz+
+ ", dataType "+componentType+
+ ", bufferClazz "+componentClazz+
", elements "+getElementNumber()+
", components "+components+
", stride "+stride+"u "+strideB+"b "+strideL+"c"+
", initialSize "+initialSize+
- ", vboBufferUsage "+vboBufferUsage+
- ", vboUsage "+vboUsage+
+ ", vboUsage 0x"+Integer.toHexString(vboUsage)+
+ ", vboTarget 0x"+Integer.toHexString(vboTarget)+
+ ", vboEnabled "+vboEnabled+
", vboName "+vboName+
", sealed "+sealed+
", bufferEnabled "+bufferEnabled+
", bufferWritten "+bufferWritten+
", buffer "+buffer+
- ", offset "+bufferOffset+
+ ", offset "+vboOffset+
+ ", alive "+alive+
"]";
}
@@ -172,38 +234,25 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
// non public matters ..
//
- protected void init(GL gl, String name, int index, int comps, int dataType, boolean normalized,
+ protected void init(String name, int index, int comps, int dataType, boolean normalized,
int stride, Buffer data, int initialSize, boolean isVertexAttribute,
GLArrayHandler glArrayHandler,
- int vboName, long bufferOffset, int vboBufferUsage)
+ int vboName, long vboOffset, int vboUsage, int vboTarget)
throws GLException
{
super.init(name, index, comps, dataType, normalized, stride, data, initialSize, isVertexAttribute, glArrayHandler,
- vboName, bufferOffset);
-
- vboUsage=true;
-
- if( ! (gl.isGL2ES2() && vboBufferUsage==GL2ES2.GL_STREAM_DRAW) ) {
- switch(vboBufferUsage) {
- case -1: // nop
- case GL.GL_STATIC_DRAW:
- case GL.GL_DYNAMIC_DRAW:
- break;
- default:
- throw new GLException("invalid vboBufferUsage: "+vboBufferUsage+":\n\t"+this);
- }
- }
- this.vboBufferUsage=vboBufferUsage;
+ vboName, vboOffset, vboUsage, vboTarget);
+
+ vboEnabled=true;
}
protected void init_vbo(GL gl) {
- if(vboUsage && vboName==0) {
+ super.init_vbo(gl);
+ if(vboEnabled && vboName==0) {
int[] tmp = new int[1];
gl.glGenBuffers(1, tmp, 0);
vboName = tmp[0];
}
}
-
- protected int vboBufferUsage;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index 88a8603f9..735bd11f7 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -9,34 +9,85 @@ import java.nio.*;
public class GLArrayDataWrapper implements GLArrayData {
- public static GLArrayDataWrapper createFixed(GL gl, int index, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer,
- int vboName, long bufferOffset)
+ /**
+ * Create a VBO, using a predefined fixed function array index, wrapping the given data.
+ *
+ * @param index The GL array index
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ * @param vboName
+ * @param vboOffset
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ *
+ * @return the new create instance
+ *
+ * @throws GLException
+ */
+ public static GLArrayDataWrapper createFixed(int index, int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer, int vboName,
+ long vboOffset, int vboUsage)
throws GLException
{
- gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true);
GLArrayDataWrapper adc = new GLArrayDataWrapper();
adc.init(null, index, comps, dataType, normalized, stride, buffer, false,
- vboName, bufferOffset);
+ vboName, vboOffset, vboUsage, GL.GL_ARRAY_BUFFER);
return adc;
}
- public static GLArrayDataWrapper createGLSL(GL gl, String name, int comps, int dataType, boolean normalized,
- int stride, Buffer buffer,
- int vboName, long bufferOffset)
+ /**
+ * Create a VBO, using a custom GLSL array attribute name, wrapping the given data.
+ *
+ * @param name The custom name for the GL attribute, maybe null if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+ * @param comps The array component number
+ * @param dataType The array index GL data type
+ * @param normalized Whether the data shall be normalized
+ * @param stride
+ * @param buffer the user define data
+ * @param vboName
+ * @param vboOffset
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ *
+ * @return the new create instance
+ * @throws GLException
+ */
+ public static GLArrayDataWrapper createGLSL(String name, int comps, int dataType, boolean normalized, int stride,
+ Buffer buffer, int vboName,
+ long vboOffset, int vboUsage)
throws GLException
{
- if(!gl.hasGLSL()) {
- throw new GLException("GLArrayDataWrapper.GLSL not supported: "+gl);
- }
- gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true);
-
GLArrayDataWrapper adc = new GLArrayDataWrapper();
adc.init(name, -1, comps, dataType, normalized, stride, buffer, true,
- vboName, bufferOffset);
+ vboName, vboOffset, vboUsage, GL.GL_ARRAY_BUFFER);
return adc;
}
+ /**
+ * Validates this instance's parameter. Called automatically by {@link GLArrayDataClient} and {@link GLArrayDataServer}.
+ * {@link GLArrayDataWrapper} does not validate it's instance by itself.
+ *
+ * @param glp the GLProfile to use
+ * @param throwException whether to throw an exception if this instance has invalid parameter or not
+ * @return true if this instance has invalid parameter, otherwise false
+ */
+ public final boolean validate(GLProfile glp, boolean throwException) {
+ if(!alive) {
+ if(throwException) {
+ throw new GLException("Instance !alive "+this);
+ }
+ return false;
+ }
+ if(this.isVertexAttribute() && !glp.hasGLSL()) {
+ if(throwException) {
+ throw new GLException("GLSL not supported on "+glp+", "+this);
+ }
+ return false;
+ }
+ return glp.isValidArrayDataType(getIndex(), getComponentNumber(), getComponentType(), isVertexAttribute(), throwException);
+ }
+
//
// Data read access
//
@@ -51,54 +102,45 @@ public class GLArrayDataWrapper implements GLArrayData {
public final String getName() { return name; }
- public final long getOffset() { return vboUsage?bufferOffset:-1; }
+ public final long getVBOOffset() { return vboEnabled?vboOffset:-1; }
- public final int getVBOName() { return vboUsage?vboName:-1; }
+ public final int getVBOName() { return vboEnabled?vboName:-1; }
- public final boolean isVBO() { return vboUsage; }
+ public final boolean isVBO() { return vboEnabled; }
+ public final int getVBOUsage() { return vboEnabled?vboUsage:-1; }
+
+ public final int getVBOTarget() { return vboEnabled?vboTarget:-1; }
+
public final Buffer getBuffer() { return buffer; }
public final int getComponentNumber() { return components; }
- public final int getComponentType() { return dataType; }
-
- public final int getComponentSize() {
- if(clazz==ByteBuffer.class) {
- return GLBuffers.SIZEOF_BYTE;
- }
- if(clazz==ShortBuffer.class) {
- return GLBuffers.SIZEOF_SHORT;
- }
- if(clazz==IntBuffer.class) {
- return GLBuffers.SIZEOF_INT;
- }
- if(clazz==FloatBuffer.class) {
- return GLBuffers.SIZEOF_FLOAT;
- }
- throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
- }
+ public final int getComponentType() { return componentType; }
+ public final int getComponentSize() { return componentSize; }
+
public final int getElementNumber() {
if(null==buffer) return 0;
return ( buffer.position()==0 ) ? ( buffer.limit() / components ) : ( buffer.position() / components ) ;
}
-
+ public final int getByteSize() {
+ if(null==buffer) return 0;
+ return ( buffer.position()==0 ) ? ( buffer.limit() * componentSize ) : ( buffer.position() * componentSize ) ;
+ }
+
public final boolean getNormalized() { return normalized; }
public final int getStride() { return stride; }
- public final Class getBufferClass() { return clazz; }
+ public final Class getBufferClass() { return componentClazz; }
public void destroy(GL gl) {
- this.buffer = null;
- this.components = 0;
- this.stride=0;
- this.strideB=0;
- this.strideL=0;
- this.vboName=0;
- this.vboUsage=false;
- this.bufferOffset=0;
+ buffer = null;
+ vboName=0;
+ vboEnabled=false;
+ vboOffset=-1;
+ alive = false;
}
public String toString() {
@@ -106,15 +148,18 @@ public class GLArrayDataWrapper implements GLArrayData {
", index "+index+
", location "+location+
", isVertexAttribute "+isVertexAttribute+
- ", dataType "+dataType+
- ", bufferClazz "+clazz+
+ ", dataType "+componentType+
+ ", bufferClazz "+componentClazz+
", elements "+getElementNumber()+
", components "+components+
", stride "+stride+"u "+strideB+"b "+strideL+"c"+
", buffer "+buffer+
- ", offset "+bufferOffset+
- ", vboUsage "+vboUsage+
+ ", offset "+vboOffset+
+ ", vboUsage 0x"+Integer.toHexString(vboUsage)+
+ ", vboTarget 0x"+Integer.toHexString(vboTarget)+
+ ", vboEnabled "+vboEnabled+
", vboName "+vboName+
+ ", alive "+alive+
"]";
}
@@ -140,76 +185,140 @@ public class GLArrayDataWrapper implements GLArrayData {
name = newName;
}
- public void setVBOUsage(boolean vboUsage) {
- this.vboUsage=vboUsage;
+ /**
+ * Enable or disable use of VBO.
+ * Only possible if a VBO buffer name is defined.
+ * @see #setVBOName(int)
+ */
+ public void setVBOEnabled(boolean vboEnabled) {
+ this.vboEnabled=vboEnabled;
}
+ /**
+ * Set the VBO buffer name, if valid (>0) enable use of VBO
+ * @see #setVBOEnabled(boolean)
+ */
public void setVBOName(int vboName) {
this.vboName=vboName;
- setVBOUsage(vboName>0);
+ setVBOEnabled(vboName>0);
}
- protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
+ /**
+ * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW}
+ */
+ public void setVBOUsage(int vboUsage) {
+ this.vboUsage = vboUsage;
+ }
+
+ /**
+ * @param vboTarget either {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER}
+ */
+ public void setVBOTarget(int vboTarget) {
+ this.vboTarget = vboTarget;
+ }
+
+ protected void init(String name, int index, int components, int componentType,
+ boolean normalized, int stride, Buffer data,
boolean isVertexAttribute,
- int vboName, long bufferOffset)
+ int vboName, long vboOffset, int vboUsage, int vboTarget)
throws GLException
{
this.isVertexAttribute = isVertexAttribute;
this.index = index;
this.location = -1;
// We can't have any dependence on the FixedFuncUtil class here for build bootstrapping reasons
- this.name = (null==name)?FixedFuncPipeline.getPredefinedArrayIndexName(index):name;
- if(null==this.name) {
- throw new GLException("Not a valid GL array index: "+index);
+
+ if( GL.GL_ELEMENT_ARRAY_BUFFER == vboTarget ) {
+ // ok ..
+ } else if( GL.GL_ARRAY_BUFFER == vboTarget ) {
+ // check name ..
+ this.name = ( null == name ) ? FixedFuncPipeline.getPredefinedArrayIndexName(index) : name ;
+ if(null == this.name ) {
+ throw new GLException("Not a valid array buffer index: "+index);
+ }
+ } else if( 0 <= vboTarget ) {
+ throw new GLException("Invalid GPUBuffer target: 0x"+Integer.toHexString(vboTarget));
}
- this.dataType = dataType;
- this.clazz = getBufferClass(dataType);
- switch(dataType) {
+
+ this.componentType = componentType;
+ componentClazz = getBufferClass(componentType);
+ switch(componentType) {
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
case GL.GL_SHORT:
case GL.GL_UNSIGNED_SHORT:
- case GL2ES1.GL_FIXED:
+ case GL.GL_FIXED:
this.normalized = normalized;
break;
default:
this.normalized = false;
}
+ componentSize = GLBuffers.sizeOfGLType(componentType);
+ if(0 > componentSize) {
+ throw new GLException("Given componentType not supported: "+componentType+":\n\t"+this);
+ }
+ if(0 >= components) {
+ throw new GLException("Invalid number of components: " + components);
+ }
+ this.components = components;
- int bpc = getComponentSize();
- if(0<stride && stride<comps*bpc) {
- throw new GLException("stride ("+stride+") lower than component bytes, "+comps+" * "+bpc);
+ if(0<stride && stride<components*componentSize) {
+ throw new GLException("stride ("+stride+") lower than component bytes, "+components+" * "+componentSize);
}
- if(0<stride && stride%bpc!=0) {
- throw new GLException("stride ("+stride+") not a multiple of bpc "+bpc);
+ if(0<stride && stride%componentSize!=0) {
+ throw new GLException("stride ("+stride+") not a multiple of bpc "+componentSize);
}
this.buffer = data;
- this.components = comps;
this.stride=stride;
- this.strideB=(0==stride)?comps*bpc:stride;
- this.strideL=(0==stride)?comps:strideB/bpc;
+ this.strideB=(0==stride)?components*componentSize:stride;
+ this.strideL=(0==stride)?components:strideB/componentSize;
this.vboName=vboName;
- this.vboUsage=vboName>0;
- this.bufferOffset=bufferOffset;
+ this.vboEnabled=vboName>0;
+ this.vboOffset=vboOffset;
+
+ switch(vboUsage) {
+ case -1: // nop
+ case GL.GL_STATIC_DRAW:
+ case GL.GL_DYNAMIC_DRAW:
+ case GL2ES2.GL_STREAM_DRAW:
+ break;
+ default:
+ throw new GLException("invalid gpuBufferUsage: "+vboUsage+":\n\t"+this);
+ }
+ switch(vboTarget) {
+ case -1: // nop
+ case GL.GL_ARRAY_BUFFER:
+ case GL.GL_ELEMENT_ARRAY_BUFFER:
+ break;
+ default:
+ throw new GLException("invalid gpuBufferTarget: "+vboTarget+":\n\t"+this);
+ }
+ this.vboUsage=vboUsage;
+ this.vboTarget=vboTarget;
+ this.alive=true;
}
protected GLArrayDataWrapper() { }
+ protected boolean alive;
protected int index;
protected int location;
protected String name;
protected int components;
- protected int dataType;
+ protected int componentType;
+ protected Class componentClazz;
+ protected int componentSize;
protected boolean normalized;
protected int stride; // user given stride
protected int strideB; // stride in bytes
protected int strideL; // stride in logical components
- protected Class clazz;
protected Buffer buffer;
protected boolean isVertexAttribute;
- protected long bufferOffset;
+ protected long vboOffset;
protected int vboName;
- protected boolean vboUsage;
+ protected boolean vboEnabled;
+ protected int vboUsage;
+ protected int vboTarget;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/GLDataArrayHandler.java
new file mode 100644
index 000000000..74d49aa6c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLDataArrayHandler.java
@@ -0,0 +1,41 @@
+
+package com.jogamp.opengl.util;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.*;
+import com.jogamp.opengl.util.*;
+import java.nio.*;
+
+public class GLDataArrayHandler implements GLArrayHandler {
+ private GLArrayDataEditable ad;
+
+ public GLDataArrayHandler(GLArrayDataEditable ad) {
+ this.ad = ad;
+ }
+
+ public void enableBuffer(GL gl, boolean enable) {
+ GLPointerFunc glp = gl.getGL2ES1();
+ if(enable) {
+ Buffer buffer = ad.getBuffer();
+
+ if(ad.isVBO()) {
+ // always bind and refresh the VBO mgr,
+ // in case more than one gl*Pointer objects are in use
+ gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ if(!ad.isVBOWritten()) {
+ if(null!=buffer) {
+ gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSize(), buffer, ad.getVBOUsage());
+ }
+ ad.setVBOWritten(true);
+ }
+ } else if(null!=buffer) {
+ ad.setVBOWritten(true);
+ }
+ } else {
+ if(ad.isVBO()) {
+ gl.glBindBuffer(ad.getVBOTarget(), 0);
+ }
+ }
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java
index f0f5ea896..a825ca690 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -13,7 +13,7 @@ public class GLFixedArrayHandler implements GLArrayHandler {
this.ad = ad;
}
- protected final void passArrayPointer(GLPointerFunc gl) {
+ private final void passArrayPointer(GLPointerFunc gl) {
switch(ad.getIndex()) {
case GLPointerFunc.GL_VERTEX_ARRAY:
gl.glVertexPointer(ad);
@@ -42,21 +42,21 @@ public class GLFixedArrayHandler implements GLArrayHandler {
if(ad.isVBO()) {
// always bind and refresh the VBO mgr,
// in case more than one gl*Pointer objects are in use
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, ad.getVBOName());
- if(!ad.isBufferWritten()) {
+ gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ if(!ad.isVBOWritten()) {
if(null!=buffer) {
- gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * ad.getComponentSize(), buffer, ad.getBufferUsage());
+ gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSize(), buffer, ad.getVBOUsage());
}
- ad.setBufferWritten(true);
+ ad.setVBOWritten(true);
}
passArrayPointer(glp);
} else if(null!=buffer) {
passArrayPointer(glp);
- ad.setBufferWritten(true);
+ ad.setVBOWritten(true);
}
} else {
if(ad.isVBO()) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ gl.glBindBuffer(ad.getVBOTarget(), 0);
}
glp.glDisableClientState(ad.getIndex());
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index d9fce6e6a..9e92a9a1d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -2,6 +2,8 @@
package com.jogamp.opengl.util;
import com.jogamp.common.util.*;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
import javax.media.opengl.*;
import javax.media.opengl.fixedfunc.*;
import java.nio.*;
@@ -35,8 +37,8 @@ public class ImmModeSink {
* a ShaderState must be current, using ShaderState.glUseProgram().
*
* @see #draw(GL, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
public static ImmModeSink createGLSL(GL gl, int glBufferUsage, int initialSize,
int vComps, int vDataType,
@@ -745,11 +747,11 @@ public class ImmModeSink {
}
public void enableBufferGLSL(GL gl, boolean enable) {
- GL2ES2 glsl = gl.getGL2ES2();
- com.jogamp.opengl.util.glsl.ShaderState st = com.jogamp.opengl.util.glsl.ShaderState.getCurrent();
+ ShaderState st = ShaderState.getShaderState(gl);
if(null==st) {
- throw new GLException("No ShaderState current");
- }
+ throw new GLException("No ShaderState in "+gl);
+ }
+ GL2ES2 glsl = gl.getGL2ES2();
if(enable) {
glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
@@ -760,35 +762,35 @@ public class ImmModeSink {
}
if(vComps>0) {
- st.glEnableVertexAttribArray(glsl, vArrayData.getName());
- st.glVertexAttribPointer(glsl, vArrayData);
+ st.enableVertexAttribArray(glsl, vArrayData);
+ st.vertexAttribPointer(glsl, vArrayData);
}
if(cComps>0) {
- st.glEnableVertexAttribArray(glsl, cArrayData.getName());
- st.glVertexAttribPointer(glsl, cArrayData);
+ st.enableVertexAttribArray(glsl, cArrayData);
+ st.vertexAttribPointer(glsl, cArrayData);
}
if(nComps>0) {
- st.glEnableVertexAttribArray(glsl, nArrayData.getName());
- st.glVertexAttribPointer(glsl, nArrayData);
+ st.enableVertexAttribArray(glsl, nArrayData);
+ st.vertexAttribPointer(glsl, nArrayData);
}
if(tComps>0) {
- st.glEnableVertexAttribArray(glsl, tArrayData.getName());
- st.glVertexAttribPointer(glsl, tArrayData);
+ st.enableVertexAttribArray(glsl, tArrayData);
+ st.vertexAttribPointer(glsl, tArrayData);
}
glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
} else {
if(vComps>0) {
- st.glDisableVertexAttribArray(glsl, vArrayData.getName());
+ st.disableVertexAttribArray(glsl, vArrayData);
}
if(cComps>0) {
- st.glDisableVertexAttribArray(glsl, cArrayData.getName());
+ st.disableVertexAttribArray(glsl, cArrayData);
}
if(nComps>0) {
- st.glDisableVertexAttribArray(glsl, nArrayData.getName());
+ st.disableVertexAttribArray(glsl, nArrayData);
}
if(tComps>0) {
- st.glDisableVertexAttribArray(glsl, tArrayData.getName());
+ st.disableVertexAttribArray(glsl, tArrayData);
}
}
}
@@ -860,26 +862,26 @@ public class ImmModeSink {
buffer.flip();
if(vComps>0) {
- vArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_VERTEX_ARRAY, vComps, vDataType, false,
- 0, vertexArray, 0, vOffset);
+ vArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_VERTEX_ARRAY, vComps, vDataType, false, 0,
+ vertexArray, 0, vOffset, GL.GL_STATIC_DRAW);
} else {
vArrayData = null;
}
if(cComps>0) {
- cArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_COLOR_ARRAY, cComps, cDataType, false,
- 0, colorArray, 0, cOffset);
+ cArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_COLOR_ARRAY, cComps, cDataType, false, 0,
+ colorArray, 0, cOffset, GL.GL_STATIC_DRAW);
} else {
cArrayData = null;
}
if(nComps>0) {
- nArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_NORMAL_ARRAY, nComps, nDataType, false,
- 0, normalArray, 0, nOffset);
+ nArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_NORMAL_ARRAY, nComps, nDataType, false, 0,
+ normalArray, 0, nOffset, GL.GL_STATIC_DRAW);
} else {
nArrayData = null;
}
if(tComps>0) {
- tArrayData = GLArrayDataWrapper.createFixed(gl, GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, tDataType, false,
- 0, textCoordArray, 0, tOffset);
+ tArrayData = GLArrayDataWrapper.createFixed(GLPointerFunc.GL_TEXTURE_COORD_ARRAY, tComps, tDataType, false, 0,
+ textCoordArray, 0, tOffset, GL.GL_STATIC_DRAW);
} else {
tArrayData = null;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Locator.java b/src/jogl/classes/com/jogamp/opengl/util/Locator.java
index 8dbd7cd93..0176b575a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Locator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Locator.java
@@ -49,6 +49,9 @@ public class Locator {
* @see #getResource(String, ClassLoader)
*/
public static URL getResource(Class context, String path) {
+ if(null == path) {
+ return null;
+ }
ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
URL url = getResource(path, contextCL);
if (url == null && null!=context) {
@@ -73,24 +76,36 @@ public class Locator {
* @see File#File(String)
*/
public static URL getResource(String path, ClassLoader cl) {
+ if(null == path) {
+ return null;
+ }
URL url = null;
if (cl != null) {
url = cl.getResource(path);
- } else {
+ if(!urlExists(url)) {
+ url = null;
+ }
+ }
+ if(null == url) {
url = ClassLoader.getSystemResource(path);
+ if(!urlExists(url)) {
+ url = null;
+ }
}
- if(!urlExists(url)) {
- url = null;
+ if(null == url) {
try {
url = new URL(path);
+ if(!urlExists(url)) {
+ url = null;
+ }
} catch (MalformedURLException e) { }
}
- if(!urlExists(url)) {
- url = null;
+ if(null == url) {
try {
File file = new File(path);
if(file.exists()) {
url = file.toURL();
+ } else {
}
} catch (MalformedURLException e) {}
}
@@ -98,25 +113,53 @@ public class Locator {
}
/**
- * Generates a path for the 'relativeFile' relative to the 'absoluteFileLocation'
+ * Generates a path for the 'relativeFile' relative to the 'baseLocation'.
+ *
+ * @param baseLocation denotes a directory
+ * @param relativeFile denotes a relative file to the baseLocation
*/
- public static String getRelativeOf(String absoluteFileLocation, String relativeFile) {
- File file = new File(absoluteFileLocation);
- file = file.getParentFile();
- while (file != null && relativeFile.startsWith("../")) {
- file = file.getParentFile();
+ public static String getRelativeOf(File baseLocation, String relativeFile) {
+ if(null == relativeFile) {
+ return null;
+ }
+
+ while (baseLocation != null && relativeFile.startsWith("../")) {
+ baseLocation = baseLocation.getParentFile();
relativeFile = relativeFile.substring(3);
}
- if (file != null) {
- String res = new File(file, relativeFile).getPath();
- // Handle things on Windows
- return res.replace('\\', '/');
- } else {
- return relativeFile;
+ if (baseLocation != null) {
+ final File file = new File(baseLocation, relativeFile);
+ // Handle things on Windows
+ return file.getPath().replace('\\', '/');
}
+ return null;
}
/**
+ * Generates a path for the 'relativeFile' relative to the 'baseLocation'.
+ *
+ * @param baseLocation denotes a URL to a file
+ * @param relativeFile denotes a relative file to the baseLocation's parent directory
+ */
+ public static String getRelativeOf(URL baseLocation, String relativeFile) {
+ String urlPath = baseLocation.getPath();
+
+ if ( baseLocation.toString().startsWith("jar") ) {
+ JarURLConnection jarConnection;
+ try {
+ jarConnection = (JarURLConnection) baseLocation.openConnection();
+ urlPath = jarConnection.getEntryName();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ // Try relative path first
+ return getRelativeOf(new File(urlPath).getParentFile(), relativeFile);
+ }
+
+ /**
* Returns true, if the url exists,
* trying to open a connection.
*/
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index 86882176a..de28dc70a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -1590,7 +1590,7 @@ public class TextRenderer {
int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs();
int i = 0;
while (i < lengthInGlyphs) {
- Character letter = CharacterCache.valueOf(inString.charAt(i));
+ Character letter = CharacterCache.valueOf(inString.charAt(i));
GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter);
if (metrics == null) {
metrics = fullRunGlyphVector.getGlyphMetrics(i);
@@ -1656,7 +1656,7 @@ public class TextRenderer {
// if the unicode or glyph ID would be out of bounds of the
// glyph cache.
private Glyph getGlyph(CharSequence inString,
- GlyphMetrics glyphMetrics,
+ GlyphMetrics glyphMetrics,
int index) {
char unicodeID = inString.charAt(index);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
index 86dca59f4..922fc69c1 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
@@ -307,7 +307,7 @@ public class TextureRenderer {
*/
public void dispose() throws GLException {
if (texture != null) {
- texture.dispose();
+ texture.destroy(GLContext.getCurrentGL());
texture = null;
}
if (image != null) {
@@ -576,23 +576,23 @@ public class TextureRenderer {
gl.glEnable(GL2.GL_BLEND);
gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
Texture texture = getTexture();
- texture.enable();
- texture.bind();
+ texture.enable(gl);
+ texture.bind(gl);
gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
// Change polygon color to last saved
gl.glColor4f(r, g, b, a);
if (smoothingChanged) {
smoothingChanged = false;
if (smoothing) {
- texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
if (mipmap) {
- texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR_MIPMAP_LINEAR);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR_MIPMAP_LINEAR);
} else {
- texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
}
} else {
- texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
- texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
}
}
}
@@ -600,7 +600,7 @@ public class TextureRenderer {
private void endRendering(boolean ortho) {
GL2 gl = GLContext.getCurrentGL().getGL2();
Texture texture = getTexture();
- texture.disable();
+ texture.disable(gl);
if (ortho) {
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPopMatrix();
@@ -661,15 +661,16 @@ public class TextureRenderer {
// OpenGL and Java 2D actually line up correctly for
// updateSubImage calls, so we don't need to do any argument
// conversion here (i.e., flipping the Y coordinate).
- texture.updateSubImage(textureData, 0, x, y, x, y, width, height);
+ texture.updateSubImage(GLContext.getCurrentGL(), textureData, 0, x, y, x, y, width, height);
}
}
// Returns true if the texture was newly allocated, false if not
private boolean ensureTexture() {
+ GL gl = GLContext.getCurrentGL();
if (mustReallocateTexture) {
if (texture != null) {
- texture.dispose();
+ texture.destroy(gl);
texture = null;
}
mustReallocateTexture = false;
@@ -679,7 +680,7 @@ public class TextureRenderer {
texture = TextureIO.newTexture(textureData);
if (mipmap && !texture.isUsingAutoMipmapGeneration()) {
// Only try this once
- texture.dispose();
+ texture.destroy(gl);
mipmap = false;
textureData.setMipmap(false);
texture = TextureIO.newTexture(textureData);
@@ -687,8 +688,8 @@ public class TextureRenderer {
if (!smoothing) {
// The TextureIO classes default to GL_LINEAR filtering
- texture.setTexParameteri(GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
- texture.setTexParameteri(GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
+ texture.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
}
return true;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java
index 8befc13ba..010ce6699 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/gl2/GLUT.java
@@ -163,7 +163,7 @@ public class GLUT {
public void glutSolidCylinder(double radius, double height, int slices, int stacks) {
GL2 gl = GLUgl2.getCurrentGL2();
-
+
// Prepare table of points for drawing end caps
double [] x = new double[slices];
double [] y = new double[slices];
@@ -174,7 +174,7 @@ public class GLUT {
x[i] = Math.cos(angle) * radius;
y[i] = Math.sin(angle) * radius;
}
-
+
// Draw bottom cap
gl.glBegin(GL2.GL_TRIANGLE_FAN);
gl.glNormal3d(0,0,-1);
@@ -184,7 +184,7 @@ public class GLUT {
}
gl.glVertex3d(x[0], y[0], 0);
gl.glEnd();
-
+
// Draw top cap
gl.glBegin(GL2.GL_TRIANGLE_FAN);
gl.glNormal3d(0,0,1);
@@ -194,7 +194,7 @@ public class GLUT {
}
gl.glVertex3d(x[0], y[0], height);
gl.glEnd();
-
+
// Draw walls
quadObjInit(glu);
glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index 95a550ab6..73a1c2721 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -28,56 +28,68 @@
package com.jogamp.opengl.util.glsl;
-import javax.media.opengl.*;
-import com.jogamp.opengl.util.*;
-import java.nio.*;
+import java.nio.Buffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+import com.jogamp.opengl.util.GLArrayDataEditable;
+import com.jogamp.opengl.util.GLArrayHandler;
public class GLSLArrayHandler implements GLArrayHandler {
+ private static final boolean DEBUG = ShaderState.DEBUG;
private GLArrayDataEditable ad;
+ private ShaderState st;
- public GLSLArrayHandler(GLArrayDataEditable ad) {
+ public GLSLArrayHandler(ShaderState st, GLArrayDataEditable ad) {
+ this.st = st;
this.ad = ad;
}
- protected final void passVertexAttribPointer(GL2ES2 gl, ShaderState st) {
- st.glVertexAttribPointer(gl, ad);
- }
-
public void enableBuffer(GL gl, boolean enable) {
if(!gl.isGL2ES2()) {
throw new GLException("GLSLArrayHandler expects a GL2ES2 implementation");
}
GL2ES2 glsl = gl.getGL2ES2();
- ShaderState st = ShaderState.getCurrent();
- if(null==st) {
- throw new GLException("No ShaderState current");
- }
if(enable) {
- st.glEnableVertexAttribArray(glsl, ad.getName());
+ st.enableVertexAttribArray(glsl, ad);
Buffer buffer = ad.getBuffer();
if(ad.isVBO()) {
- // always bind and refresh the VBO mgr,
- // in case more than one gl*Pointer objects are in use
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, ad.getVBOName());
- if(!ad.isBufferWritten()) {
+ // bind and refresh the VBO / vertex-attr only if necessary
+ if(!ad.isVBOWritten()) {
+ if(DEBUG) {
+ System.err.println("XXX VA "+ad.getName()+" VBO write: "+ad.getVBOName());
+ }
+ glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
if(null!=buffer) {
- glsl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * ad.getComponentSize(), buffer, ad.getBufferUsage());
+ glsl.glBufferData(ad.getVBOTarget(), ad.getByteSize(), buffer, ad.getVBOUsage());
+ }
+ ad.setVBOWritten(true);
+ st.vertexAttribPointer(glsl, ad);
+ } else {
+ // didn't experience a performance hit on this query ..
+ int[] qi = new int[1];
+ glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
+ if(ad.getVBOName() != qi[0]) {
+ if(DEBUG) {
+ System.err.println("XXX VA "+ad.getName()+" VBO rebind: "+qi[0]+" -> "+ad.getVBOName());
+ }
+ glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+ st.vertexAttribPointer(glsl, ad);
}
- ad.setBufferWritten(true);
}
- passVertexAttribPointer(glsl, st);
} else if(null!=buffer) {
- passVertexAttribPointer(glsl, st);
- ad.setBufferWritten(true);
+ st.vertexAttribPointer(glsl, ad);
+ ad.setVBOWritten(true);
}
} else {
if(ad.isVBO()) {
- glsl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
+ glsl.glBindBuffer(ad.getVBOTarget(), 0);
}
- st.glDisableVertexAttribArray(glsl, ad.getName());
+ st.disableVertexAttribArray(glsl, ad);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
index 1f59318f2..20b032a41 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderCode.java
@@ -155,9 +155,9 @@ public class ShaderCode {
return res;
}
}
- Set binFmts = ShaderUtil.getShaderBinaryFormats(gl);
- for(Iterator iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
- int bFmt = ((Integer)(iter.next())).intValue();
+ Set<Integer> binFmts = ShaderUtil.getShaderBinaryFormats(gl);
+ for(Iterator<Integer> iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
+ int bFmt = iter.next().intValue();
String bFmtPath = getBinarySubPath(bFmt);
if(null==bFmtPath) continue;
binFileName = binRoot + '/' + bFmtPath + '/' + basename + "." + getFileSuffix(true, type);
@@ -174,16 +174,8 @@ public class ShaderCode {
/**
* returns the uniq shader id as an integer
- * @see #key()
*/
- public int id() { return id.intValue(); }
-
- /**
- * returns the uniq shader id as an Integer
- *
- * @see #id()
- */
- public Integer key() { return id; }
+ public int id() { return id; }
public int shaderType() { return shaderType; }
public String shaderTypeStr() { return shaderTypeStr(shaderType); }
@@ -239,7 +231,7 @@ public class ShaderCode {
shaderSource=null;
shaderBinaryFormat=-1;
shaderType=-1;
- id=null;
+ id=-1;
}
public boolean equals(Object obj) {
@@ -250,7 +242,7 @@ public class ShaderCode {
return false;
}
public int hashCode() {
- return id.intValue();
+ return id;
}
public String toString() {
StringBuffer buf = new StringBuffer("ShaderCode [id="+id+", type="+shaderTypeStr()+", valid="+valid+", shader: ");
@@ -290,26 +282,35 @@ public class ShaderCode {
}
}
- public static void readShaderSource(ClassLoader context, String path, URL url, StringBuffer result) {
+ public static void readShaderSource(Class context, URL url, StringBuffer result) {
try {
+ if(DEBUG_CODE) {
+ System.err.println("ShaderCode.readShaderSource<0>: "+url);
+ }
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line = null;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#include ")) {
String includeFile = line.substring(9).trim();
+ URL nextURL = null;
+
// Try relative path first
- String next = Locator.getRelativeOf(path, includeFile);
- URL nextURL = Locator.getResource(next, context);
+ String next = Locator.getRelativeOf(url, includeFile);
+ if(null != next) {
+ nextURL = Locator.getResource(context, next);
+ }
if (nextURL == null) {
// Try absolute path
- next = includeFile;
- nextURL = Locator.getResource(next, context);
+ nextURL = Locator.getResource(context, includeFile);
}
if (nextURL == null) {
// Fail
throw new FileNotFoundException("Can't find include file " + includeFile);
}
- readShaderSource(context, next, nextURL, result);
+ if(DEBUG_CODE) {
+ System.err.println("ShaderCode.readShaderSource<I>: "+url+" + "+includeFile+" := "+nextURL);
+ }
+ readShaderSource(context, nextURL, result);
} else {
result.append(line + "\n");
}
@@ -320,16 +321,12 @@ public class ShaderCode {
}
public static String readShaderSource(Class context, String path) {
- ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
URL url = Locator.getResource(context, path);
if (url == null) {
return null;
- }
- File pf = new File(url.getPath());
- path = pf.getParent() + "/" ;
-
+ }
StringBuffer result = new StringBuffer();
- readShaderSource(contextCL, path, url, result);
+ readShaderSource(context, url, result);
return result.toString();
}
@@ -354,12 +351,12 @@ public class ShaderCode {
protected int shaderBinaryFormat = -1;
protected IntBuffer shader = null;
protected int shaderType = -1;
- protected Integer id = null;
+ protected int id = -1;
protected boolean valid=false;
- private static synchronized Integer getNextID() {
- return new Integer(nextID++);
+ private static synchronized int getNextID() {
+ return nextID++;
}
protected static int nextID = 1;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
index b6908c1a1..b622571e7 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java
@@ -30,11 +30,12 @@ package com.jogamp.opengl.util.glsl;
import javax.media.opengl.*;
-import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.io.PrintStream;
public class ShaderProgram {
+
public ShaderProgram() {
id = getNextID();
}
@@ -51,16 +52,8 @@ public class ShaderProgram {
/**
* returns the uniq shader id as an integer
- * @see #key()
- */
- public int id() { return id.intValue(); }
-
- /**
- * returns the uniq shader id as an Integer
- *
- * @see #id()
*/
- public Integer key() { return id; }
+ public int id() { return id; }
/**
* Detaches all shader codes and deletes the program.
@@ -88,15 +81,18 @@ public class ShaderProgram {
* If releaseShaderToo is true, destroys the shader codes as well.
*/
public synchronized void release(GL2ES2 gl, boolean releaseShaderToo) {
- glUseProgram(gl, false);
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- ShaderCode shaderCode = (ShaderCode) iter.next();
- ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader());
+ useProgram(gl, false);
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = iter.next();
+ if(attachedShaderCode.remove(shaderCode)) {
+ ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader());
+ }
if(releaseShaderToo) {
shaderCode.destroy(gl);
}
}
- shaderMap.clear();
+ allShaderCode.clear();
+ attachedShaderCode.clear();
gl.glDeleteProgram(shaderProgram);
shaderProgram=-1;
}
@@ -106,35 +102,78 @@ public class ShaderProgram {
//
/**
- * Adds a new shader to a this non running program.
- *
- * @return false if the program is in use, or the shader already exist,
- * otherwise true.
+ * Adds a new shader to this program.
+ *
+ * <p>This command does not compile and attach the shader,
+ * use {@link #add(GL2ES2, ShaderCode)} for this purpose.</p>
*/
- public synchronized boolean add(ShaderCode shaderCode) {
- if(shaderMap.containsKey(shaderCode.key())) return false;
- shaderMap.put(shaderCode.key(), shaderCode);
- return true;
+ public synchronized void add(ShaderCode shaderCode) throws GLException {
+ allShaderCode.add(shaderCode);
}
+ public synchronized boolean contains(ShaderCode shaderCode) {
+ return allShaderCode.contains(shaderCode);
+ }
+
+ /**
+ * Warning slow O(n) operation ..
+ * @param id
+ * @return
+ */
public synchronized ShaderCode getShader(int id) {
- return (ShaderCode) shaderMap.get(new Integer(id));
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = iter.next();
+ if(shaderCode.id() == id) {
+ return shaderCode;
+ }
+ }
+ return null;
}
//
- // Program handling
+ // ShaderCode / Program handling
//
/**
- * Replace a shader in a 'running' program.
- * Refetches all previously bin/get attribute names
- * and resets all attribute data as well
+ * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
+ *
+ * @param gl
+ */
+ public synchronized final void init(GL2ES2 gl) {
+ if(0>shaderProgram) {
+ shaderProgram = gl.glCreateProgram();
+ }
+ }
+
+ /**
+ * Adds a new shader to a this non running program.
+ *
+ * <p>Compiles and attaches the shader, if not done yet.</p>
+ *
+ * @return true if the shader was successfully added, false if compilation failed.
+ */
+ public synchronized boolean add(GL2ES2 gl, ShaderCode shaderCode, PrintStream verboseOut) {
+ init(gl);
+ if( allShaderCode.add(shaderCode) ) {
+ if(!shaderCode.compile(gl, verboseOut)) {
+ return false;
+ }
+ if(attachedShaderCode.add(shaderCode)) {
+ ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Replace a shader in a program and re-links the program.
*
* @param gl
- * @param oldShaderID the to be replace Shader
+ * @param oldShader the to be replace Shader
* @param newShader the new ShaderCode
- * @param verboseOut the optional verbose outputstream
- * @throws GLException is the program is not linked
+ * @param verboseOut the optional verbose output stream
+ *
+ * @return true if all steps are valid, shader compilation, attachment and linking; otherwise false.
*
* @see ShaderState#glEnableVertexAttribArray
* @see ShaderState#glDisableVertexAttribArray
@@ -145,47 +184,44 @@ public class ShaderProgram {
* @see ShaderState#glResetAllVertexAttributes
* @see ShaderState#glResetAllVertexAttributes
*/
- public synchronized boolean glReplaceShader(GL2ES2 gl, int oldShaderID, ShaderCode newShader, PrintStream verboseOut) {
- if(!programLinked) throw new GLException("Program is not linked");
- boolean shaderWasInUse = programInUse;
- glUseProgram(gl, false);
+ public synchronized boolean replaceShader(GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) {
+ init(gl);
+
if(!newShader.compile(gl, verboseOut)) {
return false;
- }
- if(oldShaderID>=0) {
- ShaderCode oldShader = (ShaderCode) shaderMap.remove(new Integer(oldShaderID));
- if(null!=oldShader) {
+ }
+
+ boolean shaderWasInUse = inUse();
+ if(shaderWasInUse) {
+ useProgram(gl, false);
+ }
+
+ if(null != oldShader && allShaderCode.remove(oldShader)) {
+ if(attachedShaderCode.remove(oldShader)) {
ShaderUtil.detachShader(gl, shaderProgram, oldShader.shader());
}
}
+
add(newShader);
-
- ShaderUtil.attachShader(gl, shaderProgram, newShader.shader());
- gl.glLinkProgram(shaderProgram);
- if ( ! ShaderUtil.isProgramValid(gl, shaderProgram, System.err) ) {
- return false;
+ if(attachedShaderCode.add(newShader)) {
+ ShaderUtil.attachShader(gl, shaderProgram, newShader.shader());
}
-
- if(shaderWasInUse) {
- glUseProgram(gl, true);
+
+ gl.glLinkProgram(shaderProgram);
+
+ programLinked = ShaderUtil.isProgramValid(gl, shaderProgram, System.err);
+ if ( programLinked && shaderWasInUse ) {
+ useProgram(gl, true);
}
- return true;
+ return programLinked;
}
/**
- * Creates the empty GL program object using {@link GL2ES2#glCreateProgram()}
- *
- * @param gl
- */
- public final void init(GL2ES2 gl) {
- if(0>shaderProgram) {
- shaderProgram = gl.glCreateProgram();
- }
- }
-
- /**
- * Compiles and links the shader code to the program.
- * Within this process, all GL resources (shader and program objects) are created if necessary.
+ * Links the shader code to the program.
+ *
+ * <p>Compiles and attaches the shader code to the program if not done by yet</p>
+ *
+ * <p>Within this process, all GL resources (shader and program objects) are created if necessary.</p>
*
* @param gl
* @param verboseOut
@@ -194,18 +230,16 @@ public class ShaderProgram {
* @see #init(GL2ES2)
*/
public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
- if(programLinked) throw new GLException("Program is already linked");
+ init(gl);
- if(0>shaderProgram) {
- shaderProgram = gl.glCreateProgram();
- }
-
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- ShaderCode shaderCode = (ShaderCode) iter.next();
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ final ShaderCode shaderCode = iter.next();
if(!shaderCode.compile(gl, verboseOut)) {
return false;
}
- ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ if(attachedShaderCode.add(shaderCode)) {
+ ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader());
+ }
}
// Link the program
@@ -225,40 +259,37 @@ public class ShaderProgram {
}
public int hashCode() {
- return id.intValue();
+ return id;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("ShaderProgram[id="+id);
buf.append(", linked="+programLinked+", inUse="+programInUse+", program: "+shaderProgram+", [");
- for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
- buf.append((ShaderCode) iter.next());
+ for(Iterator<ShaderCode> iter=allShaderCode.iterator(); iter.hasNext(); ) {
+ buf.append(iter.next());
buf.append(" ");
}
buf.append("]");
return buf.toString();
}
- protected synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ protected synchronized void useProgram(GL2ES2 gl, boolean on) {
if(!programLinked) throw new GLException("Program is not linked");
if(programInUse==on) return;
gl.glUseProgram(on?shaderProgram:0);
programInUse = on;
-
- //Throwable tX = new Throwable("Info: ShaderProgram.glUseProgram: "+on);
- //tX.printStackTrace();
-
}
protected boolean programLinked = false;
protected boolean programInUse = false;
protected int shaderProgram=-1;
- protected HashMap shaderMap = new HashMap();
- protected Integer id = null;
+ protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>();
+ protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>();
+ protected int id = -1;
- private static synchronized Integer getNextID() {
- return new Integer(nextID++);
+ private static synchronized int getNextID() {
+ return nextID++;
}
protected static int nextID = 1;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
index 57ae6cfda..f8fe987d7 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java
@@ -28,13 +28,23 @@
package com.jogamp.opengl.util.glsl;
-import javax.media.opengl.*;
-import jogamp.opengl.Debug;
-
+import java.security.AccessController;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.security.*;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLArrayData;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLUniformData;
+
+import jogamp.opengl.Debug;
+
+import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.opengl.util.GLArrayDataEditable;
public class ShaderState {
public static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLSLState", true, AccessController.getContext());
@@ -47,38 +57,107 @@ public class ShaderState {
public void setVerbose(boolean v) { verbose=v; }
/**
- * Fetches the current shader state from the thread local storage (TLS)
+ * Fetches the current shader state from this thread (TLS) current GLContext
*
- * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
- public static synchronized ShaderState getCurrent() {
- GLContext current = GLContext.getCurrent();
- if(null==current) {
- throw new GLException("No context is current on this thread");
- }
- return (ShaderState) current.getAttachedObject(ShaderState.class.getName());
+ public static synchronized ShaderState getCurrentShaderState() {
+ return getShaderState(GLContext.getCurrentGL());
+ }
+
+ /**
+ * Fetches the shader state from the GL object's GLContext
+ *
+ * @param gl the GL object referencing the GLContext
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
+ */
+ public static synchronized ShaderState getShaderState(GL gl) {
+ return (ShaderState) gl.getContext().getAttachedObject(ShaderState.class.getName());
+ }
+
+ /**
+ * Returns the attached user object for the given name to this ShaderState.
+ */
+ public final Object getAttachedObject(String name) {
+ return attachedObjectsByString.get(name);
}
/**
+ * Attach user object for the given name to this ShaderState.
+ * Returns the previously set object or null.
+ *
+ * @return the previous mapped object or null if none
+ */
+ public final Object attachObject(String name, Object obj) {
+ return attachedObjectsByString.put(name, obj);
+ }
+
+ /**
+ * @param name name of the mapped object to detach
+ *
+ * @return the previous mapped object or null if none
+ */
+ public final Object detachObject(String name) {
+ return attachedObjectsByString.remove(name);
+ }
+
+ /**
+ * Returns the attached user object for the given name to this ShaderState.
+ */
+ public final Object getAttachedObject(int name) {
+ return attachedObjectsByInt.get(name);
+ }
+
+ /**
+ * Attach user object for the given name to this ShaderState.
+ * Returns the previously set object or null.
+ */
+ public final Object attachObject(int name, Object obj) {
+ return attachedObjectsByInt.put(name, obj);
+ }
+
+ public final Object detachObject(int name) {
+ return attachedObjectsByInt.remove(name);
+ }
+
+ /**
* Turns the shader program on or off.<br>
* Puts this ShaderState to to the thread local storage (TLS),
* if <code>on</code> is <code>true</code>.
*
- * @see com.jogamp.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrent()
+ * @throws GLException if no program is attached
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#useProgram(GL2ES2, boolean)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getShaderState(GL)
+ * @see com.jogamp.opengl.util.glsl.ShaderState#getCurrentShaderState()
*/
- public synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ public synchronized void useProgram(GL2ES2 gl, boolean on) throws GLException {
+ if(null==shaderProgram) { throw new GLException("No program is attached"); }
if(on) {
- if(null!=shaderProgram) {
- shaderProgram.glUseProgram(gl, true);
- } else {
- throw new GLException("No program is attached");
- }
// update the current ShaderState to the TLS ..
- gl.getContext().putAttachedObject(ShaderState.class.getName(), this);
- } else if(null!=shaderProgram) {
- shaderProgram.glUseProgram(gl, false);
+ gl.getContext().attachObject(ShaderState.class.getName(), this);
+ if(shaderProgram.linked()) {
+ shaderProgram.useProgram(gl, true);
+ if(resetAllShaderData) {
+ resetAllAttributes(gl);
+ resetAllUniforms(gl);
+ }
+ } else if(resetAllShaderData) {
+ setAllAttributes(gl);
+ if(!shaderProgram.link(gl, System.err)) {
+ throw new GLException("could not link program: "+shaderProgram);
+ }
+ shaderProgram.useProgram(gl, true);
+ resetAllUniforms(gl);
+ }
+ resetAllShaderData = false;
+ } else {
+ shaderProgram.useProgram(gl, false);
}
}
@@ -93,11 +172,16 @@ public class ShaderState {
/**
* Attach or switch a shader program
*
- * Attaching a shader program the first time,
+ * <p>Attaching a shader program the first time,
* as well as switching to another program on the fly,
- * while managing all attribute and uniform data.
+ * while managing all attribute and uniform data.</p>
+ *
+ * <p>[Re]sets all data and use program in case of a program switch.<br>
+ * Use program if linked in case of a 1st time attachment.</p>
+ *
+ * @throws GLException if program was not linked and linking fails
*/
- public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog) {
+ public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog) throws GLException {
boolean prgInUse = false; // earmarked state
if(DEBUG) {
@@ -118,19 +202,21 @@ public class ShaderState {
return;
}
prgInUse = shaderProgram.inUse();
- shaderProgram.glUseProgram(gl, false);
+ useProgram(gl, false);
+ resetAllShaderData = true;
}
// register new one
shaderProgram = prog;
if(null!=shaderProgram) {
- // reinstall all data ..
- shaderProgram.glUseProgram(gl, true);
- glResetAllVertexAttributes(gl);
- glResetAllUniforms(gl);
- if(!prgInUse) {
- shaderProgram.glUseProgram(gl, false);
+ // [re]set all data and use program if switching program,
+ // or use program if program is linked
+ if(shaderProgram.linked() || resetAllShaderData) {
+ useProgram(gl, true);
+ if(!prgInUse) {
+ shaderProgram.useProgram(gl, false);
+ }
}
}
if(DEBUG) {
@@ -141,25 +227,27 @@ public class ShaderState {
public ShaderProgram shaderProgram() { return shaderProgram; }
/**
- * Calls release(gl, true, true)
+ * Calls {@link #release(GL2ES2, boolean, boolean, boolean) release(gl, true, true, true)}
*
* @see #glReleaseAllVertexAttributes
* @see #glReleaseAllUniforms
- * @see #release(GL2ES2, boolean, boolean)
+ * @see #release(GL2ES2, boolean, boolean, boolean)
*/
public synchronized void destroy(GL2ES2 gl) {
- release(gl, true, true);
+ release(gl, true, true, true);
+ attachedObjectsByString.clear();
+ attachedObjectsByInt.clear();
}
/**
- * Calls release(gl, false, false)
+ * Calls {@link #release(GL2ES2, boolean, boolean, boolean) release(gl, false, false, false)}
*
* @see #glReleaseAllVertexAttributes
* @see #glReleaseAllUniforms
- * @see #release(GL2ES2, boolean, boolean)
+ * @see #release(GL2ES2, boolean, boolean, boolean)
*/
public synchronized void releaseAllData(GL2ES2 gl) {
- release(gl, false, false);
+ release(gl, false, false, false);
}
/**
@@ -167,22 +255,21 @@ public class ShaderState {
* @see #glReleaseAllUniforms
* @see ShaderProgram#release(GL2ES2, boolean)
*/
- public synchronized void release(GL2ES2 gl, boolean releaseProgramToo, boolean releaseShaderToo) {
- boolean prgInUse = false;
- if(null!=shaderProgram) {
- prgInUse = shaderProgram.inUse();
- if(!prgInUse) {
- shaderProgram.glUseProgram(gl, true);
- }
+ public synchronized void release(GL2ES2 gl, boolean destroyBoundAttributes, boolean releaseProgramToo, boolean releaseShaderToo) {
+ if(null!=shaderProgram) {
+ shaderProgram.useProgram(gl, false);
}
- glReleaseAllVertexAttributes(gl);
- glReleaseAllUniforms(gl);
+ if(destroyBoundAttributes) {
+ for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
+ iter.next().destroy(gl);
+ }
+ }
+ releaseAllAttributes(gl);
+ releaseAllUniforms(gl);
if(null!=shaderProgram) {
if(releaseProgramToo) {
shaderProgram.release(gl, releaseShaderToo);
- } else if(!prgInUse) {
- shaderProgram.glUseProgram(gl, false);
- }
+ }
}
}
@@ -191,226 +278,379 @@ public class ShaderState {
//
/**
- * Binds an attribute to the shader.
- * This must be done before the program is linked !
- * n name - 1 idx, where name is a uniq key
+ * Gets the cached location of a shader attribute.
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ *
+ * @see #bindAttribLocation(GL2ES2, int, String)
+ * @see #bindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #getAttribLocation(GL2ES2, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
+ */
+ public int getAttribLocation(String name) {
+ Integer idx = (Integer) activeAttribLocationMap.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+ /**
+ * Get the previous cached vertex attribute data.
*
- * @throws GLException is the program is already linked
+ * @return the GLArrayData object, null if not previously set.
+ *
+ * @see #ownAttribute(GLArrayData, boolean)
*
- * @see #glBindAttribLocation
- * @see javax.media.opengl.GL2ES2#glBindAttribLocation
- * @see #glGetAttribLocation
- * @see javax.media.opengl.GL2ES2#glGetAttribLocation
- * @see #getAttribLocation
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
* @see ShaderProgram#glReplaceShader
*/
- public void glBindAttribLocation(GL2ES2 gl, int index, String name) {
- if(null==shaderProgram) throw new GLException("No program is attached");
- if(shaderProgram.linked()) throw new GLException("Program is already linked");
- Integer idx = new Integer(index);
- if(!attribMap2Idx.containsKey(name)) {
- attribMap2Idx.put(name, idx);
- gl.glBindAttribLocation(shaderProgram.program(), index, name);
+ public GLArrayData getAttribute(String name) {
+ return (GLArrayData) activeAttribDataMap.get(name);
+ }
+
+ /**
+ * Binds or unbinds the {@link GLArrayData} lifecycle to this ShaderState.
+ *
+ * <p>If an attribute location is cached (ie {@link #bindAttribLocation(GL2ES2, int, String)})
+ * it is promoted to the {@link GLArrayData} instance.</p>
+ *
+ * <p>The attribute will be destroyed with {@link #destroy(GL2ES2)}
+ * and it's location will be reset when switching shader with {@link #attachShaderProgram(GL2ES2, ShaderProgram)}.</p>
+ *
+ * <p>The data will not be transfered to the GPU, use {@link #vertexAttribPointer(GL2ES2, GLArrayData)} additionally.</p>
+ *
+ * @param attribute the {@link GLArrayData} which lifecycle shall be managed
+ * @param own true if <i>owning</i> shall be performs, false if <i>disowning</i>.
+ *
+ * @see #bindAttribLocation(GL2ES2, int, String)
+ * @see #getAttribute(String)
+ */
+ public void ownAttribute(GLArrayData attribute, boolean own) {
+ if(own) {
+ final int location = getAttribLocation(attribute.getName());
+ if(0<=location) {
+ attribute.setLocation(location);
+ }
+ managedAttributes.add(managedAttributes.size(), attribute);
+ } else {
+ managedAttributes.remove(attribute);
}
}
+
+ public boolean ownsAttribute(GLArrayData attribute) {
+ return managedAttributes.contains(attribute);
+ }
+
+ /**
+ * Binds a shader attribute to a location.
+ * Multiple names can be bound to one location.
+ * The value will be cached and can be retrieved via {@link #getAttribLocation(String)}
+ * before or after linking.
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is already linked
+ *
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String)
+ * @see #getAttribLocation(GL2ES2, String)
+ * @see #getAttribLocation(String)
+ */
+ public void bindAttribLocation(GL2ES2 gl, int location, String name) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ final Integer loc = new Integer(location);
+ activeAttribLocationMap.put(name, loc);
+ gl.glBindAttribLocation(shaderProgram.program(), location, name);
+ }
+
+ /**
+ * Binds a shader {@link GLArrayData} attribute to a location.
+ * Multiple names can be bound to one location.
+ * The value will be cached and can be retrieved via {@link #getAttribLocation(String)}
+ * and {@link #getAttribute(String)}before or after linking.
+ * The {@link GLArrayData}'s location will be set as well.
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is already linked
+ *
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String)
+ * @see #getAttribLocation(GL2ES2, String)
+ * @see #getAttribLocation(String)
+ * @see #getAttribute(String)
+ */
+ public void bindAttribLocation(GL2ES2 gl, int location, GLArrayData data) {
+ bindAttribLocation(gl, location, data.getName());
+ data.setLocation(location);
+ activeAttribDataMap.put(data.getName(), data);
+ }
/**
- * Gets the index of a shader attribute.
- * This must be done after the program is linked !
+ * Gets the location of a shader attribute,
+ * either the cached value {@link #getAttribLocation(String)} if valid or
+ * the retrieved one {@link GL2ES2#glGetAttribLocation(int, String)}.
+ * In the latter case the value will be cached.
*
* @return -1 if there is no such attribute available,
* otherwise >= 0
- * @throws GLException is the program is not linked
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
*
- * @see #glBindAttribLocation
- * @see javax.media.opengl.GL2ES2#glBindAttribLocation
- * @see #glGetAttribLocation
- * @see javax.media.opengl.GL2ES2#glGetAttribLocation
- * @see #getAttribLocation
- * @see ShaderProgram#glReplaceShader
+ * @see #getAttribLocation(String)
+ * @see #bindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #bindAttribLocation(GL2ES2, int, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
*/
- public int glGetAttribLocation(GL2ES2 gl, String name) {
- if(!shaderProgram.linked()) throw new GLException("Program is not linked");
- int index = getAttribLocation(name);
- if(0>index) {
- index = gl.glGetAttribLocation(shaderProgram.program(), name);
- if(0<=index) {
- Integer idx = new Integer(index);
- attribMap2Idx.put(name, idx);
+ public int getAttribLocation(GL2ES2 gl, String name) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ int location = getAttribLocation(name);
+ if(0>location) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ location = gl.glGetAttribLocation(shaderProgram.program(), name);
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeAttribLocationMap.put(name, idx);
if(DEBUG) {
- System.err.println("Info: glGetAttribLocation: "+name+", loc: "+index);
+ System.err.println("Info: glGetAttribLocation: "+name+", loc: "+location);
}
} else if(verbose) {
- Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", index: "+index);
+ Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", loc: "+location);
tX.printStackTrace();
}
}
- return index;
+ return location;
}
- protected int getAttribLocation(String name) {
- Integer idx = (Integer) attribMap2Idx.get(name);
- return (null!=idx)?idx.intValue():-1;
+ /**
+ * Gets the location of a shader attribute,
+ * either the cached value {@link #getAttribLocation(String)} if valid or
+ * the retrieved one {@link GL2ES2#glGetAttribLocation(int, String)}.
+ * In the latter case the value will be cached.
+ * The {@link GLArrayData}'s location will be set as well.
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
+ * @see #getAttribLocation(String)
+ * @see #bindAttribLocation(GL2ES2, int, GLArrayData)
+ * @see #bindAttribLocation(GL2ES2, int, String)
+ * @see GL2ES2#glGetAttribLocation(int, String)
+ * @see #getAttribute(String)
+ */
+ public int getAttribLocation(GL2ES2 gl, GLArrayData data) {
+ int location = getAttribLocation(gl, data.getName());
+ data.setLocation(location);
+ activeAttribDataMap.put(data.getName(), data);
+ return location;
}
-
-
+
//
// Enabled Vertex Arrays and its data
//
/**
- * Enable a vertex attribute array
+ * @return true if the named attribute is enable
+ */
+ public final boolean isVertexAttribArrayEnabled(String name) {
+ return enabledAttributes.contains(name);
+ }
+
+ /**
+ * @return true if the {@link GLArrayData} attribute is enable
+ */
+ public final boolean isVertexAttribArrayEnabled(GLArrayData data) {
+ return isVertexAttribArrayEnabled(data.getName());
+ }
+
+ private boolean enableVertexAttribArray(GL2ES2 gl, String name, int location) {
+ enabledAttributes.add(name);
+ if(0>location) {
+ location = getAttribLocation(gl, name);
+ if(0>location) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+location);
+ }
+ gl.glEnableVertexAttribArray(location);
+ return true;
+ }
+
+ /**
+ * Enables a vertex attribute array.
+ *
+ * This method retrieves the the location via {@link #getAttribLocation(GL2ES2, GLArrayData)}
+ * hence {@link #enableVertexAttribArray(GL2ES2, GLArrayData)} shall be preferred.
*
* Even if the attribute is not found in the current shader,
- * it is stored in this state.
+ * it is marked enabled in this state.
*
* @return false, if the name is not found, otherwise true
*
- * @throws GLException if the program is not in use
- *
+ * @throws GLException if the program is not linked and no location was cached.
+ *
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
*/
- public boolean glEnableVertexAttribArray(GL2ES2 gl, String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- enabledVertexAttribArraySet.add(name);
- int index = glGetAttribLocation(gl, name);
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
- }
- return false;
- }
- if(DEBUG) {
- System.err.println("Info: glEnableVertexAttribArray: "+name+", loc: "+index);
- }
- gl.glEnableVertexAttribArray(index);
- return true;
- }
-
- public boolean isVertexAttribArrayEnabled(String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- return enabledVertexAttribArraySet.contains(name);
+ public boolean enableVertexAttribArray(GL2ES2 gl, String name) {
+ return enableVertexAttribArray(gl, name, -1);
}
+
/**
- * Disables a vertex attribute array
+ * Enables a vertex attribute array, usually invoked by {@link GLArrayDataEditable#enableBuffer(GL, boolean)}.
*
+ * This method uses the {@link GLArrayData}'s location if set
+ * and is the preferred alternative to {@link #enableVertexAttribArray(GL2ES2, String)}.
+ * If data location is unset it will be retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)} set
+ * and cached in this state.
+ *
* Even if the attribute is not found in the current shader,
- * it is removed from this state.
+ * it is marked enabled in this state.
*
* @return false, if the name is not found, otherwise true
*
- * @throws GLException if the program is not in use
+ * @throws GLException if the program is not linked and no location was cached.
*
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
+ * @see GLArrayDataEditable#enableBuffer(GL, boolean)
*/
- public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- enabledVertexAttribArraySet.remove(name);
- int index = glGetAttribLocation(gl, name);
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
- tX.printStackTrace();
+ public boolean enableVertexAttribArray(GL2ES2 gl, GLArrayData data) {
+ if(0 > data.getLocation()) {
+ getAttribLocation(gl, data);
+ } else {
+ // ensure data is the current bound one
+ activeAttribDataMap.put(data.getName(), data);
+ }
+ return enableVertexAttribArray(gl, data.getName(), data.getLocation());
+ }
+
+ private boolean disableVertexAttribArray(GL2ES2 gl, String name, int location) {
+ enabledAttributes.remove(name);
+ if(0>location) {
+ location = getAttribLocation(gl, name);
+ if(0>location) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
}
- return false;
}
if(DEBUG) {
System.err.println("Info: glDisableVertexAttribArray: "+name);
}
- gl.glDisableVertexAttribArray(index);
+ gl.glDisableVertexAttribArray(location);
return true;
}
-
+
/**
- * Set the vertex attribute data.
- * Enable the attribute, if it is not enabled yet.
+ * Disables a vertex attribute array
*
+ * This method retrieves the the location via {@link #getAttribLocation(GL2ES2, GLArrayData)}
+ * hence {@link #disableVertexAttribArray(GL2ES2, GLArrayData)} shall be preferred.
+ *
* Even if the attribute is not found in the current shader,
- * it is stored in this state.
- *
- * @param data the GLArrayData's name must match the attributes one,
- * it's index will be set with the attribute's location,
- * if found.
+ * it is removed from this state enabled list.
*
* @return false, if the name is not found, otherwise true
*
- * @throws GLException if the program is not in use
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
*
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
*/
- public boolean glVertexAttribPointer(GL2ES2 gl, GLArrayData data) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- if(!enabledVertexAttribArraySet.contains(data.getName())) {
- if(!glEnableVertexAttribArray(gl, data.getName())) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glVertexAttribPointer: couldn't enable: "+data);
- tX.printStackTrace();
- }
- }
- }
- int index = getAttribLocation(data.getName());
- if(0>index) {
- if(verbose) {
- Throwable tX = new Throwable("Info: glVertexAttribPointer failed, no index for: "+data);
- tX.printStackTrace();
- }
- }
- data.setLocation(index);
- vertexAttribMap2Data.put(data.getName(), data);
- if(0<=index) {
- // only pass the data, if the attribute exists in the current shader
- if(DEBUG) {
- System.err.println("Info: glVertexAttribPointer: "+data);
- }
- gl.glVertexAttribPointer(data);
- return true;
- }
- return false;
+ public boolean disableVertexAttribArray(GL2ES2 gl, String name) {
+ return disableVertexAttribArray(gl, name, -1);
}
/**
- * Get the vertex attribute data, previously set.
+ * Disables a vertex attribute array
*
- * @return the GLArrayData object, null if not previously set.
+ * This method uses the {@link GLArrayData}'s location if set
+ * and is the preferred alternative to {@link #disableVertexAttribArray(GL2ES2, String)}.
+ * If data location is unset it will be retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)} set
+ * and cached in this state.
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is removed from this state enabled list.
+ *
+ * @return false, if the name is not found, otherwise true
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
*
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
* @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
*/
- public GLArrayData getVertexAttribPointer(String name) {
- return (GLArrayData) vertexAttribMap2Data.get(name);
+ public boolean disableVertexAttribArray(GL2ES2 gl, GLArrayData data) {
+ if(0 > data.getLocation()) {
+ getAttribLocation(gl, data);
+ }
+ return disableVertexAttribArray(gl, data.getName(), data.getLocation());
+ }
+
+ /**
+ * Set the {@link GLArrayData} vertex attribute data.
+ *
+ * This method uses the {@link GLArrayData}'s location if set.
+ * If data location is unset it will be retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)}, set
+ * and cached in this state.
+ *
+ * @return false, if the location could not be determined, otherwise true
+ *
+ * @throws GLException if no program is attached
+ * @throws GLException if the program is not linked and no location was cached.
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttribPointer
+ */
+ public boolean vertexAttribPointer(GL2ES2 gl, GLArrayData data) {
+ int location = data.getLocation();
+ if(0 > location) {
+ location = getAttribLocation(gl, data);
+ } /* else {
+ done via enable ..
+ // ensure data is the current bound one
+ activeAttribDataMap.put(data.getName(), data);
+ } */
+ if(0 <= location) {
+ // only pass the data, if the attribute exists in the current shader
+ if(DEBUG) {
+ System.err.println("Info: glVertexAttribPointer: "+data);
+ }
+ gl.glVertexAttribPointer(data);
+ return true;
+ }
+ return false;
}
/**
* Releases all mapped vertex attribute data,
* disables all enabled attributes and loses all indices
*
- * @throws GLException is the program is not in use but the shaderProgram is set
- *
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
@@ -420,23 +660,23 @@ public class ShaderState {
* @see #glResetAllVertexAttributes
* @see ShaderProgram#glReplaceShader
*/
- public void glReleaseAllVertexAttributes(GL2ES2 gl) {
+ public void releaseAllAttributes(GL2ES2 gl) {
if(null!=shaderProgram) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- for(Iterator iter = vertexAttribMap2Data.keySet().iterator(); iter.hasNext(); ) {
- if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
+ if(!disableVertexAttribArray(gl, iter.next())) {
throw new GLException("Internal Error: mapped vertex attribute couldn't be disabled");
}
}
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ for(Iterator<String> iter = enabledAttributes.iterator(); iter.hasNext(); ) {
+ if(!disableVertexAttribArray(gl, iter.next())) {
throw new GLException("Internal Error: prev enabled vertex attribute couldn't be disabled");
}
}
}
- vertexAttribMap2Data.clear();
- enabledVertexAttribArraySet.clear();
- attribMap2Idx.clear();
+ activeAttribDataMap.clear();
+ enabledAttributes.clear();
+ activeAttribLocationMap.clear();
+ managedAttributes.clear();
}
/**
@@ -447,8 +687,6 @@ public class ShaderState {
*
* This method purpose is more for debugging.
*
- * @throws GLException is the program is not in use but the shaderProgram is set
- *
* @see #glEnableVertexAttribArray
* @see #glDisableVertexAttribArray
* @see #glVertexAttribPointer
@@ -458,73 +696,92 @@ public class ShaderState {
* @see #glResetAllVertexAttributes
* @see ShaderProgram#glReplaceShader
*/
- public void glDisableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
-
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- String name = (String) iter.next();
+ public void disableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) {
+ for(Iterator<String> iter = enabledAttributes.iterator(); iter.hasNext(); ) {
+ String name = iter.next();
if(removeFromState) {
- enabledVertexAttribArraySet.remove(name);
+ enabledAttributes.remove(name);
}
- int index = glGetAttribLocation(gl, name);
+ int index = getAttribLocation(gl, name);
if(0<=index) {
gl.glDisableVertexAttribArray(index);
}
}
}
+ private final void relocateAttribute(GL2ES2 gl, GLArrayData attribute) {
+ // get new location ..
+ String name = attribute.getName();
+ int loc = getAttribLocation(gl, name);
+ attribute.setLocation(loc);
+
+ if(0<=loc) {
+ if(enabledAttributes.contains(name)) {
+ // enable attrib, VBO and pass location/data
+ gl.glEnableVertexAttribArray(loc);
+ }
+
+ if( attribute.isVBO() ) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
+ }
+
+ gl.glVertexAttribPointer(attribute);
+ }
+ }
+
/**
- * Reset all previously enabled mapped vertex attribute data,
- * incl enabling them
+ * Reset all previously enabled mapped vertex attribute data.
+ *
+ * <p>Attribute data is bound to the GL state</p>
+ * <p>Attribute location is bound to the program</p>
+ *
+ * <p>However, since binding an attribute to a location via {@link #bindAttribLocation(GL2ES2, int, GLArrayData)}
+ * <i>must</i> happen before linking <b>and</b> we try to promote the attributes to the new program,
+ * we have to gather the probably new location etc.</p>
*
- * @throws GLException is the program is not in use
+ * @throws GLException is the program is not linked
*
- * @see #glEnableVertexAttribArray
- * @see #glDisableVertexAttribArray
- * @see #glVertexAttribPointer
- * @see #getVertexAttribPointer
- * @see #glReleaseAllVertexAttributes
- * @see #glResetAllVertexAttributes
- * @see ShaderProgram#glReplaceShader
+ * @see #attachShaderProgram(GL2ES2, ShaderProgram)
*/
- public void glResetAllVertexAttributes(GL2ES2 gl) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- attribMap2Idx.clear();
-
- /**
- *
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- glEnableVertexAttribArray(gl, (String) iter.next());
+ private final void resetAllAttributes(GL2ES2 gl) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ activeAttribLocationMap.clear();
+
+ for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
+ iter.next().setLocation(-1);
}
- for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
- GLArrayData data = (GLArrayData) iter.next();
-
- ...
- } */
-
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- // get new location ..
- String name = (String) iter.next();
- int loc = glGetAttribLocation(gl, name);
-
- // get & update data ..
- GLArrayData data = getVertexAttribPointer(name);
- data.setLocation(loc);
- vertexAttribMap2Data.put(name, data);
+ for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
+ relocateAttribute(gl, iter.next());
+ }
+ }
- if(0>loc) {
- // not used in shader
- continue;
+ private final void setAttribute(GL2ES2 gl, GLArrayData attribute) {
+ // get new location ..
+ final String name = attribute.getName();
+ final int loc = attribute.getLocation();
+
+ if(0<=loc) {
+ this.bindAttribLocation(gl, loc, name);
+
+ if(enabledAttributes.contains(name)) {
+ // enable attrib, VBO and pass location/data
+ gl.glEnableVertexAttribArray(loc);
}
-
- // enable attrib, VBO and pass location/data
- gl.glEnableVertexAttribArray(loc);
-
- if( data.isVBO() ) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, data.getVBOName());
+
+ if( attribute.isVBO() ) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName());
}
-
- gl.glVertexAttribPointer(data);
+
+ gl.glVertexAttribPointer(attribute);
+ }
+ }
+
+ /**
+ * preserves the attribute location .. (program not linked)
+ */
+ private final void setAllAttributes(GL2ES2 gl) {
+ for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
+ setAttribute(gl, iter.next());
}
}
@@ -533,6 +790,33 @@ public class ShaderState {
//
/**
+ * Bind the {@link GLUniform} lifecycle to this ShaderState.
+ *
+ * <p>If a uniform location is cached it is promoted to the {@link GLUniformData} instance.</p>
+ *
+ * <p>The attribute will be destroyed with {@link #destroy(GL2ES2)}
+ * and it's location will be reset when switching shader with {@link #attachShaderProgram(GL2ES2, ShaderProgram)}.</p>
+ *
+ * <p>The data will not be transfered to the GPU, use {@link #uniform(GL2ES2, GLUniformData)} additionally.</p>
+ *
+ * @param uniform the {@link GLUniformData} which lifecycle shall be managed
+ *
+ * @see #getUniform(String)
+ */
+ public void ownUniform(GLUniformData uniform) {
+ final int location = getUniformLocation(uniform.getName());
+ if(0<=location) {
+ uniform.setLocation(location);
+ }
+ activeUniformDataMap.put(uniform.getName(), uniform);
+ managedUniforms.add(uniform);
+ }
+
+ public boolean ownsUniform(GLUniformData uniform) {
+ return managedUniforms.contains(uniform);
+ }
+
+ /**
* Gets the index of a shader uniform.
* This must be done when the program is in use !
*
@@ -546,24 +830,24 @@ public class ShaderState {
* @see #getUniformLocation
* @see ShaderProgram#glReplaceShader
*/
- protected int glGetUniformLocation(GL2ES2 gl, String name) {
+ protected final int getUniformLocation(GL2ES2 gl, String name) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- int index = getUniformLocation(name);
- if(0>index) {
- index = gl.glGetUniformLocation(shaderProgram.program(), name);
- if(0<=index) {
- Integer idx = new Integer(index);
- uniformMap2Idx.put(name, idx);
+ int location = getUniformLocation(name);
+ if(0>location) {
+ location = gl.glGetUniformLocation(shaderProgram.program(), name);
+ if(0<=location) {
+ Integer idx = new Integer(location);
+ activeUniformLocationMap.put(name, idx);
} else if(verbose) {
- Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+index);
+ Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+location);
tX.printStackTrace();
}
}
- return index;
+ return location;
}
- protected int getUniformLocation(String name) {
- Integer idx = (Integer) uniformMap2Idx.get(name);
+ protected final int getUniformLocation(String name) {
+ Integer idx = (Integer) activeUniformLocationMap.get(name);
return (null!=idx)?idx.intValue():-1;
}
@@ -587,11 +871,14 @@ public class ShaderState {
* @see #getUniformLocation
* @see ShaderProgram#glReplaceShader
*/
- public boolean glUniform(GL2ES2 gl, GLUniformData data) {
+ public boolean uniform(GL2ES2 gl, GLUniformData data) {
if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- int location = glGetUniformLocation(gl, data.getName());
- data.setLocation(location);
- uniformMap2Data.put(data.getName(), data);
+ int location = data.getLocation();
+ if(0>location) {
+ location = getUniformLocation(gl, data.getName());
+ data.setLocation(location);
+ }
+ activeUniformDataMap.put(data.getName(), data);
if(0<=location) {
// only pass the data, if the uniform exists in the current shader
if(DEBUG) {
@@ -608,69 +895,97 @@ public class ShaderState {
* @return the GLUniformData object, null if not previously set.
*/
public GLUniformData getUniform(String name) {
- return (GLUniformData) uniformMap2Data.get(name);
+ return activeUniformDataMap.get(name);
}
/**
* Releases all mapped uniform data
* and loses all indices
- *
- * @throws GLException is the program is not in use
*/
- public void glReleaseAllUniforms(GL2ES2 gl) {
- uniformMap2Data.clear();
- uniformMap2Idx.clear();
+ public void releaseAllUniforms(GL2ES2 gl) {
+ activeUniformDataMap.clear();
+ activeUniformLocationMap.clear();
+ managedUniforms.clear();
}
/**
* Reset all previously mapped uniform data
+ *
+ * Uniform data and location is bound to the program,
+ * hence both are updated here
*
* @throws GLException is the program is not in use
+ *
+ * @see #attachShaderProgram(GL2ES2, ShaderProgram)
*/
- public void glResetAllUniforms(GL2ES2 gl) {
- if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
- uniformMap2Idx.clear();
- for(Iterator iter = uniformMap2Data.values().iterator(); iter.hasNext(); ) {
- glUniform(gl, (GLUniformData) iter.next());
+ private final void resetAllUniforms(GL2ES2 gl) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ activeUniformLocationMap.clear();
+ for(Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
+ iter.next().setLocation(-1);
+ }
+ for(Iterator<GLUniformData> iter = activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
+ final GLUniformData uniform = iter.next();
+ uniform.setLocation(-1);
+ uniform(gl, uniform);
}
}
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("ShaderState[");
- buf.append(shaderProgram.toString());
- buf.append(",EnabledStates: [");
- for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
- buf.append("\n ");
- buf.append((String)iter.next());
- }
- buf.append("], [");
- for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
- GLArrayData data = (GLArrayData) iter.next();
- if(data.getLocation()>=0) {
- buf.append("\n ");
- buf.append(data);
- }
+ public StringBuilder toString(StringBuilder sb) {
+ if(null==sb) {
+ sb = new StringBuilder();
}
- buf.append("], [");
- for(Iterator iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) {
- GLUniformData data = (GLUniformData) iter.next();
- if(data.getLocation()>=0) {
- buf.append("\n ");
- buf.append(data);
- }
+
+ sb.append("ShaderState[");
+ sb.append(shaderProgram.toString());
+ sb.append(", enabledAttributes: [");
+ for(Iterator<String> iter = enabledAttributes.iterator(); iter.hasNext(); ) {
+ sb.append("\n ");
+ sb.append((String)iter.next());
+ }
+ sb.append("], activeAttributes [");
+ for(Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) {
+ sb.append("\n ");
+ sb.append(iter.next());
}
- buf.append("]");
- return buf.toString();
+ sb.append("], managedAttributes [");
+ for(Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) {
+ sb.append("\n ");
+ sb.append(iter.next());
+ }
+ sb.append("], activeUniforms [");
+ for(Iterator<GLUniformData> iter=activeUniformDataMap.values().iterator(); iter.hasNext(); ) {
+ sb.append("\n ");
+ sb.append(iter.next());
+ }
+ sb.append("], managedUniforms [");
+ for(Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) {
+ sb.append("\n ");
+ sb.append(iter.next());
+ }
+ sb.append("]");
+ return sb;
}
-
- protected boolean verbose = false;
- protected ShaderProgram shaderProgram=null;
- protected HashMap attribMap2Idx = new HashMap();
- protected HashSet enabledVertexAttribArraySet = new HashSet();
- protected HashMap vertexAttribMap2Data = new HashMap();
- protected HashMap uniformMap2Idx = new HashMap();
- protected HashMap uniformMap2Data = new HashMap();
-
+
+ @Override
+ public String toString() {
+ return toString(null).toString();
+ }
+
+ private boolean verbose = false;
+ private ShaderProgram shaderProgram=null;
+
+ private HashSet<String> enabledAttributes = new HashSet<String>();
+ private HashMap<String, Integer> activeAttribLocationMap = new HashMap<String, Integer>();
+ private HashMap<String, GLArrayData> activeAttribDataMap = new HashMap<String, GLArrayData>();
+ private ArrayList<GLArrayData> managedAttributes = new ArrayList<GLArrayData>();
+
+ private HashMap<String, Integer> activeUniformLocationMap = new HashMap<String, Integer>();
+ private HashMap<String, GLUniformData> activeUniformDataMap = new HashMap<String, GLUniformData>();
+ private ArrayList<GLUniformData> managedUniforms = new ArrayList<GLUniformData>();
+
+ private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
+ private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+ private boolean resetAllShaderData = false;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
index c7e845953..c81e1f961 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderUtil.java
@@ -51,7 +51,7 @@ public class ShaderUtil {
public abstract boolean isProgramValid(GL gl, int programObj);
public abstract boolean isProgramValid(GL gl, int programObj, PrintStream verboseOut);
public abstract void createShader(GL gl, int type, IntBuffer shaders);
- public abstract Set getShaderBinaryFormats(GL gl);
+ public abstract Set<Integer> getShaderBinaryFormats(GL gl);
public abstract boolean isShaderCompilerAvailable(GL gl);
public abstract void shaderSource(GL gl, int shader, java.lang.String[] source);
public abstract void shaderSource(GL gl, IntBuffer shaders, java.lang.String[][] sources);
@@ -74,7 +74,7 @@ public class ShaderUtil {
public String getShaderInfoLog(GL _gl, int shaderObj) {
GL2ES2 gl = _gl.getGL2ES2();
int[] infoLogLength=new int[1];
- gl.glGetShaderiv(shaderObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+ gl.glGetShaderiv(shaderObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
if(infoLogLength[0]==0) {
return "(no info log)";
@@ -89,7 +89,7 @@ public class ShaderUtil {
public String getProgramInfoLog(GL _gl, int programObj) {
GL2ES2 gl = _gl.getGL2ES2();
int[] infoLogLength=new int[1];
- gl.glGetProgramiv(programObj, gl.GL_INFO_LOG_LENGTH, infoLogLength, 0);
+ gl.glGetProgramiv(programObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0);
if(infoLogLength[0]==0) {
return "(no info log)";
@@ -143,14 +143,13 @@ public class ShaderUtil {
public boolean isProgramValid(GL _gl, int programObj, PrintStream verboseOut) {
GL2ES2 gl = _gl.getGL2ES2();
- int[] ires = new int[1];
if(!gl.glIsProgram(programObj)) {
if(null!=verboseOut) {
verboseOut.println("Program name invalid: "+programObj);
}
return false;
}
- if(!isProgramStatusValid(gl, programObj, gl.GL_LINK_STATUS)) {
+ if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_LINK_STATUS)) {
if(null!=verboseOut) {
verboseOut.println("Program link failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
}
@@ -159,7 +158,7 @@ public class ShaderUtil {
if ( !gl.isGLES2() || isShaderCompilerAvailable(gl) ) {
// failed on APX2500 (ES2.0, no compiler) for valid programs
gl.glValidateProgram(programObj);
- if(!isProgramStatusValid(gl, programObj, gl.GL_VALIDATE_STATUS)) {
+ if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_VALIDATE_STATUS)) {
if(null!=verboseOut) {
verboseOut.println("Program validation failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj));
}
@@ -177,17 +176,15 @@ public class ShaderUtil {
}
private Boolean shaderCompilerAvailable = null;
- private Set shaderBinaryFormats = null;
+ private Set<Integer> shaderBinaryFormats = null;
- public Set getShaderBinaryFormats(GL _gl) {
+ public Set<Integer> getShaderBinaryFormats(GL _gl) {
GL2ES2 gl = _gl.getGL2ES2();
if(null==shaderBinaryFormats) {
- if(gl.getContext()!=GLContext.getCurrent()) {
- return new HashSet(0); // bail out
- }
+ gl.getContext().validateCurrent();
int[] param = new int[1];
- shaderBinaryFormats = new HashSet();
+ shaderBinaryFormats = new HashSet<Integer>();
if (gl.isGLES2()) {
gl.glGetIntegerv(GL2ES2.GL_NUM_SHADER_BINARY_FORMATS, param, 0);
@@ -208,10 +205,8 @@ public class ShaderUtil {
public boolean isShaderCompilerAvailable(GL _gl) {
GL2ES2 gl = _gl.getGL2ES2();
if(null==shaderCompilerAvailable) {
- if(gl.getContext()!=GLContext.getCurrent()) {
- return false; // bail out
- }
- Set bfs = getShaderBinaryFormats(gl);
+ gl.getContext().validateCurrent();
+ Set<Integer> bfs = getShaderBinaryFormats(gl);
if(gl.isGLES2()) {
byte[] param = new byte[1];
gl.glGetBooleanv(GL2ES2.GL_SHADER_COMPILER, param, 0);
@@ -370,7 +365,7 @@ public class ShaderUtil {
verboseOut.println("createAndCompileShader: CompileShader failed, GL Error: 0x"+Integer.toHexString(err));
}
- return isShaderStatusValid(gl, shader, gl.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
+ return isShaderStatusValid(gl, shader, GL2ES2.GL_COMPILE_STATUS, verboseOut) && err == GL.GL_NO_ERROR;
}
}
@@ -415,7 +410,7 @@ public class ShaderUtil {
getImpl(gl).createShader(gl, type, shaders);
}
- public static Set getShaderBinaryFormats(GL gl) {
+ public static Set<Integer> getShaderBinaryFormats(GL gl) {
return getImpl(gl).getShaderBinaryFormats(gl);
}
@@ -469,7 +464,7 @@ public class ShaderUtil {
Impl impl = (Impl) context.getAttachedObject(ShaderUtil.class.getName());
if (impl == null) {
impl = new GL2ES2Impl();
- context.putAttachedObject(ShaderUtil.class.getName(), impl);
+ context.attachObject(ShaderUtil.class.getName(), impl);
}
return impl;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index 38f8ff974..35604ba30 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -178,38 +178,33 @@ public class Texture {
private static final boolean disableNPOT = Debug.isPropertyDefined("jogl.texture.nonpot", true, localACC);
private static final boolean disableTexRect = Debug.isPropertyDefined("jogl.texture.notexrect", true, localACC);
- public Texture(TextureData data) throws GLException {
+ public Texture(GL gl, TextureData data) throws GLException {
texID = 0;
- updateImage(data);
+ updateImage(gl, data);
}
// Constructor for use when creating e.g. cube maps, where there is
// no initial texture data
- public Texture(int target) throws GLException {
+ public Texture(int target) {
texID = 0;
this.target = target;
}
// Package-private constructor for creating a texture object which wraps
// an existing texture ID from another package
- Texture(int textureID,
- int target,
- int texWidth,
- int texHeight,
- int imgWidth,
- int imgHeight,
- boolean mustFlipVertically) {
- this.texID = textureID;
- this.target = target;
- this.mustFlipVertically = mustFlipVertically;
- this.texWidth = texWidth;
- this.texHeight = texHeight;
- setImageSize(imgWidth, imgHeight, target);
+ Texture(int textureID, int target, int texWidth, int texHeight, int imgWidth, int imgHeight,
+ boolean mustFlipVertically) {
+ this.texID = textureID;
+ this.target = target;
+ this.mustFlipVertically = mustFlipVertically;
+ this.texWidth = texWidth;
+ this.texHeight = texHeight;
+ setImageSize(imgWidth, imgHeight, target);
}
/**
* Enables this texture's target (e.g., GL_TEXTURE_2D) in the
- * current GL context's state. This method is a shorthand equivalent
+ * given GL context's state. This method is a shorthand equivalent
* of the following OpenGL code:
<pre>
gl.glEnable(texture.getTarget());
@@ -221,13 +216,13 @@ public class Texture {
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
- public void enable() throws GLException {
- GLContext.getCurrentGL().glEnable(target);
+ public void enable(GL gl) throws GLException {
+ gl.glEnable(target);
}
-
+
/**
* Disables this texture's target (e.g., GL_TEXTURE_2D) in the
- * current GL context's state. This method is a shorthand equivalent
+ * given GL state. This method is a shorthand equivalent
* of the following OpenGL code:
<pre>
gl.glDisable(texture.getTarget());
@@ -235,16 +230,17 @@ public class Texture {
*
* See the <a href="#perftips">performance tips</a> above for hints
* on how to maximize performance when using many Texture objects.
+ * @param gl TODO
*
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
- public void disable() throws GLException {
- GLContext.getCurrentGL().glDisable(target);
+ public void disable(GL gl) throws GLException {
+ gl.glDisable(target);
}
-
+
/**
- * Binds this texture to the current GL context. This method is a
+ * Binds this texture to the given GL context. This method is a
* shorthand equivalent of the following OpenGL code:
<pre>
gl.glBindTexture(texture.getTarget(), texture.getTextureObject());
@@ -252,36 +248,22 @@ public class Texture {
*
* See the <a href="#perftips">performance tips</a> above for hints
* on how to maximize performance when using many Texture objects.
+ * @param gl TODO
*
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
- public void bind() throws GLException {
- validateTexID(null, true);
- GLContext.getCurrentGL().glBindTexture(target, texID);
- }
-
- /**
- * Disposes the native resources used by this texture object.
- *
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
- * @deprecated use destroy(GL)
- */
- public void dispose() throws GLException {
- destroy(GLContext.getCurrentGL());
+ public void bind(GL gl) throws GLException {
+ validateTexID(gl, true);
+ gl.glBindTexture(target, texID);
}
-
+
/**
- * Disposes the native resources used by this texture object.
- *
- * @throws GLException if any OpenGL-related errors occurred
- * @deprecated use destroy(GL)
+ * @deprecated use {@link #destroy(GL)}
*/
- public void dispose(GL gl) throws GLException {
+ public final void dispose(GL gl) throws GLException {
destroy(gl);
}
-
/**
* Destroys the native resources used by this texture object.
*
@@ -414,11 +396,10 @@ public class Texture {
* Updates the entire content area of this texture using the data in
* the given image.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void updateImage(TextureData data) throws GLException {
- updateImage(data, 0);
+ public void updateImage(GL gl, TextureData data) throws GLException {
+ updateImage(gl, data, 0);
}
/**
@@ -438,11 +419,9 @@ public class Texture {
* using the data in the given image. In general this is intended
* for construction of cube maps.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void updateImage(TextureData data, int target) throws GLException {
- GL gl = GLContext.getCurrentGL();
+ public void updateImage(GL gl, TextureData data, int target) throws GLException {
validateTexID(gl, true);
imgWidth = data.getWidth();
@@ -593,7 +572,7 @@ public class Texture {
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
}
} else {
- checkCompressedTextureExtensions(data);
+ checkCompressedTextureExtensions(gl, data);
Buffer[] mipmapData = data.getMipmapData();
if (mipmapData != null) {
int width = texWidth;
@@ -610,7 +589,7 @@ public class Texture {
gl.glTexImage2D(texTarget, i, data.getInternalFormat(),
width, height, data.getBorder(),
data.getPixelFormat(), data.getPixelType(), null);
- updateSubImageImpl(data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ updateSubImageImpl(gl, data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
}
width = Math.max(width / 2, 1);
@@ -631,7 +610,7 @@ public class Texture {
gl.glCompressedTexImage2D(texTarget, 0, data.getInternalFormat(),
texWidth, texHeight, data.getBorder(),
buf.capacity(), buf);
- updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ updateSubImageImpl(gl, data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
}
} else {
if (data.getMipmap() && haveAutoMipmapGeneration && gl.isGL2ES1()) {
@@ -646,7 +625,7 @@ public class Texture {
gl.glTexImage2D(texTarget, 0, data.getInternalFormat(),
texWidth, texHeight, data.getBorder(),
data.getPixelFormat(), data.getPixelType(), null);
- updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
+ updateSubImageImpl(gl, data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
}
}
}
@@ -697,17 +676,16 @@ public class Texture {
* @param y the y offset (in pixels) relative to the lower-left corner
* of this texture
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void updateSubImage(TextureData data, int mipmapLevel, int x, int y) throws GLException {
+ public void updateSubImage(GL gl, TextureData data, int mipmapLevel, int x, int y) throws GLException {
if (usingAutoMipmapGeneration && mipmapLevel != 0) {
// When we're using mipmap generation via GL_GENERATE_MIPMAP, we
// don't need to update other mipmap levels
return;
}
- bind();
- updateSubImageImpl(data, target, mipmapLevel, x, y, 0, 0, data.getWidth(), data.getHeight());
+ bind(gl);
+ updateSubImageImpl(gl, data, target, mipmapLevel, x, y, 0, 0, data.getWidth(), data.getHeight());
}
/**
@@ -740,7 +718,7 @@ public class Texture {
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
- public void updateSubImage(TextureData data, int mipmapLevel,
+ public void updateSubImage(GL gl, TextureData data, int mipmapLevel,
int dstx, int dsty,
int srcx, int srcy,
int width, int height) throws GLException {
@@ -752,8 +730,8 @@ public class Texture {
// don't need to update other mipmap levels
return;
}
- bind();
- updateSubImageImpl(data, target, mipmapLevel, dstx, dsty, srcx, srcy, width, height);
+ bind(gl);
+ updateSubImageImpl(gl, data, target, mipmapLevel, dstx, dsty, srcx, srcy, width, height);
}
/**
@@ -765,10 +743,9 @@ public class Texture {
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
- public void setTexParameterf(int parameterName,
+ public void setTexParameterf(GL gl, int parameterName,
float value) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameterf(target, parameterName, value);
}
@@ -777,13 +754,11 @@ public class Texture {
* texture's target. Causes this texture to be bound to the current
* texture state.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void setTexParameterfv(int parameterName,
+ public void setTexParameterfv(GL gl, int parameterName,
FloatBuffer params) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameterfv(target, parameterName, params);
}
@@ -792,13 +767,11 @@ public class Texture {
* texture's target. Causes this texture to be bound to the current
* texture state.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void setTexParameterfv(int parameterName,
+ public void setTexParameterfv(GL gl, int parameterName,
float[] params, int params_offset) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameterfv(target, parameterName, params, params_offset);
}
@@ -810,13 +783,11 @@ public class Texture {
* platform and GL_CLAMP if not. Causes this texture to be bound to
* the current texture state.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void setTexParameteri(int parameterName,
+ public void setTexParameteri(GL gl, int parameterName,
int value) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameteri(target, parameterName, value);
}
@@ -825,13 +796,11 @@ public class Texture {
* target. Causes this texture to be bound to the current texture
* state.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void setTexParameteriv(int parameterName,
+ public void setTexParameteriv(GL gl, int parameterName,
IntBuffer params) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameteriv(target, parameterName, params);
}
@@ -840,23 +809,21 @@ public class Texture {
* target. Causes this texture to be bound to the current texture
* state.
*
- * @throws GLException if no OpenGL context was current or if any
- * OpenGL-related errors occurred
+ * @throws GLException if any OpenGL-related errors occurred
*/
- public void setTexParameteriv(int parameterName,
+ public void setTexParameteriv(GL gl, int parameterName,
int[] params, int params_offset) {
- bind();
- GL gl = GLContext.getCurrentGL();
+ bind(gl);
gl.glTexParameteriv(target, parameterName, params, params_offset);
}
/**
* Returns the underlying OpenGL texture object for this texture.
* Most applications will not need to access this, since it is
- * handled automatically by the bind() and dispose() APIs.
+ * handled automatically by the bind(GL) and destroy(GL) APIs.
*/
- public int getTextureObject() {
- validateTexID(null, false);
+ public int getTextureObject(GL gl) {
+ validateTexID(gl, false);
return texID;
}
@@ -936,10 +903,9 @@ public class Texture {
}
}
- private void updateSubImageImpl(TextureData data, int newTarget, int mipmapLevel,
+ private void updateSubImageImpl(GL gl, TextureData data, int newTarget, int mipmapLevel,
int dstx, int dsty,
int srcx, int srcy, int width, int height) throws GLException {
- GL gl = GLContext.getCurrentGL();
data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
@@ -1000,7 +966,7 @@ public class Texture {
height = texHeight - dsty;
}
- checkCompressedTextureExtensions(data);
+ checkCompressedTextureExtensions(gl, data);
if (data.isDataCompressed()) {
gl.glCompressedTexSubImage2D(newTarget, mipmapLevel,
@@ -1052,8 +1018,7 @@ public class Texture {
}
}
- private void checkCompressedTextureExtensions(TextureData data) {
- GL gl = GLContext.getCurrentGL();
+ private void checkCompressedTextureExtensions(GL gl, TextureData data) {
if (data.isDataCompressed()) {
switch (data.getInternalFormat()) {
case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
@@ -1073,22 +1038,20 @@ public class Texture {
}
}
- private void validateTexID(GL gl, boolean throwException) {
- if( 0 < texID ) return;
- if(null==gl) {
- GLContext ctx = GLContext.getCurrent();
- if(null!=ctx) {
- gl = ctx.getGL();
- } else if(throwException) {
- throw new GLException("No context current, can't create texture ID");
+ private boolean validateTexID(GL gl, boolean throwException) {
+ if( 0 >= texID ) {
+ if( null != gl ) {
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texID = tmp[0];
+ if ( 0 >= texID && throwException ) {
+ throw new GLException("Create texture ID invalid: texID "+texID+", glerr 0x"+Integer.toHexString(gl.glGetError()));
+ }
+ } else if ( throwException ) {
+ throw new GLException("No GL context given, can't create texture ID");
}
}
-
- if(null!=gl) {
- int[] tmp = new int[1];
- gl.glGenTextures(1, tmp, 0);
- texID = tmp[0];
- }
+ return 0 < texID;
}
// Helper routines for disabling certain codepaths
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index e86ff161b..792f80ff8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -400,12 +400,25 @@ public class TextureIO {
* @throws IllegalArgumentException if the passed TextureData was null
*/
public static Texture newTexture(TextureData data) throws GLException, IllegalArgumentException {
+ return newTexture(GLContext.getCurrentGL(), data);
+ }
+
+ /**
+ * Creates an OpenGL texture object from the specified TextureData
+ * using the current OpenGL context.
+ *
+ * @param data the texture data to turn into an OpenGL texture
+ * @throws GLException if no OpenGL context is current or if an
+ * OpenGL error occurred
+ * @throws IllegalArgumentException if the passed TextureData was null
+ */
+ public static Texture newTexture(GL gl, TextureData data) throws GLException, IllegalArgumentException {
if (data == null) {
throw new IllegalArgumentException("Null TextureData");
}
- return new Texture(data);
+ return new Texture(gl, data);
}
-
+
/**
* Creates an OpenGL texture object from the specified file using
* the current OpenGL context.
@@ -422,9 +435,10 @@ public class TextureIO {
* OpenGL error occurred
*/
public static Texture newTexture(File file, boolean mipmap) throws IOException, GLException {
- GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ GL gl = GLContext.getCurrentGL();
+ GLProfile glp = gl.getGLProfile();
TextureData data = newTextureData(glp, file, mipmap, FileUtil.getFileSuffix(file));
- Texture texture = newTexture(data);
+ Texture texture = newTexture(gl, data);
data.flush();
return texture;
}
@@ -450,9 +464,10 @@ public class TextureIO {
* OpenGL error occurred
*/
public static Texture newTexture(InputStream stream, boolean mipmap, String fileSuffix) throws IOException, GLException {
- GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ GL gl = GLContext.getCurrentGL();
+ GLProfile glp = gl.getGLProfile();
TextureData data = newTextureData(glp, stream, mipmap, fileSuffix);
- Texture texture = newTexture(data);
+ Texture texture = newTexture(gl, data);
data.flush();
return texture;
}
@@ -481,26 +496,24 @@ public class TextureIO {
if (fileSuffix == null) {
fileSuffix = FileUtil.getFileSuffix(url.getPath());
}
- GLProfile glp = GLContext.getCurrentGL().getGLProfile();
+ GL gl = GLContext.getCurrentGL();
+ GLProfile glp = gl.getGLProfile();
TextureData data = newTextureData(glp, url, mipmap, fileSuffix);
- Texture texture = newTexture(data);
+ Texture texture = newTexture(gl, data);
data.flush();
return texture;
}
/**
* Creates an OpenGL texture object associated with the given OpenGL
- * texture target using the current OpenGL context. The texture has
+ * texture target. The texture has
* no initial data. This is used, for example, to construct cube
* maps out of multiple TextureData objects.
*
* @param target the OpenGL target type, eg GL.GL_TEXTURE_2D,
* GL.GL_TEXTURE_RECTANGLE_ARB
- *
- * @throws GLException if no OpenGL context is current or if an
- * OpenGL error occurred
*/
- public static Texture newTexture(int target) throws GLException {
+ public static Texture newTexture(int target) {
return new Texture(target);
}
@@ -528,19 +541,19 @@ public class TextureIO {
* texture
*/
public static Texture newTexture(int textureID,
- int target,
- int texWidth,
- int texHeight,
- int imgWidth,
- int imgHeight,
- boolean mustFlipVertically) {
- return new Texture(textureID,
- target,
- texWidth,
- texHeight,
- imgWidth,
- imgHeight,
- mustFlipVertically);
+ int target,
+ int texWidth,
+ int texHeight,
+ int imgWidth,
+ int imgHeight,
+ boolean mustFlipVertically) {
+ return new Texture(textureID,
+ target,
+ texWidth,
+ texHeight,
+ imgWidth,
+ imgHeight,
+ mustFlipVertically);
}
/**
@@ -581,7 +594,7 @@ public class TextureIO {
}
GL2 gl = _gl.getGL2();
- texture.bind();
+ texture.bind(gl);
int internalFormat = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_INTERNAL_FORMAT);
int width = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_WIDTH);
int height = glGetTexLevelParameteri(gl, GL.GL_TEXTURE_2D, 0, GL2.GL_TEXTURE_HEIGHT);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
index d5f49599c..37dbc54df 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/LEDataInputStream.java
@@ -37,7 +37,7 @@
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
-package com.jogamp.opengl.util.texture.spi;
+package com.jogamp.opengl.util.texture.spi;
import java.io.DataInput;
import java.io.DataInputStream;
@@ -65,16 +65,16 @@ import java.io.IOException;
* for that functionality. It is not clear if it is ever going to be
* functionally required to be able to read UTF data in a LittleEndianManner<p>
*
- * @author Robin Luiten
- * @version 1.1 15/Dec/1997
+ * @author Robin Luiten
+ * @version 1.1 15/Dec/1997
*/
public class LEDataInputStream extends FilterInputStream implements DataInput
{
/**
- * To reuse some of the non endian dependent methods from
- * DataInputStreams methods.
+ * To reuse some of the non endian dependent methods from
+ * DataInputStreams methods.
*/
- DataInputStream dataIn;
+ DataInputStream dataIn;
public LEDataInputStream(InputStream in)
{
@@ -84,29 +84,29 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
public void close() throws IOException
{
- dataIn.close(); // better close as we create it.
+ dataIn.close(); // better close as we create it.
// this will close underlying as well.
}
- public synchronized final int read(byte b[]) throws IOException
+ public synchronized final int read(byte b[]) throws IOException
{
return dataIn.read(b, 0, b.length);
}
- public synchronized final int read(byte b[], int off, int len) throws IOException
+ public synchronized final int read(byte b[], int off, int len) throws IOException
{
- int rl = dataIn.read(b, off, len);
+ int rl = dataIn.read(b, off, len);
return rl;
}
public final void readFully(byte b[]) throws IOException
{
- dataIn.readFully(b, 0, b.length);
+ dataIn.readFully(b, 0, b.length);
}
- public final void readFully(byte b[], int off, int len) throws IOException
+ public final void readFully(byte b[], int off, int len) throws IOException
{
- dataIn.readFully(b, off, len);
+ dataIn.readFully(b, off, len);
}
public final int skipBytes(int n) throws IOException
@@ -116,23 +116,23 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
public final boolean readBoolean() throws IOException
{
- int ch = dataIn.read();
+ int ch = dataIn.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
- public final byte readByte() throws IOException
+ public final byte readByte() throws IOException
{
- int ch = dataIn.read();
+ int ch = dataIn.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
- public final int readUnsignedByte() throws IOException
+ public final int readUnsignedByte() throws IOException
{
- int ch = dataIn.read();
+ int ch = dataIn.read();
if (ch < 0)
throw new EOFException();
return ch;
@@ -140,47 +140,47 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
public final short readShort() throws IOException
{
- int ch1 = dataIn.read();
- int ch2 = dataIn.read();
- if ((ch1 | ch2) < 0)
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
throw new EOFException();
- return (short)((ch1 << 0) + (ch2 << 8));
+ return (short)((ch1 << 0) + (ch2 << 8));
}
- public final int readUnsignedShort() throws IOException
+ public final int readUnsignedShort() throws IOException
{
- int ch1 = dataIn.read();
- int ch2 = dataIn.read();
- if ((ch1 | ch2) < 0)
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
throw new EOFException();
- return (ch1 << 0) + (ch2 << 8);
+ return (ch1 << 0) + (ch2 << 8);
}
- public final char readChar() throws IOException
+ public final char readChar() throws IOException
{
- int ch1 = dataIn.read();
- int ch2 = dataIn.read();
- if ((ch1 | ch2) < 0)
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ if ((ch1 | ch2) < 0)
throw new EOFException();
- return (char)((ch1 << 0) + (ch2 << 8));
+ return (char)((ch1 << 0) + (ch2 << 8));
}
public final int readInt() throws IOException
{
- int ch1 = dataIn.read();
- int ch2 = dataIn.read();
- int ch3 = dataIn.read();
- int ch4 = dataIn.read();
- if ((ch1 | ch2 | ch3 | ch4) < 0)
+ int ch1 = dataIn.read();
+ int ch2 = dataIn.read();
+ int ch3 = dataIn.read();
+ int ch4 = dataIn.read();
+ if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
- return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24));
+ return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24));
}
- public final long readLong() throws IOException
+ public final long readLong() throws IOException
{
- int i1 = readInt();
- int i2 = readInt();
- return ((long)(i1) & 0xFFFFFFFFL) + (i2 << 32);
+ int i1 = readInt();
+ int i2 = readInt();
+ return ((long)(i1) & 0xFFFFFFFFL) + (i2 << 32);
}
public final float readFloat() throws IOException
@@ -188,7 +188,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
return Float.intBitsToFloat(readInt());
}
- public final double readDouble() throws IOException
+ public final double readDouble() throws IOException
{
return Double.longBitsToDouble(readLong());
}
@@ -197,7 +197,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
* dont call this it is not implemented.
* @return empty new string
**/
- public final String readLine() throws IOException
+ public final String readLine() throws IOException
{
return new String();
}
@@ -206,7 +206,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
* dont call this it is not implemented
* @return empty new string
**/
- public final String readUTF() throws IOException
+ public final String readUTF() throws IOException
{
return new String();
}
@@ -215,7 +215,7 @@ public class LEDataInputStream extends FilterInputStream implements DataInput
* dont call this it is not implemented
* @return empty new string
**/
- public final static String readUTF(DataInput in) throws IOException
+ public final static String readUTF(DataInput in) throws IOException
{
return new String();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
index bb5040a31..c60c91bda 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/SGIImage.java
@@ -477,7 +477,7 @@ public class SGIImage {
for (int z = 0; z < zsize; z++) {
for (int y = ystart; y != yend; y += yincr) {
// RLE-compress each row.
-
+
int x = 0;
byte count = 0;
boolean repeat_mode = false;
@@ -485,7 +485,7 @@ public class SGIImage {
int start_ptr = ptr;
int num_ptr = ptr++;
byte repeat_val = 0;
-
+
while (x < xsize) {
// see if we should switch modes
should_switch = false;
@@ -502,7 +502,7 @@ public class SGIImage {
if (DEBUG)
System.err.println("left side was " + ((int) imgref(data, x, y, z, xsize, ysize, zsize)) +
", right side was " + (int)imgref(data, x+i, y, z, xsize, ysize, zsize));
-
+
if (imgref(data, x, y, z, xsize, ysize, zsize) !=
imgref(data, x+i, y, z, xsize, ysize, zsize))
should_switch = false;
@@ -530,7 +530,7 @@ public class SGIImage {
repeat_mode = true;
repeat_val = imgref(data, x, y, z, xsize, ysize, zsize);
}
-
+
if (x > 0) {
// reset the number pointer
num_ptr = ptr++;
@@ -538,7 +538,7 @@ public class SGIImage {
count = 0;
}
}
-
+
// if not in repeat mode, copy element to ptr
if (!repeat_mode) {
rlebuf[ptr++] = imgref(data, x, y, z, xsize, ysize, zsize);