diff options
Diffstat (limited to 'src/jogl/classes/jogamp')
18 files changed, 389 insertions, 1049 deletions
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java deleted file mode 100644 index 515583b14..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java +++ /dev/null @@ -1,74 +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 jogamp.graph.curve.opengl; - -import com.jogamp.graph.curve.Region; -import com.jogamp.graph.curve.opengl.GLRegion; - -/** RegionFactory to create a Context specific Region implementation. - * - * @see GLRegion - */ -public class RegionFactory { - - /** - * Create a Region using the passed render mode - * - * <p> In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit - * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.</p> - * - * @param rs the RenderState to be used - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} - */ - public static GLRegion create(int renderModes) { - if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){ - return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT); - } - else{ - return new VBORegionSPES2(renderModes); - } - } - - /** Create a Single Pass Region using the passed render mode - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, - * {@link Region#VBAA_RENDERING_BIT} - * @return - */ - public static GLRegion createSinglePass(int renderModes) { - return new VBORegionSPES2(renderModes); - } - - /** Create a Two Pass (VBAA) Region using the passed render mode - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, - * {@link Region#VBAA_RENDERING_BIT} - * @return - */ - public static GLRegion createTwoPass(int renderModes, int textureUnit) { - return new VBORegion2PES2(renderModes, textureUnit); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java index 31ad974d0..c2762591a 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java @@ -32,23 +32,21 @@ import javax.media.opengl.GLException; import jogamp.graph.curve.opengl.shader.AttributeNames; -import com.jogamp.graph.curve.Region; -import com.jogamp.graph.curve.opengl.GLRegion; -import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; +import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.opengl.GLExtensions; 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 { + public RegionRendererImpl01(RenderState rs, int renderModes) { super(rs, renderModes); - } @Override - protected boolean initShaderProgram(GL2ES2 gl) { + protected final boolean initImpl(GL2ES2 gl) { final ShaderState st = rs.getShaderState(); final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RegionRendererImpl01.class, "shader", @@ -89,12 +87,7 @@ public class RegionRendererImpl01 extends RegionRenderer { } @Override - protected void destroyImpl(GL2ES2 gl) { - super.destroyImpl(gl); - } - - @Override - protected void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texSize) { - ((GLRegion)region).draw(gl, rs, vp_width, vp_height, texSize); + protected final void destroyImpl(GL2ES2 gl) { + // NOP .. all will be destroyed via RenderState } } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java deleted file mode 100644 index 4ec4d1d98..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java +++ /dev/null @@ -1,108 +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 jogamp.graph.curve.opengl; - -import javax.media.opengl.GL2ES2; -import javax.media.opengl.GLException; - -import jogamp.graph.curve.opengl.shader.AttributeNames; -import jogamp.graph.curve.text.GlyphString; - -import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.graph.curve.opengl.TextRenderer; -import com.jogamp.graph.font.Font; -import com.jogamp.opengl.GLExtensions; -import com.jogamp.opengl.util.glsl.ShaderCode; -import com.jogamp.opengl.util.glsl.ShaderProgram; -import com.jogamp.opengl.util.glsl.ShaderState; - -public class TextRendererImpl01 extends TextRenderer { - public TextRendererImpl01(RenderState rs, int type) { - super(rs, type); - } - - @Override - protected boolean initShaderProgram(GL2ES2 gl){ - final ShaderState st = rs.getShaderState(); - - final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getVertexShaderName(), true); - final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getFragmentShaderName(), true); - rsVp.defaultShaderCustomization(gl, true, true); - // rsFp.defaultShaderCustomization(gl, true, true); - int pos = rsFp.addGLSLVersion(gl); - if( gl.isGLES() ) { - pos = rsFp.insertShaderSource(0, pos, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE)); - } - final String rsFpDefPrecision = getFragmentShaderPrecision(gl); - if( null != rsFpDefPrecision ) { - rsFp.insertShaderSource(0, pos, rsFpDefPrecision); - } - - final ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - - if( !sp.init(gl) ) { - throw new GLException("RegionRenderer: Couldn't init program: "+sp); - } - st.attachShaderProgram(gl, sp, false); - st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME); - st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME); - - if(!sp.link(gl, System.err)) { - throw new GLException("TextRendererImpl01: Couldn't link program: "+sp); - } - st.useProgram(gl, true); - - if(DEBUG) { - System.err.println("TextRendererImpl01 initialized: " + Thread.currentThread()+" "+st); - } - return true; - } - - @Override - protected void destroyImpl(GL2ES2 gl) { - super.destroyImpl(gl); - } - - @Override - public void drawString3D(GL2ES2 gl, Font font, String str, float[] position, int fontSize, int[/*1*/] texSize) { - if(!isInitialized()){ - throw new GLException("TextRendererImpl01: not initialized!"); - } - GlyphString glyphString = getCachedGlyphString(font, str, fontSize); - if(null == glyphString) { - glyphString = createString(gl, font, fontSize, str); - addCachedGlyphString(gl, font, str, fontSize, glyphString); - } - - glyphString.renderString3D(gl, rs, vp_width, vp_height, texSize); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java index 77c862ed4..df3be2e06 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java @@ -39,10 +39,8 @@ import jogamp.graph.curve.opengl.shader.AttributeNames; import jogamp.graph.curve.opengl.shader.UniformNames; import com.jogamp.common.nio.Buffers; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex; - import com.jogamp.graph.curve.opengl.GLRegion; +import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; import com.jogamp.opengl.FBObject; import com.jogamp.opengl.FBObject.Attachment; @@ -54,15 +52,14 @@ import com.jogamp.opengl.util.glsl.ShaderState; public class VBORegion2PES2 extends GLRegion { private GLArrayDataServer verticeTxtAttr; private GLArrayDataServer texCoordTxtAttr; - private GLArrayDataServer indicesTxt; + private GLArrayDataServer indicesTxtBuffer; private GLArrayDataServer verticeFboAttr; private GLArrayDataServer texCoordFboAttr; private GLArrayDataServer indicesFbo; - private FBObject fbo; private TextureAttachment texA; - private PMVMatrix fboPMVMatrix; + private final PMVMatrix fboPMVMatrix; GLUniformData mgl_fboPMVMatrix; private int tex_width_c = 0; @@ -70,30 +67,57 @@ public class VBORegion2PES2 extends GLRegion { GLUniformData mgl_ActiveTexture; GLUniformData mgl_TextureSize; // if GLSL < 1.30 - public VBORegion2PES2(int renderModes, int textureEngine) { + public VBORegion2PES2(final int renderModes, final int textureUnit) { super(renderModes); + final int initialElementCount = 256; fboPMVMatrix = new PMVMatrix(); mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf()); - mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine); + mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureUnit); + + indicesTxtBuffer = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + verticeTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); + texCoordTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); } @Override - public void update(GL2ES2 gl, RenderState rs) { - if(!isDirty()) { - return; - } + protected final void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) { + indicesTxtBuffer.seal(gl, false); + indicesTxtBuffer.rewind(); + verticeTxtAttr.seal(gl, false); + verticeTxtAttr.rewind(); + texCoordTxtAttr.seal(gl, false); + texCoordTxtAttr.rewind(); + } + + @Override + protected final void pushVertex(float[] coords, float[] texParams) { + verticeTxtAttr.putf(coords[0]); + verticeTxtAttr.putf(coords[1]); + verticeTxtAttr.putf(coords[2]); + + texCoordTxtAttr.putf(texParams[0]); + texCoordTxtAttr.putf(texParams[1]); + } + + @Override + protected final void pushIndex(int idx) { + indicesTxtBuffer.puts((short)idx); + } + @Override + protected void update(final GL2ES2 gl, final RegionRenderer renderer) { if(null == indicesFbo) { - final int initialElementCount = 256; - final ShaderState st = rs.getShaderState(); + final ShaderState st = renderer.getShaderState(); - indicesFbo = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesFbo = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); indicesFbo.puts((short) 0); indicesFbo.puts((short) 1); indicesFbo.puts((short) 3); indicesFbo.puts((short) 1); indicesFbo.puts((short) 2); indicesFbo.puts((short) 3); indicesFbo.seal(true); texCoordFboAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); + false, 4, GL.GL_STATIC_DRAW); st.ownAttribute(texCoordFboAttr, true); texCoordFboAttr.putf(5); texCoordFboAttr.putf(5); texCoordFboAttr.putf(5); texCoordFboAttr.putf(6); @@ -102,69 +126,19 @@ public class VBORegion2PES2 extends GLRegion { texCoordFboAttr.seal(true); verticeFboAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); + false, 4, GL.GL_STATIC_DRAW); st.ownAttribute(verticeFboAttr, true); - - indicesTxt = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); - - verticeTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); st.ownAttribute(verticeTxtAttr, true); - - texCoordTxtAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); st.ownAttribute(texCoordTxtAttr, true); if(DEBUG_INSTANCE) { System.err.println("VBORegion2PES2 Create: " + this); } } - // process triangles - indicesTxt.seal(gl, false); - indicesTxt.rewind(); - for(int i=0; i<triangles.size(); i++) { - final Triangle t = triangles.get(i); - final Vertex[] t_vertices = t.getVertices(); - - if(t_vertices[0].getId() == Integer.MAX_VALUE){ - t_vertices[0].setId(numVertices++); - t_vertices[1].setId(numVertices++); - t_vertices[2].setId(numVertices++); - - vertices.add(t_vertices[0]); - vertices.add(t_vertices[1]); - vertices.add(t_vertices[2]); - - indicesTxt.puts((short) t_vertices[0].getId()); - indicesTxt.puts((short) t_vertices[1].getId()); - indicesTxt.puts((short) t_vertices[2].getId()); - } else { - indicesTxt.puts((short) t_vertices[0].getId()); - indicesTxt.puts((short) t_vertices[1].getId()); - indicesTxt.puts((short) t_vertices[2].getId()); - } - } - indicesTxt.seal(gl, true); - indicesTxt.enableBuffer(gl, false); - - // process vertices and update bbox - box.reset(); - verticeTxtAttr.seal(gl, false); - verticeTxtAttr.rewind(); - texCoordTxtAttr.seal(gl, false); - texCoordTxtAttr.rewind(); - for(int i=0; i<vertices.size(); i++) { - final Vertex v = vertices.get(i); - verticeTxtAttr.putf(v.getX()); - verticeTxtAttr.putf(v.getY()); - verticeTxtAttr.putf(v.getZ()); - box.resize(v.getX(), v.getY(), v.getZ()); - - final float[] tex = v.getTexCoord(); - texCoordTxtAttr.putf(tex[0]); - texCoordTxtAttr.putf(tex[1]); - } + // seal buffers + indicesTxtBuffer.seal(gl, true); + indicesTxtBuffer.enableBuffer(gl, false); texCoordTxtAttr.seal(gl, true); texCoordTxtAttr.enableBuffer(gl, false); verticeTxtAttr.seal(gl, true); @@ -187,22 +161,22 @@ public class VBORegion2PES2 extends GLRegion { // push data 2 GPU .. indicesFbo.seal(gl, true); indicesFbo.enableBuffer(gl, false); - - setDirty(false); - // the buffers were disabled, since due to real/fbo switching and other vbo usage } - int[] maxTexSize = new int[] { -1 } ; + final int[] maxTexSize = new int[] { -1 } ; @Override - protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { - if(vp_width <=0 || vp_height <= 0 || null==texWidth || texWidth[0] <= 0){ + protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] texWidth) { + final int width = renderer.getWidth(); + final int height = renderer.getHeight(); + if(width <=0 || height <= 0 || null==texWidth || texWidth[0] <= 0){ renderRegion(gl); } else { if(0 > maxTexSize[0]) { gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxTexSize, 0); } + final RenderState rs = renderer.getRenderState(); if(texWidth[0] != tex_width_c) { if(texWidth[0] > maxTexSize[0]) { texWidth[0] = maxTexSize[0]; // clip to max - write-back user value! @@ -210,11 +184,11 @@ public class VBORegion2PES2 extends GLRegion { renderRegion2FBO(gl, rs, texWidth); } // System.out.println("Scale: " + matrix.glGetMatrixf().get(1+4*3) +" " + matrix.glGetMatrixf().get(2+4*3)); - renderFBO(gl, rs, vp_width, vp_height); + renderFBO(gl, rs, width, height); } } - private void renderFBO(GL2ES2 gl, RenderState rs, int width, int hight) { + private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int hight) { final ShaderState st = rs.getShaderState(); gl.glViewport(0, 0, width, hight); @@ -235,7 +209,7 @@ public class VBORegion2PES2 extends GLRegion { // setback: gl.glActiveTexture(currentActiveTextureEngine[0]); } - private void renderRegion2FBO(GL2ES2 gl, RenderState rs, int[/*1*/] texWidth) { + private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int[/*1*/] texWidth) { final ShaderState st = rs.getShaderState(); if(0>=texWidth[0]) { @@ -280,30 +254,30 @@ public class VBORegion2PES2 extends GLRegion { mgl_TextureSize = new GLUniformData(UniformNames.gcu_TextureSize, 2, Buffers.newDirectFloatBuffer(2)); } final FloatBuffer texSize = (FloatBuffer) mgl_TextureSize.getBuffer(); - texSize.put(0, (float)fbo.getWidth()); - texSize.put(1, (float)fbo.getHeight()); + texSize.put(0, fbo.getWidth()); + texSize.put(1, fbo.getHeight()); st.uniform(gl, mgl_TextureSize); //} } - private void renderRegion(GL2ES2 gl) { + private void renderRegion(final GL2ES2 gl) { verticeTxtAttr.enableBuffer(gl, true); texCoordTxtAttr.enableBuffer(gl, true); - indicesTxt.bindBuffer(gl, true); // keeps VBO binding + indicesTxtBuffer.bindBuffer(gl, true); // keeps VBO binding - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxtBuffer.getElementCount() * indicesTxtBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); - indicesTxt.bindBuffer(gl, false); + indicesTxtBuffer.bindBuffer(gl, false); texCoordTxtAttr.enableBuffer(gl, false); verticeTxtAttr.enableBuffer(gl, false); } @Override - public void destroy(GL2ES2 gl, RenderState rs) { + protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { if(DEBUG_INSTANCE) { System.err.println("VBORegion2PES2 Destroy: " + this); } - final ShaderState st = rs.getShaderState(); + final ShaderState st = renderer.getShaderState(); if(null != fbo) { fbo.destroy(gl); fbo = null; @@ -319,9 +293,9 @@ public class VBORegion2PES2 extends GLRegion { texCoordTxtAttr.destroy(gl); texCoordTxtAttr = null; } - if(null != indicesTxt) { - indicesTxt.destroy(gl); - indicesTxt = null; + if(null != indicesTxtBuffer) { + indicesTxtBuffer.destroy(gl); + indicesTxtBuffer = null; } if(null != verticeFboAttr) { st.ownAttribute(verticeFboAttr, false); @@ -337,7 +311,5 @@ public class VBORegion2PES2 extends GLRegion { indicesFbo.destroy(gl); indicesFbo = null; } - triangles.clear(); - vertices.clear(); } } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index 9feb18a12..f4c40b0e5 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java @@ -33,118 +33,94 @@ import javax.media.opengl.GL2ES2; import jogamp.graph.curve.opengl.shader.AttributeNames; import com.jogamp.graph.curve.opengl.GLRegion; -import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Triangle; +import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.glsl.ShaderState; public class VBORegionSPES2 extends GLRegion { private GLArrayDataServer verticeAttr = null; private GLArrayDataServer texCoordAttr = null; - private GLArrayDataServer indices = null; + private GLArrayDataServer indicesBuffer = null; + private boolean buffersAttached = false; - protected VBORegionSPES2(int renderModes) { + public VBORegionSPES2(final int renderModes) { super(renderModes); + final int initialElementCount = 256; + indicesBuffer = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + + verticeAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); + + texCoordAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, + false, initialElementCount, GL.GL_STATIC_DRAW); } @Override - protected void update(GL2ES2 gl, RenderState rs) { - if(!isDirty()) { - return; - } + protected final void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) { + indicesBuffer.seal(gl, false); + indicesBuffer.rewind(); + verticeAttr.seal(gl, false); + verticeAttr.rewind(); + texCoordAttr.seal(gl, false); + texCoordAttr.rewind(); + } - if(null == indices) { - final int initialElementCount = 256; - final ShaderState st = rs.getShaderState(); + @Override + protected final void pushVertex(float[] coords, float[] texParams) { + verticeAttr.putf(coords[0]); + verticeAttr.putf(coords[1]); + verticeAttr.putf(coords[2]); - indices = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + texCoordAttr.putf(texParams[0]); + texCoordAttr.putf(texParams[1]); + } - verticeAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); - st.ownAttribute(verticeAttr, true); + @Override + protected final void pushIndex(int idx) { + indicesBuffer.puts((short)idx); + } - texCoordAttr = GLArrayDataServer.createGLSL(AttributeNames.TEXCOORD_ATTR_NAME, 2, GL2ES2.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); + @Override + protected void update(final GL2ES2 gl, final RegionRenderer renderer) { + if( !buffersAttached ) { + final ShaderState st = renderer.getShaderState(); + st.ownAttribute(verticeAttr, true); st.ownAttribute(texCoordAttr, true); - - if(DEBUG_INSTANCE) { - System.err.println("VBORegionSPES2 Create: " + this); - } - } - - // process triangles - indices.seal(gl, false); - indices.rewind(); - for(int i=0; i<triangles.size(); i++) { - final Triangle t = triangles.get(i); - final Vertex[] t_vertices = t.getVertices(); - - if(t_vertices[0].getId() == Integer.MAX_VALUE){ - t_vertices[0].setId(numVertices++); - t_vertices[1].setId(numVertices++); - t_vertices[2].setId(numVertices++); - - vertices.add(t_vertices[0]); - vertices.add(t_vertices[1]); - vertices.add(t_vertices[2]); - - indices.puts((short) t_vertices[0].getId()); - indices.puts((short) t_vertices[1].getId()); - indices.puts((short) t_vertices[2].getId()); - } else { - indices.puts((short) t_vertices[0].getId()); - indices.puts((short) t_vertices[1].getId()); - indices.puts((short) t_vertices[2].getId()); - } - } - indices.seal(gl, true); - indices.enableBuffer(gl, false); - - // process vertices and update bbox - box.reset(); - verticeAttr.seal(gl, false); - verticeAttr.rewind(); - texCoordAttr.seal(gl, false); - texCoordAttr.rewind(); - for(int i=0; i<vertices.size(); i++) { - final Vertex v = vertices.get(i); - verticeAttr.putf(v.getX()); - verticeAttr.putf(v.getY()); - verticeAttr.putf(v.getZ()); - box.resize(v.getX(), v.getY(), v.getZ()); - - final float[] tex = v.getTexCoord(); - texCoordAttr.putf(tex[0]); - texCoordAttr.putf(tex[1]); + buffersAttached = true; } + // seal buffers + indicesBuffer.seal(gl, true); + indicesBuffer.enableBuffer(gl, false); verticeAttr.seal(gl, true); verticeAttr.enableBuffer(gl, false); texCoordAttr.seal(gl, true); texCoordAttr.enableBuffer(gl, false); - - setDirty(false); + if(DEBUG_INSTANCE) { + System.err.println("VBORegionSPES2 idx "+indicesBuffer); + System.err.println("VBORegionSPES2 ver "+verticeAttr); + System.err.println("VBORegionSPES2 tex "+texCoordAttr); + } } @Override - protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { + protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] texWidth) { verticeAttr.enableBuffer(gl, true); texCoordAttr.enableBuffer(gl, true); - indices.bindBuffer(gl, true); // keeps VBO binding + indicesBuffer.bindBuffer(gl, true); // keeps VBO binding - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); - indices.bindBuffer(gl, false); + indicesBuffer.bindBuffer(gl, false); texCoordAttr.enableBuffer(gl, false); verticeAttr.enableBuffer(gl, false); } @Override - public final void destroy(GL2ES2 gl, RenderState rs) { + protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { if(DEBUG_INSTANCE) { System.err.println("VBORegionSPES2 Destroy: " + this); } - final ShaderState st = rs.getShaderState(); + final ShaderState st = renderer.getShaderState(); if(null != verticeAttr) { st.ownAttribute(verticeAttr, false); verticeAttr.destroy(gl); @@ -155,9 +131,9 @@ public class VBORegionSPES2 extends GLRegion { texCoordAttr.destroy(gl); texCoordAttr = null; } - if(null != indices) { - indices.destroy(gl); - indices = null; + if(null != indicesBuffer) { + indicesBuffer.destroy(gl); + indicesBuffer = null; } } } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java index a60f91b87..a82c2ee7a 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java @@ -29,7 +29,7 @@ package jogamp.graph.curve.tess; import java.util.ArrayList; - +import java.util.List; import com.jogamp.graph.curve.tess.Triangulator; import com.jogamp.graph.geom.Outline; @@ -48,11 +48,10 @@ public class CDTriangulator2D implements Triangulator{ protected static final boolean DEBUG = Debug.debug("Triangulation"); - private float sharpness = 0.5f; + private final float sharpness = 0.5f; private ArrayList<Loop> loops; - private ArrayList<Vertex> vertices; + // FIXME ? private ArrayList<Vertex> vertices; - private ArrayList<Triangle> triangles; private int maxTriID = 0; @@ -68,13 +67,12 @@ public class CDTriangulator2D implements Triangulator{ @Override public void reset() { maxTriID = 0; - vertices = new ArrayList<Vertex>(); - triangles = new ArrayList<Triangle>(3); + // vertices = new ArrayList<Vertex>(); loops = new ArrayList<Loop>(); } @Override - public void addCurve(Outline polyline) { + public void addCurve(List<Triangle> sink, Outline polyline) { Loop loop = null; if(!loops.isEmpty()) { @@ -82,27 +80,27 @@ public class CDTriangulator2D implements Triangulator{ } if(loop == null) { - GraphOutline outline = new GraphOutline(polyline); - GraphOutline innerPoly = extractBoundaryTriangles(outline, false); - vertices.addAll(polyline.getVertices()); + final GraphOutline outline = new GraphOutline(polyline); + final GraphOutline innerPoly = extractBoundaryTriangles(sink, outline, false); + // vertices.addAll(polyline.getVertices()); loop = new Loop(innerPoly, VectorUtil.Winding.CCW); loops.add(loop); } else { - GraphOutline outline = new GraphOutline(polyline); - GraphOutline innerPoly = extractBoundaryTriangles(outline, true); - vertices.addAll(innerPoly.getVertices()); + final GraphOutline outline = new GraphOutline(polyline); + final GraphOutline innerPoly = extractBoundaryTriangles(sink, outline, true); + // vertices.addAll(innerPoly.getVertices()); loop.addConstraintCurve(innerPoly); } } @Override - public ArrayList<Triangle> generate() { + public void generate(List<Triangle> sink) { for(int i=0;i<loops.size();i++) { Loop loop = loops.get(i); int numTries = 0; int size = loop.computeLoopSize(); while(!loop.isSimplex()){ - Triangle tri = null; + final Triangle tri; if(numTries > size){ tri = loop.cut(false); } @@ -115,7 +113,7 @@ public class CDTriangulator2D implements Triangulator{ numTries = 0; size--; tri.setId(maxTriID++); - triangles.add(tri); + sink.add(tri); if(DEBUG){ System.err.println(tri); } @@ -127,14 +125,14 @@ public class CDTriangulator2D implements Triangulator{ break; } } - Triangle tri = loop.cut(true); - if(tri != null) - triangles.add(tri); + final Triangle tri = loop.cut(true); + if(tri != null) { + sink.add(tri); + } } - return triangles; } - private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole) { + private GraphOutline extractBoundaryTriangles(List<Triangle> sink, GraphOutline outline, boolean hole) { GraphOutline innerOutline = new GraphOutline(); ArrayList<GraphVertex> outVertices = outline.getGraphPoint(); int size = outVertices.size(); @@ -145,9 +143,9 @@ public class CDTriangulator2D implements Triangulator{ GraphVertex gv1 = currentVertex; if(!currentVertex.getPoint().isOnCurve()) { - Vertex v0 = gv0.getPoint().clone(); - Vertex v2 = gv2.getPoint().clone(); - Vertex v1 = gv1.getPoint().clone(); + final Vertex v0 = gv0.getPoint().clone(); + final Vertex v2 = gv2.getPoint().clone(); + final Vertex v1 = gv1.getPoint().clone(); gv0.setBoundaryContained(true); gv1.setBoundaryContained(true); @@ -163,7 +161,7 @@ public class CDTriangulator2D implements Triangulator{ t = new Triangle(v2, v1, v0); } t.setId(maxTriID++); - triangles.add(t); + sink.add(t); if(DEBUG){ System.err.println(t); } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java index c1dafc0d1..5810e3bc9 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java @@ -37,7 +37,7 @@ import com.jogamp.opengl.math.geom.AABBox; public class Loop { private HEdge root = null; - private AABBox box = new AABBox(); + private final AABBox box = new AABBox(); private GraphOutline initialOutline = null; public Loop(GraphOutline polyline, VectorUtil.Winding winding){ @@ -272,13 +272,13 @@ public class Loop { * @return the triangle iff it satisfies, null otherwise */ private Triangle createTriangle(Vertex v1, Vertex v2, Vertex v3, HEdge rootT){ - Triangle t = new Triangle(v1, v2, v3); + final Triangle t = new Triangle(v1, v2, v3); t.setVerticesBoundary(checkVerticesBoundary(rootT)); return t; } private boolean[] checkVerticesBoundary(HEdge rootT) { - boolean[] boundary = new boolean[3]; + final boolean[] boundary = new boolean[3]; HEdge e1 = rootT; HEdge e2 = rootT.getNext(); HEdge e3 = rootT.getNext().getNext(); diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java deleted file mode 100644 index ff46c3338..000000000 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java +++ /dev/null @@ -1,99 +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 jogamp.graph.curve.text; - -import java.util.ArrayList; - -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex.Factory; - -import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.opengl.math.Quaternion; - -public class GlyphShape { - - private Quaternion quat= null; - private OutlineShape shape = null; - - /** Create a new Glyph shape - * based on Parametric curve control polyline - */ - public GlyphShape(Vertex.Factory<? extends Vertex> factory){ - shape = new OutlineShape(factory); - } - - /** Create a new GlyphShape from a {@link OutlineShape} - * @param factory vertex impl factory {@link Factory} - * @param shape {@link OutlineShape} representation of the Glyph - */ - public GlyphShape(Vertex.Factory<? extends Vertex> factory, OutlineShape shape){ - this(factory); - this.shape = shape; - this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); - } - - public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); } - - public OutlineShape getShape() { - return shape; - } - - public int getNumVertices() { - return shape.getVertices().size(); - } - - /** Get the rotational Quaternion attached to this Shape - * @return the Quaternion Object - */ - public Quaternion getQuat() { - return quat; - } - - /** Set the Quaternion that shall defien the rotation - * of this shape. - * @param quat - */ - public void setQuat(Quaternion quat) { - this.quat = quat; - } - - /** Triangluate the glyph shape - * @return ArrayList of triangles which define this shape - */ - public ArrayList<Triangle> triangulate(){ - return shape.triangulate(); - } - - /** Get the list of Vertices of this Object - * @return arrayList of Vertices - */ - public ArrayList<Vertex> getVertices(){ - return shape.getVertices(); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java deleted file mode 100644 index 2284ab669..000000000 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java +++ /dev/null @@ -1,213 +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 jogamp.graph.curve.text; - -import java.util.ArrayList; - -import com.jogamp.graph.font.Font; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex.Factory; -import com.jogamp.graph.geom.opengl.SVertex; - -import javax.media.opengl.GL2ES2; - -import jogamp.graph.curve.opengl.RegionFactory; -import jogamp.graph.font.FontInt; - -import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.curve.Region; -import com.jogamp.graph.curve.opengl.GLRegion; -import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.util.PMVMatrix; - -public class GlyphString { - /** Static font size for all default font OutlineShape generations via {@link #createString(OutlineShape, Factory, Font, String)}. - * <p>The actual font size shall be accomplished by the GL PMV matrix.</p> - */ - public static final int STATIC_FONT_SIZE = 10; - - private ArrayList<GlyphShape> glyphs = new ArrayList<GlyphShape>(); - private CharSequence str; - private String fontname; - private GLRegion region; - - private SVertex origin = new SVertex(); - - /** - * <p>Uses {@link #STATIC_FONT_SIZE}.</p> - * <p>No caching is performed.</p> - * - * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @param vertexFactory vertex impl factory {@link Factory} - * @param font the target {@link Font} - * @param str string text - * @return the created {@link GlyphString} instance - */ - public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, String str) { - return createString(shape, vertexFactory, font, STATIC_FONT_SIZE, str); - } - - /** - * <p>No caching is performed.</p> - * - * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @param vertexFactory vertex impl factory {@link Factory} - * @param font the target {@link Font} - * @param fontSize font size - * @param str string text - * @return the created {@link GlyphString} instance - */ - public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, int fontSize, String str) { - ArrayList<OutlineShape> shapes = ((FontInt)font).getOutlineShapes(str, fontSize, vertexFactory); - - GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str); - glyphString.createfromOutlineShapes(vertexFactory, shapes); - if(null != shape) { - for(int i=0; i<glyphString.glyphs.size(); i++) { - shape.addOutlineShape(glyphString.glyphs.get(i).getShape()); - } - } - return glyphString; - } - - /** Create a new GlyphString object - * @param fontname the name of the font that this String is - * associated with - * @param str the string object - */ - public GlyphString(String fontname, CharSequence str){ - this.fontname = fontname; - this.str = str; - } - - public void addGlyphShape(GlyphShape glyph){ - glyphs.add(glyph); - } - - public CharSequence getString(){ - return str; - } - - /**Creates the Curve based Glyphs from a list of {@link OutlineShape} - * @param vertexFactory vertex impl factory {@link Factory} - * @param shapes list of {@link OutlineShape} - */ - public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, ArrayList<OutlineShape> shapes) { - final int numGlyps = shapes.size(); - for (int index=0;index<numGlyps;index++){ - if(shapes.get(index) == null){ - continue; - } - GlyphShape glyphShape = new GlyphShape(vertexFactory, shapes.get(index)); - - if(glyphShape.getNumVertices() < 3) { - continue; - } - addGlyphShape(glyphShape); - } - } - - - /** Generate a OGL Region to represent this Object. - * @param gl the current gl object - * @param rs the current attached RenderState - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} - */ - public GLRegion createRegion(GL2ES2 gl, int renderModes){ - region = RegionFactory.create(renderModes); - // region.setFlipped(true); - - int numVertices = region.getNumVertices(); - - for(int i=0; i< glyphs.size(); i++) { - final GlyphShape glyph = glyphs.get(i); - ArrayList<Triangle> gtris = glyph.triangulate(); - region.addTriangles(gtris); - - final ArrayList<Vertex> gVertices = glyph.getVertices(); - for(int j=0; j<gVertices.size(); j++) { - final Vertex gVert = gVertices.get(j); - gVert.setId(numVertices++); - region.addVertex(gVert); - } - } - return region; - } - - /** Generate a Hashcode for this object - * @return a string defining the hashcode - */ - public String getTextHashCode(){ - return "" + fontname.hashCode() + str.hashCode(); - } - - /** Render the Object based using the associated Region - * previously generated. - */ - public void renderString3D(GL2ES2 gl) { - region.draw(gl, null, 0, 0, null); - } - /** Render the Object based using the associated Region - * previously generated. - * @param matrix current {@link PMVMatrix}. - * @param rs the RenderState to be used - * @param vp_width current screen width - * @param vp_height current screen height - * @param texWidth desired texture width for multipass-rendering. - * The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched. - */ - public void renderString3D(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { - region.draw(gl, rs, vp_width, vp_height, texWidth); - } - - /** Get the Origin of this GlyphString - * @return - */ - public Vertex getOrigin() { - return origin; - } - - /** Destroy the associated OGL objects - * @param rs the current attached RenderState - */ - public void destroy(GL2ES2 gl, RenderState rs) { - if(null != gl && null != rs) { - region.destroy(gl, rs); - region = null; - } else if(null != region) { - throw new InternalError("destroy called w/o GL context, but has a region"); - } - glyphs.clear(); - } - - public AABBox getBounds(){ - return region.getBounds(); - } -} diff --git a/src/jogl/classes/jogamp/graph/font/FontInt.java b/src/jogl/classes/jogamp/graph/font/FontInt.java deleted file mode 100644 index 4366724ad..000000000 --- a/src/jogl/classes/jogamp/graph/font/FontInt.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2011 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.font; - -import java.util.ArrayList; - -import jogamp.graph.geom.plane.Path2D; - -import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.font.Font; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Vertex.Factory; - -public interface FontInt extends Font { - - public interface GlyphInt extends Font.Glyph { - public Path2D getPath(); // unscaled path - public Path2D getPath(float pixelSize); - } - - public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory); -} diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 67ae6c387..8dd9ce4d7 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -27,9 +27,6 @@ */ package jogamp.graph.font.typecast; -import java.util.ArrayList; - -import jogamp.graph.font.FontInt; import jogamp.graph.font.typecast.ot.OTFont; import jogamp.graph.font.typecast.ot.OTFontCollection; import jogamp.graph.font.typecast.ot.table.CmapFormat; @@ -37,32 +34,29 @@ import jogamp.graph.font.typecast.ot.table.CmapIndexEntry; import jogamp.graph.font.typecast.ot.table.CmapTable; import jogamp.graph.font.typecast.ot.table.HdmxTable; import jogamp.graph.font.typecast.ot.table.ID; -import jogamp.graph.geom.plane.AffineTransform; -import jogamp.graph.geom.plane.Path2D; import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; -import com.jogamp.graph.font.Font.Glyph; +import com.jogamp.graph.geom.SVertex; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.opengl.math.geom.AABBox; -class TypecastFont implements FontInt { +class TypecastFont implements Font { static final boolean DEBUG = false; + private static final Vertex.Factory<SVertex> vertexFactory = SVertex.factory(); - final OTFontCollection fontset; - final OTFont font; - TypecastHMetrics metrics; - final CmapFormat cmapFormat; - int cmapentries; - + // private final OTFontCollection fontset; + /* pp */ final OTFont font; + private final CmapFormat cmapFormat; + private final int cmapentries; + private final IntObjectHashMap char2Glyph; + private final TypecastHMetrics metrics; // FIXME: Add cache size to limit memory usage ?? - IntObjectHashMap char2Glyph; - public TypecastFont(OTFontCollection fontset) { - this.fontset = fontset; + public TypecastFont(final OTFontCollection fontset) { + // this.fontset = fontset; this.font = fontset.getFont(0); // FIXME: Generic attempt to find the best CmapTable, @@ -124,10 +118,13 @@ class TypecastFont implements FontInt { } } - cmapentries = 0; - for (int i = 0; i < cmapFormat.getRangeCount(); ++i) { - CmapFormat.Range range = cmapFormat.getRange(i); - cmapentries += range.getEndCode() - range.getStartCode() + 1; // end included + { + int _cmapentries = 0; + for (int i = 0; i < cmapFormat.getRangeCount(); ++i) { + CmapFormat.Range range = cmapFormat.getRange(i); + _cmapentries += range.getEndCode() - range.getStartCode() + 1; // end included + } + cmapentries = _cmapentries; } if(DEBUG) { System.err.println("font direction hint: "+font.getHeadTable().getFontDirectionHint()); @@ -140,12 +137,13 @@ class TypecastFont implements FontInt { for (int j = range.getStartCode(); j <= range.getEndCode(); ++j) { final int code = cmapFormat.mapCharCode(j); if(code < 15) { - System.err.println(" char: " + (int)j + " ( " + (char)j +" ) -> " + code); + System.err.println(" char: " + j + " ( " + (char)j +" ) -> " + code); } } } } char2Glyph = new IntObjectHashMap(cmapentries + cmapentries/4); + metrics = new TypecastHMetrics(this); } @Override @@ -168,15 +166,12 @@ class TypecastFont implements FontInt { } @Override - public float getAdvanceWidth(int i, float pixelSize) { - return font.getHmtxTable().getAdvanceWidth(i) * metrics.getScale(pixelSize); + public float getAdvanceWidth(int glyphID, float pixelSize) { + return font.getHmtxTable().getAdvanceWidth(glyphID) * metrics.getScale(pixelSize); } @Override - public Metrics getMetrics() { - if (metrics == null) { - metrics = new TypecastHMetrics(this); - } + public final Metrics getMetrics() { return metrics; } @@ -202,10 +197,10 @@ class TypecastFont implements FontInt { if(null == glyph) { throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+code); } - Path2D path = TypecastRenderer.buildPath(glyph); - result = new TypecastGlyph(this, symbol, code, glyph.getBBox(), glyph.getAdvanceWidth(), path); + final OutlineShape shape = TypecastRenderer.buildShape(symbol, glyph, vertexFactory); + result = new TypecastGlyph(this, symbol, code, glyph.getBBox(), glyph.getAdvanceWidth(), shape); if(DEBUG) { - System.err.println("New glyph: " + (int)symbol + " ( " + (char)symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + path); + System.err.println("New glyph: " + (int)symbol + " ( " + symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + shape); } final HdmxTable hdmx = font.getHdmxTable(); if (null!= result && null != hdmx) { @@ -227,18 +222,21 @@ class TypecastFont implements FontInt { } @Override - public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory) { - AffineTransform transform = new AffineTransform(vertexFactory); - return TypecastRenderer.getOutlineShapes(this, string, pixelSize, transform, vertexFactory); + public float getLineHeight(float pixelSize) { + final Metrics metrics = getMetrics(); + final float lineGap = metrics.getLineGap(pixelSize) ; // negative value! + final float ascent = metrics.getAscent(pixelSize) ; // negative value! + final float descent = metrics.getDescent(pixelSize) ; // positive value! + final float advanceY = lineGap - descent + ascent; // negative value! + return -advanceY; } @Override public float getStringWidth(CharSequence string, float pixelSize) { float width = 0; final int len = string.length(); - for (int i=0; i< len; i++) - { - char character = string.charAt(i); + for (int i=0; i< len; i++) { + final char character = string.charAt(i); if (character == '\n') { width = 0; } else { @@ -246,7 +244,6 @@ class TypecastFont implements FontInt { width += glyph.getAdvance(pixelSize, false); } } - return (int)(width + 0.5f); } @@ -254,12 +251,10 @@ class TypecastFont implements FontInt { public float getStringHeight(CharSequence string, float pixelSize) { int height = 0; - for (int i=0; i<string.length(); i++) - { - char character = string.charAt(i); - if (character != ' ') - { - Glyph glyph = getGlyph(character); + for (int i=0; i<string.length(); i++) { + final char character = string.charAt(i); + if (character != ' ') { + final Glyph glyph = getGlyph(character); AABBox bbox = glyph.getBBox(pixelSize); height = (int)Math.ceil(Math.max(bbox.getHeight(), height)); } @@ -272,11 +267,8 @@ class TypecastFont implements FontInt { if (string == null) { return new AABBox(); } - final Metrics metrics = getMetrics(); - final float lineGap = metrics.getLineGap(pixelSize); - final float ascent = metrics.getAscent(pixelSize); - final float descent = metrics.getDescent(pixelSize); - final float advanceY = lineGap - descent + ascent; + final float lineHeight = getLineHeight(pixelSize); + float totalHeight = 0; float totalWidth = 0; float curLineWidth = 0; @@ -285,14 +277,14 @@ class TypecastFont implements FontInt { if (character == '\n') { totalWidth = Math.max(curLineWidth, totalWidth); curLineWidth = 0; - totalHeight -= advanceY; + totalHeight += lineHeight; continue; } Glyph glyph = getGlyph(character); curLineWidth += glyph.getAdvance(pixelSize, true); } if (curLineWidth > 0) { - totalHeight -= advanceY; + totalHeight += lineHeight; totalWidth = Math.max(curLineWidth, totalWidth); } return new AABBox(0, 0, 0, totalWidth, totalHeight,0); diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java index 574aeb86d..82971848e 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java @@ -29,18 +29,15 @@ package jogamp.graph.font.typecast; import java.util.HashMap; -import jogamp.graph.font.FontInt; -import jogamp.graph.geom.plane.AffineTransform; -import jogamp.graph.geom.plane.Path2D; - +import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; import com.jogamp.opengl.math.geom.AABBox; -public class TypecastGlyph implements FontInt.GlyphInt { +public class TypecastGlyph implements Font.Glyph { public class Advance { - final Font font; - final float advance; + private final Font font; + private final float advance; HashMap<Float, Float> size2advance = new HashMap<Float, Float>(); public Advance(Font font, float advance) @@ -65,7 +62,7 @@ public class TypecastGlyph implements FontInt.GlyphInt { public float get(float size, boolean useFrationalMetrics) { - Float fo = size2advance.get(size); + final Float fo = size2advance.get(size); if(null == fo) { float value = (this.advance * getScale(size)); if (useFrationalMetrics == false) { @@ -90,8 +87,8 @@ public class TypecastGlyph implements FontInt.GlyphInt { public class Metrics { - AABBox bbox; - Advance advance; + private final AABBox bbox; + private final Advance advance; public Metrics(Font font, AABBox bbox, float advance) { @@ -136,105 +133,86 @@ public class TypecastGlyph implements FontInt.GlyphInt { public static final short MAX_ID = (short)((1 << 16) - 2); private final Font font; + private final char symbol; + private final OutlineShape shape; // in EM units + private final short id; + private final int advance; + private final Metrics metrics; - char symbol; - short id; - int advance; - Metrics metrics; - - protected Path2D path; // in EM units - protected Path2D pathSized; - protected float numberSized; - - protected TypecastGlyph(Font font, char symbol) { - this.font = font; - this.symbol = symbol; - } - - protected TypecastGlyph(Font font, - char symbol, short id, AABBox bbox, int advance, Path2D path) { + protected TypecastGlyph(Font font, char symbol, short id, AABBox bbox, int advance, OutlineShape shape) { this.font = font; this.symbol = symbol; - this.advance = advance; - - init(id, bbox, advance); - - this.path = path; - this.pathSized = null; - this.numberSized = 0.0f; - } - - void init(short id, AABBox bbox, int advance) { + this.shape = shape; this.id = id; this.advance = advance; this.metrics = new Metrics(this.font, bbox, this.advance); } + /** public void reset(Path2D path) { this.path = path; this.metrics.reset(); - } + } */ @Override - public Font getFont() { + public final Font getFont() { return this.font; } @Override - public char getSymbol() { + public final char getSymbol() { return this.symbol; } - AABBox getBBoxUnsized() { + final AABBox getBBoxUnsized() { return this.metrics.getBBox(); } - public AABBox getBBox() { + @Override + public final AABBox getBBox() { return this.metrics.getBBox(); } - public Metrics getMetrics() { + public final Metrics getMetrics() { return this.metrics; } - public short getID() { + @Override + public final short getID() { return this.id; } - public float getScale(float pixelSize) { + @Override + public final float getScale(float pixelSize) { return this.metrics.getScale(pixelSize); } @Override - public AABBox getBBox(float pixelSize) { + public final AABBox getBBox(float pixelSize) { final float size = getScale(pixelSize); AABBox newBox = getBBox().clone(); newBox.scale(size); return newBox; } - protected void addAdvance(float advance, float size) { + protected final void addAdvance(float advance, float size) { this.metrics.addAdvance(advance, size); } @Override - public float getAdvance(float pixelSize, boolean useFrationalMetrics) { + public final float getAdvance(float pixelSize, boolean useFrationalMetrics) { return this.metrics.getAdvance(pixelSize, useFrationalMetrics); } @Override - public Path2D getPath() { - return this.path; + public final OutlineShape getShape() { + return this.shape; } @Override - public Path2D getPath(float pixelSize) { - final float size = getScale(pixelSize); - - if (this.numberSized != size) { - this.numberSized = size; - this.pathSized = AffineTransform.getScaleInstance(null, size, size).createTransformedShape(getPath()); - } - return this.pathSized; + public final int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + font.getName(Font.NAME_UNIQUNAME).hashCode(); + return ((hash << 5) - hash) + id; } } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java index ecc41e438..7efad5fb0 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java @@ -50,7 +50,7 @@ class TypecastHMetrics implements Metrics { headTable = this.fontImpl.font.getHeadTable(); hheaTable = this.fontImpl.font.getHheaTable(); // vheaTable = this.fontImpl.font.getVheaTable(); - unitsPerEM_Inv = 1.0f / ( (float) headTable.getUnitsPerEm() ); + unitsPerEM_Inv = 1.0f / ( headTable.getUnitsPerEm() ); int maxWidth = headTable.getXMax() - headTable.getXMin(); int maxHeight = headTable.getYMax() - headTable.getYMin(); diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java index 127e260ca..1f7134e14 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java @@ -27,196 +27,155 @@ */ package jogamp.graph.font.typecast; -import java.util.ArrayList; - -import jogamp.graph.font.FontInt.GlyphInt; import jogamp.graph.font.typecast.ot.OTGlyph; import jogamp.graph.font.typecast.ot.Point; -import jogamp.graph.geom.plane.AffineTransform; -import jogamp.graph.geom.plane.Path2D; -import jogamp.graph.geom.plane.PathIterator; import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.font.Font; -import com.jogamp.graph.font.Font.Glyph; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; /** - * Factory to build a {@link com.jogamp.graph.geom.Path2D Path2D} from + * Factory to build an {@link OutlineShape} from * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}s. + * + * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html */ public class TypecastRenderer { + private static final boolean DEBUG = false; - private static void getPaths(TypecastFont font, - CharSequence string, float pixelSize, AffineTransform transform, Path2D[] p) - { - if (string == null) { - return; - } - Font.Metrics metrics = font.getMetrics(); - float advanceTotal = 0; - float lineGap = metrics.getLineGap(pixelSize) ; - float ascent = metrics.getAscent(pixelSize) ; - float descent = metrics.getDescent(pixelSize) ; - if (transform == null) { - transform = new AffineTransform(); - } - AffineTransform t = new AffineTransform(); - - float advanceY = lineGap - descent + ascent; - float y = 0; - for (int i=0; i<string.length(); i++) - { - p[i] = new Path2D(); - p[i].reset(); - t.setTransform(transform); - char character = string.charAt(i); - if (character == '\n') { - y += advanceY; - advanceTotal = 0; - continue; - } else if (character == ' ') { - advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE, pixelSize); - continue; - } - Glyph glyph = font.getGlyph(character); - Path2D gp = ((GlyphInt)glyph).getPath(); - float scale = metrics.getScale(pixelSize); - t.translate(advanceTotal, y); - t.scale(scale, scale); - p[i].append(gp.iterator(t), false); - advanceTotal += glyph.getAdvance(pixelSize, true); - } + private static void addShapeMoveTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1) { + shape.closeLastOutline(); + shape.addEmptyOutline(); + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, true)); // p1.onCurve)); } - - public static ArrayList<OutlineShape> getOutlineShapes(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory<? extends Vertex> vertexFactory) { - Path2D[] paths = new Path2D[string.length()]; - getPaths(font, string, pixelSize, transform, paths); - - ArrayList<OutlineShape> shapes = new ArrayList<OutlineShape>(); - final int numGlyps = paths.length; - for (int index=0;index<numGlyps;index++) { - if(paths[index] == null){ - continue; - } - OutlineShape shape = new OutlineShape(vertexFactory); - shapes.add(shape); - PathIterator iterator = paths[index].iterator(transform); - if(null != iterator){ - while(!iterator.isDone()){ - float[] coords = new float[6]; - int segmentType = iterator.currentSegment(coords); - addPathVertexToOutline(shape, vertexFactory, coords, segmentType); - iterator.next(); - } - } - } - return shapes; + private static void addShapeLineTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1) { + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, true)); // p1.onCurve)); } - private static void addPathVertexToOutline(OutlineShape shape, Factory<? extends Vertex> vertexFactory, float[] coords, int segmentType){ - switch(segmentType) { - case PathIterator.SEG_MOVETO: - shape.closeLastOutline(); - shape.addEmptyOutline(); - shape.addVertex(0, vertexFactory.create(coords, 0, 2, true)); - break; - case PathIterator.SEG_LINETO: - shape.addVertex(0, vertexFactory.create(coords, 0, 2, true)); - break; - case PathIterator.SEG_QUADTO: - shape.addVertex(0, vertexFactory.create(coords, 0, 2, false)); - shape.addVertex(0, vertexFactory.create(coords, 2, 2, true)); - break; - case PathIterator.SEG_CUBICTO: - shape.addVertex(0, vertexFactory.create(coords, 0, 2, false)); - shape.addVertex(0, vertexFactory.create(coords, 2, 2, false)); - shape.addVertex(0, vertexFactory.create(coords, 4, 2, true)); - break; - case PathIterator.SEG_CLOSE: - shape.closeLastOutline(); - break; - default: - throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType); - } + private static void addShapeQuadTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1, Point p2) { + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, false)); // p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2.x, p2.y, 0, true)); // p2.onCurve)); + } + private static void addShapeQuadTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1, float p2x, float p2y, boolean p2OnCurve) { + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, false)); // p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2x, p2y, 0, true)); // p2OnCurve)); } - /** - * Build a {@link com.jogamp.graph.geom.Path2D Path2D} from a - * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}. This glyph path can then - * be transformed and rendered. - */ - public static Path2D buildPath(OTGlyph glyph) { + private static void addShapeCubicTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1, Point p2, Point p3) { + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, false)); // p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2.x, p2.y, 0, false)); // p2.onCurve)); + shape.addVertex(0, vertexFactory.create(p3.x, p3.y, 0, true)); // p3.onCurve)); + // shape.addVertex(0, vertexFactory.create(coords, 0, 2, false)); + // shape.addVertex(0, vertexFactory.create(coords, 2, 2, false)); + // shape.addVertex(0, vertexFactory.create(coords, 4, 2, true)); + } + private static void addShapeClose(final OutlineShape shape, Factory<? extends Vertex> vertexFactory) { + shape.closeLastOutline(); + } + */ + + public static OutlineShape buildShape(char symbol, OTGlyph glyph, Factory<? extends Vertex> vertexFactory) { + // + // See Typecast: GlyphPathFactory.addContourToPath(..) + // if (glyph == null) { return null; } - Path2D glyphPath = new Path2D(); + final OutlineShape shape = new OutlineShape(vertexFactory); // Iterate through all of the points in the glyph. Each time we find a // contour end point, add the point range to the path. - int firstIndex = 0; + int startIndex = 0; int count = 0; for (int i = 0; i < glyph.getPointCount(); i++) { count++; - if (glyph.getPoint(i).endOfContour) { - addContourToPath(glyphPath, glyph, firstIndex, count); - firstIndex = i + 1; - count = 0; - } - } - return glyphPath; - } - - private static void addContourToPath(Path2D gp, OTGlyph glyph, int startIndex, int count) { - int offset = 0; - while (offset < count) { - Point point = glyph.getPoint(startIndex + offset%count); - Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count); - Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count); - if(offset == 0) - { - gp.moveTo(point.x, point.y); - } + if ( glyph.getPoint(i).endOfContour ) { + int offset = 0; + while (offset < count) { + final Point point = glyph.getPoint(startIndex + offset%count); + final Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count); + final Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count); + if( DEBUG ) { + final Point point_minus1 = glyph.getPoint((offset==0) ? startIndex+count-1 : startIndex+(offset-1)%count); + System.err.println("GlyphShape<"+symbol+">: "+count+" points, offset "+offset); + System.err.println("\t p-1 "+point_minus1); + System.err.println("\t p0 "+point); + System.err.println("\t p1 "+point_plus1); + System.err.println("\t p2 "+point_plus2); + } + if(offset == 0) + { + addShapeMoveTo(shape, vertexFactory, point); + // gp.moveTo(point.x, point.y); + } - if (point.onCurve) { - if (point_plus1.onCurve) { - // s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y); - gp.lineTo( point_plus1.x, point_plus1.y ); - offset++; - } else { - if (point_plus2.onCurve) { - // s = new QuadCurve2D.Float( point.x, point.y, point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y); - gp.quadTo(point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y); - offset+=2; + if (point.onCurve) { + if (point_plus1.onCurve) { + // Branch-1: point.onCurve && point_plus1.onCurve + if( DEBUG ) { System.err.println("B1 .. line-to p0-p1"); } + + // s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y); + // gp.lineTo( point_plus1.x, point_plus1.y ); + addShapeLineTo(shape, vertexFactory, point_plus1); + offset++; + } else { + if (point_plus2.onCurve) { + // Branch-2: point.onCurve && !point_plus1.onCurve && point_plus2.onCurve + if( DEBUG ) { System.err.println("B2 .. quad-to p0-p1-p2"); } + + // s = new QuadCurve2D.Float( point.x, point.y, point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y); + // gp.quadTo(point_plus1.x, point_plus1.y, point_plus2.x, point_plus2.y); + addShapeQuadTo(shape, vertexFactory, point_plus1, point_plus2); + offset+=2; + } else { + // Branch-3: point.onCurve && !point_plus1.onCurve && !point_plus2.onCurve + if( DEBUG ) { System.err.println("B3 .. quad-to p0-p1-p2h **** MID"); } + + // s = new QuadCurve2D.Float(point.x,point.y,point_plus1.x,point_plus1.y, + // midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y)); + // gp.quadTo(point_plus1.x, point_plus1.y, midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y)); + addShapeQuadTo(shape, vertexFactory, point_plus1, + midValue(point_plus1.x, point_plus2.x), + midValue(point_plus1.y, point_plus2.y), false); + // offset++; // Don't skip point_plus2, not completed yet FIXME ? + offset+=2; // As done in Typecast + } + } } else { - // s = new QuadCurve2D.Float(point.x,point.y,point_plus1.x,point_plus1.y, - // midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y)); - gp.quadTo(point_plus1.x, point_plus1.y, midValue(point_plus1.x, point_plus2.x), midValue(point_plus1.y, point_plus2.y)); - offset+=2; + if (!point_plus1.onCurve) { + // Branch-4: !point.onCurve && !point_plus1.onCurve + if( DEBUG ) { System.err.println("B4 .. quad-to pM-p0-p1h ***** MID"); } + // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), + // point.x, point.y, + // midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y)); + addShapeQuadTo(shape, vertexFactory, point, + midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y), false); + offset++; + } else { + // Branch-5: !point.onCurve && point_plus1.onCurve + if( DEBUG ) { System.err.println("B5 .. quad-to pM-p0-p1"); } + // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), + // point.x, point.y, point_plus1.x, point_plus1.y); + // gp.quadTo(point.x, point.y, point_plus1.x, point_plus1.y); + addShapeQuadTo(shape, vertexFactory, point, point_plus1); + offset++; + } } } - } else { - if (point_plus1.onCurve) { - // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), - // point.x, point.y, point_plus1.x, point_plus1.y); - //gp.curve3(point_plus1.x, point_plus1.y, point.x, point.y); - gp.quadTo(point.x, point.y, point_plus1.x, point_plus1.y); - offset++; - - } else { - // s = new QuadCurve2D.Float(midValue(point_minus1.x, point.x), midValue(point_minus1.y, point.y), point.x, point.y, - // midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y)); - //gp.curve3(midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y), point.x, point.y); - gp.quadTo(point.x, point.y, midValue(point.x, point_plus1.x), midValue(point.y, point_plus1.y)); - offset++; - } + startIndex = i + 1; + count = 0; } } + shape.closeLastOutline(); + return shape; } - private static int midValue(int a, int b) { - return a + (b - a)/2; + private static float midValue(float a, float b) { + return a + (b - a)/2f; } + /** + private static Point midPoint(Point a, Point b, boolean onCurve) { + return new Point(midValue(a.x, b.x), midValue(a.y, b.y), onCurve, false); + } */ } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/ot/Point.java b/src/jogl/classes/jogamp/graph/font/typecast/ot/Point.java index f1a090d68..0cac8ab44 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/ot/Point.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/ot/Point.java @@ -18,7 +18,6 @@ public class Point { public int y = 0; public boolean onCurve = true; public boolean endOfContour = false; - public boolean touched = false; public Point(int x, int y, boolean onCurve, boolean endOfContour) { this.x = x; @@ -26,4 +25,8 @@ public class Point { this.onCurve = onCurve; this.endOfContour = endOfContour; } + + public String toString() { + return "P["+x+"/"+y+", on "+onCurve+", end "+endOfContour+"]"; + } } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/t2/T2Interpreter.java b/src/jogl/classes/jogamp/graph/font/typecast/t2/T2Interpreter.java index 181ec7e10..73f26b27c 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/t2/T2Interpreter.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/t2/T2Interpreter.java @@ -39,11 +39,11 @@ public class T2Interpreter { private static final int SUBR_STACK_LIMIT = 10; private static final int TRANSIENT_ARRAY_ELEMENT_COUNT = 32; - private Number[] _argStack = new Number[ARGUMENT_STACK_LIMIT]; + private final Number[] _argStack = new Number[ARGUMENT_STACK_LIMIT]; private int _argStackIndex = 0; - private int[] _subrStack = new int[SUBR_STACK_LIMIT]; + private final int[] _subrStack = new int[SUBR_STACK_LIMIT]; private int _subrStackIndex = 0; - private Number[] _transientArray = new Number[TRANSIENT_ARRAY_ELEMENT_COUNT]; + private final Number[] _transientArray = new Number[TRANSIENT_ARRAY_ELEMENT_COUNT]; private ArrayList<Point> _points; diff --git a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java index 32e2b6a39..5953ea89b 100644 --- a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java @@ -121,6 +121,8 @@ public class AffineTransform implements Cloneable, Serializable { } } + public final Vertex.Factory<? extends Vertex> getFactory() { return pointFactory; } + /* * Method returns type of affine transformation. * @@ -401,33 +403,45 @@ public class AffineTransform implements Cloneable, Serializable { ); } - public Vertex transform(Vertex src, Vertex dst) { + public final Vertex transform(final Vertex src, Vertex dst) { if (dst == null) { - dst = pointFactory.create(); + dst = pointFactory.create(src.getId(), src.isOnCurve(), src.getTexCoord()); } - - float x = src.getX(); - float y = src.getY(); - - dst.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, 0f); + final float x = src.getX(); + final float y = src.getY(); + dst.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, src.getZ()); return dst; } - public void transform(Vertex[] src, int srcOff, Vertex[] dst, int dstOff, int length) { + public final void transform(Vertex[] src, int srcOff, Vertex[] dst, int dstOff, int length) { while (--length >= 0) { Vertex srcPoint = src[srcOff++]; - float x = srcPoint.getX(); - float y = srcPoint.getY(); Vertex dstPoint = dst[dstOff]; if (dstPoint == null) { throw new IllegalArgumentException("dst["+dstOff+"] is null"); } - dstPoint.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, 0f); + final float x = srcPoint.getX(); + final float y = srcPoint.getY(); + dstPoint.setCoord(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12, srcPoint.getZ()); dst[dstOff++] = dstPoint; } } - public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) { + public final void transform(final float[] src, final float[] dst) { + final float x = src[0]; + final float y = src[1]; + dst[0] = x * m00 + y * m01 + m02; + dst[1] = x * m10 + y * m11 + m12; + } + + public final void transform(final float[] src, final int srcOff, final float[] dst, final int dstOff) { + final float x = src[srcOff + 0]; + final float y = src[srcOff + 1]; + dst[dstOff + 0] = x * m00 + y * m01 + m02; + dst[dstOff + 1] = x * m10 + y * m11 + m12; + } + + public final void transform(final float[] src, int srcOff, final float[] dst, int dstOff, int length) { int step = 2; if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) { srcOff = srcOff + length * 2 - 2; @@ -435,8 +449,8 @@ public class AffineTransform implements Cloneable, Serializable { step = -2; } while (--length >= 0) { - float x = src[srcOff + 0]; - float y = src[srcOff + 1]; + final float x = src[srcOff + 0]; + final float y = src[srcOff + 1]; dst[dstOff + 0] = x * m00 + y * m01 + m02; dst[dstOff + 1] = x * m10 + y * m11 + m12; srcOff += step; @@ -446,13 +460,11 @@ public class AffineTransform implements Cloneable, Serializable { public Vertex deltaTransform(Vertex src, Vertex dst) { if (dst == null) { - dst = pointFactory.create(); + dst = pointFactory.create(src.getId(), src.isOnCurve(), src.getTexCoord()); } - - float x = src.getX(); - float y = src.getY(); - - dst.setCoord(x * m00 + y * m01, x * m10 + y * m11, 0f); + final float x = src.getX(); + final float y = src.getY(); + dst.setCoord(x * m00 + y * m01, x * m10 + y * m11, src.getZ()); return dst; } @@ -471,13 +483,11 @@ public class AffineTransform implements Cloneable, Serializable { throw new NoninvertibleTransformException(determinantIsZero); } if (dst == null) { - dst = pointFactory.create(); + dst = pointFactory.create(src.getId(), src.isOnCurve(), src.getTexCoord()); } - - float x = src.getX() - m02; - float y = src.getY() - m12; - - dst.setCoord((x * m11 - y * m01) / det, (y * m00 - x * m10) / det, 0f); + final float x = src.getX() - m02; + final float y = src.getY() - m12; + dst.setCoord((x * m11 - y * m01) / det, (y * m00 - x * m10) / det, src.getZ()); return dst; } @@ -502,7 +512,7 @@ public class AffineTransform implements Cloneable, Serializable { return null; } if (src instanceof Path2D) { - return ((Path2D)src).createTransformedShape(this); + return src.createTransformedShape(this); } PathIterator path = src.iterator(this); Path2D dst = new Path2D(path.getWindingRule()); diff --git a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java index 33b80d6b8..a87c0a0a1 100644 --- a/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java +++ b/src/jogl/classes/jogamp/graph/geom/plane/Path2D.java @@ -21,8 +21,8 @@ package jogamp.graph.geom.plane; import java.util.NoSuchElementException; +import com.jogamp.graph.geom.SVertex; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.opengl.SVertex; import com.jogamp.opengl.math.geom.AABBox; |