diff options
author | Sven Gothel <[email protected]> | 2011-03-30 07:26:56 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-03-30 07:26:56 +0200 |
commit | 4644863fbf6e8223b7843c63f9c5466f34fc8eeb (patch) | |
tree | 5852882b24faee76c7860688da98e23daa078721 /src/com/jogamp/graph/curve/opengl | |
parent | dbcd775a7763ca131280a8341775fdfa50c4f909 (diff) |
Relocate Hw*Renderer -> opengl subpackage
Diffstat (limited to 'src/com/jogamp/graph/curve/opengl')
4 files changed, 853 insertions, 0 deletions
diff --git a/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java b/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.java new file mode 100755 index 000000000..9fa67a0be --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/HwRegionRenderer.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 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<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 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<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();
+ }
+}
diff --git a/src/com/jogamp/graph/curve/opengl/HwTextRenderer.java b/src/com/jogamp/graph/curve/opengl/HwTextRenderer.java new file mode 100644 index 000000000..f9a104ad0 --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/HwTextRenderer.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 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<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 HwTextRenderer(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, 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<GlyphString> iterator = strings.values().iterator(); + while(iterator.hasNext()){ + GlyphString glyphString = iterator.next(); + glyphString.destroy(); + } + strings.clear(); + } +} diff --git a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp new file mode 100644 index 000000000..2b3a0ce1d --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.fp @@ -0,0 +1,99 @@ +//#version 100 + +uniform float p1y; +uniform float g_alpha; +uniform vec3 g_color; +uniform float a_strength; + +varying vec2 v_texCoord; + +vec3 b_color = vec3(0.0, 0.0, 0.0); + +uniform sampler2D texture; +vec4 weights = vec4(0.075, 0.06, 0.045, 0.025); + +void main (void) +{ + vec2 rtex = vec2(abs(v_texCoord.x),abs(v_texCoord.y)); + vec3 c = g_color; + + float alpha = 0.0; + + if((v_texCoord.x == 0.0) && (v_texCoord.y == 0.0)){ + alpha = g_alpha; + } + else if((v_texCoord.x >= 5.0)){ + vec2 dfx = dFdx(v_texCoord); + vec2 dfy = dFdy(v_texCoord); + + vec2 size = 1.0/textureSize(texture,0); //version 130 + rtex -= 5.0; + vec4 t = texture2D(texture, rtex)* 0.18; + + t += texture2D(texture, rtex + size*(vec2(1, 0)))*weights.x; + t += texture2D(texture, rtex - size*(vec2(1, 0)))*weights.x; + t += texture2D(texture, rtex + size*(vec2(0, 1)))*weights.x; + t += texture2D(texture, rtex - size*(vec2(0, 1)))*weights.x; + + t += texture2D(texture, rtex + 2.0*size*(vec2(1, 0))) *weights.y; + t += texture2D(texture, rtex - 2.0*size*(vec2(1, 0)))*weights.y; + t += texture2D(texture, rtex + 2.0*size*(vec2(0, 1)))*weights.y; + t += texture2D(texture, rtex - 2.0*size*(vec2(0, 1)))*weights.y; + + t += texture2D(texture, rtex + 3.0*size*(vec2(1, 0))) *weights.z; + t += texture2D(texture, rtex - 3.0*size*(vec2(1, 0)))*weights.z; + t += texture2D(texture, rtex + 3.0*size*(vec2(0, 1)))*weights.z; + t += texture2D(texture, rtex - 3.0*size*(vec2(0, 1)))*weights.z; + + t += texture2D(texture, rtex + 4.0*size*(vec2(1, 0))) *weights.w; + t += texture2D(texture, rtex - 4.0*size*(vec2(1, 0)))*weights.w; + t += texture2D(texture, rtex + 4.0*size*(vec2(0, 1)))*weights.w; + t += texture2D(texture, rtex - 4.0*size*(vec2(0, 1)))*weights.w; + + if(t.w == 0.0){ + discard; + } + + c = t.xyz; + alpha = g_alpha* t.w; + } + /////////////////////////////////////////////////////////// + else if ((v_texCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)){ + vec2 dtx = dFdx(rtex); + vec2 dty = dFdy(rtex); + + rtex.y -= 0.1; + if(rtex.y < 0.0) { + if(v_texCoord.y < 0.0) + discard; + else{ + rtex.y = 0.0; + } + } + + vec2 f = vec2((dtx.y - 2.0*p1y*dtx.x + 4.0*p1y*rtex.x*dtx.x), (dty.y - 2.0*p1y*dty.x + 4.0*p1y*rtex.x*dty.x)); + + float position = rtex.y - ((2.0 * rtex.x * p1y) * (1.0 - rtex.x)); + float d = position/(length(f)); + + float a = (0.5 - d * sign(v_texCoord.y)); + + + if (a >= 1.0) { + alpha = g_alpha; + // c = vec3(1.0,1.0,1.0); + } + else if (a <= 0.0) { + alpha = 0.0;//discard; + // c = vec3(0.0,0.0,0.0); + + } + else { + alpha = g_alpha*a; + // c = vec3(a,a,a); + mix(b_color,g_color, a); + } + } + + gl_FragColor = vec4(c, alpha); +} diff --git a/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp new file mode 100644 index 000000000..bc9ecb41e --- /dev/null +++ b/src/com/jogamp/graph/curve/opengl/shader/curverenderer.vp @@ -0,0 +1,13 @@ +//#version 100 + +uniform mat4 mgl_PMVMatrix[2]; +attribute vec4 v_position; +attribute vec2 texCoord; + +varying vec2 v_texCoord; + +void main(void) +{ + gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * v_position; + v_texCoord = texCoord.st; +}
\ No newline at end of file |