aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/graph/curve/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/graph/curve/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java113
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java167
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java103
3 files changed, 383 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
new file mode 100644
index 000000000..c1fec10b8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -0,0 +1,113 @@
+package com.jogamp.graph.curve.opengl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.media.opengl.GL2ES2;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.RegionFactory;
+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
+ */
+ public static RegionRenderer create(Vertex.Factory<? extends Vertex> factory, int type) {
+ return new jogamp.graph.curve.opengl.RegionRendererImpl01(factory, type);
+ }
+
+ public RegionRenderer(Vertex.Factory<? extends Vertex> factory, int type) {
+ super(factory, type);
+ }
+
+ /** Render an array of {@link OutlineShape}s combined in one region
+ * at the position provided the triangles of the
+ * shapes will be generated, if not yet generated
+ * @param outlineShapes array of OutlineShapes to Render.
+ * @param position the initial translation of the outlineShapes.
+ * @param texSize texture size for multipass render *
+ * @throws Exception if HwRegionRenderer not initialized
+ */
+ public abstract void renderOutlineShapes(GL2ES2 gl, OutlineShape[] outlineShapes, float[] position, int texSize);
+
+ /** Render an {@link OutlineShape} in 3D space at the position provided
+ * the triangles of the shapes will be generated, if not yet generated
+ * @param outlineShape the OutlineShape to Render.
+ * @param position the initial translation of the outlineShape.
+ * @param texSize texture size for multipass render
+ * @throws Exception if HwRegionRenderer not initialized
+ */
+ public abstract void renderOutlineShape(GL2ES2 gl, OutlineShape outlineShape, float[] position, int texSize);
+
+ protected HashMap<Integer, Region> regions = new HashMap<Integer, Region>();
+
+ public void flushCache() {
+ Iterator<Region> iterator = regions.values().iterator();
+ while(iterator.hasNext()){
+ Region region = iterator.next();
+ region.destroy();
+ }
+ regions.clear();
+ }
+
+ /** Create an ogl {@link Region} defining this {@link OutlineShape}
+ * @param sharpness parameter for Region generation
+ * @return the resulting Region.
+ */
+ protected Region createRegion(GL2ES2 gl, OutlineShape outlineShape, float sharpness) {
+ Region region = RegionFactory.create(gl.getContext(), st, renderType);
+
+ outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
+
+ ArrayList<Triangle> triangles = (ArrayList<Triangle>) outlineShape.triangulate(sharpness);
+ ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices();
+ region.addVertices(vertices);
+ region.addTriangles(triangles);
+
+ region.update();
+ 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);
+
+ int numVertices = region.getNumVertices();
+
+ for(OutlineShape outlineShape:outlineShapes){
+ outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
+
+ ArrayList<Triangle> triangles = outlineShape.triangulate(sharpness);
+ region.addTriangles(triangles);
+
+ ArrayList<Vertex> vertices = outlineShape.getVertices();
+ for(Vertex vert:vertices){
+ vert.setId(numVertices++);
+ }
+ region.addVertices(vertices);
+ }
+
+ region.update();
+ return region;
+ }
+
+ protected static int getHashCode(OutlineShape outlineShape){
+ return outlineShape.hashCode();
+ }
+
+ protected static int getHashCode(OutlineShape[] outlineShapes){
+ int hashcode = 0;
+ for(OutlineShape outlineShape:outlineShapes){
+ hashcode += getHashCode(outlineShape);
+ }
+ return hashcode;
+ }
+} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
new file mode 100644
index 000000000..863928ed4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
@@ -0,0 +1,167 @@
+package com.jogamp.graph.curve.opengl;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import jogamp.opengl.Debug;
+
+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 abstract boolean initImpl(GL2ES2 gl);
+
+ protected abstract void disposeImpl(GL2ES2 gl);
+
+ /**
+ * Flushes all cached data
+ */
+ public abstract void flushCache();
+
+ 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;
+
+ private boolean vboSupported = false;
+ private boolean initialized = false;
+
+ /**
+ *
+ * @param factory
+ * @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) {
+ this.renderType = renderType;
+ this.pointFactory = (null != factory) ? factory : SVertex.factory();
+ }
+
+ public Vertex.Factory<? extends Vertex> getFactory() { return pointFactory; }
+
+ public final boolean isInitialized() { return initialized; }
+
+ public final boolean isVBOSupported() { return vboSupported; }
+
+ public final int getRenderType() { return renderType; }
+
+ public final int getWidth() { return vp_width; }
+ public final int getHeight() { return vp_height; }
+
+ /**
+ * Initialize shaders and bindings for GPU based rendering.
+ * Leaves the renderer enabled, ie ShaderState on.
+ *
+ * @param gl the current GL state
+ * @return true if succeeded, false otherwise
+ */
+ public boolean init(GL2ES2 gl) {
+ if(initialized){
+ if(DEBUG) {
+ System.err.println("TextRenderer: Already initialized!");
+ }
+ return true;
+ }
+ vboSupported = gl.isFunctionAvailable("glGenBuffers") &&
+ gl.isFunctionAvailable("glBindBuffer") &&
+ gl.isFunctionAvailable("glBufferData") &&
+ gl.isFunctionAvailable("glDrawElements") &&
+ gl.isFunctionAvailable("glVertexAttribPointer") &&
+ gl.isFunctionAvailable("glDeleteBuffers");
+
+ if(DEBUG) {
+ System.err.println("TextRendererImpl01: VBO Supported = " + isVBOSupported());
+ }
+
+ initialized = initImpl(gl);
+ return initialized;
+ }
+
+ public void dispose(GL2ES2 gl) {
+ if(!initialized){
+ if(DEBUG) {
+ System.err.println("TextRenderer: Not initialized!");
+ }
+ return;
+ }
+ disposeImpl(gl);
+ st.destroy(gl);
+ flushCache();
+ initialized = false;
+ }
+
+ public final ShaderState getShaderState() { return st; }
+
+ public final PMVMatrix getMatrix() { return pmvMatrix; }
+
+ 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 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 resetModelview(GL2ES2 gl) {
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ if(initialized && null != gl && st.inUse()) {
+ st.glUniform(gl, mgl_PMVMatrix);
+ }
+ }
+
+ public void updateMatrix(GL2ES2 gl) {
+ if(initialized && null != gl && st.inUse()) {
+ st.glUniform(gl, mgl_PMVMatrix);
+ }
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
new file mode 100644
index 000000000..2bb99d27c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
@@ -0,0 +1,103 @@
+package com.jogamp.graph.curve.opengl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.media.opengl.GL2ES2;
+
+import jogamp.graph.curve.text.GlyphString;
+import jogamp.graph.font.FontInt;
+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.
+ */
+ public static TextRenderer create(Vertex.Factory<? extends Vertex> factory, int type) {
+ return new jogamp.graph.curve.opengl.TextRendererImpl01(factory, type);
+ }
+
+ protected TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) {
+ super(factory, 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
+ * @param gl the current GL state
+ * @param font {@link Font} to be used
+ * @param str text to be rendered
+ * @param position the lower left corner of the string
+ * @param fontSize font size
+ * @param texSize texture size for multipass render
+ * @throws Exception if TextRenderer not initialized
+ */
+ public abstract void renderString3D(GL2ES2 gl, Font font,
+ String str, float[] position, int fontSize, int texSize);
+
+ /**Create the resulting {@link GlyphString} that represents
+ * the String wrt to the font.
+ * @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);
+
+ Path2D[] paths = new Path2D[str.length()];
+ ((FontInt)font).getOutline(str, size, affineTransform, paths);
+
+ GlyphString glyphString = new GlyphString(pointFactory, font.getName(), str);
+ glyphString.createfromFontPath(paths, affineTransform);
+ glyphString.generateRegion(gl.getContext(), sharpness, st, renderType);
+
+ return glyphString;
+ }
+
+ public void flushCache() {
+ Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
+ while(iterator.hasNext()){
+ GlyphString glyphString = iterator.next();
+ glyphString.destroy();
+ }
+ stringCacheMap.clear();
+ stringCacheArray.clear();
+ }
+
+ public final void setCacheMaxSize(int newSize ) { stringCacheMaxSize = newSize; validateCache(0); }
+ public final int getCacheMaxSize() { return stringCacheMaxSize; }
+ 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 GlyphString getCachedGlyphString(Font font, String str, int fontSize) {
+ final String key = font.getName() + "." + str.hashCode() + "." + fontSize;
+ return stringCacheMap.get(key);
+ }
+
+ protected void addCachedGlyphString(Font font, String str, int fontSize, GlyphString glyphString) {
+ final String key = font.getName() + "." + str.hashCode() + "." + fontSize;
+ validateCache(1);
+ stringCacheMap.put(key, glyphString);
+ stringCacheArray.add(stringCacheArray.size(), key);
+ }
+
+ // 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
+} \ No newline at end of file