diff options
author | Sven Gothel <sgothel@jausoft.com> | 2011-03-30 13:56:48 +0200 |
---|---|---|
committer | Sven Gothel <sgothel@jausoft.com> | 2011-03-30 13:56:48 +0200 |
commit | dbc74b98eb7429cbb51f7af0572ab53ddd0d9edc (patch) | |
tree | 9902e64c12ed222fa47d0e49390548cbcd252698 /src/com/jogamp/graph/curve | |
parent | e952e7dbac7a6b746b8465aa63423f1aa138ca27 (diff) |
Refactor: Public *Renderer / Unify Region Demos / Using own Screenshot (non AWT, plain GL2ES2)
Refactor: Public *Renderer
- Sharing common base abstract class Renderer.java
- Having public abstract classes RegionRenderer and TextRenderer
- Implementation non public, accessed via factory
- + shared code
- + clean API (same stuff)
Unify Region Demos
- reduced code / path, sharing common demo/test features Text/Region
Using own Screenshot (non AWT, plain GL2ES2)
- Remove AWT dependency
- Allow GL2ES2 screenshots
- Less complex
Diffstat (limited to 'src/com/jogamp/graph/curve')
-rw-r--r--[-rwxr-xr-x] | src/com/jogamp/graph/curve/opengl/RegionRenderer.java | 500 | ||||
-rw-r--r-- | src/com/jogamp/graph/curve/opengl/Renderer.java | 161 | ||||
-rw-r--r-- | src/com/jogamp/graph/curve/opengl/TextRenderer.java | 392 | ||||
-rw-r--r-- | src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp | 99 | ||||
-rw-r--r-- | src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp | 13 |
5 files changed, 332 insertions, 833 deletions
diff --git a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java index e75ca25cd..4be1506d5 100755..100644 --- a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -1,388 +1,112 @@ -/**
- * 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 java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLUniformData;
-import javax.media.opengl.fixedfunc.GLMatrixFunc;
-
-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;
-
-import jogamp.opengl.Debug;
-import com.jogamp.opengl.util.PMVMatrix;
-import com.jogamp.opengl.util.glsl.ShaderCode;
-import com.jogamp.opengl.util.glsl.ShaderProgram;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-public class RegionRenderer {
- protected static final boolean DEBUG = Debug.debug("RegionRenderer");
-
- private ShaderState st;
- private PMVMatrix pmvMatrix = new PMVMatrix();
-
- /**Sharpness is equivalent to the value of t value of texture coord
- * on the off-curve vertex. The high value of sharpness will
- * result in high curvature.
- */
- private float sharpness = 0.5f;
- private float alpha = 1.0f;
- private float strength = 3.0f;
- private boolean initialized = false;
-
- private int regionType = Region.SINGLE_PASS;
-
- private GLContext context;
- private FloatBuffer color = FloatBuffer.allocate(3);
- private HashMap<Integer, Region> regions = new HashMap<Integer, Region>();
-
- /** Create a Hardware accelerated Region Renderer
- * @param context OpenGL rendering context
- * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory.
- */
- public RegionRenderer(GLContext context) {
- this.context = context;
- init(context, 0.5f);
- }
- /** Create a Hardware accelerated Region Renderer
- * @param context OpenGL rendering context
- * @param type region type (single or multipass)
- */
- public RegionRenderer(GLContext context, int type) {
- this.context = context;
- this.regionType = type;
- init(context, 0.5f);
- }
-
- private boolean init(GLContext context, float sharpvalue){
- if(initialized){
- if(DEBUG) {
- System.err.println("HWRegionRenderer: Already initialized!");
- }
- return true;
- }
- sharpness = sharpvalue;
-
- GL2ES2 gl = context.getGL().getGL2ES2();
-
- boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") &&
- gl.isFunctionAvailable("glBindBuffer") &&
- gl.isFunctionAvailable("glBufferData") &&
- gl.isFunctionAvailable("glDrawElements") &&
- gl.isFunctionAvailable("glVertexAttribPointer") &&
- gl.isFunctionAvailable("glDeleteBuffers");
-
- if(DEBUG) {
- System.err.println("HWRegionRenderer: VBO Supported = " + VBOsupported);
- }
-
- if(!VBOsupported){
- return false;
- }
-
- gl.setSwapInterval(1);
-
- gl.glEnable(GL2ES2.GL_BLEND);
- gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA);
-
- initShader(gl);
-
- st.glUseProgram(gl, true);
-
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
-
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- resetMatrix();
-
- if(!st.glUniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) {
- if(DEBUG){
- System.err.println("Error setting PMVMatrix in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("p1y", sharpness))) {
- if(DEBUG){
- System.err.println("Error setting sharpness in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- if(DEBUG){
- System.err.println("Error setting global alpha in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("g_color", 3, color))) {
- if(DEBUG){
- System.err.println("Error setting global color in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
- st.glUseProgram(gl, false);
-
- if(DEBUG) {
- System.err.println("HWRegionRenderer initialized: " + Thread.currentThread()+" "+st);
- }
- initialized = true;
- return true;
- }
-
- public float getAlpha() {
- return alpha;
- }
- public void setAlpha(float alpha_t) {
- alpha = alpha_t;
- }
-
- public void setColor(float r, float g, float b){
- color.put(r);
- color.put(g);
- color.put(b);
- color.rewind();
- }
-
- public void rotate(float angle, float x, float y, float z){
- pmvMatrix.glRotatef(angle, x, y, z);
- }
- public void translate(float x, float y, float z){
- pmvMatrix.glTranslatef(x, y, z);
- }
-
- public void resetMatrix(){
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
- }
-
- /**
- * @param drawable
- * @param angle
- * @param ratio
- * @param near
- * @param far
- * @return
- */
- public boolean reshape(GLAutoDrawable drawable, float angle, float ratio, float near, float far){
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.gluPerspective(angle, ratio, near, far);
-
- if(null==st) {
- if(DEBUG){
- System.err.println("HWRegionRenderer: Shader State is null, or not");
- }
- return false;
- }
- GL2ES2 gl = drawable.getGL().getGL2ES2();
-
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- st.glUseProgram(gl, false);
- return true;
- }
-
- private void initShader(GL2ES2 gl) {
- ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, RegionRenderer.class,
- "shader", "shader/bin", "curverenderer");
- ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, RegionRenderer.class,
- "shader", "shader/bin", "curverenderer");
-
- ShaderProgram sp = new ShaderProgram();
- sp.add(rsVp);
- sp.add(rsFp);
-
- if(!sp.link(gl, System.err)) {
- throw new GLException("HWRegionRenderer: Couldn't link program: "+sp);
- }
-
- st = new ShaderState();
- st.attachShaderProgram(gl, sp);
- gl.glBindAttribLocation(sp.id(), 0, "v_position");
- gl.glBindAttribLocation(sp.id(), 1, "texCoord");
- }
-
- private Region createRegion(OutlineShape outlineShape) {
- Region region = RegionFactory.create(context, st, regionType);
-
- outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
-
- ArrayList<Triangle<Vertex>> triangles = (ArrayList<Triangle<Vertex>>) outlineShape.triangulate(sharpness);
- ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices();
- region.addVertices(vertices);
- region.addTriangles(triangles);
-
- region.update();
- return region;
- }
-
- private Region createRegion(OutlineShape[] outlineShapes) {
- Region region = RegionFactory.create(context, st, regionType);
-
- int numVertices = region.getNumVertices();
-
- for(OutlineShape outlineShape:outlineShapes){
- outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
-
- ArrayList<Triangle<Vertex>> 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;
- }
-
-
- /** Render outline 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.
- * @throws Exception if HwRegionRenderer not initialized
- */
- public void renderOutlineShape(OutlineShape outlineShape, float[] position) throws Exception{
- if(!initialized){
- throw new Exception("HWRegionRenderer: not initialized!");
- }
- int hashCode = getHashCode(outlineShape);
- Region region = regions.get(hashCode);
-
- if(null == region) {
- region = createRegion(outlineShape);
- regions.put(hashCode, region);
- }
-
- GL2ES2 gl = context.getGL().getGL2ES2();
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- System.err.println("Error setting global alpha in shader: "+st);
- }
- GLUniformData gcolorUD = st.getUniform("g_color");
- if(null!=gcolorUD) {
- st.glUniform(gl, gcolorUD);
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
-
- region.render(null, 0, 0, 0);
- st.glUseProgram(gl, false);
- }
-
- /** Render a list of Outline shapes combined in one region
- * at the position provided the triangles of the
- * shapes will be generated, if not yet generated
- * @param outlineShapes the list of OutlineShapes to Render.
- * @param position the initial translation of the outlineShapes.
- * @throws Exception if HwRegionRenderer not initialized
- */
- public void renderOutlineShapes(OutlineShape[] outlineShapes, float[] position) throws Exception{
- if(!initialized){
- throw new Exception("HWRegionRenderer: not initialized!");
- }
-
- int hashCode = getHashCode(outlineShapes);
- Region region = regions.get(hashCode);
-
- if(null == region) {
- region = createRegion(outlineShapes);
- regions.put(hashCode, region);
- }
-
- GL2ES2 gl = context.getGL().getGL2ES2();
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- System.err.println("Error setting global alpha in shader: "+st);
- }
- GLUniformData gcolorUD = st.getUniform("g_color");
- if(null!=gcolorUD) {
- st.glUniform(gl, gcolorUD);
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
- region.render(null, 0, 0, 0);
- st.glUseProgram(gl, false);
- }
-
- private int getHashCode(OutlineShape outlineShape){
- return outlineShape.hashCode();
- }
-
- private int getHashCode(OutlineShape[] outlineShapes){
- int hashcode = 0;
- for(OutlineShape outlineShape:outlineShapes){
- hashcode += getHashCode(outlineShape);
- }
- return hashcode;
- }
-
- /** Clears the cached string curves
- * and destorys underlying buffers
- */
- public void clearCached() {
- Iterator<Region> iterator = regions.values().iterator();
- while(iterator.hasNext()){
- Region region = iterator.next();
- region.destroy();
- }
- regions.clear();
- }
-}
+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 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 Outline shapes 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 outline 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 flushCash() { + Iterator<Region> iterator = regions.values().iterator(); + while(iterator.hasNext()){ + Region region = iterator.next(); + region.destroy(); + } + regions.clear(); + } + + /** + * @param sharpness parameter for Region generation + * @return the resulting Region inclusive the generated region + */ + protected Region createRegion(GL2ES2 gl, OutlineShape outlineShape, float sharpness) { + Region region = RegionFactory.create(gl.getContext(), st, regionType); + + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList<Triangle<Vertex>> triangles = (ArrayList<Triangle<Vertex>>) outlineShape.triangulate(sharpness); + ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices(); + region.addVertices(vertices); + region.addTriangles(triangles); + + region.update(); + return region; + } + + /** + * @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, regionType); + + int numVertices = region.getNumVertices(); + + for(OutlineShape outlineShape:outlineShapes){ + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList<Triangle<Vertex>> 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/com/jogamp/graph/curve/opengl/Renderer.java b/src/com/jogamp/graph/curve/opengl/Renderer.java new file mode 100644 index 000000000..a1755e003 --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/Renderer.java @@ -0,0 +1,161 @@ +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.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 abstract boolean initImpl(GL2ES2 gl); + + protected abstract void disposeImpl(GL2ES2 gl); + + /** + * Flushes all cached data + */ + public abstract void flushCash(); + + 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 regionType = Region.SINGLE_PASS; + protected int vp_width = 0; + protected int vp_height = 0; + + private boolean vboSupported = false; + private boolean initialized = false; + + protected Renderer(Vertex.Factory<? extends Vertex> factory, int type) { + this.regionType = type; + 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 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); + flushCash(); + 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/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/com/jogamp/graph/curve/opengl/TextRenderer.java index 703f82373..04988a3ab 100644 --- a/src/com/jogamp/graph/curve/opengl/TextRenderer.java +++ b/src/com/jogamp/graph/curve/opengl/TextRenderer.java @@ -1,353 +1,79 @@ -/** - * 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 java.util.HashMap; import java.util.Iterator; import javax.media.opengl.GL2ES2; -import javax.media.opengl.GLException; -import javax.media.opengl.GLUniformData; -import javax.media.opengl.fixedfunc.GLMatrixFunc; 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.curve.Region; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.opengl.SVertex; -import jogamp.opengl.Debug; -import com.jogamp.opengl.util.PMVMatrix; -import com.jogamp.opengl.util.glsl.ShaderCode; -import com.jogamp.opengl.util.glsl.ShaderProgram; -import com.jogamp.opengl.util.glsl.ShaderState; -public class TextRenderer { - protected static final boolean DEBUG = Debug.debug("TextRenderer"); - static final boolean FONTTOOL_CUSTOM = false; - - private ShaderState st = new ShaderState(); - - private PMVMatrix pmvMatrix = new PMVMatrix(); - private GLUniformData mgl_PMVMatrix; - - /**Sharpness is equivalent to the value of t value of texture coord - * on the off-curve vertex. The high value of sharpness will - * result in high curvature. - */ - private GLUniformData mgl_sharpness = new GLUniformData("p1y", 0.5f); - private GLUniformData mgl_alpha = new GLUniformData("g_alpha", 1.0f); - private GLUniformData mgl_color = new GLUniformData("g_color", 3, FloatBuffer.allocate(3)); - private GLUniformData mgl_strength = new GLUniformData("a_strength", 1.8f); - - private boolean initialized = false; - - private int regionType = Region.SINGLE_PASS; - - private HashMap<String, GlyphString> strings = new HashMap<String, GlyphString>(); - private final Vertex.Factory<? extends Vertex> pointFactory; - - int win_width = 0; - int win_height = 0; - - /** - * Create a Hardware accelerated Text Renderer. - * @param context OpenGL rendering context - * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. - */ - public TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) { - this.pointFactory = (null != factory) ? factory : SVertex.factory(); - this.regionType = type; - } - - /** - * Initialize shaders and bindings for GPU based text Rendering, - * should be called only once. - * Leaves the renderer enables, ie ShaderState on. - * - * @param drawable the current drawable - * @param shapvalue shaprness around the off-curve vertices - * @return true if init succeeded, false otherwise - */ - public boolean init(GL2ES2 gl){ - if(initialized){ - if(DEBUG) { - System.err.println("HWTextRenderer: Already initialized!"); - } - return true; - } - - boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") && - gl.isFunctionAvailable("glBindBuffer") && - gl.isFunctionAvailable("glBufferData") && - gl.isFunctionAvailable("glDrawElements") && - gl.isFunctionAvailable("glVertexAttribPointer") && - gl.isFunctionAvailable("glDeleteBuffers"); - - if(DEBUG) { - System.err.println("HWTextRenderer: VBO Supported = " + VBOsupported); - } - - if(!VBOsupported){ - return false; - } - - gl.glEnable(GL2ES2.GL_BLEND); - gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); - - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, TextRenderer.class, - "shader", "shader/bin", "curverenderer"); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, TextRenderer.class, - "shader", "shader/bin", "curverenderer"); - - ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - - if(!sp.link(gl, System.err)) { - throw new GLException("HWTextRenderer: Couldn't link program: "+sp); - } - - st.attachShaderProgram(gl, sp); - gl.glBindAttribLocation(sp.id(), 0, "v_position"); - gl.glBindAttribLocation(sp.id(), 1, "texCoord"); - - st.glUseProgram(gl, true); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - resetMatrix(null); - - mgl_PMVMatrix = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); - if(!st.glUniform(gl, mgl_PMVMatrix)) { - if(DEBUG){ - System.err.println("Error setting PMVMatrix in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_sharpness)) { - if(DEBUG){ - System.err.println("Error setting sharpness in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_alpha)) { - if(DEBUG){ - System.err.println("Error setting global alpha in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_color)) { - if(DEBUG){ - System.err.println("Error setting global color in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_strength)) { - System.err.println("Error setting antialias strength in shader: "+st); - } - - if(DEBUG) { - System.err.println("HWTextRenderer initialized: " + Thread.currentThread()+" "+st); - } - initialized = true; - return true; - } - - public void dispose(GL2ES2 gl) { - st.destroy(gl); - flushCash(); - } - - public float getAlpha() { - return mgl_alpha.floatValue(); - } - - public ShaderState getShaderState() { - return st; - } - - public void setAlpha(GL2ES2 gl, float alpha_t) { - mgl_alpha.setData(alpha_t); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_alpha); - } - } - - public void setColor(GL2ES2 gl, float r, float g, float b){ - FloatBuffer fb = (FloatBuffer) mgl_color.getBuffer(); - fb.put(0, r); - fb.put(1, r); - fb.put(2, r); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_color); - } - } - - public final PMVMatrix matrix() { return pmvMatrix; } - - public void rotate(GL2ES2 gl, float angle, float x, float y, float z){ - pmvMatrix.glRotatef(angle, x, y, z); - if(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(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void resetMatrix(GL2ES2 gl){ - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void setMatrix(GL2ES2 gl){ - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void updateAllShaderValues(GL2ES2 gl) { - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - st.glUniform(gl, mgl_alpha); - st.glUniform(gl, mgl_color); - st.glUniform(gl, mgl_strength); - } +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); } - /** - * @param gl - * @param angle - * @param ratio - * @param near - * @param far - * @return - */ - public boolean reshapePerspective(GL2ES2 gl, float angle, int width, int height, float near, float far){ - win_width = width; - win_height = height; - float ratio = (float)width/(float)height; - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.gluPerspective(angle, ratio, near, far); - - if(null != gl) { - st.glUniform(gl, mgl_PMVMatrix); - } - - return true; - } - - public boolean reshapeOrtho(GL2ES2 gl, int width, int height, float near, float far) { - win_width = width; - win_height = height; - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.glOrthof(0, width, 0, height, near, far); - - if(null != gl) { - st.glUniform(gl, mgl_PMVMatrix); - } - - return true; - } + protected TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) { + super(factory, type); + } - private GlyphString createString(GL2ES2 gl, Font font, int size, String str) { - 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(), mgl_sharpness.floatValue(), st, regionType); - return glyphString; - } - - - /** 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 font font to be used - * @param str text to be rendered - * @param position the lower left corner of the string + /** 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 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 void renderString3D(GL2ES2 gl, Font font, String str, float[] position, int fontSize, int texSize) { - if(!initialized){ - throw new GLException("HWTextRenderer: not initialized!"); - } - String fontStrHash = getTextHashCode(font, str, fontSize); - GlyphString glyphString = strings.get(fontStrHash); - if(null == glyphString) { - glyphString = createString(gl, font, fontSize, str); - strings.put(fontStrHash, glyphString); - } - - glyphString.renderString3D(pmvMatrix, win_width, win_height, texSize); - } - - private String getTextHashCode(Font font, String str, int fontSize) { - // FIXME: use integer hash code - return font.getName() + "." + str.hashCode() + "." + fontSize; - } + * @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); - /** Clears the cached string curves - * and destorys underlying buffers - */ - public void flushCash() { - Iterator<GlyphString> iterator = strings.values().iterator(); - while(iterator.hasNext()){ - GlyphString glyphString = iterator.next(); - glyphString.destroy(); - } - strings.clear(); - } -} + protected HashMap<String, GlyphString> strings = new HashMap<String, GlyphString>(); + + /** + * + * @param font + * @param size + * @param str + * @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, regionType); + + return glyphString; + } + + protected static String getTextHashCode(Font font, String str, int fontSize) { + // FIXME: use integer hash code + return font.getName() + "." + str.hashCode() + "." + fontSize; + } + + public void flushCash() { + Iterator<GlyphString> iterator = strings.values().iterator(); + while(iterator.hasNext()){ + GlyphString glyphString = iterator.next(); + glyphString.destroy(); + } + strings.clear(); + } +}
\ No newline at end of file diff --git a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp deleted file mode 100644 index 2b3a0ce1d..000000000 --- a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp +++ /dev/null @@ -1,99 +0,0 @@ -//#version 100 - -uniform float p1y; -uniform float g_alpha; -uniform vec3 g_color; -uniform float a_strength; - -varying vec2 v_texCoord; - -vec3 b_color = vec3(0.0, 0.0, 0.0); - -uniform sampler2D texture; -vec4 weights = vec4(0.075, 0.06, 0.045, 0.025); - -void main (void) -{ - vec2 rtex = vec2(abs(v_texCoord.x),abs(v_texCoord.y)); - vec3 c = g_color; - - float alpha = 0.0; - - if((v_texCoord.x == 0.0) && (v_texCoord.y == 0.0)){ - alpha = g_alpha; - } - else if((v_texCoord.x >= 5.0)){ - vec2 dfx = dFdx(v_texCoord); - vec2 dfy = dFdy(v_texCoord); - - vec2 size = 1.0/textureSize(texture,0); //version 130 - rtex -= 5.0; - vec4 t = texture2D(texture, rtex)* 0.18; - - t += texture2D(texture, rtex + size*(vec2(1, 0)))*weights.x; - t += texture2D(texture, rtex - size*(vec2(1, 0)))*weights.x; - t += texture2D(texture, rtex + size*(vec2(0, 1)))*weights.x; - t += texture2D(texture, rtex - size*(vec2(0, 1)))*weights.x; - - t += texture2D(texture, rtex + 2.0*size*(vec2(1, 0))) *weights.y; - t += texture2D(texture, rtex - 2.0*size*(vec2(1, 0)))*weights.y; - t += texture2D(texture, rtex + 2.0*size*(vec2(0, 1)))*weights.y; - t += texture2D(texture, rtex - 2.0*size*(vec2(0, 1)))*weights.y; - - t += texture2D(texture, rtex + 3.0*size*(vec2(1, 0))) *weights.z; - t += texture2D(texture, rtex - 3.0*size*(vec2(1, 0)))*weights.z; - t += texture2D(texture, rtex + 3.0*size*(vec2(0, 1)))*weights.z; - t += texture2D(texture, rtex - 3.0*size*(vec2(0, 1)))*weights.z; - - t += texture2D(texture, rtex + 4.0*size*(vec2(1, 0))) *weights.w; - t += texture2D(texture, rtex - 4.0*size*(vec2(1, 0)))*weights.w; - t += texture2D(texture, rtex + 4.0*size*(vec2(0, 1)))*weights.w; - t += texture2D(texture, rtex - 4.0*size*(vec2(0, 1)))*weights.w; - - if(t.w == 0.0){ - discard; - } - - c = t.xyz; - alpha = g_alpha* t.w; - } - /////////////////////////////////////////////////////////// - else if ((v_texCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)){ - vec2 dtx = dFdx(rtex); - vec2 dty = dFdy(rtex); - - rtex.y -= 0.1; - if(rtex.y < 0.0) { - if(v_texCoord.y < 0.0) - discard; - else{ - rtex.y = 0.0; - } - } - - vec2 f = vec2((dtx.y - 2.0*p1y*dtx.x + 4.0*p1y*rtex.x*dtx.x), (dty.y - 2.0*p1y*dty.x + 4.0*p1y*rtex.x*dty.x)); - - float position = rtex.y - ((2.0 * rtex.x * p1y) * (1.0 - rtex.x)); - float d = position/(length(f)); - - float a = (0.5 - d * sign(v_texCoord.y)); - - - if (a >= 1.0) { - alpha = g_alpha; - // c = vec3(1.0,1.0,1.0); - } - else if (a <= 0.0) { - alpha = 0.0;//discard; - // c = vec3(0.0,0.0,0.0); - - } - else { - alpha = g_alpha*a; - // c = vec3(a,a,a); - mix(b_color,g_color, a); - } - } - - gl_FragColor = vec4(c, alpha); -} diff --git a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp deleted file mode 100644 index bc9ecb41e..000000000 --- a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp +++ /dev/null @@ -1,13 +0,0 @@ -//#version 100 - -uniform mat4 mgl_PMVMatrix[2]; -attribute vec4 v_position; -attribute vec2 texCoord; - -varying vec2 v_texCoord; - -void main(void) -{ - gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * v_position; - v_texCoord = texCoord.st; -}
\ No newline at end of file |