From e952e7dbac7a6b746b8465aa63423f1aa138ca27 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 30 Mar 2011 07:28:56 +0200 Subject: Renamed Hw*Renderer -> *Renderer --- .../graph/curve/opengl/HwRegionRenderer.java | 388 --------------------- .../jogamp/graph/curve/opengl/HwTextRenderer.java | 353 ------------------- .../jogamp/graph/curve/opengl/RegionRenderer.java | 388 +++++++++++++++++++++ .../jogamp/graph/curve/opengl/TextRenderer.java | 353 +++++++++++++++++++ 4 files changed, 741 insertions(+), 741 deletions(-) delete mode 100755 src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java delete mode 100644 src/com/jogamp/graph/curve/opengl/HwTextRenderer.java create mode 100755 src/com/jogamp/graph/curve/opengl/RegionRenderer.java create mode 100644 src/com/jogamp/graph/curve/opengl/TextRenderer.java (limited to 'src/com/jogamp/graph') diff --git a/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java b/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java deleted file mode 100755 index 9fa67a0be..000000000 --- a/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java +++ /dev/null @@ -1,388 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package 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 HwRegionRenderer { - protected static final boolean DEBUG = Debug.debug("RegionRenderer"); - - private ShaderState st; - private PMVMatrix pmvMatrix = new PMVMatrix(); - - /**Sharpness is equivalent to the value of t value of texture coord - * on the off-curve vertex. The high value of sharpness will - * result in high curvature. - */ - private float sharpness = 0.5f; - private float alpha = 1.0f; - private float strength = 3.0f; - private boolean initialized = false; - - private int regionType = Region.SINGLE_PASS; - - private GLContext context; - private FloatBuffer color = FloatBuffer.allocate(3); - private HashMap regions = new HashMap(); - - /** Create a Hardware accelerated Region Renderer - * @param context OpenGL rendering context - * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. - */ - public HwRegionRenderer(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 HwRegionRenderer(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, HwRegionRenderer.class, - "shader", "shader/bin", "curverenderer"); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, HwRegionRenderer.class, - "shader", "shader/bin", "curverenderer"); - - ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - - if(!sp.link(gl, System.err)) { - throw new GLException("HWRegionRenderer: Couldn't link program: "+sp); - } - - st = new ShaderState(); - st.attachShaderProgram(gl, sp); - gl.glBindAttribLocation(sp.id(), 0, "v_position"); - gl.glBindAttribLocation(sp.id(), 1, "texCoord"); - } - - private Region createRegion(OutlineShape outlineShape) { - Region region = RegionFactory.create(context, st, regionType); - - outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); - - ArrayList> triangles = (ArrayList>) outlineShape.triangulate(sharpness); - ArrayList vertices = (ArrayList) outlineShape.getVertices(); - region.addVertices(vertices); - region.addTriangles(triangles); - - region.update(); - return region; - } - - private Region createRegion(OutlineShape[] outlineShapes) { - Region region = RegionFactory.create(context, st, regionType); - - int numVertices = region.getNumVertices(); - - for(OutlineShape outlineShape:outlineShapes){ - outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); - - ArrayList> triangles = outlineShape.triangulate(sharpness); - region.addTriangles(triangles); - - ArrayList vertices = outlineShape.getVertices(); - for(Vertex vert:vertices){ - vert.setId(numVertices++); - } - region.addVertices(vertices); - } - - region.update(); - return region; - } - - - /** Render outline in 3D space at the position provided - * the triangles of the shapes will be generated, if not yet generated - * @param outlineShape the OutlineShape to Render. - * @param position the initial translation of the outlineShape. - * @throws Exception if HwRegionRenderer not initialized - */ - public void renderOutlineShape(OutlineShape outlineShape, float[] position) throws Exception{ - if(!initialized){ - throw new Exception("HWRegionRenderer: not initialized!"); - } - int hashCode = getHashCode(outlineShape); - Region region = regions.get(hashCode); - - if(null == region) { - region = createRegion(outlineShape); - regions.put(hashCode, region); - } - - GL2ES2 gl = context.getGL().getGL2ES2(); - st.glUseProgram(gl, true); - GLUniformData ud = st.getUniform("mgl_PMVMatrix"); - if(null!=ud) { - st.glUniform(gl, ud); - } - if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) { - System.err.println("Error setting global alpha in shader: "+st); - } - GLUniformData gcolorUD = st.getUniform("g_color"); - if(null!=gcolorUD) { - st.glUniform(gl, gcolorUD); - } - if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) { - System.err.println("Error setting antialias strength in shader: "+st); - } - - region.render(null, 0, 0, 0); - st.glUseProgram(gl, false); - } - - /** Render a list of Outline shapes combined in one region - * at the position provided the triangles of the - * shapes will be generated, if not yet generated - * @param outlineShapes the list of OutlineShapes to Render. - * @param position the initial translation of the outlineShapes. - * @throws Exception if HwRegionRenderer not initialized - */ - public void renderOutlineShapes(OutlineShape[] outlineShapes, float[] position) throws Exception{ - if(!initialized){ - throw new Exception("HWRegionRenderer: not initialized!"); - } - - int hashCode = getHashCode(outlineShapes); - Region region = regions.get(hashCode); - - if(null == region) { - region = createRegion(outlineShapes); - regions.put(hashCode, region); - } - - GL2ES2 gl = context.getGL().getGL2ES2(); - st.glUseProgram(gl, true); - GLUniformData ud = st.getUniform("mgl_PMVMatrix"); - if(null!=ud) { - st.glUniform(gl, ud); - } - if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) { - System.err.println("Error setting global alpha in shader: "+st); - } - GLUniformData gcolorUD = st.getUniform("g_color"); - if(null!=gcolorUD) { - st.glUniform(gl, gcolorUD); - } - if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) { - System.err.println("Error setting antialias strength in shader: "+st); - } - region.render(null, 0, 0, 0); - st.glUseProgram(gl, false); - } - - private int getHashCode(OutlineShape outlineShape){ - return outlineShape.hashCode(); - } - - private int getHashCode(OutlineShape[] outlineShapes){ - int hashcode = 0; - for(OutlineShape outlineShape:outlineShapes){ - hashcode += getHashCode(outlineShape); - } - return hashcode; - } - - /** Clears the cached string curves - * and destorys underlying buffers - */ - public void clearCached() { - Iterator iterator = regions.values().iterator(); - while(iterator.hasNext()){ - Region region = iterator.next(); - region.destroy(); - } - regions.clear(); - } -} diff --git a/src/com/jogamp/graph/curve/opengl/HwTextRenderer.java b/src/com/jogamp/graph/curve/opengl/HwTextRenderer.java deleted file mode 100644 index f9a104ad0..000000000 --- a/src/com/jogamp/graph/curve/opengl/HwTextRenderer.java +++ /dev/null @@ -1,353 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package 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 HwTextRenderer { - protected static final boolean DEBUG = Debug.debug("TextRenderer"); - static final boolean FONTTOOL_CUSTOM = false; - - private ShaderState st = new ShaderState(); - - private PMVMatrix pmvMatrix = new PMVMatrix(); - private GLUniformData mgl_PMVMatrix; - - /**Sharpness is equivalent to the value of t value of texture coord - * on the off-curve vertex. The high value of sharpness will - * result in high curvature. - */ - private GLUniformData mgl_sharpness = new GLUniformData("p1y", 0.5f); - private GLUniformData mgl_alpha = new GLUniformData("g_alpha", 1.0f); - private GLUniformData mgl_color = new GLUniformData("g_color", 3, FloatBuffer.allocate(3)); - private GLUniformData mgl_strength = new GLUniformData("a_strength", 1.8f); - - private boolean initialized = false; - - private int regionType = Region.SINGLE_PASS; - - private HashMap strings = new HashMap(); - private final Vertex.Factory pointFactory; - - int win_width = 0; - int win_height = 0; - - /** - * Create a Hardware accelerated Text Renderer. - * @param context OpenGL rendering context - * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. - */ - public HwTextRenderer(Vertex.Factory factory, int type) { - this.pointFactory = (null != factory) ? factory : SVertex.factory(); - this.regionType = type; - } - - /** - * Initialize shaders and bindings for GPU based text Rendering, - * should be called only once. - * Leaves the renderer enables, ie ShaderState on. - * - * @param drawable the current drawable - * @param shapvalue shaprness around the off-curve vertices - * @return true if init succeeded, false otherwise - */ - public boolean init(GL2ES2 gl){ - if(initialized){ - if(DEBUG) { - System.err.println("HWTextRenderer: Already initialized!"); - } - return true; - } - - boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") && - gl.isFunctionAvailable("glBindBuffer") && - gl.isFunctionAvailable("glBufferData") && - gl.isFunctionAvailable("glDrawElements") && - gl.isFunctionAvailable("glVertexAttribPointer") && - gl.isFunctionAvailable("glDeleteBuffers"); - - if(DEBUG) { - System.err.println("HWTextRenderer: VBO Supported = " + VBOsupported); - } - - if(!VBOsupported){ - return false; - } - - gl.glEnable(GL2ES2.GL_BLEND); - gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); - - ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, HwTextRenderer.class, - "shader", "shader/bin", "curverenderer"); - ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, HwTextRenderer.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); - } - } - - /** - * @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; - } - - 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 - * @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; - } - - /** Clears the cached string curves - * and destorys underlying buffers - */ - public void flushCash() { - Iterator iterator = strings.values().iterator(); - while(iterator.hasNext()){ - GlyphString glyphString = iterator.next(); - glyphString.destroy(); - } - strings.clear(); - } -} diff --git a/src/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java new file mode 100755 index 000000000..e75ca25cd --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -0,0 +1,388 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.curve.RegionFactory; +import com.jogamp.graph.geom.Triangle; +import com.jogamp.graph.geom.Vertex; + +import jogamp.opengl.Debug; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class RegionRenderer { + protected static final boolean DEBUG = Debug.debug("RegionRenderer"); + + private ShaderState st; + private PMVMatrix pmvMatrix = new PMVMatrix(); + + /**Sharpness is equivalent to the value of t value of texture coord + * on the off-curve vertex. The high value of sharpness will + * result in high curvature. + */ + private float sharpness = 0.5f; + private float alpha = 1.0f; + private float strength = 3.0f; + private boolean initialized = false; + + private int regionType = Region.SINGLE_PASS; + + private GLContext context; + private FloatBuffer color = FloatBuffer.allocate(3); + private HashMap regions = new HashMap(); + + /** Create a Hardware accelerated Region Renderer + * @param context OpenGL rendering context + * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. + */ + public RegionRenderer(GLContext context) { + this.context = context; + init(context, 0.5f); + } + /** Create a Hardware accelerated Region Renderer + * @param context OpenGL rendering context + * @param type region type (single or multipass) + */ + public RegionRenderer(GLContext context, int type) { + this.context = context; + this.regionType = type; + init(context, 0.5f); + } + + private boolean init(GLContext context, float sharpvalue){ + if(initialized){ + if(DEBUG) { + System.err.println("HWRegionRenderer: Already initialized!"); + } + return true; + } + sharpness = sharpvalue; + + GL2ES2 gl = context.getGL().getGL2ES2(); + + boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") && + gl.isFunctionAvailable("glBindBuffer") && + gl.isFunctionAvailable("glBufferData") && + gl.isFunctionAvailable("glDrawElements") && + gl.isFunctionAvailable("glVertexAttribPointer") && + gl.isFunctionAvailable("glDeleteBuffers"); + + if(DEBUG) { + System.err.println("HWRegionRenderer: VBO Supported = " + VBOsupported); + } + + if(!VBOsupported){ + return false; + } + + gl.setSwapInterval(1); + + gl.glEnable(GL2ES2.GL_BLEND); + gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); + + initShader(gl); + + st.glUseProgram(gl, true); + + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + resetMatrix(); + + if(!st.glUniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) { + if(DEBUG){ + System.err.println("Error setting PMVMatrix in shader: "+st); + } + return false; + } + if(!st.glUniform(gl, new GLUniformData("p1y", sharpness))) { + if(DEBUG){ + System.err.println("Error setting sharpness in shader: "+st); + } + return false; + } + if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) { + if(DEBUG){ + System.err.println("Error setting global alpha in shader: "+st); + } + return false; + } + if(!st.glUniform(gl, new GLUniformData("g_color", 3, color))) { + if(DEBUG){ + System.err.println("Error setting global color in shader: "+st); + } + return false; + } + if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) { + System.err.println("Error setting antialias strength in shader: "+st); + } + st.glUseProgram(gl, false); + + if(DEBUG) { + System.err.println("HWRegionRenderer initialized: " + Thread.currentThread()+" "+st); + } + initialized = true; + return true; + } + + public float getAlpha() { + return alpha; + } + public void setAlpha(float alpha_t) { + alpha = alpha_t; + } + + public void setColor(float r, float g, float b){ + color.put(r); + color.put(g); + color.put(b); + color.rewind(); + } + + public void rotate(float angle, float x, float y, float z){ + pmvMatrix.glRotatef(angle, x, y, z); + } + public void translate(float x, float y, float z){ + pmvMatrix.glTranslatef(x, y, z); + } + + public void resetMatrix(){ + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + } + + /** + * @param drawable + * @param angle + * @param ratio + * @param near + * @param far + * @return + */ + public boolean reshape(GLAutoDrawable drawable, float angle, float ratio, float near, float far){ + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.gluPerspective(angle, ratio, near, far); + + if(null==st) { + if(DEBUG){ + System.err.println("HWRegionRenderer: Shader State is null, or not"); + } + return false; + } + GL2ES2 gl = drawable.getGL().getGL2ES2(); + + st.glUseProgram(gl, true); + GLUniformData ud = st.getUniform("mgl_PMVMatrix"); + if(null!=ud) { + st.glUniform(gl, ud); + } + st.glUseProgram(gl, false); + return true; + } + + private void initShader(GL2ES2 gl) { + ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, RegionRenderer.class, + "shader", "shader/bin", "curverenderer"); + ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, RegionRenderer.class, + "shader", "shader/bin", "curverenderer"); + + ShaderProgram sp = new ShaderProgram(); + sp.add(rsVp); + sp.add(rsFp); + + if(!sp.link(gl, System.err)) { + throw new GLException("HWRegionRenderer: Couldn't link program: "+sp); + } + + st = new ShaderState(); + st.attachShaderProgram(gl, sp); + gl.glBindAttribLocation(sp.id(), 0, "v_position"); + gl.glBindAttribLocation(sp.id(), 1, "texCoord"); + } + + private Region createRegion(OutlineShape outlineShape) { + Region region = RegionFactory.create(context, st, regionType); + + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList> triangles = (ArrayList>) outlineShape.triangulate(sharpness); + ArrayList vertices = (ArrayList) outlineShape.getVertices(); + region.addVertices(vertices); + region.addTriangles(triangles); + + region.update(); + return region; + } + + private Region createRegion(OutlineShape[] outlineShapes) { + Region region = RegionFactory.create(context, st, regionType); + + int numVertices = region.getNumVertices(); + + for(OutlineShape outlineShape:outlineShapes){ + outlineShape.transformOutlines(OutlineShape.QUADRATIC_NURBS); + + ArrayList> triangles = outlineShape.triangulate(sharpness); + region.addTriangles(triangles); + + ArrayList vertices = outlineShape.getVertices(); + for(Vertex vert:vertices){ + vert.setId(numVertices++); + } + region.addVertices(vertices); + } + + region.update(); + return region; + } + + + /** Render outline in 3D space at the position provided + * the triangles of the shapes will be generated, if not yet generated + * @param outlineShape the OutlineShape to Render. + * @param position the initial translation of the outlineShape. + * @throws Exception if HwRegionRenderer not initialized + */ + public void renderOutlineShape(OutlineShape outlineShape, float[] position) throws Exception{ + if(!initialized){ + throw new Exception("HWRegionRenderer: not initialized!"); + } + int hashCode = getHashCode(outlineShape); + Region region = regions.get(hashCode); + + if(null == region) { + region = createRegion(outlineShape); + regions.put(hashCode, region); + } + + GL2ES2 gl = context.getGL().getGL2ES2(); + st.glUseProgram(gl, true); + GLUniformData ud = st.getUniform("mgl_PMVMatrix"); + if(null!=ud) { + st.glUniform(gl, ud); + } + if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) { + System.err.println("Error setting global alpha in shader: "+st); + } + GLUniformData gcolorUD = st.getUniform("g_color"); + if(null!=gcolorUD) { + st.glUniform(gl, gcolorUD); + } + if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) { + System.err.println("Error setting antialias strength in shader: "+st); + } + + region.render(null, 0, 0, 0); + st.glUseProgram(gl, false); + } + + /** Render a list of Outline shapes combined in one region + * at the position provided the triangles of the + * shapes will be generated, if not yet generated + * @param outlineShapes the list of OutlineShapes to Render. + * @param position the initial translation of the outlineShapes. + * @throws Exception if HwRegionRenderer not initialized + */ + public void renderOutlineShapes(OutlineShape[] outlineShapes, float[] position) throws Exception{ + if(!initialized){ + throw new Exception("HWRegionRenderer: not initialized!"); + } + + int hashCode = getHashCode(outlineShapes); + Region region = regions.get(hashCode); + + if(null == region) { + region = createRegion(outlineShapes); + regions.put(hashCode, region); + } + + GL2ES2 gl = context.getGL().getGL2ES2(); + st.glUseProgram(gl, true); + GLUniformData ud = st.getUniform("mgl_PMVMatrix"); + if(null!=ud) { + st.glUniform(gl, ud); + } + if(!st.glUniform(gl, new GLUniformData("g_alpha", alpha))) { + System.err.println("Error setting global alpha in shader: "+st); + } + GLUniformData gcolorUD = st.getUniform("g_color"); + if(null!=gcolorUD) { + st.glUniform(gl, gcolorUD); + } + if(!st.glUniform(gl, new GLUniformData("a_strength", strength))) { + System.err.println("Error setting antialias strength in shader: "+st); + } + region.render(null, 0, 0, 0); + st.glUseProgram(gl, false); + } + + private int getHashCode(OutlineShape outlineShape){ + return outlineShape.hashCode(); + } + + private int getHashCode(OutlineShape[] outlineShapes){ + int hashcode = 0; + for(OutlineShape outlineShape:outlineShapes){ + hashcode += getHashCode(outlineShape); + } + return hashcode; + } + + /** Clears the cached string curves + * and destorys underlying buffers + */ + public void clearCached() { + Iterator iterator = regions.values().iterator(); + while(iterator.hasNext()){ + Region region = iterator.next(); + region.destroy(); + } + regions.clear(); + } +} diff --git a/src/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/com/jogamp/graph/curve/opengl/TextRenderer.java new file mode 100644 index 000000000..703f82373 --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/TextRenderer.java @@ -0,0 +1,353 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; +import java.util.HashMap; +import java.util.Iterator; + +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLException; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import jogamp.graph.curve.text.GlyphString; +import jogamp.graph.font.FontInt; +import jogamp.graph.geom.plane.AffineTransform; +import jogamp.graph.geom.plane.Path2D; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.graph.geom.opengl.SVertex; +import jogamp.opengl.Debug; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class TextRenderer { + protected static final boolean DEBUG = Debug.debug("TextRenderer"); + static final boolean FONTTOOL_CUSTOM = false; + + private ShaderState st = new ShaderState(); + + private PMVMatrix pmvMatrix = new PMVMatrix(); + private GLUniformData mgl_PMVMatrix; + + /**Sharpness is equivalent to the value of t value of texture coord + * on the off-curve vertex. The high value of sharpness will + * result in high curvature. + */ + private GLUniformData mgl_sharpness = new GLUniformData("p1y", 0.5f); + private GLUniformData mgl_alpha = new GLUniformData("g_alpha", 1.0f); + private GLUniformData mgl_color = new GLUniformData("g_color", 3, FloatBuffer.allocate(3)); + private GLUniformData mgl_strength = new GLUniformData("a_strength", 1.8f); + + private boolean initialized = false; + + private int regionType = Region.SINGLE_PASS; + + private HashMap strings = new HashMap(); + private final Vertex.Factory pointFactory; + + int win_width = 0; + int win_height = 0; + + /** + * Create a Hardware accelerated Text Renderer. + * @param context OpenGL rendering context + * @param factory optional Point.Factory for Vertex construction. Default is Vertex.Factory. + */ + public TextRenderer(Vertex.Factory factory, int type) { + this.pointFactory = (null != factory) ? factory : SVertex.factory(); + this.regionType = type; + } + + /** + * Initialize shaders and bindings for GPU based text Rendering, + * should be called only once. + * Leaves the renderer enables, ie ShaderState on. + * + * @param drawable the current drawable + * @param shapvalue shaprness around the off-curve vertices + * @return true if init succeeded, false otherwise + */ + public boolean init(GL2ES2 gl){ + if(initialized){ + if(DEBUG) { + System.err.println("HWTextRenderer: Already initialized!"); + } + return true; + } + + boolean VBOsupported = gl.isFunctionAvailable("glGenBuffers") && + gl.isFunctionAvailable("glBindBuffer") && + gl.isFunctionAvailable("glBufferData") && + gl.isFunctionAvailable("glDrawElements") && + gl.isFunctionAvailable("glVertexAttribPointer") && + gl.isFunctionAvailable("glDeleteBuffers"); + + if(DEBUG) { + System.err.println("HWTextRenderer: VBO Supported = " + VBOsupported); + } + + if(!VBOsupported){ + return false; + } + + gl.glEnable(GL2ES2.GL_BLEND); + gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA); + + ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, TextRenderer.class, + "shader", "shader/bin", "curverenderer"); + ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, TextRenderer.class, + "shader", "shader/bin", "curverenderer"); + + ShaderProgram sp = new ShaderProgram(); + sp.add(rsVp); + sp.add(rsFp); + + if(!sp.link(gl, System.err)) { + throw new GLException("HWTextRenderer: Couldn't link program: "+sp); + } + + st.attachShaderProgram(gl, sp); + gl.glBindAttribLocation(sp.id(), 0, "v_position"); + gl.glBindAttribLocation(sp.id(), 1, "texCoord"); + + st.glUseProgram(gl, true); + + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + resetMatrix(null); + + mgl_PMVMatrix = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); + if(!st.glUniform(gl, mgl_PMVMatrix)) { + if(DEBUG){ + System.err.println("Error setting PMVMatrix in shader: "+st); + } + return false; + } + + if(!st.glUniform(gl, mgl_sharpness)) { + if(DEBUG){ + System.err.println("Error setting sharpness in shader: "+st); + } + return false; + } + + if(!st.glUniform(gl, mgl_alpha)) { + if(DEBUG){ + System.err.println("Error setting global alpha in shader: "+st); + } + return false; + } + + if(!st.glUniform(gl, mgl_color)) { + if(DEBUG){ + System.err.println("Error setting global color in shader: "+st); + } + return false; + } + + if(!st.glUniform(gl, mgl_strength)) { + System.err.println("Error setting antialias strength in shader: "+st); + } + + if(DEBUG) { + System.err.println("HWTextRenderer initialized: " + Thread.currentThread()+" "+st); + } + initialized = true; + return true; + } + + public void dispose(GL2ES2 gl) { + st.destroy(gl); + flushCash(); + } + + public float getAlpha() { + return mgl_alpha.floatValue(); + } + + public ShaderState getShaderState() { + return st; + } + + public void setAlpha(GL2ES2 gl, float alpha_t) { + mgl_alpha.setData(alpha_t); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_alpha); + } + } + + public void setColor(GL2ES2 gl, float r, float g, float b){ + FloatBuffer fb = (FloatBuffer) mgl_color.getBuffer(); + fb.put(0, r); + fb.put(1, r); + fb.put(2, r); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_color); + } + } + + public final PMVMatrix matrix() { return pmvMatrix; } + + public void rotate(GL2ES2 gl, float angle, float x, float y, float z){ + pmvMatrix.glRotatef(angle, x, y, z); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + public void translate(GL2ES2 gl, float x, float y, float z){ + pmvMatrix.glTranslatef(x, y, z); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void resetMatrix(GL2ES2 gl){ + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void setMatrix(GL2ES2 gl){ + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + } + } + + public void updateAllShaderValues(GL2ES2 gl) { + if(null != gl && st.inUse()) { + st.glUniform(gl, mgl_PMVMatrix); + st.glUniform(gl, mgl_alpha); + st.glUniform(gl, mgl_color); + st.glUniform(gl, mgl_strength); + } + } + + /** + * @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; + } + + 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 + * @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; + } + + /** Clears the cached string curves + * and destorys underlying buffers + */ + public void flushCash() { + Iterator iterator = strings.values().iterator(); + while(iterator.hasNext()){ + GlyphString glyphString = iterator.next(); + glyphString.destroy(); + } + strings.clear(); + } +} -- cgit v1.2.3