From dbc74b98eb7429cbb51f7af0572ab53ddd0d9edc Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 30 Mar 2011 13:56:48 +0200 Subject: 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 --- .../jogamp/graph/curve/opengl/RegionRenderer.java | 500 +++++---------------- src/com/jogamp/graph/curve/opengl/Renderer.java | 161 +++++++ .../jogamp/graph/curve/opengl/TextRenderer.java | 392 +++------------- .../graph/curve/opengl/shader/curverenderer.fp | 99 ---- .../graph/curve/opengl/shader/curverenderer.vp | 13 - src/demo/GPURegionNewtDemo01.java | 167 +++---- src/demo/GPURegionNewtDemo02.java | 260 +++++------ src/demo/GPURegionRendererListenerBase01.java | 53 +++ src/demo/GPURendererListenerBase01.java | 231 ++++++++++ src/demo/GPUTextGLListenerBase01.java | 324 ------------- src/demo/GPUTextNewtDemo01.java | 17 +- src/demo/GPUTextNewtDemo02.java | 15 +- src/demo/GPUTextRendererListenerBase01.java | 190 ++++++++ src/demo/ReadBufferUtil.java | 107 +++++ src/demo/Screenshot.java | 39 ++ .../graph/curve/opengl/RegionRendererImpl01.java | 206 +++++++++ .../graph/curve/opengl/TextRendererImpl01.java | 189 ++++++++ .../graph/curve/opengl/shader/curverenderer01.fp | 99 ++++ .../graph/curve/opengl/shader/curverenderer01.vp | 13 + .../test/junit/graph/TestRegionRenderer01.java | 152 +++++++ .../test/junit/graph/TestTextRenderer01.java | 31 +- 21 files changed, 1814 insertions(+), 1444 deletions(-) mode change 100755 => 100644 src/com/jogamp/graph/curve/opengl/RegionRenderer.java create mode 100644 src/com/jogamp/graph/curve/opengl/Renderer.java delete mode 100644 src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp delete mode 100644 src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp mode change 100755 => 100644 src/demo/GPURegionNewtDemo02.java create mode 100644 src/demo/GPURegionRendererListenerBase01.java create mode 100644 src/demo/GPURendererListenerBase01.java delete mode 100644 src/demo/GPUTextGLListenerBase01.java create mode 100644 src/demo/GPUTextRendererListenerBase01.java create mode 100644 src/demo/ReadBufferUtil.java create mode 100644 src/demo/Screenshot.java create mode 100755 src/jogamp/graph/curve/opengl/RegionRendererImpl01.java create mode 100644 src/jogamp/graph/curve/opengl/TextRendererImpl01.java create mode 100644 src/jogamp/graph/curve/opengl/shader/curverenderer01.fp create mode 100644 src/jogamp/graph/curve/opengl/shader/curverenderer01.vp create mode 100644 src/test/com/jogamp/opengl/test/junit/graph/TestRegionRenderer01.java (limited to 'src') diff --git a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java old mode 100755 new mode 100644 index e75ca25cd..4be1506d5 --- 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 regions = new HashMap(); - - /** 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> triangles = (ArrayList>) outlineShape.triangulate(sharpness); - ArrayList vertices = (ArrayList) 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> triangles = outlineShape.triangulate(sharpness); - region.addTriangles(triangles); - - ArrayList 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 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 factory, int type) { + return new jogamp.graph.curve.opengl.RegionRendererImpl01(factory, type); + } + + public RegionRenderer(Vertex.Factory 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 regions = new HashMap(); + + public void flushCash() { + Iterator 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> triangles = (ArrayList>) outlineShape.triangulate(sharpness); + ArrayList vertices = (ArrayList) 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> triangles = outlineShape.triangulate(sharpness); + region.addTriangles(triangles); + + ArrayList 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 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 factory, int type) { + this.regionType = type; + this.pointFactory = (null != factory) ? factory : SVertex.factory(); + } + + public Vertex.Factory 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 strings = new HashMap(); - private final Vertex.Factory 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 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 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 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 iterator = strings.values().iterator(); - while(iterator.hasNext()){ - GlyphString glyphString = iterator.next(); - glyphString.destroy(); - } - strings.clear(); - } -} + protected HashMap strings = new HashMap(); + + /** + * + * @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 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 diff --git a/src/demo/GPURegionNewtDemo01.java b/src/demo/GPURegionNewtDemo01.java index d58d4148d..676621692 100755 --- a/src/demo/GPURegionNewtDemo01.java +++ b/src/demo/GPURegionNewtDemo01.java @@ -32,18 +32,14 @@ import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLEventListener; import javax.media.opengl.GLProfile; import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.geom.opengl.SVertex; -import com.jogamp.newt.event.KeyEvent; -import com.jogamp.newt.event.KeyListener; -import com.jogamp.newt.event.WindowAdapter; -import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.util.FPSAnimator; +import com.jogamp.opengl.util.Animator; /** Demonstrate the rendering of multiple outlines into one region/OutlineShape * These Outlines are not necessary connected or contained. @@ -53,21 +49,18 @@ import com.jogamp.opengl.util.FPSAnimator; * */ public class GPURegionNewtDemo01 { - private static void create(){ - new RegionNewtWindow(); - } - public static void main(String[] args) { - create(); - } -} - -class RegionNewtWindow { + static final boolean DEBUG = false; + static final boolean TRACE = false; + + public static void main(String[] args) { + GPURegionNewtDemo01 test = new GPURegionNewtDemo01(); + test.testMe(); + } + RegionGLListener regionGLListener = null; - - public RegionNewtWindow(){ - createWindow(); - } - private void createWindow() { + GLWindow window; + + public void testMe() { GLProfile.initSingleton(true); GLProfile glp = GLProfile.getGL2ES2(); GLCapabilities caps = new GLCapabilities(glp); @@ -75,65 +68,45 @@ class RegionNewtWindow { caps.setSampleBuffers(true); caps.setNumSamples(4); // 2 samples is not enough .. System.out.println("Requested: " + caps); - final GLWindow window = GLWindow.create(caps); - window.setPosition(10, 10); - window.setSize(500, 500); - window.setTitle("GPU Curve Region Newt Demo 01 - r2t0 msaa1"); - regionGLListener = new RegionGLListener(); + + GLWindow w = GLWindow.create(caps); + w.setPosition(10, 10); + w.setSize(800, 400); + w.setTitle("GPU Curve Region Newt Demo 01 - r2t0 msaa1"); + + regionGLListener = createRegionRendererListener(w); + window.addGLEventListener(regionGLListener); + window.enablePerfLog(true); window.setVisible(true); - window.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent arg0) { - if(arg0.getKeyCode() == KeyEvent.VK_1){ - regionGLListener.zoomIn(); - } - else if(arg0.getKeyCode() == KeyEvent.VK_2){ - regionGLListener.zoomOut(); - } - else if(arg0.getKeyCode() == KeyEvent.VK_UP){ - regionGLListener.move(0, -1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){ - regionGLListener.move(0, 1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){ - regionGLListener.move(1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){ - regionGLListener.move(-1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_0){ - regionGLListener.rotate(1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_9){ - regionGLListener.rotate(-1); - } - } - public void keyTyped(KeyEvent arg0) {} - public void keyReleased(KeyEvent arg0) {} - }); - - FPSAnimator animator = new FPSAnimator(60); + //FPSAnimator animator = new FPSAnimator(60); + Animator animator = new Animator(); animator.add(window); - window.addWindowListener(new WindowAdapter() { - public void windowDestroyNotify(WindowEvent arg0) { - System.exit(0); - }; - }); animator.start(); } - private class RegionGLListener implements GLEventListener{ - RegionRenderer regionRenderer = null; - + + public RegionGLListener createRegionRendererListener(GLWindow w) { + this.window = w; + + RegionGLListener l = new RegionGLListener(); + l.attachInputListenerTo(w); + + return l; + } + + public class RegionGLListener extends GPURegionRendererListenerBase01 { OutlineShape outlineShape = null; - public RegionGLListener() {} + public RegionGLListener() { + super(SVertex.factory(), Region.SINGLE_PASS, DEBUG, TRACE); + setMatrix(-20, 00, 0f, -50, 400); + } private void createTestOutline(){ float offset = 0; - outlineShape = new OutlineShape(SVertex.factory()); + outlineShape = new OutlineShape(getRenderer().getFactory()); outlineShape.addVertex(0.0f,-10.0f, true); outlineShape.addVertex(15.0f,-10.0f, true); outlineShape.addVertex(10.0f,5.0f, false); @@ -169,64 +142,38 @@ class RegionNewtWindow { } public void init(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); + super.init(drawable); + + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + final RegionRenderer regionRenderer = (RegionRenderer) getRenderer(); + gl.setSwapInterval(1); gl.glEnable(GL2ES2.GL_DEPTH_TEST); - regionRenderer = new RegionRenderer(drawable.getContext()); - regionRenderer.setAlpha(1.0f); - regionRenderer.setColor(0.0f, 0.0f, 0.0f); + regionRenderer.init(gl); + regionRenderer.setAlpha(gl, 1.0f); + regionRenderer.setColor(gl, 0.0f, 0.0f, 0.0f); //gl.glSampleCoverage(0.95f, false); //gl.glEnable(GL2GL3.GL_SAMPLE_COVERAGE); // sample coverage doesn't really make a difference to lines //gl.glEnable(GL2GL3.GL_SAMPLE_ALPHA_TO_ONE); MSAATool.dump(drawable); + createTestOutline(); } - float ang = 0; - float zoom = -70; - float xTran = -20; - float yTran = 5; - public void display(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - regionRenderer.resetMatrix(); - regionRenderer.translate(xTran, yTran, zoom); - regionRenderer.rotate(ang, 0, 1, 0); - - try { - regionRenderer.renderOutlineShape(outlineShape, new float[]{0,0,0}); - } catch (Exception e) { - e.printStackTrace(); - } - } - public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height){ - GL2ES2 gl = drawable.getGL().getGL2ES2(); - gl.glViewport(xstart, ystart, width, height); - - regionRenderer.reshape(drawable, 45.0f, (float)width / (float)height, 0.1f, 7000.0f); - } + final RegionRenderer regionRenderer = (RegionRenderer) getRenderer(); + + regionRenderer.resetModelview(null); + regionRenderer.translate(null, getXTran(), getYTran(), getZoom()); + regionRenderer.rotate(gl, getAngle(), 0, 1, 0); - public void zoomIn(){ - zoom++; - } - public void zoomOut(){ - zoom--; - } - public void move(float x, float y){ - xTran += x; - yTran += y; - } - public void rotate(float delta){ - ang+= delta; - ang%=360; - } - public void dispose(GLAutoDrawable arg0) { - regionRenderer.clearCached(); - - } + regionRenderer.renderOutlineShape(gl, outlineShape, getPosition(), getTexSize()); + } } } diff --git a/src/demo/GPURegionNewtDemo02.java b/src/demo/GPURegionNewtDemo02.java old mode 100755 new mode 100644 index 19889ac6e..a7b56ad42 --- a/src/demo/GPURegionNewtDemo02.java +++ b/src/demo/GPURegionNewtDemo02.java @@ -32,193 +32,145 @@ import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLEventListener; import javax.media.opengl.GLProfile; import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.geom.opengl.SVertex; -import com.jogamp.newt.event.KeyEvent; -import com.jogamp.newt.event.KeyListener; -import com.jogamp.newt.event.WindowAdapter; -import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.util.FPSAnimator; +import com.jogamp.opengl.util.Animator; /** Demonstrate the rendering of multiple OutlineShapes * into one region * */ public class GPURegionNewtDemo02 { - private static void create(){ - new RegionsNewtWindow(); - } - public static void main(String[] args) { - create(); - } -} - -class RegionsNewtWindow { + static final boolean DEBUG = false; + static final boolean TRACE = false; + + public static void main(String[] args) { + GPURegionNewtDemo02 test = new GPURegionNewtDemo02(); + test.testMe(); + } + RegionGLListener regionGLListener = null; - - public RegionsNewtWindow(){ - createWindow(); - } - private void createWindow() { + GLWindow window; + public void testMe() { GLProfile.initSingleton(true); - GLProfile glp = GLProfile.getGL2ES2(); - GLCapabilities caps = new GLCapabilities(glp); - System.out.println("Requested: "+caps); - final GLWindow window = GLWindow.create(caps); - window.setPosition(10, 10); - window.setSize(500, 500); - - window.setTitle("GPU Curve Region Newt Demo 02 - r2t0 msaa0"); - regionGLListener = new RegionGLListener(); - window.addGLEventListener(regionGLListener); - + GLProfile glp = GLProfile.get(GLProfile.GL3); + GLCapabilities caps = new GLCapabilities(glp); + caps.setAlphaBits(4); + System.out.println("Requested: " + caps); + + GLWindow w = GLWindow.create(caps); + w.setPosition(10, 10); + w.setSize(800, 400); + w.setTitle("GPU Curve Region Newt Demo 02 - r2t1 msaa0"); + + regionGLListener = createRegionRendererListener(w); + window.addGLEventListener(regionGLListener); + + window.enablePerfLog(true); window.setVisible(true); - window.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent arg0) { - if(arg0.getKeyCode() == KeyEvent.VK_1){ - regionGLListener.zoomIn(); - } - else if(arg0.getKeyCode() == KeyEvent.VK_2){ - regionGLListener.zoomOut(); - } - else if(arg0.getKeyCode() == KeyEvent.VK_UP){ - regionGLListener.move(0, -1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){ - regionGLListener.move(0, 1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){ - regionGLListener.move(1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){ - regionGLListener.move(-1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_0){ - regionGLListener.rotate(1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_9){ - regionGLListener.rotate(-1); - } - } - public void keyTyped(KeyEvent arg0) {} - public void keyReleased(KeyEvent arg0) {} - }); - - FPSAnimator animator = new FPSAnimator(60); + //FPSAnimator animator = new FPSAnimator(60); + Animator animator = new Animator(); animator.add(window); - window.addWindowListener(new WindowAdapter() { - public void windowDestroyNotify(WindowEvent arg0) { - System.exit(0); - }; - }); animator.start(); } - private class RegionGLListener implements GLEventListener{ - RegionRenderer regionRenderer = null; - - OutlineShape[] outlineShapes = new OutlineShape[2]; + + public RegionGLListener createRegionRendererListener(GLWindow w) { + this.window = w; + + RegionGLListener l = new RegionGLListener(); + l.attachInputListenerTo(w); + + return l; + } + + public class RegionGLListener extends GPURegionRendererListenerBase01 { + OutlineShape[] outlineShapes = new OutlineShape[2]; - public RegionGLListener() {} - - private void createTestOutline(){ - float offset = 0; - outlineShapes[0] = new OutlineShape(SVertex.factory()); - outlineShapes[0].addVertex(0.0f,-10.0f,true); - outlineShapes[0].addVertex(15.0f,-10.0f, true); - outlineShapes[0].addVertex(10.0f,5.0f, false); - outlineShapes[0].addVertex(15.0f,10.0f, true); - outlineShapes[0].addVertex(6.0f,15.0f, false); - outlineShapes[0].addVertex(5.0f,8.0f, false); - outlineShapes[0].addVertex(0.0f,10.0f,true); - outlineShapes[0].closeLastOutline(); - outlineShapes[0].addEmptyOutline(); - outlineShapes[0].addVertex(5.0f,-5.0f,true); - outlineShapes[0].addVertex(10.0f,-5.0f, false); - outlineShapes[0].addVertex(10.0f,0.0f, true); - outlineShapes[0].addVertex(5.0f,0.0f, false); - outlineShapes[0].closeLastOutline(); - - /** Same shape as above but without any off-curve vertices */ - outlineShapes[1] = new OutlineShape(SVertex.factory()); - offset = 30; - outlineShapes[1].addVertex(offset+0.0f,-10.0f, true); - outlineShapes[1].addVertex(offset+17.0f,-10.0f, true); - outlineShapes[1].addVertex(offset+11.0f,5.0f, true); - outlineShapes[1].addVertex(offset+16.0f,10.0f, true); - outlineShapes[1].addVertex(offset+7.0f,15.0f, true); - outlineShapes[1].addVertex(offset+6.0f,8.0f, true); - outlineShapes[1].addVertex(offset+0.0f,10.0f, true); - outlineShapes[1].closeLastOutline(); - outlineShapes[1].addEmptyOutline(); - outlineShapes[1].addVertex(offset+5.0f,0.0f, true); - outlineShapes[1].addVertex(offset+5.0f,-5.0f, true); - outlineShapes[1].addVertex(offset+10.0f,-5.0f, true); - outlineShapes[1].addVertex(offset+10.0f,0.0f, true); - outlineShapes[1].closeLastOutline(); + public RegionGLListener() { + super(SVertex.factory(), Region.TWO_PASS, DEBUG, TRACE); + setMatrix(-20, 00, 0f, -50, 400); + //setMatrix(-20, 00, 0f, -400, 400); + //setMatrix(-20, 00, 0f, -400, 400); + //setMatrix(-20, 00, 0f, -100, 800); } + + private void createTestOutline(){ + float offset = 0; + outlineShapes[0] = new OutlineShape(SVertex.factory()); + outlineShapes[0].addVertex(0.0f,-10.0f,true); + outlineShapes[0].addVertex(15.0f,-10.0f, true); + outlineShapes[0].addVertex(10.0f,5.0f, false); + outlineShapes[0].addVertex(15.0f,10.0f, true); + outlineShapes[0].addVertex(6.0f,15.0f, false); + outlineShapes[0].addVertex(5.0f,8.0f, false); + outlineShapes[0].addVertex(0.0f,10.0f,true); + outlineShapes[0].closeLastOutline(); + outlineShapes[0].addEmptyOutline(); + outlineShapes[0].addVertex(5.0f,-5.0f,true); + outlineShapes[0].addVertex(10.0f,-5.0f, false); + outlineShapes[0].addVertex(10.0f,0.0f, true); + outlineShapes[0].addVertex(5.0f,0.0f, false); + outlineShapes[0].closeLastOutline(); + + /** Same shape as above but without any off-curve vertices */ + outlineShapes[1] = new OutlineShape(SVertex.factory()); + offset = 30; + outlineShapes[1].addVertex(offset+0.0f,-10.0f, true); + outlineShapes[1].addVertex(offset+17.0f,-10.0f, true); + outlineShapes[1].addVertex(offset+11.0f,5.0f, true); + outlineShapes[1].addVertex(offset+16.0f,10.0f, true); + outlineShapes[1].addVertex(offset+7.0f,15.0f, true); + outlineShapes[1].addVertex(offset+6.0f,8.0f, true); + outlineShapes[1].addVertex(offset+0.0f,10.0f, true); + outlineShapes[1].closeLastOutline(); + outlineShapes[1].addEmptyOutline(); + outlineShapes[1].addVertex(offset+5.0f,0.0f, true); + outlineShapes[1].addVertex(offset+5.0f,-5.0f, true); + outlineShapes[1].addVertex(offset+10.0f,-5.0f, true); + outlineShapes[1].addVertex(offset+10.0f,0.0f, true); + outlineShapes[1].closeLastOutline(); + } public void init(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); + super.init(drawable); + + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + final RegionRenderer regionRenderer = (RegionRenderer) getRenderer(); + gl.setSwapInterval(1); gl.glEnable(GL2ES2.GL_DEPTH_TEST); - regionRenderer = new RegionRenderer(drawable.getContext()); - regionRenderer.setAlpha(1.0f); - regionRenderer.setColor(0.0f, 0.0f, 0.0f); + regionRenderer.init(gl); + regionRenderer.setAlpha(gl, 1.0f); + regionRenderer.setColor(gl, 0.0f, 0.0f, 0.0f); + //gl.glSampleCoverage(0.95f, false); + //gl.glEnable(GL2GL3.GL_SAMPLE_COVERAGE); // sample coverage doesn't really make a difference to lines + //gl.glEnable(GL2GL3.GL_SAMPLE_ALPHA_TO_ONE); MSAATool.dump(drawable); + createTestOutline(); } - float ang = 0; - float zoom = -70; - float xTran = -20; - float yTran = 5; - public void display(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); + GL2ES2 gl = drawable.getGL().getGL2ES2(); - gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - regionRenderer.resetMatrix(); - regionRenderer.translate(xTran, yTran, zoom); - regionRenderer.rotate(ang, 0, 1, 0); + final RegionRenderer regionRenderer = (RegionRenderer) getRenderer(); + + regionRenderer.resetModelview(null); + regionRenderer.translate(null, getXTran(), getYTran(), getZoom()); + regionRenderer.rotate(gl, getAngle(), 0, 1, 0); - try { - regionRenderer.renderOutlineShapes(outlineShapes, new float[]{0,0,0}); - } catch (Exception e) { - e.printStackTrace(); - } - } - public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height){ - GL2ES2 gl = drawable.getGL().getGL2ES2(); - gl.glViewport(xstart, ystart, width, height); - - regionRenderer.reshape(drawable, 45.0f, (float)width / (float)height, 0.1f, 7000.0f); - } - - public void zoomIn(){ - zoom++; - } - public void zoomOut(){ - zoom--; - } - public void move(float x, float y){ - xTran += x; - yTran += y; - } - public void rotate(float delta){ - ang+= delta; - ang%=360; - } - public void dispose(GLAutoDrawable arg0) { - regionRenderer.clearCached(); + regionRenderer.renderOutlineShapes(gl, outlineShapes, getPosition(), getTexSize()); - } + } } } diff --git a/src/demo/GPURegionRendererListenerBase01.java b/src/demo/GPURegionRendererListenerBase01.java new file mode 100644 index 000000000..19742a17a --- /dev/null +++ b/src/demo/GPURegionRendererListenerBase01.java @@ -0,0 +1,53 @@ +/** + * 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 demo; + +import jogamp.graph.curve.opengl.RegionRendererImpl01; + +import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.geom.Vertex; + +/** + * + * Action Keys: + * - 1/2: zoom in/out + * - 3/4: font +/- + * - 6/7: 2nd pass texture size + * - 0/9: rotate + * - s: toogle draw 'font set' + * - f: toggle draw fps + * - v: toggle v-sync + * - space: toggle font (ubuntu/java) + */ +public abstract class GPURegionRendererListenerBase01 extends GPURendererListenerBase01 { + OutlineShape outlineShape = null; + + public GPURegionRendererListenerBase01(Vertex.Factory factory, int mode, boolean debug, boolean trace) { + super(new RegionRendererImpl01(factory, mode), debug, trace); + } +} \ No newline at end of file diff --git a/src/demo/GPURendererListenerBase01.java b/src/demo/GPURendererListenerBase01.java new file mode 100644 index 000000000..ae72e6f66 --- /dev/null +++ b/src/demo/GPURendererListenerBase01.java @@ -0,0 +1,231 @@ +/** + * 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 demo; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLPipelineFactory; +import javax.media.opengl.GLRunnable; + +import com.jogamp.graph.curve.opengl.Renderer; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.KeyListener; +import com.jogamp.newt.opengl.GLWindow; + +/** + * + * Action Keys: + * - 1/2: zoom in/out + * - 6/7: 2nd pass texture size + * - 0/9: rotate + * - v: toggle v-sync + */ +public abstract class GPURendererListenerBase01 implements GLEventListener { + private Screenshot screenshot; + private Renderer renderer; + private boolean debug; + private boolean trace; + + private KeyAction keyAction; + + private volatile GLAutoDrawable autoDrawable = null; + + private final float[] position = new float[] {0,0,0}; + + private float xTran = -10; + private float yTran = 10; + private float ang = 0f; + private float zoom = -70f; + private int texSize = 400; + + boolean updateMatrix = true; + + public GPURendererListenerBase01(Renderer renderer, boolean debug, boolean trace) { + this.renderer = renderer; + this.debug = debug; + this.trace = trace; + this.screenshot = new Screenshot(); + } + + public final Renderer getRenderer() { return renderer; } + public final float getZoom() { return zoom; } + public final float getXTran() { return xTran; } + public final float getYTran() { return yTran; } + public final float getAngle() { return ang; } + public final int getTexSize() { return texSize; } + public final float[] getPosition() { return position; } + + public void setMatrix(float xtrans, float ytrans, float angle, int zoom, int fbosize) { + this.xTran = xtrans; + this.yTran = ytrans; + this.ang = angle; + this.zoom = zoom; + this.texSize = fbosize; + updateMatrix = true; + } + + public void init(GLAutoDrawable drawable) { + autoDrawable = drawable; + GL2ES2 gl = drawable.getGL().getGL2ES2(); + if(debug) { + gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2ES2(); + } + if(trace) { + gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2(); + } + gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) { + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + gl.glViewport(xstart, ystart, width, height); + renderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); + + dumpMatrix(); + } + + public void dispose(GLAutoDrawable drawable) { + autoDrawable = null; + GL2ES2 gl = drawable.getGL().getGL2ES2(); + screenshot.dispose(); + renderer.dispose(gl); + } + + public void zoom(int v){ + zoom += v; + updateMatrix = true; + dumpMatrix(); + } + + public void move(float x, float y){ + xTran += x; + yTran += y; + updateMatrix = true; + dumpMatrix(); + } + public void rotate(float delta){ + ang += delta; + ang %= 360.0f; + updateMatrix = true; + dumpMatrix(); + } + + void dumpMatrix() { + System.err.println("Matrix: " + xTran + "/" + yTran + " x"+zoom + " @"+ang); + } + + /** Attach the input listener to the window */ + public void attachInputListenerTo(GLWindow window) { + if ( null == keyAction ) { + keyAction = new KeyAction(); + window.addKeyListener(keyAction); + } + } + + public void detachFrom(GLWindow window) { + if ( null == keyAction ) { + return; + } + window.removeGLEventListener(this); + window.removeKeyListener(keyAction); + } + + public void printScreen(GLAutoDrawable drawable, String dir, String tech, String objName, boolean exportAlpha) throws GLException, IOException { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), texSize, objName); + + String filename = dir + tech + sw +".tga"; + screenshot.surface2File(drawable, filename /*, exportAlpha */); + } + + public class KeyAction implements KeyListener { + public void keyPressed(KeyEvent arg0) { + if(arg0.getKeyCode() == KeyEvent.VK_1){ + zoom(10); + } + else if(arg0.getKeyCode() == KeyEvent.VK_2){ + zoom(-10); + } + else if(arg0.getKeyCode() == KeyEvent.VK_UP){ + move(0, -1); + } + else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){ + move(0, 1); + } + else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){ + move(1, 0); + } + else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){ + move(-1, 0); + } + else if(arg0.getKeyCode() == KeyEvent.VK_6){ + texSize -= 10; + System.err.println("Tex Size: " + texSize); + } + else if(arg0.getKeyCode() == KeyEvent.VK_7){ + texSize += 10; + System.err.println("Tex Size: " + texSize); + } + else if(arg0.getKeyCode() == KeyEvent.VK_0){ + rotate(1); + } + else if(arg0.getKeyCode() == KeyEvent.VK_9){ + rotate(-1); + } + else if(arg0.getKeyChar() == 'v') { + if(null != autoDrawable) { + autoDrawable.invoke(false, new GLRunnable() { + public void run(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); + int i = gl.getSwapInterval(); + i = i==0 ? 1 : 0; + gl.setSwapInterval(i); + final GLAnimatorControl a = drawable.getAnimator(); + if( null != a ) { + a.resetCounter(); + } + System.err.println("Swap Interval: "+i); + } + }); + } + } + } + public void keyTyped(KeyEvent arg0) {} + public void keyReleased(KeyEvent arg0) {} + } +} diff --git a/src/demo/GPUTextGLListenerBase01.java b/src/demo/GPUTextGLListenerBase01.java deleted file mode 100644 index 238a733ce..000000000 --- a/src/demo/GPUTextGLListenerBase01.java +++ /dev/null @@ -1,324 +0,0 @@ -/** - * 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 demo; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; - -import javax.media.opengl.GL; -import javax.media.opengl.GL2ES2; -import javax.media.opengl.GLAnimatorControl; -import javax.media.opengl.GLAutoDrawable; -import javax.media.opengl.GLEventListener; -import javax.media.opengl.GLException; -import javax.media.opengl.GLPipelineFactory; -import javax.media.opengl.GLRunnable; - -import com.jogamp.graph.curve.opengl.TextRenderer; -import com.jogamp.graph.font.Font; -import com.jogamp.graph.font.FontFactory; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.newt.event.KeyEvent; -import com.jogamp.newt.event.KeyListener; -import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.util.awt.Screenshot; - -/** - * - * Action Keys: - * - 1/2: zoom in/out - * - 3/4: font +/- - * - 6/7: 2nd pass texture size - * - 0/9: rotate - * - s: toogle draw 'font set' - * - f: toggle draw fps - * - v: toggle v-sync - * - space: toggle font (ubuntu/java) - */ -public abstract class GPUTextGLListenerBase01 implements GLEventListener { - Vertex.Factory vfactory; - protected TextRenderer textRenderer; - int fontSet = FontFactory.UBUNTU; - Font font; - boolean debug; - boolean trace; - - KeyAction keyAction; - - volatile GLAutoDrawable autoDrawable = null; - boolean drawFontSet = true; - boolean drawFPS = true; - boolean updateFont = true; - int fontSize = 40; - final int fontSizeModulo = 100; - - final float[] position = new float[] {0,0,0}; - - float xTran = -10; - float yTran = 10; - float ang = 0f; - float zoom = -70f; - int texSize = 400; - - boolean updateMatrix = true; - static final String text1; - static final String text2; - - static { - text1 = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]"; - text2 = "The quick brown fox jumps over the lazy dog"; - } - - public GPUTextGLListenerBase01(Vertex.Factory vfactory, int mode, boolean debug, boolean trace) { - // this.font = FontFactory.get(FontFactory.JAVA).getDefault(); - this.font = FontFactory.get(fontSet).getDefault(); - this.vfactory = vfactory; - this.textRenderer = new TextRenderer(vfactory, mode); - this.debug = debug; - this.trace = trace; - } - - public void setMatrix(float xtrans, float ytrans, float angle, int zoom, int fbosize) { - this.xTran = xtrans; - this.yTran = ytrans; - this.ang = angle; - this.zoom = zoom; - this.texSize = fbosize; - updateMatrix = true; - } - - public void init(GLAutoDrawable drawable) { - autoDrawable = drawable; - GL2ES2 gl = drawable.getGL().getGL2ES2(); - if(debug) { - gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2ES2(); - } - if(trace) { - gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2(); - } - gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - } - - public void reshape(GLAutoDrawable drawable, int xstart, int ystart, int width, int height) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); - - gl.glViewport(xstart, ystart, width, height); - textRenderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); - - dumpMatrix(true); - } - protected boolean printScreen = true; - public void display(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); - - gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Demo02 needs to have this set here as well .. hmm ? - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - if(drawFPS || drawFontSet || updateMatrix) { - final int width = drawable.getWidth(); - final int height = drawable.getHeight(); - final GLAnimatorControl animator = drawable.getAnimator(); - final boolean _drawFPS = drawFPS && null != animator && animator.getTotalFrames()>10; - - if(_drawFPS || drawFontSet) { - textRenderer.reshapeOrtho(null, width, height, 0.1f, 7000.0f); - } - if(_drawFPS) { - final float fps = ( animator.getTotalFrames() * 1000.0f ) / (float) animator.getDuration() ; - final String fpsS = String.valueOf(fps); - final int fpsSp = fpsS.indexOf('.'); - textRenderer.resetMatrix(null); - textRenderer.translate(gl, 0, 0, -6000); - textRenderer.renderString3D(gl, font, fpsS.substring(0, fpsSp+2), position, fontSize, texSize); - } - if(drawFontSet) { - textRenderer.resetMatrix(null); - textRenderer.translate(gl, 0, height-50, -6000); - textRenderer.renderString3D(gl, font, text1, position, fontSize, texSize); - } - if(_drawFPS || drawFontSet) { - textRenderer.reshapePerspective(null, 45.0f, width, height, 0.1f, 7000.0f); - } - - textRenderer.resetMatrix(null); - textRenderer.translate(null, xTran, yTran, zoom); - textRenderer.rotate(gl, ang, 0, 1, 0); - updateMatrix = false; - } - - textRenderer.renderString3D(gl, font, text2, position, fontSize, texSize); - } - - public void dispose(GLAutoDrawable drawable) { - autoDrawable = null; - GL2ES2 gl = drawable.getGL().getGL2ES2(); - textRenderer.dispose(gl); - } - - public void fontIncr(int v) { - fontSize = Math.abs((fontSize + v) % fontSizeModulo) ; - updateFont = true; - dumpMatrix(true); - } - - public void zoom(int v){ - zoom += v; - updateMatrix = true; - dumpMatrix(false); - } - - public void nextFontSet() { - fontSet = ( fontSet == FontFactory.UBUNTU ) ? FontFactory.JAVA : FontFactory.UBUNTU ; - font = FontFactory.get(fontSet).getDefault(); - } - - public void setFontSet(int set, int family, int stylebits) { - fontSet = set; - font = FontFactory.get(fontSet).get(family, stylebits); - } - - public void move(float x, float y){ - xTran += x; - yTran += y; - updateMatrix = true; - dumpMatrix(false); - } - public void rotate(float delta){ - ang += delta; - ang %= 360.0f; - updateMatrix = true; - dumpMatrix(false); - } - - void dumpMatrix(boolean bbox) { - System.err.println("Matrix: " + xTran + "/" + yTran + " x"+zoom + " @"+ang +" fontSize "+fontSize); - if(bbox) { - System.err.println("bbox: "+font.getStringBounds(text2, fontSize)); - } - } - - public void attachTo(GLWindow window) { - if ( null == keyAction ) { - keyAction = new KeyAction(); - } - window.addGLEventListener(this); - window.addKeyListener(keyAction); - } - - public void detachFrom(GLWindow window) { - if ( null == keyAction ) { - return; - } - window.removeGLEventListener(this); - window.removeKeyListener(keyAction); - } - - public void printScreen(String dir, String tech, int width, int height, boolean exportAlpha) throws GLException, IOException { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.printf("-%03dx%03d-Z%04d-T%04d-%s", width, height, (int)Math.abs(zoom), texSize, font.getName()); - - String filename = dir + tech + sw +".tga"; - Screenshot.writeToTargaFile(new File(filename), width, height, exportAlpha); - } - - public class KeyAction implements KeyListener { - public void keyPressed(KeyEvent arg0) { - if(arg0.getKeyCode() == KeyEvent.VK_1){ - zoom(10); - } - else if(arg0.getKeyCode() == KeyEvent.VK_2){ - zoom(-10); - } - else if(arg0.getKeyCode() == KeyEvent.VK_3){ - fontIncr(10); - } - else if(arg0.getKeyCode() == KeyEvent.VK_4){ - fontIncr(-10); - } - else if(arg0.getKeyCode() == KeyEvent.VK_UP){ - move(0, -1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){ - move(0, 1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){ - move(1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){ - move(-1, 0); - } - else if(arg0.getKeyCode() == KeyEvent.VK_6){ - texSize -= 10; - System.err.println("Tex Size: " + texSize); - } - else if(arg0.getKeyCode() == KeyEvent.VK_7){ - texSize += 10; - System.err.println("Tex Size: " + texSize); - } - else if(arg0.getKeyCode() == KeyEvent.VK_0){ - rotate(1); - } - else if(arg0.getKeyCode() == KeyEvent.VK_9){ - rotate(-1); - } - else if(arg0.getKeyChar() == 's') { - drawFontSet = !drawFontSet; - System.err.println("Draw font set: "+drawFontSet); - } - else if(arg0.getKeyChar() == 'f'){ - drawFPS = !drawFPS; - System.err.println("Draw FPS: "+drawFPS); - } - else if(arg0.getKeyChar() == 'v') { - if(null != autoDrawable) { - autoDrawable.invoke(false, new GLRunnable() { - public void run(GLAutoDrawable drawable) { - GL gl = drawable.getGL(); - int i = gl.getSwapInterval(); - i = i==0 ? 1 : 0; - gl.setSwapInterval(i); - final GLAnimatorControl a = drawable.getAnimator(); - if( null != a ) { - a.resetCounter(); - } - System.err.println("Swap Interval: "+i); - } - }); - } - } - else if(arg0.getKeyChar() == ' ') { - nextFontSet(); - } - } - public void keyTyped(KeyEvent arg0) {} - public void keyReleased(KeyEvent arg0) {} - } -} \ No newline at end of file diff --git a/src/demo/GPUTextNewtDemo01.java b/src/demo/GPUTextNewtDemo01.java index 934eba1ba..9a3067548 100644 --- a/src/demo/GPUTextNewtDemo01.java +++ b/src/demo/GPUTextNewtDemo01.java @@ -34,6 +34,7 @@ import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.TextRenderer; import com.jogamp.graph.geom.opengl.SVertex; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; @@ -58,14 +59,14 @@ public class GPUTextNewtDemo01 { caps.setNumSamples(4); // 2 samples is not enough .. System.out.println("Requested: "+caps); - window = GLWindow.create(caps); - + window = GLWindow.create(caps); window.setPosition(10, 10); window.setSize(800, 400); - window.setTitle("GPU Text Newt Demo 01 - r2t0 msaa1"); + textGLListener = new TextGLListener(); - textGLListener.attachTo(window); + textGLListener.attachInputListenerTo(window); + window.addGLEventListener(textGLListener); window.enablePerfLog(true); window.setVisible(true); @@ -75,7 +76,7 @@ public class GPUTextNewtDemo01 { animator.start(); } - private class TextGLListener extends GPUTextGLListenerBase01 { + private class TextGLListener extends GPUTextRendererListenerBase01 { public TextGLListener() { super(SVertex.factory(), Region.SINGLE_PASS, DEBUG, TRACE); // FBO size unrelated with 1 pass @@ -85,10 +86,12 @@ public class GPUTextNewtDemo01 { } public void init(GLAutoDrawable drawable) { - GL2ES2 gl = drawable.getGL().getGL2ES2(); - super.init(drawable); + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + final TextRenderer textRenderer = (TextRenderer) getRenderer(); + gl.setSwapInterval(1); gl.glEnable(GL2ES2.GL_DEPTH_TEST); textRenderer.init(gl); diff --git a/src/demo/GPUTextNewtDemo02.java b/src/demo/GPUTextNewtDemo02.java index b46053f1d..2078527dc 100644 --- a/src/demo/GPUTextNewtDemo02.java +++ b/src/demo/GPUTextNewtDemo02.java @@ -34,6 +34,7 @@ import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.TextRenderer; import com.jogamp.graph.geom.opengl.SVertex; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; @@ -52,8 +53,7 @@ public class GPUTextNewtDemo02 { public static void main(String[] args) { GPUTextNewtDemo02 test = new GPUTextNewtDemo02(); - test.testMe(); - + test.testMe(); } GLWindow window; @@ -61,7 +61,7 @@ public class GPUTextNewtDemo02 { public void testMe() { GLProfile.initSingleton(true); - GLProfile glp = GLProfile.get(GLProfile.GL3bc); + GLProfile glp = GLProfile.get(GLProfile.GL3); GLCapabilities caps = new GLCapabilities(glp); caps.setAlphaBits(4); @@ -74,7 +74,8 @@ public class GPUTextNewtDemo02 { window.setTitle("GPU Text Newt Demo 02 - r2t1 msaa0"); textGLListener = new TextGLListener(); - textGLListener.attachTo(window); + textGLListener.attachInputListenerTo(window); + window.addGLEventListener(textGLListener); window.enablePerfLog(true); window.setVisible(true); @@ -85,7 +86,7 @@ public class GPUTextNewtDemo02 { animator.start(); } - private class TextGLListener extends GPUTextGLListenerBase01 { + private class TextGLListener extends GPUTextRendererListenerBase01 { public TextGLListener() { super(SVertex.factory(), Region.TWO_PASS, DEBUG, TRACE); // FIXME: Rami will fix FBO size !! @@ -95,9 +96,11 @@ public class GPUTextNewtDemo02 { } public void init(GLAutoDrawable drawable) { + super.init(drawable); + GL3 gl = drawable.getGL().getGL3(); - super.init(drawable); + final TextRenderer textRenderer = (TextRenderer) getRenderer(); gl.setSwapInterval(1); gl.glEnable(GL3.GL_DEPTH_TEST); diff --git a/src/demo/GPUTextRendererListenerBase01.java b/src/demo/GPUTextRendererListenerBase01.java new file mode 100644 index 000000000..4ee4f62de --- /dev/null +++ b/src/demo/GPUTextRendererListenerBase01.java @@ -0,0 +1,190 @@ +/** + * 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 demo; + +import java.io.IOException; +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLException; +import com.jogamp.graph.curve.opengl.TextRenderer; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.KeyListener; +import com.jogamp.newt.opengl.GLWindow; + +/** + * + * GPURendererListenerBase01 Keys: + * - 1/2: zoom in/out + * - 6/7: 2nd pass texture size + * - 0/9: rotate + * - v: toggle v-sync + * + * Additional Keys: + * - 3/4: font +/- + * - s: toogle draw 'font set' + * - f: toggle draw fps + * - space: toggle font (ubuntu/java) + */ +public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerBase01 { + int fontSet = FontFactory.UBUNTU; + Font font; + + boolean drawFontSet = true; + boolean drawFPS = true; + boolean updateFont = true; + int fontSize = 40; + final int fontSizeModulo = 100; + + static final String text1 = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]"; + static final String text2 = "The quick brown fox jumps over the lazy dog"; + + public GPUTextRendererListenerBase01(Vertex.Factory factory, int mode, boolean debug, boolean trace) { + super(TextRenderer.create(factory, mode), debug, trace); + this.font = FontFactory.get(fontSet).getDefault(); + } + + public void display(GLAutoDrawable drawable) { + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Demo02 needs to have this set here as well .. hmm ? + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + + final TextRenderer textRenderer = (TextRenderer) getRenderer(); + + if(drawFPS || drawFontSet || updateMatrix) { + final int width = drawable.getWidth(); + final int height = drawable.getHeight(); + final GLAnimatorControl animator = drawable.getAnimator(); + final boolean _drawFPS = drawFPS && null != animator && animator.getTotalFrames()>10; + + if(_drawFPS || drawFontSet) { + textRenderer.reshapeOrtho(null, width, height, 0.1f, 7000.0f); + } + if(_drawFPS) { + final float fps = ( animator.getTotalFrames() * 1000.0f ) / (float) animator.getDuration() ; + final String fpsS = String.valueOf(fps); + final int fpsSp = fpsS.indexOf('.'); + textRenderer.resetModelview(null); + textRenderer.translate(gl, 0, 0, -6000); + textRenderer.renderString3D(gl, font, fpsS.substring(0, fpsSp+2), getPosition(), fontSize, getTexSize()); + } + if(drawFontSet) { + textRenderer.resetModelview(null); + textRenderer.translate(gl, 0, height-50, -6000); + textRenderer.renderString3D(gl, font, text1, getPosition(), fontSize, getTexSize()); + } + if(_drawFPS || drawFontSet) { + textRenderer.reshapePerspective(null, 45.0f, width, height, 0.1f, 7000.0f); + } + + textRenderer.resetModelview(null); + textRenderer.translate(null, getXTran(), getYTran(), getZoom()); + textRenderer.rotate(gl, getAngle(), 0, 1, 0); + updateMatrix = false; + } + + textRenderer.renderString3D(gl, font, text2, getPosition(), fontSize, getTexSize()); + } + + public void fontIncr(int v) { + fontSize = Math.abs((fontSize + v) % fontSizeModulo) ; + updateFont = true; + dumpMatrix(true); + } + + public void nextFontSet() { + fontSet = ( fontSet == FontFactory.UBUNTU ) ? FontFactory.JAVA : FontFactory.UBUNTU ; + font = FontFactory.get(fontSet).getDefault(); + } + + public void setFontSet(int set, int family, int stylebits) { + fontSet = set; + font = FontFactory.get(fontSet).get(family, stylebits); + } + + void dumpMatrix(boolean bbox) { + System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZoom() + " @"+getAngle() +" fontSize "+fontSize); + if(bbox) { + System.err.println("bbox: "+font.getStringBounds(text2, fontSize)); + } + } + + KeyAction keyAction = null; + + @Override + public void attachInputListenerTo(GLWindow window) { + if ( null == keyAction ) { + keyAction = new KeyAction(); + window.addKeyListener(keyAction); + super.attachInputListenerTo(window); + } + + } + + @Override + public void detachFrom(GLWindow window) { + super.detachFrom(window); + if ( null == keyAction ) { + return; + } + window.removeKeyListener(keyAction); + } + + public void printScreen(GLAutoDrawable drawable, String dir, String tech, boolean exportAlpha) throws GLException, IOException { + printScreen(drawable, dir, tech, font.getName(), exportAlpha); + } + + public class KeyAction implements KeyListener { + public void keyPressed(KeyEvent arg0) { + if(arg0.getKeyCode() == KeyEvent.VK_3){ + fontIncr(10); + } + else if(arg0.getKeyCode() == KeyEvent.VK_4){ + fontIncr(-10); + } + else if(arg0.getKeyChar() == 's') { + drawFontSet = !drawFontSet; + System.err.println("Draw font set: "+drawFontSet); + } + else if(arg0.getKeyChar() == 'f'){ + drawFPS = !drawFPS; + System.err.println("Draw FPS: "+drawFPS); + } + else if(arg0.getKeyChar() == ' ') { + nextFontSet(); + } + } + public void keyTyped(KeyEvent arg0) {} + public void keyReleased(KeyEvent arg0) {} + } +} \ No newline at end of file diff --git a/src/demo/ReadBufferUtil.java b/src/demo/ReadBufferUtil.java new file mode 100644 index 000000000..1de61974b --- /dev/null +++ b/src/demo/ReadBufferUtil.java @@ -0,0 +1,107 @@ +/** + * 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 demo; + +import com.jogamp.opengl.util.GLBuffers; +import java.nio.*; +import javax.media.opengl.*; + +import com.jogamp.opengl.util.texture.Texture; +import com.jogamp.opengl.util.texture.TextureData; + +public class ReadBufferUtil { + protected int readPixelSizeLast = 0; + protected Buffer readPixelBuffer = null; + protected TextureData readTextureData = null; + protected Texture readTexture = new Texture(GL.GL_TEXTURE_2D); + + public Buffer getPixelBuffer() { return readPixelBuffer; } + public void rewindPixelBuffer() { readPixelBuffer.rewind(); } + + public TextureData getTextureData() { return readTextureData; } + public Texture getTexture() { return readTexture; } + + public boolean isValid() { + return null!=readTexture && null!=readTextureData && null!=readPixelBuffer ; + } + + public void fetchOffscreenTexture(GLDrawable drawable, GL gl) { + int readPixelSize = drawable.getWidth() * drawable.getHeight() * 3 ; // RGB + boolean newData = false; + if(readPixelSize>readPixelSizeLast) { + readPixelBuffer = GLBuffers.newDirectGLBuffer(GL.GL_UNSIGNED_BYTE, readPixelSize); + readPixelSizeLast = readPixelSize ; + try { + readTextureData = new TextureData( + gl.getGLProfile(), + // gl.isGL2GL3()?gl.GL_RGBA:gl.GL_RGB, + GL.GL_RGB, + drawable.getWidth(), drawable.getHeight(), + 0, + GL.GL_RGB, + GL.GL_UNSIGNED_BYTE, + false, false, + false /* flip */, + readPixelBuffer, + null /* Flusher */); + newData = true; + } catch (Exception e) { + readTextureData = null; + readPixelBuffer = null; + readPixelSizeLast = 0; + throw new RuntimeException("can not fetch offscreen texture", e); + } + } + if(null!=readPixelBuffer) { + readPixelBuffer.clear(); + gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, readPixelBuffer); + readPixelBuffer.rewind(); + if(newData) { + readTexture.updateImage(readTextureData); + } else { + readTexture.updateSubImage(readTextureData, 0, + 0, 0, // src offset + 0, 0, // dst offset + drawable.getWidth(), drawable.getHeight()); + } + readPixelBuffer.rewind(); + } + } + + @SuppressWarnings("deprecation") + public void dispose() { + readTexture.dispose(); + readTextureData = null; + readPixelBuffer.clear(); + readPixelBuffer = null; + readPixelSizeLast = 0; + } + +} + diff --git a/src/demo/Screenshot.java b/src/demo/Screenshot.java new file mode 100644 index 000000000..8e05b17ea --- /dev/null +++ b/src/demo/Screenshot.java @@ -0,0 +1,39 @@ +package demo; + +import java.io.File; +import java.io.IOException; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; + +import com.jogamp.opengl.util.texture.TextureIO; + +public class Screenshot { + + ReadBufferUtil readBufferUtil = new ReadBufferUtil(); + + public void dispose() { + readBufferUtil.dispose(); + } + + public void surface2File(GLAutoDrawable drawable, String filename) { + GL gl = drawable.getGL(); + // FIXME glFinish() is an expensive paranoia sync, should not be necessary due to spec + gl.glFinish(); + readBufferUtil.fetchOffscreenTexture(drawable, gl); + gl.glFinish(); + try { + surface2File(filename); + } catch (IOException ex) { + throw new RuntimeException("can not write survace to file", ex); + } + } + + void surface2File(String filename) throws IOException { + File file = new File(filename); + TextureIO.write(readBufferUtil.getTextureData(), file); + System.err.println("Wrote: " + file.getAbsolutePath() + ", ..."); + readBufferUtil.rewindPixelBuffer(); + } + +} diff --git a/src/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogamp/graph/curve/opengl/RegionRendererImpl01.java new file mode 100755 index 000000000..c1f293fff --- /dev/null +++ b/src/jogamp/graph/curve/opengl/RegionRendererImpl01.java @@ -0,0 +1,206 @@ +/** + * 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 jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; +import javax.media.opengl.GL2ES2; +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.opengl.RegionRenderer; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.glsl.ShaderState; + + +public class RegionRendererImpl01 extends RegionRenderer { + /**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); + 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", 3.0f); + + public RegionRendererImpl01(Vertex.Factory factory, int type) { + super(factory, type); + } + + protected boolean initImpl(GL2ES2 gl) { + 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("RegionRenderer: 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, RegionRendererImpl01.class, + "shader", "shader/bin", "curverenderer01"); + ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, RegionRendererImpl01.class, + "shader", "shader/bin", "curverenderer01"); + + ShaderProgram sp = new ShaderProgram(); + sp.add(rsVp); + sp.add(rsFp); + + if(!sp.link(gl, System.err)) { + throw new GLException("RegionRenderer: 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"); + + 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(); + resetModelview(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("RegionRendererImpl01 initialized: " + Thread.currentThread()+" "+st); + } + return true; + } + + @Override + protected void disposeImpl(GL2ES2 gl) { + } + + + @Override + public float getAlpha() { + return mgl_alpha.floatValue(); + } + + @Override + public void setAlpha(GL2ES2 gl, float alpha_t) { + mgl_alpha.setData(alpha_t); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_alpha); + } + } + + @Override + 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); + } + } + + + @Override + public void renderOutlineShape(GL2ES2 gl, OutlineShape outlineShape, float[] position, int texSize) { + if(!isInitialized()){ + throw new GLException("RegionRendererImpl01: not initialized!"); + } + int hashCode = getHashCode(outlineShape); + Region region = regions.get(hashCode); + + if(null == region) { + region = createRegion(gl, outlineShape, mgl_sharpness.floatValue()); + regions.put(hashCode, region); + } + region.render(pmvMatrix, vp_width, vp_height, texSize); + } + + @Override + public void renderOutlineShapes(GL2ES2 gl, OutlineShape[] outlineShapes, float[] position, int texSize) { + if(!isInitialized()){ + throw new GLException("RegionRendererImpl01: not initialized!"); + } + + int hashCode = getHashCode(outlineShapes); + Region region = regions.get(hashCode); + + if(null == region) { + region = createRegion(gl, outlineShapes, mgl_sharpness.floatValue()); + regions.put(hashCode, region); + } + region.render(pmvMatrix, vp_width, vp_height, texSize); + } +} diff --git a/src/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogamp/graph/curve/opengl/TextRendererImpl01.java new file mode 100644 index 000000000..aa3202805 --- /dev/null +++ b/src/jogamp/graph/curve/opengl/TextRendererImpl01.java @@ -0,0 +1,189 @@ +/** + * 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 jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; + +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 com.jogamp.graph.curve.opengl.TextRenderer; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; + +public class TextRendererImpl01 extends TextRenderer { + /**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); + 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); + + public TextRendererImpl01(Vertex.Factory factory, int type) { + super(factory, type); + } + + @Override + protected boolean initImpl(GL2ES2 gl){ + 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("TextRendererImpl01: 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, TextRendererImpl01.class, + "shader", "shader/bin", "curverenderer01"); + ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, TextRendererImpl01.class, + "shader", "shader/bin", "curverenderer01"); + + ShaderProgram sp = new ShaderProgram(); + sp.add(rsVp); + sp.add(rsFp); + + if(!sp.link(gl, System.err)) { + throw new GLException("TextRendererImpl01: 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(); + resetModelview(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("TextRendererImpl01 initialized: " + Thread.currentThread()+" "+st); + } + return true; + } + + @Override + protected void disposeImpl(GL2ES2 gl) { + } + + @Override + public float getAlpha() { + return mgl_alpha.floatValue(); + } + + @Override + public void setAlpha(GL2ES2 gl, float alpha_t) { + mgl_alpha.setData(alpha_t); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_alpha); + } + } + + @Override + 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); + } + } + + @Override + public void renderString3D(GL2ES2 gl, Font font, String str, float[] position, int fontSize, int texSize) { + if(!isInitialized()){ + throw new GLException("TextRendererImpl01: not initialized!"); + } + String fontStrHash = getTextHashCode(font, str, fontSize); + GlyphString glyphString = strings.get(fontStrHash); + if(null == glyphString) { + glyphString = createString(gl, font, fontSize, str, mgl_sharpness.floatValue()); + strings.put(fontStrHash, glyphString); + } + + glyphString.renderString3D(pmvMatrix, vp_width, vp_height, texSize); + } + +} diff --git a/src/jogamp/graph/curve/opengl/shader/curverenderer01.fp b/src/jogamp/graph/curve/opengl/shader/curverenderer01.fp new file mode 100644 index 000000000..2b3a0ce1d --- /dev/null +++ b/src/jogamp/graph/curve/opengl/shader/curverenderer01.fp @@ -0,0 +1,99 @@ +//#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/jogamp/graph/curve/opengl/shader/curverenderer01.vp b/src/jogamp/graph/curve/opengl/shader/curverenderer01.vp new file mode 100644 index 000000000..bc9ecb41e --- /dev/null +++ b/src/jogamp/graph/curve/opengl/shader/curverenderer01.vp @@ -0,0 +1,13 @@ +//#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 diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRenderer01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRenderer01.java new file mode 100644 index 000000000..35f0325c9 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRenderer01.java @@ -0,0 +1,152 @@ +package test.com.jogamp.opengl.test.junit.graph; + +import java.io.IOException; + +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.newt.opengl.GLWindow; + +import demo.GPURegionNewtDemo01; +import demo.GPURegionNewtDemo02; +import demo.GPURegionRendererListenerBase01; + +public class TestRegionRenderer01 { + + public static void main(String args[]) throws IOException { + String tstname = TestRegionRenderer01.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + NativeWindowFactory.initSingleton(true); + } + + static void destroyWindow(GLWindow window) { + if(null!=window) { + window.destroy(); + } + } + + static GLWindow createWindow(String title, GLCapabilitiesImmutable caps, int width, int height) { + Assert.assertNotNull(caps); + + GLWindow window = GLWindow.create(caps); + window.setSize(width, height); + window.setPosition(10, 10); + window.setTitle(title); + Assert.assertNotNull(window); + window.setVisible(true); + + return window; + } + + @Test + public void testRegionRendererR2T01() throws InterruptedException { + GLProfile glp = GLProfile.get(GLProfile.GL3); + GLCapabilities caps = new GLCapabilities(glp); + caps.setOnscreen(false); + caps.setAlphaBits(4); + + GLWindow window = createWindow("shape-r2t1-msaa0", caps, 800,400); + + GPURegionNewtDemo02 demo02 = new GPURegionNewtDemo02(); + GPURegionNewtDemo02.RegionGLListener demo02Listener = demo02.createRegionRendererListener(window); + + RegionGLListener listener = new RegionGLListener(demo02Listener, window.getTitle(), "GPURegionNewtDemo02"); + window.addGLEventListener(listener); + + listener.setTech(-20, 00, 0f, -300, 400); + window.display(); + + listener.setTech(-20, 00, 0f, -150, 800); + window.display(); + + listener.setTech(-20, 00, 0f, -50, 1000); + window.display(); + + destroyWindow(window); + } + + @Test + public void testRegionRendererMSAA01() throws InterruptedException { + GLProfile glp = GLProfile.get(GLProfile.GL2ES2); + GLCapabilities caps = new GLCapabilities(glp); + caps.setOnscreen(false); + caps.setAlphaBits(4); + caps.setSampleBuffers(true); + caps.setNumSamples(4); + + GLWindow window = createWindow("shape-r2t0-msaa1", caps, 800, 400); + + GPURegionNewtDemo01 demo01 = new GPURegionNewtDemo01(); + GPURegionNewtDemo01.RegionGLListener demo01Listener = demo01.createRegionRendererListener(window); + + RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegionNewtDemo01"); + window.addGLEventListener(listener); + + listener.setTech(-20, 00, 0f, -300, 400); + window.display(); + + listener.setTech(-20, 00, 0f, -150, 800); + window.display(); + + listener.setTech(-20, 00, 0f, -50, 1000); + window.display(); + + destroyWindow(window); + } + + private class RegionGLListener implements GLEventListener { + String winTitle; + String name; + GPURegionRendererListenerBase01 impl; + + public RegionGLListener(GPURegionRendererListenerBase01 impl, String title, String name) { + this.impl = impl; + this.winTitle = title; + this.name = name; + } + + public void setTech(float xt, float yt, float angle, int zoom, int fboSize){ + impl.setMatrix(xt, yt, angle, zoom, fboSize); + } + + public void init(GLAutoDrawable drawable) { + impl.init(drawable); + } + + public void display(GLAutoDrawable drawable) { + impl.display(drawable); + + try { + impl.printScreen(drawable, "./", winTitle, name, false); + } catch (GLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void dispose(GLAutoDrawable drawable) { + impl.dispose(drawable); + + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + impl.reshape(drawable, x, y, width, height); + + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRenderer01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRenderer01.java index 501bdbb75..8f5174a89 100755 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRenderer01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRenderer01.java @@ -16,14 +16,20 @@ import org.junit.BeforeClass; import org.junit.Test; import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.opengl.TextRenderer; import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.geom.opengl.SVertex; import com.jogamp.newt.opengl.GLWindow; -import demo.GPUTextGLListenerBase01; +import demo.GPUTextRendererListenerBase01; public class TestTextRenderer01 { + public static void main(String args[]) throws IOException { + String tstname = TestRegionRenderer01.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + @BeforeClass public static void initClass() { GLProfile.initSingleton(true); @@ -51,14 +57,15 @@ public class TestTextRenderer01 { @Test public void testTextRendererR2T01() throws InterruptedException { - GLProfile glp = GLProfile.get(GLProfile.GL3bc); + GLProfile glp = GLProfile.get(GLProfile.GL3); GLCapabilities caps = new GLCapabilities(glp); caps.setOnscreen(false); caps.setAlphaBits(4); - GLWindow window = createWindow("r2t1-msaa0", caps, 800,400); + GLWindow window = createWindow("text-r2t1-msaa0", caps, 800,400); TextGLListener textGLListener = new TextGLListener(Region.TWO_PASS); - textGLListener.attachTo(window); + textGLListener.attachInputListenerTo(window); + window.addGLEventListener(textGLListener); textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0); textGLListener.setTech(-400, -30, 0f, -1000, 400); @@ -92,9 +99,10 @@ public class TestTextRenderer01 { caps.setSampleBuffers(true); caps.setNumSamples(4); - GLWindow window = createWindow("r2t0-msaa1", caps, 800, 400); + GLWindow window = createWindow("text-r2t0-msaa1", caps, 800, 400); TextGLListener textGLListener = new TextGLListener(Region.SINGLE_PASS); - textGLListener.attachTo(window); + textGLListener.attachInputListenerTo(window); + window.addGLEventListener(textGLListener); textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0); textGLListener.setTech(-400, -30, 0f, -1000, 0); @@ -119,15 +127,15 @@ public class TestTextRenderer01 { destroyWindow(window); } - private class TextGLListener extends GPUTextGLListenerBase01 { + private class TextGLListener extends GPUTextRendererListenerBase01 { String winTitle; public TextGLListener(int type) { super(SVertex.factory(), type, false, false); } - public void attachTo(GLWindow window) { - super.attachTo(window); + public void attachInputListenerTo(GLWindow window) { + super.attachInputListenerTo(window); winTitle = window.getTitle(); } public void setTech(float xt, float yt, float angle, int zoom, int fboSize){ @@ -139,6 +147,9 @@ public class TestTextRenderer01 { super.init(drawable); gl.setSwapInterval(1); gl.glEnable(GL.GL_DEPTH_TEST); + + final TextRenderer textRenderer = (TextRenderer) getRenderer(); + textRenderer.init(gl); textRenderer.setAlpha(gl, 1.0f); textRenderer.setColor(gl, 0.0f, 0.0f, 0.0f); @@ -148,7 +159,7 @@ public class TestTextRenderer01 { super.display(drawable); try { - printScreen("./", winTitle, drawable.getWidth(), drawable.getHeight(), false); + printScreen(drawable, "./", winTitle, false); } catch (GLException e) { e.printStackTrace(); } catch (IOException e) { -- cgit v1.2.3