diff options
author | Sven Gothel <[email protected]> | 2011-03-30 13:56:48 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-03-30 13:56:48 +0200 |
commit | dbc74b98eb7429cbb51f7af0572ab53ddd0d9edc (patch) | |
tree | 9902e64c12ed222fa47d0e49390548cbcd252698 | |
parent | e952e7dbac7a6b746b8465aa63423f1aa138ca27 (diff) |
Refactor: Public *Renderer / Unify Region Demos / Using own Screenshot (non AWT, plain GL2ES2)
Refactor: Public *Renderer
- Sharing common base abstract class Renderer.java
- Having public abstract classes RegionRenderer and TextRenderer
- Implementation non public, accessed via factory
- + shared code
- + clean API (same stuff)
Unify Region Demos
- reduced code / path, sharing common demo/test features Text/Region
Using own Screenshot (non AWT, plain GL2ES2)
- Remove AWT dependency
- Allow GL2ES2 screenshots
- Less complex
18 files changed, 1513 insertions, 1143 deletions
diff --git a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java index e75ca25cd..4be1506d5 100755..100644 --- a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -1,388 +1,112 @@ -/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.graph.curve.opengl;
-
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLUniformData;
-import javax.media.opengl.fixedfunc.GLMatrixFunc;
-
-import com.jogamp.graph.curve.OutlineShape;
-import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.curve.RegionFactory;
-import com.jogamp.graph.geom.Triangle;
-import com.jogamp.graph.geom.Vertex;
-
-import jogamp.opengl.Debug;
-import com.jogamp.opengl.util.PMVMatrix;
-import com.jogamp.opengl.util.glsl.ShaderCode;
-import com.jogamp.opengl.util.glsl.ShaderProgram;
-import com.jogamp.opengl.util.glsl.ShaderState;
-
-public class RegionRenderer {
- protected static final boolean DEBUG = Debug.debug("RegionRenderer");
-
- private ShaderState st;
- private PMVMatrix pmvMatrix = new PMVMatrix();
-
- /**Sharpness is equivalent to the value of t value of texture coord
- * on the off-curve vertex. The high value of sharpness will
- * result in high curvature.
- */
- private float sharpness = 0.5f;
- private float alpha = 1.0f;
- private float strength = 3.0f;
- private boolean initialized = false;
-
- private int regionType = Region.SINGLE_PASS;
-
- private GLContext context;
- private FloatBuffer color = FloatBuffer.allocate(3);
- private HashMap<Integer, Region> regions = new HashMap<Integer, Region>();
-
- /** Create a Hardware accelerated Region Renderer
- * @param context OpenGL rendering context
- * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory.
- */
- public RegionRenderer(GLContext context) {
- this.context = context;
- init(context, 0.5f);
- }
- /** Create a Hardware accelerated Region Renderer
- * @param context OpenGL rendering context
- * @param type region type (single or multipass)
- */
- public RegionRenderer(GLContext context, int type) {
- this.context = context;
- this.regionType = type;
- init(context, 0.5f);
- }
-
- private boolean init(GLContext context, float sharpvalue){
- if(initialized){
- if(DEBUG) {
- System.err.println("HWRegionRenderer: Already initialized!");
- }
- return true;
- }
- sharpness = sharpvalue;
-
- GL2ES2 gl = context.getGL().getGL2ES2();
-
- boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") &&
- gl.isFunctionAvailable("glBindBuffer") &&
- gl.isFunctionAvailable("glBufferData") &&
- gl.isFunctionAvailable("glDrawElements") &&
- gl.isFunctionAvailable("glVertexAttribPointer") &&
- gl.isFunctionAvailable("glDeleteBuffers");
-
- if(DEBUG) {
- System.err.println("HWRegionRenderer: VBO Supported = " + VBOsupported);
- }
-
- if(!VBOsupported){
- return false;
- }
-
- gl.setSwapInterval(1);
-
- gl.glEnable(GL2ES2.GL_BLEND);
- gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA);
-
- initShader(gl);
-
- st.glUseProgram(gl, true);
-
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
-
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- resetMatrix();
-
- if(!st.glUniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) {
- if(DEBUG){
- System.err.println("Error setting PMVMatrix in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("p1y", sharpness))) {
- if(DEBUG){
- System.err.println("Error setting sharpness in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- if(DEBUG){
- System.err.println("Error setting global alpha in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("g_color", 3, color))) {
- if(DEBUG){
- System.err.println("Error setting global color in shader: "+st);
- }
- return false;
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
- st.glUseProgram(gl, false);
-
- if(DEBUG) {
- System.err.println("HWRegionRenderer initialized: " + Thread.currentThread()+" "+st);
- }
- initialized = true;
- return true;
- }
-
- public float getAlpha() {
- return alpha;
- }
- public void setAlpha(float alpha_t) {
- alpha = alpha_t;
- }
-
- public void setColor(float r, float g, float b){
- color.put(r);
- color.put(g);
- color.put(b);
- color.rewind();
- }
-
- public void rotate(float angle, float x, float y, float z){
- pmvMatrix.glRotatef(angle, x, y, z);
- }
- public void translate(float x, float y, float z){
- pmvMatrix.glTranslatef(x, y, z);
- }
-
- public void resetMatrix(){
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
- }
-
- /**
- * @param drawable
- * @param angle
- * @param ratio
- * @param near
- * @param far
- * @return
- */
- public boolean reshape(GLAutoDrawable drawable, float angle, float ratio, float near, float far){
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.gluPerspective(angle, ratio, near, far);
-
- if(null==st) {
- if(DEBUG){
- System.err.println("HWRegionRenderer: Shader State is null, or not");
- }
- return false;
- }
- GL2ES2 gl = drawable.getGL().getGL2ES2();
-
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- st.glUseProgram(gl, false);
- return true;
- }
-
- private void initShader(GL2ES2 gl) {
- ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, RegionRenderer.class,
- "shader", "shader/bin", "curverenderer");
- ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, RegionRenderer.class,
- "shader", "shader/bin", "curverenderer");
-
- ShaderProgram sp = new ShaderProgram();
- sp.add(rsVp);
- sp.add(rsFp);
-
- if(!sp.link(gl, System.err)) {
- throw new GLException("HWRegionRenderer: Couldn't link program: "+sp);
- }
-
- st = new ShaderState();
- st.attachShaderProgram(gl, sp);
- gl.glBindAttribLocation(sp.id(), 0, "v_position");
- gl.glBindAttribLocation(sp.id(), 1, "texCoord");
- }
-
- private Region createRegion(OutlineShape outlineShape) {
- Region region = RegionFactory.create(context, st, regionType);
-
- outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
-
- ArrayList<Triangle<Vertex>> triangles = (ArrayList<Triangle<Vertex>>) outlineShape.triangulate(sharpness);
- ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices();
- region.addVertices(vertices);
- region.addTriangles(triangles);
-
- region.update();
- return region;
- }
-
- private Region createRegion(OutlineShape[] outlineShapes) {
- Region region = RegionFactory.create(context, st, regionType);
-
- int numVertices = region.getNumVertices();
-
- for(OutlineShape outlineShape:outlineShapes){
- outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS);
-
- ArrayList<Triangle<Vertex>> triangles = outlineShape.triangulate(sharpness);
- region.addTriangles(triangles);
-
- ArrayList<Vertex> vertices = outlineShape.getVertices();
- for(Vertex vert:vertices){
- vert.setId(numVertices++);
- }
- region.addVertices(vertices);
- }
-
- region.update();
- return region;
- }
-
-
- /** Render outline in 3D space at the position provided
- * the triangles of the shapes will be generated, if not yet generated
- * @param outlineShape the OutlineShape to Render.
- * @param position the initial translation of the outlineShape.
- * @throws Exception if HwRegionRenderer not initialized
- */
- public void renderOutlineShape(OutlineShape outlineShape, float[] position) throws Exception{
- if(!initialized){
- throw new Exception("HWRegionRenderer: not initialized!");
- }
- int hashCode = getHashCode(outlineShape);
- Region region = regions.get(hashCode);
-
- if(null == region) {
- region = createRegion(outlineShape);
- regions.put(hashCode, region);
- }
-
- GL2ES2 gl = context.getGL().getGL2ES2();
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- System.err.println("Error setting global alpha in shader: "+st);
- }
- GLUniformData gcolorUD = st.getUniform("g_color");
- if(null!=gcolorUD) {
- st.glUniform(gl, gcolorUD);
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
-
- region.render(null, 0, 0, 0);
- st.glUseProgram(gl, false);
- }
-
- /** Render a list of Outline shapes combined in one region
- * at the position provided the triangles of the
- * shapes will be generated, if not yet generated
- * @param outlineShapes the list of OutlineShapes to Render.
- * @param position the initial translation of the outlineShapes.
- * @throws Exception if HwRegionRenderer not initialized
- */
- public void renderOutlineShapes(OutlineShape[] outlineShapes, float[] position) throws Exception{
- if(!initialized){
- throw new Exception("HWRegionRenderer: not initialized!");
- }
-
- int hashCode = getHashCode(outlineShapes);
- Region region = regions.get(hashCode);
-
- if(null == region) {
- region = createRegion(outlineShapes);
- regions.put(hashCode, region);
- }
-
- GL2ES2 gl = context.getGL().getGL2ES2();
- st.glUseProgram(gl, true);
- GLUniformData ud = st.getUniform("mgl_PMVMatrix");
- if(null!=ud) {
- st.glUniform(gl, ud);
- }
- if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) {
- System.err.println("Error setting global alpha in shader: "+st);
- }
- GLUniformData gcolorUD = st.getUniform("g_color");
- if(null!=gcolorUD) {
- st.glUniform(gl, gcolorUD);
- }
- if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) {
- System.err.println("Error setting antialias strength in shader: "+st);
- }
- region.render(null, 0, 0, 0);
- st.glUseProgram(gl, false);
- }
-
- private int getHashCode(OutlineShape outlineShape){
- return outlineShape.hashCode();
- }
-
- private int getHashCode(OutlineShape[] outlineShapes){
- int hashcode = 0;
- for(OutlineShape outlineShape:outlineShapes){
- hashcode += getHashCode(outlineShape);
- }
- return hashcode;
- }
-
- /** Clears the cached string curves
- * and destorys underlying buffers
- */
- public void clearCached() {
- Iterator<Region> iterator = regions.values().iterator();
- while(iterator.hasNext()){
- Region region = iterator.next();
- region.destroy();
- }
- regions.clear();
- }
-}
+package com.jogamp.graph.curve.opengl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import javax.media.opengl.GL2ES2; + +import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.RegionFactory; +import com.jogamp.graph.geom.Triangle; +import com.jogamp.graph.geom.Vertex; + +public abstract class RegionRenderer extends Renderer { + + /** Create a Hardware accelerated Region Renderer + */ + public static RegionRenderer create(Vertex.Factory<? extends Vertex> factory, int type) { + return new jogamp.graph.curve.opengl.RegionRendererImpl01(factory, type); + } + + public RegionRenderer(Vertex.Factory<? extends Vertex> factory, int type) { + super(factory, type); + } + + /** Render an array of Outline shapes combined in one region + * at the position provided the triangles of the + * shapes will be generated, if not yet generated + * @param outlineShapes array of OutlineShapes to Render. + * @param position the initial translation of the outlineShapes. + * @param texSize texture size for multipass render * + * @throws Exception if HwRegionRenderer not initialized + */ + public abstract void renderOutlineShapes(GL2ES2 gl, OutlineShape[] outlineShapes, float[] position, int texSize); + + /** Render outline in 3D space at the position provided + * the triangles of the shapes will be generated, if not yet generated + * @param outlineShape the OutlineShape to Render. + * @param position the initial translation of the outlineShape. + * @param texSize texture size for multipass render + * @throws Exception if HwRegionRenderer not initialized + */ + public abstract void renderOutlineShape(GL2ES2 gl, OutlineShape outlineShape, float[] position, int texSize); + + protected HashMap<Integer, Region> regions = new HashMap<Integer, Region>(); + + public void flushCash() { + Iterator<Region> iterator = regions.values().iterator(); + while(iterator.hasNext()){ + Region region = iterator.next(); + region.destroy(); + } + regions.clear(); + } + + /** + * @param sharpness parameter for Region generation + * @return the resulting Region inclusive the generated region + */ + protected Region createRegion(GL2ES2 gl, OutlineShape outlineShape, float sharpness) { + Region region = RegionFactory.create(gl.getContext(), st, regionType); + + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList<Triangle<Vertex>> triangles = (ArrayList<Triangle<Vertex>>) outlineShape.triangulate(sharpness); + ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices(); + region.addVertices(vertices); + region.addTriangles(triangles); + + region.update(); + return region; + } + + /** + * @param sharpness parameter for Region generation + * @return the resulting Region inclusive the generated region + */ + protected Region createRegion(GL2ES2 gl, OutlineShape[] outlineShapes, float sharpness) { + Region region = RegionFactory.create(gl.getContext(), st, regionType); + + int numVertices = region.getNumVertices(); + + for(OutlineShape outlineShape:outlineShapes){ + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList<Triangle<Vertex>> triangles = outlineShape.triangulate(sharpness); + region.addTriangles(triangles); + + ArrayList<Vertex> vertices = outlineShape.getVertices(); + for(Vertex vert:vertices){ + vert.setId(numVertices++); + } + region.addVertices(vertices); + } + + region.update(); + return region; + } + + protected static int getHashCode(OutlineShape outlineShape){ + return outlineShape.hashCode(); + } + + protected static int getHashCode(OutlineShape[] outlineShapes){ + int hashcode = 0; + for(OutlineShape outlineShape:outlineShapes){ + hashcode += getHashCode(outlineShape); + } + return hashcode; + } +}
\ No newline at end of file diff --git a/src/com/jogamp/graph/curve/opengl/Renderer.java b/src/com/jogamp/graph/curve/opengl/Renderer.java new file mode 100644 index 000000000..a1755e003 --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/Renderer.java @@ -0,0 +1,161 @@ +package com.jogamp.graph.curve.opengl; + +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import jogamp.opengl.Debug; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.graph.geom.opengl.SVertex; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderState; + +public abstract class Renderer { + protected static final boolean DEBUG = Debug.debug("CurveRenderer"); + + protected abstract boolean initImpl(GL2ES2 gl); + + protected abstract void disposeImpl(GL2ES2 gl); + + /** + * Flushes all cached data + */ + public abstract void flushCash(); + + public abstract float getAlpha(); + + public abstract void setAlpha(GL2ES2 gl, float alpha_t); + + public abstract void setColor(GL2ES2 gl, float r, float g, float b); + + protected final Vertex.Factory<? extends Vertex> pointFactory; + protected ShaderState st = new ShaderState(); + protected PMVMatrix pmvMatrix = new PMVMatrix(); + protected GLUniformData mgl_PMVMatrix; + protected int regionType = Region.SINGLE_PASS; + protected int vp_width = 0; + protected int vp_height = 0; + + private boolean vboSupported = false; + private boolean initialized = false; + + protected Renderer(Vertex.Factory<? extends Vertex> factory, int type) { + this.regionType = type; + this.pointFactory = (null != factory) ? factory : SVertex.factory(); + } + + public Vertex.Factory<? extends Vertex> getFactory() { return pointFactory; } + + public final boolean isInitialized() { return initialized; } + + public final boolean isVBOSupported() { return vboSupported; } + + public final int getWidth() { return vp_width; } + public final int getHeight() { return vp_height; } + + /** + * Initialize shaders and bindings for GPU based rendering. + * Leaves the renderer enabled, ie ShaderState on. + * + * @param gl the current GL state + * @return true if succeeded, false otherwise + */ + public boolean init(GL2ES2 gl) { + if(initialized){ + if(DEBUG) { + System.err.println("TextRenderer: Already initialized!"); + } + return true; + } + vboSupported = gl.isFunctionAvailable("glGenBuffers") && + gl.isFunctionAvailable("glBindBuffer") && + gl.isFunctionAvailable("glBufferData") && + gl.isFunctionAvailable("glDrawElements") && + gl.isFunctionAvailable("glVertexAttribPointer") && + gl.isFunctionAvailable("glDeleteBuffers"); + + if(DEBUG) { + System.err.println("TextRendererImpl01: VBO Supported = " + isVBOSupported()); + } + + initialized = initImpl(gl); + return initialized; + } + + public void dispose(GL2ES2 gl) { + if(!initialized){ + if(DEBUG) { + System.err.println("TextRenderer: Not initialized!"); + } + return; + } + disposeImpl(gl); + st.destroy(gl); + flushCash(); + initialized = false; + } + + public final ShaderState getShaderState() { return st; } + + public final PMVMatrix getMatrix() { return pmvMatrix; } + + public void rotate(GL2ES2 gl, float angle, float x, float y, float z) { + pmvMatrix.glRotatef(angle, x, y, z); + if(initialized && null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void translate(GL2ES2 gl, float x, float y, float z) { + pmvMatrix.glTranslatef(x, y, z); + if(initialized && null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void resetModelview(GL2ES2 gl) { + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + if(initialized && null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void updateMatrix(GL2ES2 gl) { + if(initialized && null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public boolean reshapePerspective(GL2ES2 gl, float angle, int width, int height, float near, float far) { + this.vp_width = width; + this.vp_height = height; + float ratio = (float)width/(float)height; + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.gluPerspective(angle, ratio, near, far); + + if(initialized && null != gl) { + st.glUniform(gl, mgl_PMVMatrix); + } + + return true; + } + + public boolean reshapeOrtho(GL2ES2 gl, int width, int height, float near, float far) { + this.vp_width = width; + this.vp_height = height; + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glOrthof(0, width, 0, height, near, far); + + if(initialized && null != gl) { + st.glUniform(gl, mgl_PMVMatrix); + } + + return true; + } + +}
\ No newline at end of file diff --git a/src/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/com/jogamp/graph/curve/opengl/TextRenderer.java index 703f82373..04988a3ab 100644 --- a/src/com/jogamp/graph/curve/opengl/TextRenderer.java +++ b/src/com/jogamp/graph/curve/opengl/TextRenderer.java @@ -1,353 +1,79 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ package com.jogamp.graph.curve.opengl; -import java.nio.FloatBuffer; import java.util.HashMap; import java.util.Iterator; import javax.media.opengl.GL2ES2; -import javax.media.opengl.GLException; -import javax.media.opengl.GLUniformData; -import javax.media.opengl.fixedfunc.GLMatrixFunc; import jogamp.graph.curve.text.GlyphString; import jogamp.graph.font.FontInt; import jogamp.graph.geom.plane.AffineTransform; import jogamp.graph.geom.plane.Path2D; -import com.jogamp.graph.curve.Region; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.opengl.SVertex; -import jogamp.opengl.Debug; -import com.jogamp.opengl.util.PMVMatrix; -import com.jogamp.opengl.util.glsl.ShaderCode; -import com.jogamp.opengl.util.glsl.ShaderProgram; -import com.jogamp.opengl.util.glsl.ShaderState; -public class TextRenderer { - protected static final boolean DEBUG = Debug.debug("TextRenderer"); - static final boolean FONTTOOL_CUSTOM = false; - - private ShaderState st = new ShaderState(); - - private PMVMatrix pmvMatrix = new PMVMatrix(); - private GLUniformData mgl_PMVMatrix; - - /**Sharpness is equivalent to the value of t value of texture coord - * on the off-curve vertex. The high value of sharpness will - * result in high curvature. - */ - private GLUniformData mgl_sharpness = new GLUniformData("p1y", 0.5f); - private GLUniformData mgl_alpha = new GLUniformData("g_alpha", 1.0f); - private GLUniformData mgl_color = new GLUniformData("g_color", 3, FloatBuffer.allocate(3)); - private GLUniformData mgl_strength = new GLUniformData("a_strength", 1.8f); - - private boolean initialized = false; - - private int regionType = Region.SINGLE_PASS; - - private HashMap<String, GlyphString> strings = new HashMap<String, GlyphString>(); - private final Vertex.Factory<? extends Vertex> pointFactory; - - int win_width = 0; - int win_height = 0; - - /** - * Create a Hardware accelerated Text Renderer. - * @param context OpenGL rendering context - * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. - */ - public TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) { - this.pointFactory = (null != factory) ? factory : SVertex.factory(); - this.regionType = type; - } - - /** - * Initialize shaders and bindings for GPU based text Rendering, - * should be called only once. - * Leaves the renderer enables, ie ShaderState on. - * - * @param drawable the current drawable - * @param shapvalue shaprness around the off-curve vertices - * @return true if init succeeded, false otherwise - */ - public boolean init(GL2ES2 gl){ - if(initialized){ - if(DEBUG) { - System.err.println("HWTextRenderer: Already initialized!"); - } - return true; - } - - boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") && - gl.isFunctionAvailable("glBindBuffer") && - gl.isFunctionAvailable("glBufferData") && - gl.isFunctionAvailable("glDrawElements") && - gl.isFunctionAvailable("glVertexAttribPointer") && - gl.isFunctionAvailable("glDeleteBuffers"); - - if(DEBUG) { - System.err.println("HWTextRenderer: VBO Supported = " + VBOsupported); - } - - if(!VBOsupported){ - return false; - } - - gl.glEnable(GL2ES2.GL_BLEND); - gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); - - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, TextRenderer.class, - "shader", "shader/bin", "curverenderer"); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, TextRenderer.class, - "shader", "shader/bin", "curverenderer"); - - ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - - if(!sp.link(gl, System.err)) { - throw new GLException("HWTextRenderer: Couldn't link program: "+sp); - } - - st.attachShaderProgram(gl, sp); - gl.glBindAttribLocation(sp.id(), 0, "v_position"); - gl.glBindAttribLocation(sp.id(), 1, "texCoord"); - - st.glUseProgram(gl, true); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - resetMatrix(null); - - mgl_PMVMatrix = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); - if(!st.glUniform(gl, mgl_PMVMatrix)) { - if(DEBUG){ - System.err.println("Error setting PMVMatrix in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_sharpness)) { - if(DEBUG){ - System.err.println("Error setting sharpness in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_alpha)) { - if(DEBUG){ - System.err.println("Error setting global alpha in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_color)) { - if(DEBUG){ - System.err.println("Error setting global color in shader: "+st); - } - return false; - } - - if(!st.glUniform(gl, mgl_strength)) { - System.err.println("Error setting antialias strength in shader: "+st); - } - - if(DEBUG) { - System.err.println("HWTextRenderer initialized: " + Thread.currentThread()+" "+st); - } - initialized = true; - return true; - } - - public void dispose(GL2ES2 gl) { - st.destroy(gl); - flushCash(); - } - - public float getAlpha() { - return mgl_alpha.floatValue(); - } - - public ShaderState getShaderState() { - return st; - } - - public void setAlpha(GL2ES2 gl, float alpha_t) { - mgl_alpha.setData(alpha_t); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_alpha); - } - } - - public void setColor(GL2ES2 gl, float r, float g, float b){ - FloatBuffer fb = (FloatBuffer) mgl_color.getBuffer(); - fb.put(0, r); - fb.put(1, r); - fb.put(2, r); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_color); - } - } - - public final PMVMatrix matrix() { return pmvMatrix; } - - public void rotate(GL2ES2 gl, float angle, float x, float y, float z){ - pmvMatrix.glRotatef(angle, x, y, z); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - public void translate(GL2ES2 gl, float x, float y, float z){ - pmvMatrix.glTranslatef(x, y, z); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void resetMatrix(GL2ES2 gl){ - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void setMatrix(GL2ES2 gl){ - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - } - } - - public void updateAllShaderValues(GL2ES2 gl) { - if(null != gl && st.inUse()) { - st.glUniform(gl, mgl_PMVMatrix); - st.glUniform(gl, mgl_alpha); - st.glUniform(gl, mgl_color); - st.glUniform(gl, mgl_strength); - } +public abstract class TextRenderer extends Renderer { + + /** + * Create a Hardware accelerated Text Renderer. + * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. + */ + public static TextRenderer create(Vertex.Factory<? extends Vertex> factory, int type) { + return new jogamp.graph.curve.opengl.TextRendererImpl01(factory, type); } - /** - * @param gl - * @param angle - * @param ratio - * @param near - * @param far - * @return - */ - public boolean reshapePerspective(GL2ES2 gl, float angle, int width, int height, float near, float far){ - win_width = width; - win_height = height; - float ratio = (float)width/(float)height; - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.gluPerspective(angle, ratio, near, far); - - if(null != gl) { - st.glUniform(gl, mgl_PMVMatrix); - } - - return true; - } - - public boolean reshapeOrtho(GL2ES2 gl, int width, int height, float near, float far) { - win_width = width; - win_height = height; - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - pmvMatrix.glOrthof(0, width, 0, height, near, far); - - if(null != gl) { - st.glUniform(gl, mgl_PMVMatrix); - } - - return true; - } + protected TextRenderer(Vertex.Factory<? extends Vertex> factory, int type) { + super(factory, type); + } - private GlyphString createString(GL2ES2 gl, Font font, int size, String str) { - AffineTransform affineTransform = new AffineTransform(pointFactory); - - Path2D[] paths = new Path2D[str.length()]; - ((FontInt)font).getOutline(str, size, affineTransform, paths); - - GlyphString glyphString = new GlyphString(pointFactory, font.getName(), str); - glyphString.createfromFontPath(paths, affineTransform); - - glyphString.generateRegion(gl.getContext(), mgl_sharpness.floatValue(), st, regionType); - return glyphString; - } - - - /** Render the String in 3D space wrt to the font provided at the position provided - * the outlines will be generated, if not yet generated - * @param font font to be used - * @param str text to be rendered - * @param position the lower left corner of the string + /** Render the String in 3D space wrt to the font provided at the position provided + * the outlines will be generated, if not yet generated + * @param gl the current GL state + * @param font font to be used + * @param str text to be rendered + * @param position the lower left corner of the string * @param fontSize font size - * @param texSize texture size for multipass render - * @throws Exception if TextRenderer not initialized - */ - public void renderString3D(GL2ES2 gl, Font font, String str, float[] position, int fontSize, int texSize) { - if(!initialized){ - throw new GLException("HWTextRenderer: not initialized!"); - } - String fontStrHash = getTextHashCode(font, str, fontSize); - GlyphString glyphString = strings.get(fontStrHash); - if(null == glyphString) { - glyphString = createString(gl, font, fontSize, str); - strings.put(fontStrHash, glyphString); - } - - glyphString.renderString3D(pmvMatrix, win_width, win_height, texSize); - } - - private String getTextHashCode(Font font, String str, int fontSize) { - // FIXME: use integer hash code - return font.getName() + "." + str.hashCode() + "." + fontSize; - } + * @param texSize texture size for multipass render + * @throws Exception if TextRenderer not initialized + */ + public abstract void renderString3D(GL2ES2 gl, Font font, + String str, float[] position, int fontSize, int texSize); - /** Clears the cached string curves - * and destorys underlying buffers - */ - public void flushCash() { - Iterator<GlyphString> iterator = strings.values().iterator(); - while(iterator.hasNext()){ - GlyphString glyphString = iterator.next(); - glyphString.destroy(); - } - strings.clear(); - } -} + protected HashMap<String, GlyphString> strings = new HashMap<String, GlyphString>(); + + /** + * + * @param font + * @param size + * @param str + * @param sharpness parameter for Region generation of the resulting GlyphString + * @return the resulting GlyphString inclusive the generated region + */ + protected GlyphString createString(GL2ES2 gl, Font font, int size, String str, float sharpness) { + AffineTransform affineTransform = new AffineTransform(pointFactory); + + Path2D[] paths = new Path2D[str.length()]; + ((FontInt)font).getOutline(str, size, affineTransform, paths); + + GlyphString glyphString = new GlyphString(pointFactory, font.getName(), str); + glyphString.createfromFontPath(paths, affineTransform); + glyphString.generateRegion(gl.getContext(), sharpness, st, regionType); + + return glyphString; + } + + protected static String getTextHashCode(Font font, String str, int fontSize) { + // FIXME: use integer hash code + return font.getName() + "." + str.hashCode() + "." + fontSize; + } + + public void flushCash() { + Iterator<GlyphString> iterator = strings.values().iterator(); + while(iterator.hasNext()){ + GlyphString glyphString = iterator.next(); + glyphString.destroy(); + } + strings.clear(); + } +}
\ No newline at end of file diff --git a/src/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 index 19889ac6e..a7b56ad42 100755..100644 --- 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<? extends Vertex> 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/GPUTextGLListenerBase01.java b/src/demo/GPURendererListenerBase01.java index 238a733ce..ae72e6f66 100644 --- a/src/demo/GPUTextGLListenerBase01.java +++ b/src/demo/GPURendererListenerBase01.java @@ -27,7 +27,6 @@ */ package demo; -import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -41,69 +40,53 @@ 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.graph.curve.opengl.Renderer; 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<? extends Vertex> vfactory; - protected TextRenderer textRenderer; - int fontSet = FontFactory.UBUNTU; - Font font; - boolean debug; - boolean trace; +public abstract class GPURendererListenerBase01 implements GLEventListener { + private Screenshot screenshot; + private Renderer renderer; + private boolean debug; + private boolean trace; - KeyAction keyAction; + private KeyAction keyAction; - volatile GLAutoDrawable autoDrawable = null; - boolean drawFontSet = true; - boolean drawFPS = true; - boolean updateFont = true; - int fontSize = 40; - final int fontSizeModulo = 100; + private volatile GLAutoDrawable autoDrawable = null; - final float[] position = new float[] {0,0,0}; + private final float[] position = new float[] {0,0,0}; - float xTran = -10; - float yTran = 10; - float ang = 0f; - float zoom = -70f; - int texSize = 400; + private float xTran = -10; + private float yTran = 10; + private float ang = 0f; + private float zoom = -70f; + private 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<? extends Vertex> 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); + 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; @@ -130,106 +113,47 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener { GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glViewport(xstart, ystart, width, height); - textRenderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); + renderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f); - dumpMatrix(true); + dumpMatrix(); } - 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); + screenshot.dispose(); + renderer.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); + dumpMatrix(); } public void move(float x, float y){ xTran += x; yTran += y; updateMatrix = true; - dumpMatrix(false); + dumpMatrix(); } public void rotate(float delta){ ang += delta; ang %= 360.0f; updateMatrix = true; - dumpMatrix(false); + dumpMatrix(); } - 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)); - } + void dumpMatrix() { + System.err.println("Matrix: " + xTran + "/" + yTran + " x"+zoom + " @"+ang); } - public void attachTo(GLWindow window) { + /** Attach the input listener to the window */ + public void attachInputListenerTo(GLWindow window) { if ( null == keyAction ) { keyAction = new KeyAction(); + window.addKeyListener(keyAction); } - window.addGLEventListener(this); - window.addKeyListener(keyAction); } public void detachFrom(GLWindow window) { @@ -240,13 +164,13 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener { window.removeKeyListener(keyAction); } - public void printScreen(String dir, String tech, int width, int height, boolean exportAlpha) throws GLException, IOException { + 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", width, height, (int)Math.abs(zoom), texSize, font.getName()); + 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.writeToTargaFile(new File(filename), width, height, exportAlpha); + screenshot.surface2File(drawable, filename /*, exportAlpha */); } public class KeyAction implements KeyListener { @@ -257,12 +181,6 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener { 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); } @@ -289,14 +207,6 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener { 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() { @@ -314,11 +224,8 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener { }); } } - 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<? extends Vertex> 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<? extends Vertex> 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<? extends Vertex> 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/com/jogamp/graph/curve/opengl/shader/curverenderer.fp b/src/jogamp/graph/curve/opengl/shader/curverenderer01.fp index 2b3a0ce1d..2b3a0ce1d 100644 --- a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp +++ b/src/jogamp/graph/curve/opengl/shader/curverenderer01.fp diff --git a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp b/src/jogamp/graph/curve/opengl/shader/curverenderer01.vp index bc9ecb41e..bc9ecb41e 100644 --- a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp +++ b/src/jogamp/graph/curve/opengl/shader/curverenderer01.vp 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) {
|