diff options
Diffstat (limited to 'src/jogl/classes/jogamp')
31 files changed, 1667 insertions, 1614 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..e50caa663 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); + public RegionRendererImpl01(final RenderState rs, final int renderModes, final GLCallback enableCallback, final GLCallback disableCallback) { + super(rs, renderModes, enableCallback, disableCallback); } @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 deleted file mode 100644 index 77c862ed4..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java +++ /dev/null @@ -1,343 +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 java.nio.FloatBuffer; - -import javax.media.opengl.GL2ES2; -// FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER ! -import javax.media.opengl.GL; -import javax.media.opengl.GLUniformData; -import javax.media.opengl.fixedfunc.GLMatrixFunc; - -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.RenderState; -import com.jogamp.opengl.FBObject; -import com.jogamp.opengl.FBObject.Attachment; -import com.jogamp.opengl.FBObject.TextureAttachment; -import com.jogamp.opengl.util.GLArrayDataServer; -import com.jogamp.opengl.util.PMVMatrix; -import com.jogamp.opengl.util.glsl.ShaderState; - -public class VBORegion2PES2 extends GLRegion { - private GLArrayDataServer verticeTxtAttr; - private GLArrayDataServer texCoordTxtAttr; - private GLArrayDataServer indicesTxt; - private GLArrayDataServer verticeFboAttr; - private GLArrayDataServer texCoordFboAttr; - private GLArrayDataServer indicesFbo; - - - private FBObject fbo; - private TextureAttachment texA; - private PMVMatrix fboPMVMatrix; - GLUniformData mgl_fboPMVMatrix; - - private int tex_width_c = 0; - private int tex_height_c = 0; - GLUniformData mgl_ActiveTexture; - GLUniformData mgl_TextureSize; // if GLSL < 1.30 - - public VBORegion2PES2(int renderModes, int textureEngine) { - super(renderModes); - fboPMVMatrix = new PMVMatrix(); - mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf()); - mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine); - } - - @Override - public void update(GL2ES2 gl, RenderState rs) { - if(!isDirty()) { - return; - } - - if(null == indicesFbo) { - final int initialElementCount = 256; - final ShaderState st = rs.getShaderState(); - - indicesFbo = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, 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); - st.ownAttribute(texCoordFboAttr, true); - texCoordFboAttr.putf(5); texCoordFboAttr.putf(5); - texCoordFboAttr.putf(5); texCoordFboAttr.putf(6); - texCoordFboAttr.putf(6); texCoordFboAttr.putf(6); - texCoordFboAttr.putf(6); texCoordFboAttr.putf(5); - texCoordFboAttr.seal(true); - - verticeFboAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, - false, initialElementCount, 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]); - } - texCoordTxtAttr.seal(gl, true); - texCoordTxtAttr.enableBuffer(gl, false); - verticeTxtAttr.seal(gl, true); - verticeTxtAttr.enableBuffer(gl, false); - - // update all bbox related data - verticeFboAttr.seal(gl, false); - verticeFboAttr.rewind(); - verticeFboAttr.putf(box.getLow()[0]); verticeFboAttr.putf(box.getLow()[1]); verticeFboAttr.putf(box.getLow()[2]); - verticeFboAttr.putf(box.getLow()[0]); verticeFboAttr.putf(box.getHigh()[1]); verticeFboAttr.putf(box.getLow()[2]); - verticeFboAttr.putf(box.getHigh()[0]); verticeFboAttr.putf(box.getHigh()[1]); verticeFboAttr.putf(box.getLow()[2]); - verticeFboAttr.putf(box.getHigh()[0]); verticeFboAttr.putf(box.getLow()[1]); verticeFboAttr.putf(box.getLow()[2]); - verticeFboAttr.seal(gl, true); - verticeFboAttr.enableBuffer(gl, false); - - fboPMVMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - fboPMVMatrix.glLoadIdentity(); - fboPMVMatrix.glOrthof(box.getLow()[0], box.getHigh()[0], box.getLow()[1], box.getHigh()[1], -1, 1); - - // 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 } ; - - @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){ - renderRegion(gl); - } else { - if(0 > maxTexSize[0]) { - gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxTexSize, 0); - } - if(texWidth[0] != tex_width_c) { - if(texWidth[0] > maxTexSize[0]) { - texWidth[0] = maxTexSize[0]; // clip to max - write-back user value! - } - 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); - } - } - - private void renderFBO(GL2ES2 gl, RenderState rs, int width, int hight) { - final ShaderState st = rs.getShaderState(); - - gl.glViewport(0, 0, width, hight); - st.uniform(gl, mgl_ActiveTexture); - gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue()); - fbo.use(gl, texA); - verticeFboAttr.enableBuffer(gl, true); - texCoordFboAttr.enableBuffer(gl, true); - indicesFbo.bindBuffer(gl, true); // keeps VBO binding - - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); - - indicesFbo.bindBuffer(gl, false); - texCoordFboAttr.enableBuffer(gl, false); - verticeFboAttr.enableBuffer(gl, false); - fbo.unuse(gl); - - // setback: gl.glActiveTexture(currentActiveTextureEngine[0]); - } - - private void renderRegion2FBO(GL2ES2 gl, RenderState rs, int[/*1*/] texWidth) { - final ShaderState st = rs.getShaderState(); - - if(0>=texWidth[0]) { - throw new IllegalArgumentException("texWidth must be greater than 0: "+texWidth[0]); - } - - tex_width_c = texWidth[0]; - tex_height_c = (int) ( ( ( tex_width_c * box.getHeight() ) / box.getWidth() ) + 0.5f ); - - // System.out.println("FBO Size: "+texWidth[0]+" -> "+tex_width_c+"x"+tex_height_c); - // System.out.println("FBO Scale: " + m.glGetMatrixf().get(0) +" " + m.glGetMatrixf().get(5)); - - if(null != fbo && fbo.getWidth() != tex_width_c && fbo.getHeight() != tex_height_c ) { - fbo.reset(gl, tex_width_c, tex_height_c); - } - - if(null == fbo) { - fbo = new FBObject(); - fbo.reset(gl, tex_width_c, tex_height_c); - // FIXME: shall not use bilinear, due to own AA ? However, w/o bilinear result is not smooth - texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); - // texA = fbo.attachTexture2D(gl, 0, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); - fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); - } else { - fbo.bind(gl); - } - - //render texture - gl.glViewport(0, 0, tex_width_c, tex_height_c); - st.uniform(gl, mgl_fboPMVMatrix); // use orthogonal matrix - - gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT); - renderRegion(gl); - fbo.unbind(gl); - - st.uniform(gl, rs.getPMVMatrix()); // switch back to real PMV matrix - - // if( !gl.isGL3() ) { - // GLSL < 1.30 - if(null == mgl_TextureSize) { - 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()); - st.uniform(gl, mgl_TextureSize); - //} - } - - private void renderRegion(GL2ES2 gl) { - verticeTxtAttr.enableBuffer(gl, true); - texCoordTxtAttr.enableBuffer(gl, true); - indicesTxt.bindBuffer(gl, true); // keeps VBO binding - - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); - - indicesTxt.bindBuffer(gl, false); - texCoordTxtAttr.enableBuffer(gl, false); - verticeTxtAttr.enableBuffer(gl, false); - } - - @Override - public void destroy(GL2ES2 gl, RenderState rs) { - if(DEBUG_INSTANCE) { - System.err.println("VBORegion2PES2 Destroy: " + this); - } - final ShaderState st = rs.getShaderState(); - if(null != fbo) { - fbo.destroy(gl); - fbo = null; - texA = null; - } - if(null != verticeTxtAttr) { - st.ownAttribute(verticeTxtAttr, false); - verticeTxtAttr.destroy(gl); - verticeTxtAttr = null; - } - if(null != texCoordTxtAttr) { - st.ownAttribute(texCoordTxtAttr, false); - texCoordTxtAttr.destroy(gl); - texCoordTxtAttr = null; - } - if(null != indicesTxt) { - indicesTxt.destroy(gl); - indicesTxt = null; - } - if(null != verticeFboAttr) { - st.ownAttribute(verticeFboAttr, false); - verticeFboAttr.destroy(gl); - verticeFboAttr = null; - } - if(null != texCoordFboAttr) { - st.ownAttribute(texCoordFboAttr, false); - texCoordFboAttr.destroy(gl); - texCoordFboAttr = null; - } - if(null != indicesFbo) { - indicesFbo.destroy(gl); - indicesFbo = null; - } - triangles.clear(); - vertices.clear(); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java new file mode 100644 index 000000000..176b39c25 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -0,0 +1,411 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; + +import javax.media.opengl.GL2ES2; +// FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER ! +import javax.media.opengl.GL; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import jogamp.graph.curve.opengl.shader.AttributeNames; +import jogamp.graph.curve.opengl.shader.UniformNames; + +import com.jogamp.common.nio.Buffers; +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.opengl.FBObject; +import com.jogamp.opengl.FBObject.Attachment; +import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.GLArrayDataServer; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class VBORegion2PMSAAES2 extends GLRegion { + private static final boolean DEBUG_FBO_1 = false; + private static final boolean DEBUG_FBO_2 = false; + private GLArrayDataServer verticeTxtAttr; + private GLArrayDataServer texCoordTxtAttr; + private GLArrayDataServer indicesTxtBuffer; + private GLArrayDataServer verticeFboAttr; + private GLArrayDataServer texCoordFboAttr; + private GLArrayDataServer indicesFbo; + + private FBObject fbo; + private final PMVMatrix fboPMVMatrix; + GLUniformData mgl_fboPMVMatrix; + + private int fboWidth = 0; + private int fboHeight = 0; + GLUniformData mgl_ActiveTexture; + GLUniformData mgl_TextureSize; + + final int[] maxTexSize = new int[] { -1 } ; + + public VBORegion2PMSAAES2(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, 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 + 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 ShaderState st = renderer.getShaderState(); + + 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, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(texCoordFboAttr, true); + texCoordFboAttr.putf(0); texCoordFboAttr.putf(0); + texCoordFboAttr.putf(0); texCoordFboAttr.putf(1); + texCoordFboAttr.putf(1); texCoordFboAttr.putf(1); + texCoordFboAttr.putf(1); texCoordFboAttr.putf(0); + texCoordFboAttr.seal(true); + + verticeFboAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(verticeFboAttr, true); + + st.ownAttribute(verticeTxtAttr, true); + st.ownAttribute(texCoordTxtAttr, true); + + if(Region.DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Create: " + this); + } + } + // seal buffers + indicesTxtBuffer.seal(gl, true); + indicesTxtBuffer.enableBuffer(gl, false); + texCoordTxtAttr.seal(gl, true); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.seal(gl, true); + verticeTxtAttr.enableBuffer(gl, false); + + // update all bbox related data + verticeFboAttr.seal(gl, false); + verticeFboAttr.rewind(); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMaxY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()); verticeFboAttr.putf(box.getMaxY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.seal(gl, true); + verticeFboAttr.enableBuffer(gl, false); + + fboPMVMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + fboPMVMatrix.glLoadIdentity(); + fboPMVMatrix.glOrthof(box.getMinX(), box.getMaxX(), box.getMinY(), box.getMaxY(), -1, 1); + + // push data 2 GPU .. + indicesFbo.seal(gl, true); + indicesFbo.enableBuffer(gl, false); + + // trigger renderRegion2FBO ! + fboHeight = 0; + fboWidth = 0; + // the buffers were disabled, since due to real/fbo switching and other vbo usage + } + + private final AABBox drawWinBox = new AABBox(); + private final int[] drawView = new int[] { 0, 0, 0, 0 }; + private final float[] drawTmpV3 = new float[3]; + + @Override + protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + final int width = renderer.getWidth(); + final int height = renderer.getHeight(); + if(width <=0 || height <= 0 || null==sampleCount || sampleCount[0] <= 0){ + renderRegion(gl); + } else { + if(0 > maxTexSize[0]) { + gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxTexSize, 0); + } + final RenderState rs = renderer.getRenderState(); + float renderFboWidth, renderFboHeight; + int targetFboWidth, targetFboHeight; + float diffWidth, diffHeight; + { + // Calculate perspective pixel width/height for FBO, + // considering the sampleCount. + drawView[2] = width; + drawView[3] = height; + box.mapToWindow(drawWinBox, renderer.getMatrix(), drawView, true /* useCenterZ */, drawTmpV3); + renderFboWidth = drawWinBox.getWidth(); + renderFboHeight = drawWinBox.getHeight(); + targetFboWidth = (int)Math.ceil(renderFboWidth); + targetFboHeight = (int)Math.ceil(renderFboHeight); + diffWidth = targetFboWidth-renderFboWidth; + diffHeight = targetFboHeight-renderFboHeight; + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.MinMax view[%d, %d]: FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n", + drawView[2], drawView[3], + renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight, + diffWidth, diffHeight, sampleCount[0]); + } + } + final int deltaFboWidth = Math.abs(targetFboWidth-fboWidth); + final int deltaFboHeight = Math.abs(targetFboHeight-fboHeight); + final int maxDeltaFbo, maxLengthFbo; + if( deltaFboWidth >= deltaFboHeight ) { + maxDeltaFbo = deltaFboWidth; + maxLengthFbo = fboWidth > 0 ? fboWidth : 1; + } else { + maxDeltaFbo = deltaFboHeight; + maxLengthFbo = fboHeight > 0 ? fboHeight : 1; + } + final float pctFboDelta = (float)maxDeltaFbo / (float)maxLengthFbo; + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); + } + if( pctFboDelta > 0.1f || ( fbo != null && fbo.getNumSamples() != sampleCount[0] ) ) { // more than 10% ! + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); + System.err.printf("XXX.MSAA %d, %d x %d%n", + sampleCount[0], targetFboWidth, targetFboHeight); + } + // FIXME: maxTexSize test not correct + boolean rescale = false; + if( targetFboWidth > maxTexSize[0] ) { + targetFboWidth = maxTexSize[0]; + renderFboWidth = targetFboWidth; + rescale = true; + } + if( targetFboHeight > maxTexSize[0] ) { + targetFboHeight = maxTexSize[0]; + renderFboHeight = targetFboHeight; + rescale = true; + } + if(rescale) { + diffWidth = targetFboWidth-renderFboWidth; + diffHeight = targetFboHeight-renderFboHeight; + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.Rescale (MAX): FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n", + renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight, + diffWidth, diffHeight, sampleCount[0]); + } + } + verticeFboAttr.seal(false); + verticeFboAttr.rewind(); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.seal(true); + fboPMVMatrix.glLoadIdentity(); + fboPMVMatrix.glOrthof(box.getMinX(), box.getMaxX()+diffWidth, + box.getMinY(), box.getMaxY()+diffHeight, -1, 1); + renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, sampleCount); + } else { + texCoordFboAttr.setVBOWritten(false); + } + // System.out.println("Scale: " + matrix.glGetMatrixf().get(1+4*3) +" " + matrix.glGetMatrixf().get(2+4*3)); + renderFBO(gl, rs, width, height); + } + } + private void setTexSize(final GL2ES2 gl, final ShaderState st, boolean firstPass) { + if(null == mgl_TextureSize) { + mgl_TextureSize = new GLUniformData(UniformNames.gcu_TextureSize, 3, Buffers.newDirectFloatBuffer(3)); + } + final FloatBuffer texSize = (FloatBuffer) mgl_TextureSize.getBuffer(); + if( firstPass ) { + texSize.put(2, 0f); + } else { + texSize.put(0, fboWidth); + texSize.put(1, fboHeight); + texSize.put(2, 1f); + } + st.uniform(gl, mgl_TextureSize); + } + + private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int height) { + final ShaderState st = rs.getShaderState(); + + gl.glViewport(0, 0, width, height); + st.uniform(gl, mgl_ActiveTexture); + gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue()); + setTexSize(gl, st, false); + + fbo.use(gl, fbo.getSamplingSink()); + verticeFboAttr.enableBuffer(gl, true); + texCoordFboAttr.enableBuffer(gl, true); + indicesFbo.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesFbo.bindBuffer(gl, false); + texCoordFboAttr.enableBuffer(gl, false); + verticeFboAttr.enableBuffer(gl, false); + fbo.unuse(gl); + + // setback: gl.glActiveTexture(currentActiveTextureEngine[0]); + } + + private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight, int[] sampleCount) { + final ShaderState st = rs.getShaderState(); + + if( 0 >= targetFboWidth || 0 >= targetFboHeight ) { + throw new IllegalArgumentException("fboSize must be greater than 0: "+targetFboWidth+"x"+targetFboHeight); + } + + if(null == fbo) { + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + fbo = new FBObject(); + fbo.reset(gl, fboWidth, fboHeight, sampleCount[0], false); + sampleCount[0] = fbo.getNumSamples(); + fbo.attachColorbuffer(gl, 0, true); + fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + final FBObject ssink = new FBObject(); + { + ssink.reset(gl, fboWidth, fboHeight); + // FIXME: shall not use bilinear (GL_LINEAR), due to MSAA ??? + // ssink.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + ssink.attachTexture2D(gl, 0, true, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + ssink.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + } + fbo.setSamplingSink(ssink); + fbo.resetSamplingSink(gl); // validate + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.createFBO: %dx%d%n%s%n", fboWidth, fboHeight, fbo.toString()); + } + } else if( targetFboWidth != fboWidth || targetFboHeight != fboHeight || fbo.getNumSamples() != sampleCount[0] ) { + fbo.reset(gl, targetFboWidth, targetFboHeight, sampleCount[0], true /* resetSamplingSink */); + sampleCount[0] = fbo.getNumSamples(); + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.resetFBO: %dx%d -> %dx%d%n%s%n", fboWidth, fboHeight, targetFboWidth, targetFboHeight, fbo ); + } + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + } + fbo.bind(gl); + setTexSize(gl, st, true); + + //render texture + gl.glViewport(0, 0, fboWidth, fboHeight); + st.uniform(gl, mgl_fboPMVMatrix); // use orthogonal matrix + + gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT); + renderRegion(gl); + fbo.unbind(gl); + + st.uniform(gl, rs.getPMVMatrix()); // switch back to real PMV matrix + } + + private void renderRegion(final GL2ES2 gl) { + verticeTxtAttr.enableBuffer(gl, true); + texCoordTxtAttr.enableBuffer(gl, true); + indicesTxtBuffer.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxtBuffer.getElementCount() * indicesTxtBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesTxtBuffer.bindBuffer(gl, false); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.enableBuffer(gl, false); + } + + @Override + protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { + if(DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Destroy: " + this); + } + final ShaderState st = renderer.getShaderState(); + if(null != fbo) { + fbo.destroy(gl); + fbo = null; + } + if(null != verticeTxtAttr) { + st.ownAttribute(verticeTxtAttr, false); + verticeTxtAttr.destroy(gl); + verticeTxtAttr = null; + } + if(null != texCoordTxtAttr) { + st.ownAttribute(texCoordTxtAttr, false); + texCoordTxtAttr.destroy(gl); + texCoordTxtAttr = null; + } + if(null != indicesTxtBuffer) { + indicesTxtBuffer.destroy(gl); + indicesTxtBuffer = null; + } + if(null != verticeFboAttr) { + st.ownAttribute(verticeFboAttr, false); + verticeFboAttr.destroy(gl); + verticeFboAttr = null; + } + if(null != texCoordFboAttr) { + st.ownAttribute(texCoordFboAttr, false); + texCoordFboAttr.destroy(gl); + texCoordFboAttr = null; + } + if(null != indicesFbo) { + indicesFbo.destroy(gl); + indicesFbo = null; + } + } +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java new file mode 100644 index 000000000..3f3709d6e --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -0,0 +1,408 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.graph.curve.opengl; + +import java.nio.FloatBuffer; + +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GL; +import javax.media.opengl.GLUniformData; +import javax.media.opengl.fixedfunc.GLMatrixFunc; + +import jogamp.graph.curve.opengl.shader.AttributeNames; +import jogamp.graph.curve.opengl.shader.UniformNames; + +import com.jogamp.common.nio.Buffers; +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.opengl.FBObject; +import com.jogamp.opengl.FBObject.Attachment; +import com.jogamp.opengl.FBObject.TextureAttachment; +import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.GLArrayDataServer; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderState; + +public class VBORegion2PVBAAES2 extends GLRegion { + private static final boolean DEBUG_FBO_1 = false; + private static final boolean DEBUG_FBO_2 = false; + private GLArrayDataServer verticeTxtAttr; + private GLArrayDataServer texCoordTxtAttr; + private GLArrayDataServer indicesTxtBuffer; + private GLArrayDataServer verticeFboAttr; + private GLArrayDataServer texCoordFboAttr; + private GLArrayDataServer indicesFbo; + + private FBObject fbo; + private TextureAttachment texA; + private final PMVMatrix fboPMVMatrix; + GLUniformData mgl_fboPMVMatrix; + + private int fboWidth = 0; + private int fboHeight = 0; + GLUniformData mgl_ActiveTexture; + GLUniformData mgl_TextureSize; + + final int[] maxTexSize = new int[] { -1 } ; + + public VBORegion2PVBAAES2(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, 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 + 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 ShaderState st = renderer.getShaderState(); + + 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, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(texCoordFboAttr, true); + texCoordFboAttr.putf(0); texCoordFboAttr.putf(0); + texCoordFboAttr.putf(0); texCoordFboAttr.putf(1); + texCoordFboAttr.putf(1); texCoordFboAttr.putf(1); + texCoordFboAttr.putf(1); texCoordFboAttr.putf(0); + texCoordFboAttr.seal(true); + + verticeFboAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, + false, 4, GL.GL_STATIC_DRAW); + st.ownAttribute(verticeFboAttr, true); + + st.ownAttribute(verticeTxtAttr, true); + st.ownAttribute(texCoordTxtAttr, true); + + if(Region.DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Create: " + this); + } + } + // seal buffers + indicesTxtBuffer.seal(gl, true); + indicesTxtBuffer.enableBuffer(gl, false); + texCoordTxtAttr.seal(gl, true); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.seal(gl, true); + verticeTxtAttr.enableBuffer(gl, false); + + // update all bbox related data + verticeFboAttr.seal(gl, false); + verticeFboAttr.rewind(); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMaxY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()); verticeFboAttr.putf(box.getMaxY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.seal(gl, true); + verticeFboAttr.enableBuffer(gl, false); + + fboPMVMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + fboPMVMatrix.glLoadIdentity(); + fboPMVMatrix.glOrthof(box.getMinX(), box.getMaxX(), box.getMinY(), box.getMaxY(), -1, 1); + + // push data 2 GPU .. + indicesFbo.seal(gl, true); + indicesFbo.enableBuffer(gl, false); + + // trigger renderRegion2FBO ! + fboHeight = 0; + fboWidth = 0; + // the buffers were disabled, since due to real/fbo switching and other vbo usage + } + + private final AABBox drawWinBox = new AABBox(); + private final int[] drawView = new int[] { 0, 0, 0, 0 }; + private final float[] drawTmpV3 = new float[3]; + + @Override + protected void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) { + final int width = renderer.getWidth(); + final int height = renderer.getHeight(); + if(width <=0 || height <= 0 || null==sampleCount || sampleCount[0] <= 0){ + renderRegion(gl); + } else { + if(0 > maxTexSize[0]) { + gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, maxTexSize, 0); + } + final RenderState rs = renderer.getRenderState(); + final float winWidth, winHeight; + int targetFboWidth, targetFboHeight; + float renderFboWidth, renderFboHeight; + float diffWidth, diffHeight; + { + // Calculate perspective pixel width/height for FBO, + // considering the sampleCount. + drawView[2] = width; + drawView[3] = height; + box.mapToWindow(drawWinBox, renderer.getMatrix(), drawView, true /* useCenterZ */, drawTmpV3); + winWidth = drawWinBox.getWidth(); + winHeight = drawWinBox.getHeight(); + diffWidth = (float)Math.ceil(winWidth)-winWidth; + diffHeight = (float)Math.ceil(winHeight)-winHeight; + renderFboWidth = winWidth*sampleCount[0]; + renderFboHeight = winHeight*sampleCount[0]; + targetFboWidth = (int)Math.ceil(renderFboWidth); + targetFboHeight = (int)Math.ceil(renderFboHeight); + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.MinMax1 view[%d, %d] -> win[%.3f, %.3f]: FBO f[%.3f, %.3f], i[%d x %d], d[%.3f, %.3f], msaa %d%n", + drawView[2], drawView[3], + winWidth, winHeight, + renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight, + diffWidth, diffHeight, sampleCount[0]); + } + } + final int deltaFboWidth = Math.abs(targetFboWidth-fboWidth); + final int deltaFboHeight = Math.abs(targetFboHeight-fboHeight); + final int maxDeltaFbo, maxLengthFbo; + if( deltaFboWidth >= deltaFboHeight ) { + maxDeltaFbo = deltaFboWidth; + maxLengthFbo = fboWidth > 0 ? fboWidth : 1; + } else { + maxDeltaFbo = deltaFboHeight; + maxLengthFbo = fboHeight > 0 ? fboHeight : 1; + } + final float pctFboDelta = (float)maxDeltaFbo / (float)maxLengthFbo; + if( DEBUG_FBO_2 ) { + System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); + } + if( pctFboDelta > 0.1f ) { // more than 10% ! + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.maxDelta: %d / %d = %.3f%n", maxDeltaFbo, maxLengthFbo, pctFboDelta); + System.err.printf("XXX.Scale %d * [%f x %f]: %d x %d%n", + sampleCount[0], winWidth, winHeight, targetFboWidth, targetFboHeight); + } + final int maxLength = Math.max(targetFboWidth, targetFboHeight); + if( maxLength > maxTexSize[0] ) { + if( targetFboWidth > targetFboHeight ) { + sampleCount[0] = (int)Math.floor(maxTexSize[0] / winWidth); + } else { + sampleCount[0] = (int)Math.floor(maxTexSize[0] / winHeight); + } + renderFboWidth = winWidth*sampleCount[0]; + renderFboHeight = winHeight*sampleCount[0]; + targetFboWidth = (int)Math.ceil(renderFboWidth); + targetFboHeight = (int)Math.ceil(renderFboHeight); + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.Rescale (MAX): win[%.3f, %.3f]: FBO f[%.3f, %.3f], i[%d x %d], msaa %d%n", + winWidth, winHeight, + renderFboWidth, renderFboHeight, targetFboWidth, targetFboHeight, sampleCount[0]); + } + if( sampleCount[0] <= 0 ) { + // Last way out! + renderRegion(gl); + return; + } + } + verticeFboAttr.seal(false); + verticeFboAttr.rewind(); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMinX()); verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMaxY()+diffHeight); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.putf(box.getMaxX()+diffWidth); verticeFboAttr.putf(box.getMinY()); verticeFboAttr.putf(box.getMinZ()); + verticeFboAttr.seal(true); + fboPMVMatrix.glLoadIdentity(); + fboPMVMatrix.glOrthof(box.getMinX(), box.getMaxX()+diffWidth, + box.getMinY(), box.getMaxY()+diffHeight, -1, 1); + renderRegion2FBO(gl, rs, targetFboWidth, targetFboHeight, sampleCount[0]); + } + // System.out.println("Scale: " + matrix.glGetMatrixf().get(1+4*3) +" " + matrix.glGetMatrixf().get(2+4*3)); + renderFBO(gl, rs, width, height, sampleCount[0]); + } + } + private void setTexSize(final GL2ES2 gl, final ShaderState st, boolean firstPass, int sampleCount) { + if(null == mgl_TextureSize) { + mgl_TextureSize = new GLUniformData(UniformNames.gcu_TextureSize, 3, Buffers.newDirectFloatBuffer(3)); + } + final FloatBuffer texSize = (FloatBuffer) mgl_TextureSize.getBuffer(); + if( firstPass ) { + texSize.put(2, 0f); + } else { + texSize.put(0, fboWidth); + texSize.put(1, fboHeight); + texSize.put(2, sampleCount); + } + st.uniform(gl, mgl_TextureSize); + } + + private void renderFBO(final GL2ES2 gl, final RenderState rs, final int width, final int height, int sampleCount) { + final ShaderState st = rs.getShaderState(); + + gl.glViewport(0, 0, width, height); + st.uniform(gl, mgl_ActiveTexture); + gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue()); + setTexSize(gl, st, false, sampleCount); + + fbo.use(gl, texA); + verticeFboAttr.enableBuffer(gl, true); + texCoordFboAttr.enableBuffer(gl, true); + indicesFbo.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesFbo.bindBuffer(gl, false); + texCoordFboAttr.enableBuffer(gl, false); + verticeFboAttr.enableBuffer(gl, false); + fbo.unuse(gl); + + // setback: gl.glActiveTexture(currentActiveTextureEngine[0]); + } + + private void renderRegion2FBO(final GL2ES2 gl, final RenderState rs, final int targetFboWidth, final int targetFboHeight, int sampleCount) { + final ShaderState st = rs.getShaderState(); + + if( 0 >= targetFboWidth || 0 >= targetFboHeight ) { + throw new IllegalArgumentException("fboSize must be greater than 0: "+targetFboWidth+"x"+targetFboHeight); + } + + if(null == fbo) { + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + fbo = new FBObject(); + fbo.reset(gl, fboWidth, fboHeight); + // Shall not use bilinear (GL_LINEAR), due to own VBAA. Result is smooth w/o it now! + // texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE); + fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.createFBO: %dx%d%n%s%n", fboWidth, fboHeight, fbo.toString()); + } + } else if( targetFboWidth != fboWidth || targetFboHeight != fboHeight ) { + fbo.reset(gl, targetFboWidth, targetFboHeight); + fbo.bind(gl); + if( DEBUG_FBO_1 ) { + System.err.printf("XXX.resetFBO: %dx%d -> %dx%d%n%s%n", fboWidth, fboHeight, targetFboWidth, targetFboHeight, fbo ); + } + fboWidth = targetFboWidth; + fboHeight = targetFboHeight; + } else { + fbo.bind(gl); + } + setTexSize(gl, st, true, sampleCount); + + //render texture + gl.glViewport(0, 0, fboWidth, fboHeight); + st.uniform(gl, mgl_fboPMVMatrix); // use orthogonal matrix + + gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT | GL2ES2.GL_DEPTH_BUFFER_BIT); + renderRegion(gl); + fbo.unbind(gl); + + st.uniform(gl, rs.getPMVMatrix()); // switch back to real PMV matrix + } + + private void renderRegion(final GL2ES2 gl) { + verticeTxtAttr.enableBuffer(gl, true); + texCoordTxtAttr.enableBuffer(gl, true); + indicesTxtBuffer.bindBuffer(gl, true); // keeps VBO binding + + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxtBuffer.getElementCount() * indicesTxtBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + + indicesTxtBuffer.bindBuffer(gl, false); + texCoordTxtAttr.enableBuffer(gl, false); + verticeTxtAttr.enableBuffer(gl, false); + } + + @Override + protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { + if(DEBUG_INSTANCE) { + System.err.println("VBORegion2PES2 Destroy: " + this); + } + final ShaderState st = renderer.getShaderState(); + if(null != fbo) { + fbo.destroy(gl); + fbo = null; + texA = null; + } + if(null != verticeTxtAttr) { + st.ownAttribute(verticeTxtAttr, false); + verticeTxtAttr.destroy(gl); + verticeTxtAttr = null; + } + if(null != texCoordTxtAttr) { + st.ownAttribute(texCoordTxtAttr, false); + texCoordTxtAttr.destroy(gl); + texCoordTxtAttr = null; + } + if(null != indicesTxtBuffer) { + indicesTxtBuffer.destroy(gl); + indicesTxtBuffer = null; + } + if(null != verticeFboAttr) { + st.ownAttribute(verticeFboAttr, false); + verticeFboAttr.destroy(gl); + verticeFboAttr = null; + } + if(null != texCoordFboAttr) { + st.ownAttribute(texCoordFboAttr, false); + texCoordFboAttr.destroy(gl); + texCoordFboAttr = null; + } + if(null != indicesFbo) { + indicesFbo.destroy(gl); + indicesFbo = null; + } + } +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index 9feb18a12..bdf824b6a 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*/] sampleCount) { 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/opengl/shader/curverenderer01-1pass-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm-weight.fp index 7643dab7b..940e95071 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass-weight.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm-weight.fp @@ -14,21 +14,26 @@ #include uniforms.glsl
#include varyings.glsl
+const vec3 zero3 = vec3(0);
+
void main (void)
{
+ vec3 c;
+ float alpha;
+
vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y));
- vec3 c = gcu_ColorStatic.rgb;
-
- float alpha = 0.0;
-
- if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) {
+
+ if( gcv_TexCoord.x == 0.0 && gcv_TexCoord.y == 0.0 ) {
+ // pass-1: Lines
+ c = gcu_ColorStatic.rgb;
alpha = gcu_Alpha;
- }
- else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) {
+ } else if ( gcv_TexCoord.x > 0.0 && ( rtex.y > 0.0 || rtex.x == 1.0 ) ) {
+ // pass-1: curves
rtex.y -= 0.1;
if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) {
// discard; // freezes NV tegra2 compiler
+ c = zero3;
alpha = 0.0;
} else {
rtex.y = max(rtex.y, 0.0);
@@ -45,10 +50,12 @@ void main (void) float gd = (aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0)*(aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0);
vec2 f = vec2((dtx.y - (w*dtx.x*(1.0 - 2.0*rtex.x))/gd), (dty.y - (w*dty.x*(1.0 - 2.0*rtex.x))/gd));
- // FIXME: will we ever set gcu_Alpha != 1.0 ? If not, a==alpha!
- float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
- alpha = gcu_Alpha * a;
+ c = gcu_ColorStatic.rgb;
+ alpha = gcu_Alpha * clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
}
+ } else {
+ c = zero3;
+ alpha = 0.0;
}
mgl_FragColor = vec4(c, alpha);
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm.fp index e12eef4b1..2175c1a31 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass.fp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-1pass_norm.fp @@ -14,21 +14,35 @@ #include uniforms.glsl #include varyings.glsl +const vec3 zero3 = vec3(0); + void main (void) { + vec3 c; + float alpha; + + /** + * CDTriangulator2D.extractBoundaryTriangles(..): + * 0 > gcv_TexCoord.y : hole or holeLike + * 0 < gcv_TexCoord.y : !hole (outer) + * + * 0 == gcv_TexCoord.x : vertex-0 of triangle + * 0.5 == gcv_TexCoord.x : vertex-1 of triangle + * 1 == gcv_TexCoord.x : vertex-2 of triangle + */ vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); - vec3 c = gcu_ColorStatic.rgb; - - float alpha = 0.0; - if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) { + if( gcv_TexCoord.x == 0.0 && gcv_TexCoord.y == 0.0 ) { + // pass-1: Lines + c = gcu_ColorStatic.rgb; alpha = gcu_Alpha; - } - else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) { + } else if ( gcv_TexCoord.x > 0.0 && ( rtex.y > 0.0 || rtex.x == 1.0 ) ) { + // pass-1: curves rtex.y -= 0.1; if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) { // discard; // freezes NV tegra2 compiler + c = zero3; alpha = 0.0; } else { rtex.y = max(rtex.y, 0.0); @@ -39,11 +53,12 @@ void main (void) vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); float position = rtex.y - (rtex.x * (1.0 - rtex.x)); - // FIXME: will we ever set gcu_Alpha != 1.0 ? If not, a==alpha! - float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); - alpha = gcu_Alpha * a; + c = gcu_ColorStatic.rgb; + alpha = gcu_Alpha * clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); } + } else { + c = zero3; + alpha = 0.0; } - mgl_FragColor = vec4(c, alpha); } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp deleted file mode 100644 index fb71abd14..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass-weight.fp +++ /dev/null @@ -1,97 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved.
-
-//
-// 2-pass shader w/ weight
-//
-
-#if __VERSION__ >= 130
- #define varying in
- out vec4 mgl_FragColor;
- #define texture2D texture
-#else
- #define mgl_FragColor gl_FragColor
-#endif
-
-#include uniforms.glsl
-#include varyings.glsl
-
-const vec4 tex_weights = vec4(0.075, 0.06, 0.045, 0.025);
-
-void main (void)
-{
- vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y));
- vec3 c = gcu_ColorStatic.rgb;
-
- float alpha = 0.0;
-
- if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) {
- alpha = gcu_Alpha;
- }
- else if((gcv_TexCoord.x >= 5.0)) {
- vec2 dfx = dFdx(gcv_TexCoord);
- vec2 dfy = dFdy(gcv_TexCoord);
-
- vec2 size = 1.0/gcu_TextureSize;
-
- rtex -= 5.0;
- vec4 t = texture2D(gcu_TextureUnit, rtex)* 0.18;
-
- t += texture2D(gcu_TextureUnit, rtex + size*(vec2(1, 0)))*tex_weights.x;
- t += texture2D(gcu_TextureUnit, rtex - size*(vec2(1, 0)))*tex_weights.x;
- t += texture2D(gcu_TextureUnit, rtex + size*(vec2(0, 1)))*tex_weights.x;
- t += texture2D(gcu_TextureUnit, rtex - size*(vec2(0, 1)))*tex_weights.x;
-
- t += texture2D(gcu_TextureUnit, rtex + 2.0*size*(vec2(1, 0)))*tex_weights.y;
- t += texture2D(gcu_TextureUnit, rtex - 2.0*size*(vec2(1, 0)))*tex_weights.y;
- t += texture2D(gcu_TextureUnit, rtex + 2.0*size*(vec2(0, 1)))*tex_weights.y;
- t += texture2D(gcu_TextureUnit, rtex - 2.0*size*(vec2(0, 1)))*tex_weights.y;
-
- t += texture2D(gcu_TextureUnit, rtex + 3.0*size*(vec2(1, 0)))*tex_weights.z;
- t += texture2D(gcu_TextureUnit, rtex - 3.0*size*(vec2(1, 0)))*tex_weights.z;
- t += texture2D(gcu_TextureUnit, rtex + 3.0*size*(vec2(0, 1)))*tex_weights.z;
- t += texture2D(gcu_TextureUnit, rtex - 3.0*size*(vec2(0, 1)))*tex_weights.z;
-
- t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(1, 0)))*tex_weights.w;
- t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(1, 0)))*tex_weights.w;
- t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(0, 1)))*tex_weights.w;
- t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(0, 1)))*tex_weights.w;
-
- #if 0
- if(t.w == 0.0) {
- discard; // discard freezes NV tegra2 compiler
- }
- #endif
-
- c = t.xyz;
- alpha = gcu_Alpha * t.w;
- }
- ///////////////////////////////////////////////////////////
- else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) {
- rtex.y -= 0.1;
-
- if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) {
- // discard; // freezes NV tegra2 compiler
- alpha = 0.0;
- } else {
- rtex.y = max(rtex.y, 0.0);
-
- vec2 dtx = dFdx(rtex);
- vec2 dty = dFdy(rtex);
-
- float w = gcu_Weight;
- float pd = ((2.0 - (2.0*w))*rtex.x*rtex.x) + 2.0*(w-1.0)*rtex.x + 1.0;
- float position = rtex.y - ((w*rtex.x*(1.0 - rtex.x))/pd);
-
- float aph = 2.0 - 2.0*w;
-
- float gd = (aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0)*(aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0);
- vec2 f = vec2((dtx.y - (w*dtx.x*(1.0 - 2.0*rtex.x))/gd), (dty.y - (w*dty.x*(1.0 - 2.0*rtex.x))/gd));
-
- // FIXME: will we ever set gcu_Alpha != 1.0 ? If not, a==alpha!
- float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
- alpha = gcu_Alpha * a;
- }
- }
-
- mgl_FragColor = vec4(c, alpha);
-}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp deleted file mode 100644 index 8e5600dd9..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass.fp +++ /dev/null @@ -1,91 +0,0 @@ -//Copyright 2010 JogAmp Community. All rights reserved. - -// -// 2-pass shader w/o weight -// - -#if __VERSION__ >= 130 - #define varying in - out vec4 mgl_FragColor; - #define texture2D texture -#else - #define mgl_FragColor gl_FragColor -#endif - -#include uniforms.glsl -#include varyings.glsl - -const vec4 tex_weights = vec4(0.075, 0.06, 0.045, 0.025); - -void main (void) -{ - vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); - vec3 c = gcu_ColorStatic.rgb; - - float alpha = 0.0; - float enable = 1.0; - - if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) { - alpha = gcu_Alpha; - } - else if((gcv_TexCoord.x >= 5.0)) { - vec2 dfx = dFdx(gcv_TexCoord); - vec2 dfy = dFdy(gcv_TexCoord); - - vec2 size = 1.0/gcu_TextureSize; - - rtex -= 5.0; - vec4 t = texture2D(gcu_TextureUnit, rtex)* 0.18; - - t += texture2D(gcu_TextureUnit, rtex + size*(vec2(1, 0)))*tex_weights.x; - t += texture2D(gcu_TextureUnit, rtex - size*(vec2(1, 0)))*tex_weights.x; - t += texture2D(gcu_TextureUnit, rtex + size*(vec2(0, 1)))*tex_weights.x; - t += texture2D(gcu_TextureUnit, rtex - size*(vec2(0, 1)))*tex_weights.x; - - t += texture2D(gcu_TextureUnit, rtex + 2.0*size*(vec2(1, 0)))*tex_weights.y; - t += texture2D(gcu_TextureUnit, rtex - 2.0*size*(vec2(1, 0)))*tex_weights.y; - t += texture2D(gcu_TextureUnit, rtex + 2.0*size*(vec2(0, 1)))*tex_weights.y; - t += texture2D(gcu_TextureUnit, rtex - 2.0*size*(vec2(0, 1)))*tex_weights.y; - - t += texture2D(gcu_TextureUnit, rtex + 3.0*size*(vec2(1, 0)))*tex_weights.z; - t += texture2D(gcu_TextureUnit, rtex - 3.0*size*(vec2(1, 0)))*tex_weights.z; - t += texture2D(gcu_TextureUnit, rtex + 3.0*size*(vec2(0, 1)))*tex_weights.z; - t += texture2D(gcu_TextureUnit, rtex - 3.0*size*(vec2(0, 1)))*tex_weights.z; - - t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(1, 0)))*tex_weights.w; - t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(1, 0)))*tex_weights.w; - t += texture2D(gcu_TextureUnit, rtex + 4.0*size*(vec2(0, 1)))*tex_weights.w; - t += texture2D(gcu_TextureUnit, rtex - 4.0*size*(vec2(0, 1)))*tex_weights.w; - - #if 0 - if(t.w == 0.0){ - discard; // discard freezes NV tegra2 compiler - } - #endif - - c = t.xyz; - alpha = gcu_Alpha * t.w; - } - else if ((gcv_TexCoord.x > 0.0) && (rtex.y > 0.0 || rtex.x == 1.0)) { - rtex.y -= 0.1; - - if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) { - // discard; // freezes NV tegra2 compiler - alpha = 0.0; - } else { - rtex.y = max(rtex.y, 0.0); - - vec2 dtx = dFdx(rtex); - vec2 dty = dFdy(rtex); - - vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); - float position = rtex.y - (rtex.x * (1.0 - rtex.x)); - - // FIXME: will we ever set gcu_Alpha != 1.0 ? If not, a==alpha! - float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); - alpha = gcu_Alpha * a; - } - } - - mgl_FragColor = vec4(c, alpha); -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp new file mode 100644 index 000000000..733669e64 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa-weight.fp @@ -0,0 +1,76 @@ +//Copyright 2010 JogAmp Community. All rights reserved.
+
+//
+// 2-pass shader w/ weight
+//
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+#include uniforms.glsl
+#include varyings.glsl
+
+const vec3 zero3 = vec3(0);
+
+void main (void)
+{
+ vec3 c;
+ float alpha;
+
+ if( 0 < gcu_TextureSize.z ) {
+ // Pass-2: Dump Texture
+ vec4 t = texture2D(gcu_TextureUnit, gcv_TexCoord);
+ #if 0
+ if( 0.0 == t.a ) {
+ discard; // discard freezes NV tegra2 compiler
+ }
+ #endif
+
+ c = t.rgb;
+ alpha = gcu_Alpha * t.a;
+ } else {
+ // Pass-1
+ vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y));
+
+ if( gcv_TexCoord.x == 0.0 && gcv_TexCoord.y == 0.0 ) {
+ // pass-1: Lines
+ c = gcu_ColorStatic.rgb;
+ alpha = 1.0;
+ } else if ( gcv_TexCoord.x > 0.0 && (rtex.y > 0.0 || rtex.x == 1.0) ) {
+ // pass-1: curves
+ rtex.y -= 0.1;
+
+ if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) {
+ // discard; // freezes NV tegra2 compiler
+ c = zero3;
+ alpha = 0.0;
+ } else {
+ rtex.y = max(rtex.y, 0.0);
+
+ vec2 dtx = dFdx(rtex);
+ vec2 dty = dFdy(rtex);
+
+ float w = gcu_Weight;
+ float pd = ((2.0 - (2.0*w))*rtex.x*rtex.x) + 2.0*(w-1.0)*rtex.x + 1.0;
+ float position = rtex.y - ((w*rtex.x*(1.0 - rtex.x))/pd);
+
+ float aph = 2.0 - 2.0*w;
+
+ float gd = (aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0)*(aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0);
+ vec2 f = vec2((dtx.y - (w*dtx.x*(1.0 - 2.0*rtex.x))/gd), (dty.y - (w*dty.x*(1.0 - 2.0*rtex.x))/gd));
+
+ c = gcu_ColorStatic.rgb;
+ alpha = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
+ }
+ } else {
+ c = zero3;
+ alpha = 0.0;
+ }
+ }
+ mgl_FragColor = vec4(c, alpha);
+}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp new file mode 100644 index 000000000..2536e251b --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_msaa.fp @@ -0,0 +1,88 @@ +//Copyright 2010 JogAmp Community. All rights reserved. + +// +// 2-pass shader w/o weight +// + +#if __VERSION__ >= 130 + #define varying in + out vec4 mgl_FragColor; + #define texture2D texture +#else + #define mgl_FragColor gl_FragColor +#endif + +#include uniforms.glsl +#include varyings.glsl + +// #define PREALPHA 1 + +const vec3 zero3 = vec3(0); + +void main (void) +{ + vec3 c; + float alpha; + + if( 0 < gcu_TextureSize.z ) { + // Pass-2: Dump Texture + vec4 t = texture2D(gcu_TextureUnit, gcv_TexCoord); + #if 0 + if( 0.0 == t.a ) { + discard; // discard freezes NV tegra2 compiler + } + #endif + + c = t.rgb; + #ifdef PREALPHA + // alpha = mix(0.0, gcu_Alpha, t.a); // t.a one of [ 0.0, 1.0 ] + // ^^ for = 0.0 == t.a ? 0.0 : gcu_Alpha; + // mix(x, y, a) := x * ( 1 - a ) + y * a + alpha = gcu_Alpha; + #else + alpha = gcu_Alpha * t.a; + #endif + } else { + // Pass-1 + vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); + + if( gcv_TexCoord.x == 0.0 && gcv_TexCoord.y == 0.0 ) { + // pass-1: Lines + c = gcu_ColorStatic.rgb; + alpha = 1.0; + } else if ( gcv_TexCoord.x > 0.0 && (rtex.y > 0.0 || rtex.x == 1.0) ) { + // pass-1: curves + rtex.y -= 0.1; + + if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) { + // discard; // freezes NV tegra2 compiler + c = zero3; + alpha = 0.0; + } else { + rtex.y = max(rtex.y, 0.0); + + vec2 dtx = dFdx(rtex); + vec2 dty = dFdy(rtex); + + vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); + float position = rtex.y - (rtex.x * (1.0 - rtex.x)); + + #ifdef PREALPHA + float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); + c = gcu_ColorStatic.rgb * a; + alpha = mix(1.0, 0.0, step(a, 0.0)); + // ^^ = 0.0 < a ? 1.0 : 0.0; + // step(e, x) := e > x ? 0.0 : 1.0 + // mix(x, y, a) := x * ( 1 - a ) + y * a + #else + c = gcu_ColorStatic.rgb; + alpha = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); + #endif + } + } else { + c = zero3; + alpha = 0.0; + } + } + mgl_FragColor = vec4(c, alpha); +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp new file mode 100644 index 000000000..3b1b55c87 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa-weight.fp @@ -0,0 +1,109 @@ +//Copyright 2010 JogAmp Community. All rights reserved.
+
+//
+// 2-pass shader w/ weight
+//
+
+#if __VERSION__ >= 130
+ #define varying in
+ out vec4 mgl_FragColor;
+ #define texture2D texture
+#else
+ #define mgl_FragColor gl_FragColor
+#endif
+
+#include uniforms.glsl
+#include varyings.glsl
+
+const vec3 zero3 = vec3(0);
+
+void main (void)
+{
+ vec3 c;
+ float alpha;
+
+ if( 0 < gcu_TextureSize.z ) {
+ // Pass-2: AA on Texture
+ // Note: gcv_TexCoord is in center of sample pixels.
+
+ float sampleCount = gcu_TextureSize.z;
+ vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size
+
+ float sample_weight = 1 / ( 2 * sampleCount );
+ // float sample_weight = 1 / ( 2 * sampleCount + 1 );
+
+ vec4 t = vec4(0);
+ // vec4 t = texture2D(gcu_TextureUnit, gcv_TexCoord)* sample_weight; // center: +1
+
+ // SampleCount 2
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-0.5, -0.5)))*sample_weight; // NW
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-0.5, 0.5)))*sample_weight; // SW
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 0.5, 0.5)))*sample_weight; // SE
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 0.5, -0.5)))*sample_weight; // NE
+ if( sampleCount > 2 ) {
+ // SampleCount 4
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-1.5, -1.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-1.5, 1.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 1.5, 1.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 1.5, -1.5)))*sample_weight;
+ if( sampleCount > 4 ) {
+ // SampleCount 8
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-2.5, -2.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-2.5, 2.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 2.5, 2.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 2.5, -2.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-3.5, -3.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-3.5, 3.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 3.5, 3.5)))*sample_weight;
+ t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 3.5, -3.5)))*sample_weight;
+ }
+ }
+ #if 0
+ if(t.w == 0.0){
+ discard; // discard freezes NV tegra2 compiler
+ }
+ #endif
+
+ c = t.rgb;
+ alpha = gcu_Alpha * t.a;
+ } else {
+ // pass-1
+ vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y));
+
+ if((gcv_TexCoord.x == 0.0) && (gcv_TexCoord.y == 0.0)) {
+ // pass-1: Lines
+ c = gcu_ColorStatic.rgb;
+ alpha = 1.0;
+ } else if ( gcv_TexCoord.x > 0.0 && (rtex.y > 0.0 || rtex.x == 1.0) ) {
+ // pass-1: curves
+ rtex.y -= 0.1;
+
+ if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) {
+ // discard; // freezes NV tegra2 compiler
+ c = zero3;
+ alpha = 0.0;
+ } else {
+ rtex.y = max(rtex.y, 0.0);
+
+ vec2 dtx = dFdx(rtex);
+ vec2 dty = dFdy(rtex);
+
+ float w = gcu_Weight;
+ float pd = ((2.0 - (2.0*w))*rtex.x*rtex.x) + 2.0*(w-1.0)*rtex.x + 1.0;
+ float position = rtex.y - ((w*rtex.x*(1.0 - rtex.x))/pd);
+
+ float aph = 2.0 - 2.0*w;
+
+ float gd = (aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0)*(aph*rtex.x*rtex.x + 2.0*rtex.x + 1.0);
+ vec2 f = vec2((dtx.y - (w*dtx.x*(1.0 - 2.0*rtex.x))/gd), (dty.y - (w*dty.x*(1.0 - 2.0*rtex.x))/gd));
+
+ c = gcu_ColorStatic.rgb;
+ alpha = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0);
+ }
+ } else {
+ c = zero3;
+ alpha = 0.0;
+ }
+ }
+ mgl_FragColor = vec4(c, alpha);
+}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp new file mode 100644 index 000000000..8237fa55b --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-2pass_vbaa.fp @@ -0,0 +1,103 @@ +//Copyright 2010 JogAmp Community. All rights reserved. + +// +// 2-pass shader w/o weight +// + +#if __VERSION__ >= 130 + #define varying in + out vec4 mgl_FragColor; + #define texture2D texture +#else + #define mgl_FragColor gl_FragColor +#endif + +#include uniforms.glsl +#include varyings.glsl + +const vec3 zero3 = vec3(0); + +void main (void) +{ + vec3 c; + float alpha; + + if( 0 < gcu_TextureSize.z ) { + // Pass-2: AA on Texture + // Note: gcv_TexCoord is in center of sample pixels. + + float sampleCount = gcu_TextureSize.z; + vec2 psize = 1.0 / gcu_TextureSize.xy; // pixel size + + float sample_weight = 1 / ( 2 * sampleCount ); + // float sample_weight = 1 / ( 2 * sampleCount + 1 ); + + vec4 t = vec4(0); + // vec4 t = texture2D(gcu_TextureUnit, gcv_TexCoord)* sample_weight; // center: +1 + + // SampleCount 2 + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-0.5, -0.5)))*sample_weight; // NW + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-0.5, 0.5)))*sample_weight; // SW + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 0.5, 0.5)))*sample_weight; // SE + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 0.5, -0.5)))*sample_weight; // NE + if( sampleCount > 2 ) { + // SampleCount 4 + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-1.5, -1.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-1.5, 1.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 1.5, 1.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 1.5, -1.5)))*sample_weight; + if( sampleCount > 4 ) { + // SampleCount 8 + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-2.5, -2.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-2.5, 2.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 2.5, 2.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 2.5, -2.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-3.5, -3.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2(-3.5, 3.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 3.5, 3.5)))*sample_weight; + t += texture2D(gcu_TextureUnit, gcv_TexCoord + psize*(vec2( 3.5, -3.5)))*sample_weight; + } + } + #if 0 + if(t.w == 0.0){ + discard; // discard freezes NV tegra2 compiler + } + #endif + + c = t.rgb; + alpha = gcu_Alpha * t.a; + } else { + // pass-1 + vec2 rtex = vec2(abs(gcv_TexCoord.x),abs(gcv_TexCoord.y)); + + if( gcv_TexCoord.x == 0.0 && gcv_TexCoord.y == 0.0 ) { + // pass-1: Lines + c = gcu_ColorStatic.rgb; + alpha = 1.0; + } else if ( gcv_TexCoord.x > 0.0 && (rtex.y > 0.0 || rtex.x == 1.0) ) { + // pass-1: curves + rtex.y -= 0.1; + + if(rtex.y < 0.0 && gcv_TexCoord.y < 0.0) { + // discard; // freezes NV tegra2 compiler + c = zero3; + alpha = 0.0; + } else { + rtex.y = max(rtex.y, 0.0); + + vec2 dtx = dFdx(rtex); + vec2 dty = dFdy(rtex); + + vec2 f = vec2((dtx.y - dtx.x + 2.0*rtex.x*dtx.x), (dty.y - dty.x + 2.0*rtex.x*dty.x)); + float position = rtex.y - (rtex.x * (1.0 - rtex.x)); + + c = gcu_ColorStatic.rgb; + alpha = clamp(0.5 - ( position/length(f) ) * sign(gcv_TexCoord.y), 0.0, 1.0); + } + } else { + c = zero3; + alpha = 0.0; + } + } + mgl_FragColor = vec4(c, alpha); +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl index 5bbd5de14..92e78d5de 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl @@ -6,11 +6,10 @@ uniform mat4 gcu_PMVMatrix[3]; // P, Mv, and Mvi uniform vec3 gcu_ColorStatic; uniform float gcu_Alpha; uniform float gcu_Weight; -uniform sampler2D gcu_TextureUnit; +uniform sampler2D gcu_TextureUnit; -// #if __VERSION__ < 130 -uniform vec2 gcu_TextureSize; -// #endif +/** 3rd component: 0: pass-1, >0: pass-2, sampleCount */ +uniform vec3 gcu_TextureSize; // const int MAX_TEXTURE_UNITS = 8; // <= gl_MaxTextureImageUnits // const int MAX_LIGHTS = 8; diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java index a60f91b87..35263407d 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; @@ -44,15 +44,12 @@ import jogamp.opengl.Debug; * Closed Regions with optional n holes. * */ -public class CDTriangulator2D implements Triangulator{ +public class CDTriangulator2D implements Triangulator { protected static final boolean DEBUG = Debug.debug("Triangulation"); - private float sharpness = 0.5f; - private ArrayList<Loop> loops; - private ArrayList<Vertex> vertices; + private final ArrayList<Loop> loops = new ArrayList<Loop>(); - private ArrayList<Triangle> triangles; private int maxTriID = 0; @@ -62,19 +59,14 @@ public class CDTriangulator2D implements Triangulator{ reset(); } - /** Reset the triangulation to initial state - * Clearing cached data - */ @Override - public void reset() { + public final void reset() { maxTriID = 0; - vertices = new ArrayList<Vertex>(); - triangles = new ArrayList<Triangle>(3); - loops = new ArrayList<Loop>(); + loops.clear(); } @Override - public void addCurve(Outline polyline) { + public final void addCurve(final List<Triangle> sink, final Outline polyline, final float sharpness) { Loop loop = null; if(!loops.isEmpty()) { @@ -82,27 +74,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, sharpness); + // 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, sharpness); + // vertices.addAll(innerPoly.getVertices()); loop.addConstraintCurve(innerPoly); } } @Override - public ArrayList<Triangle> generate() { + public final void generate(List<Triangle> sink) { for(int i=0;i<loops.size();i++) { - Loop loop = loops.get(i); + final 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 +107,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,27 +119,27 @@ 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) { - GraphOutline innerOutline = new GraphOutline(); - ArrayList<GraphVertex> outVertices = outline.getGraphPoint(); - int size = outVertices.size(); + private GraphOutline extractBoundaryTriangles(final List<Triangle> sink, final GraphOutline outline, final boolean hole, final float sharpness) { + final GraphOutline innerOutline = new GraphOutline(); + final ArrayList<GraphVertex> outVertices = outline.getGraphPoint(); + final int size = outVertices.size(); for(int i=0; i < size; i++) { - GraphVertex currentVertex = outVertices.get(i); - GraphVertex gv0 = outVertices.get((i+size-1)%size); - GraphVertex gv2 = outVertices.get((i+1)%size); - GraphVertex gv1 = currentVertex; + final GraphVertex currentVertex = outVertices.get(i); + final GraphVertex gv0 = outVertices.get((i+size-1)%size); + final GraphVertex gv2 = outVertices.get((i+1)%size); + final GraphVertex gv1 = currentVertex; - if(!currentVertex.getPoint().isOnCurve()) { - Vertex v0 = gv0.getPoint().clone(); - Vertex v2 = gv2.getPoint().clone(); - Vertex v1 = gv1.getPoint().clone(); + if( !currentVertex.getPoint().isOnCurve() ) { + 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,23 +155,22 @@ 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); } if( hole || holeLike ) { v0.setTexCoord(0, -0.1f); v2.setTexCoord(1, -0.1f); - v1.setTexCoord(0.5f, -1*sharpness -0.1f); + v1.setTexCoord(0.5f, -1*sharpness-0.1f); innerOutline.addVertex(currentVertex); } else { v0.setTexCoord(0, 0.1f); v2.setTexCoord(1, 0.1f); v1.setTexCoord(0.5f, sharpness+0.1f); } - } - else { - if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){ + } else { + if( !gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve() ) { currentVertex.setBoundaryContained(true); } innerOutline.addVertex(currentVertex); @@ -189,16 +180,13 @@ public class CDTriangulator2D implements Triangulator{ } private Loop getContainerLoop(Outline polyline) { - ArrayList<Vertex> vertices = polyline.getVertices(); + final ArrayList<Vertex> vertices = polyline.getVertices(); for(int i=0; i < loops.size(); i++) { - Loop loop = loops.get(i); - boolean inside = false; + final Loop loop = loops.get(i); for(int j=0; j < vertices.size(); j++) { - Vertex v = vertices.get(j); - inside |= loop.checkInside(v); - } - if(inside) { - return loop; + if( loop.checkInside( vertices.get(j) ) ) { + return loop; + } } } return null; 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/UbuntuFontLoader.java b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java index e1e44c92c..c7efe143b 100644 --- a/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java +++ b/src/jogl/classes/jogamp/graph/font/UbuntuFontLoader.java @@ -38,9 +38,7 @@ import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontSet; import com.jogamp.graph.font.FontFactory; -import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URLConnection; import java.security.AccessController; import java.security.PrivilegedAction; diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 67ae6c387..3cd9ab7c1 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,30 @@ 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; + private final float[] tmpV3 = new float[3]; // 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 +119,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 +138,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 +167,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 +198,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 +223,26 @@ 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 final float getPixelSize(float fontSize /* points per inch */, float resolution) { + return fontSize * resolution / ( 72 /* points per inch */ ); + } + + @Override + 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 +250,6 @@ class TypecastFont implements FontInt { width += glyph.getAdvance(pixelSize, false); } } - return (int)(width + 0.5f); } @@ -254,13 +257,11 @@ 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); - AABBox bbox = glyph.getBBox(pixelSize); + 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, tmpV3); height = (int)Math.ceil(Math.max(bbox.getHeight(), height)); } } @@ -272,11 +273,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 +283,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..b0e283278 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, float[] tmpV3) { final float size = getScale(pixelSize); AABBox newBox = getBBox().clone(); - newBox.scale(size); + newBox.scale(size, tmpV3); 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..4064e6463 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(); @@ -82,9 +82,9 @@ class TypecastHMetrics implements Metrics { return pixelSize * unitsPerEM_Inv; } @Override - public final AABBox getBBox(float pixelSize) { + public final AABBox getBBox(float pixelSize, float[] tmpV3) { AABBox res = new AABBox(bbox.getLow(), bbox.getHigh()); - res.scale(getScale(pixelSize)); + res.scale(getScale(pixelSize), tmpV3); return res; } }
\ No newline at end of file diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java index 127e260ca..6768b18c3 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java @@ -27,196 +27,192 @@ */ 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://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html + * http://walon.org/pub/ttf/ttf_glyphs.htm */ 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(false); + shape.addEmptyOutline(); + shape.addVertex(0, vertexFactory.create(p1.x, p1.y, 0, 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, 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, p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2.x, p2.y, 0, 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, p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2x, p2y, 0, 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, p1.onCurve)); + shape.addVertex(0, vertexFactory.create(p2.x, p2.y, 0, p2.onCurve)); + shape.addVertex(0, vertexFactory.create(p3.x, p3.y, 0, p3.onCurve)); + } */ + + 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); + buildShapeImpl(shape, symbol, glyph, vertexFactory); + shape.closeLastOutline(false); + return shape; + } + /** + private static void buildShapeImpl02(final OutlineShape shape, char symbol, OTGlyph glyph, Factory<? extends Vertex> 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; + if ( glyph.getPoint(i).endOfContour ) { + for(int j=0; j<count; j++) { + final Point p = glyph.getPoint(startIndex + j); + shape.addVertex(0, vertexFactory.create(p.x, p.y, 0, p.onCurve)); + } + shape.closeLastOutline(false); + startIndex = 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); - } + private static void buildShapeImpl(final OutlineShape shape, char symbol, OTGlyph glyph, Factory<? extends Vertex> 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 startIndex = 0; + int count = 0; + final int totalPoints = glyph.getPointCount(); + for (int i = 0; i < totalPoints; i++) { + count++; + if ( glyph.getPoint(i).endOfContour ) { + int offset = 0; + while ( offset < count - 1 ) { // require at least +1 point (last one is end-of-contour) + final Point p0 = glyph.getPoint(startIndex + offset%count); + final Point p1 = glyph.getPoint(startIndex + (offset+1)%count); + final Point p2 = glyph.getPoint(startIndex + (offset+2)%count); + final Point p3 = offset+3 < count ? glyph.getPoint(startIndex + offset+3) : null; + if( DEBUG ) { + System.err.println("GlyphShape<"+symbol+">: offset "+offset+" of "+count+"/"+totalPoints+" points"); + final int pMIdx= (offset==0) ? startIndex+count-1 : startIndex+(offset-1)%count; + final Point pM = glyph.getPoint(pMIdx); + final int p0Idx = startIndex + offset%count; + final int p1Idx = startIndex + (offset+1)%count; + final int p2Idx = startIndex + (offset+2)%count; + final int p3Idx = startIndex + (offset+3)%count; + System.err.println("\t pM["+pMIdx+"] "+pM); + System.err.println("\t p0["+p0Idx+"] "+p0); + System.err.println("\t p1["+p1Idx+"] "+p1); + System.err.println("\t p2["+p2Idx+"] "+p2); + System.err.println("\t p3["+p3Idx+"] "+p3); + } + if(offset == 0) { + addShapeMoveTo(shape, vertexFactory, p0); + // 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( p0.endOfContour ) { + // Branch-0: EOC ** SHALL NEVER HAPPEN ** + if( DEBUG ) { System.err.println("B0 .. end-of-contour **** EOC"); } + shape.closeLastOutline(false); + break; + } else if (p0.onCurve) { + if (p1.onCurve) { + // Branch-1: point.onCurve && p1.onCurve + if( DEBUG ) { System.err.println("B1 .. line-to p0-p1"); } + + // s = new Line2D.Float(point.x, point.y, p1.x, p1.y); + // gp.lineTo( p1.x, p1.y ); + addShapeLineTo(shape, vertexFactory, p1); + offset++; + } else { + if (p2.onCurve) { + // Branch-2: point.onCurve && !p1.onCurve && p2.onCurve + if( DEBUG ) { System.err.println("B2 .. quad-to p0-p1-p2"); } + + // s = new QuadCurve2D.Float( point.x, point.y, p1.x, p1.y, p2.x, p2.y); + // gp.quadTo(p1.x, p1.y, p2.x, p2.y); + addShapeQuadTo(shape, vertexFactory, p1, p2); + offset+=2; + } else { + if (null != p3 && p3.onCurve) { + // Branch-3: point.onCurve && !p1.onCurve && !p2.onCurve && p3.onCurve + if( DEBUG ) { System.err.println("B3 .. 2-quad p0-p1-p1_2, p1_2-p2-p3 **** 2QUAD"); } + // addShapeCubicTo(shape, vertexFactory, p1, p2, p3); + addShapeQuadTo(shape, vertexFactory, p1, + midValue(p1.x, p2.x), + midValue(p1.y, p2.y), true); + addShapeQuadTo(shape, vertexFactory, p2, p3); + offset+=3; + } else { + // Branch-4: point.onCurve && !p1.onCurve && !p2.onCurve && !p3.onCurve + if( DEBUG ) { System.err.println("B4 .. quad-to p0-p1-p2h **** MID"); } + + // s = new QuadCurve2D.Float(point.x,point.y,p1.x,p1.y, + // midValue(p1.x, p2.x), midValue(p1.y, p2.y)); + // gp.quadTo(p1.x, p1.y, midValue(p1.x, p2.x), midValue(p1.y, p2.y)); + addShapeQuadTo(shape, vertexFactory, p1, + midValue(p1.x, p2.x), + midValue(p1.y, p2.y), true); + offset+=2; // Skip p2 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 (!p1.onCurve) { + // Branch-5: !point.onCurve && !p1.onCurve + if( DEBUG ) { System.err.println("B5 .. quad-to pMh-p0-p1h ***** MID"); } + // s = new QuadCurve2D.Float(midValue(pM.x, point.x), midValue(pM.y, point.y), + // point.x, point.y, + // midValue(point.x, p1.x), midValue(point.y, p1.y)); + addShapeQuadTo(shape, vertexFactory, p0, + midValue(p0.x, p1.x), midValue(p0.y, p1.y), true); + offset++; + } else { + // Branch-6: !point.onCurve && p1.onCurve + if( DEBUG ) { System.err.println("B6 .. quad-to pMh-p0-p1"); } + // s = new QuadCurve2D.Float(midValue(pM.x, point.x), midValue(pM.y, point.y), + // point.x, point.y, p1.x, p1.y); + // gp.quadTo(point.x, point.y, p1.x, p1.y); + addShapeQuadTo(shape, vertexFactory, p0, p1); + 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++; - } + shape.closeLastOutline(false); + startIndex = i + 1; + count = 0; } } } - 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; } } 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/ot/table/GlyfCompositeDescript.java b/src/jogl/classes/jogamp/graph/font/typecast/ot/table/GlyfCompositeDescript.java index 50e0fa339..fabc71a77 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/ot/table/GlyfCompositeDescript.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/ot/table/GlyfCompositeDescript.java @@ -65,7 +65,7 @@ import java.util.ArrayList; */ public class GlyfCompositeDescript extends GlyfDescript { - private ArrayList<GlyfCompositeComp> _components = + private final ArrayList<GlyfCompositeComp> _components = new ArrayList<GlyfCompositeComp>(); public GlyfCompositeDescript( @@ -167,8 +167,9 @@ public class GlyfCompositeDescript extends GlyfDescript { @Override public int getContourCount() { - GlyfCompositeComp c = _components.get(_components.size()-1); - return c.getFirstContour() + _parentTable.getDescription(c.getGlyphIndex()).getContourCount(); + final GlyfCompositeComp c = _components.get(_components.size()-1); + final GlyfDescript d = _parentTable.getDescription(c.getGlyphIndex()); + return c.getFirstContour() + ( null != d ? d.getContourCount() : 0 ); } public int getComponentIndex(int i) { 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..621802c36 100644 --- a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java @@ -19,18 +19,13 @@ */ package jogamp.graph.geom.plane; -import java.io.IOException; -import java.io.Serializable; - // import jogamp.opengl.util.HashCode; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.opengl.math.FloatUtil; -public class AffineTransform implements Cloneable, Serializable { - - private static final long serialVersionUID = 1330973210523860834L; +public class AffineTransform implements Cloneable { static final String determinantIsZero = "Determinant is zero"; @@ -74,16 +69,12 @@ public class AffineTransform implements Cloneable, Serializable { public AffineTransform() { pointFactory = null; - type = TYPE_IDENTITY; - m00 = m11 = 1.0f; - m10 = m01 = m02 = m12 = 0.0f; + setToIdentity(); } public AffineTransform(Factory<? extends Vertex> factory) { pointFactory = factory; - type = TYPE_IDENTITY; - m00 = m11 = 1.0f; - m10 = m01 = m02 = m12 = 0.0f; + setToIdentity(); } public AffineTransform(AffineTransform t) { @@ -121,6 +112,8 @@ public class AffineTransform implements Cloneable, Serializable { } } + public final Vertex.Factory<? extends Vertex> getFactory() { return pointFactory; } + /* * Method returns type of affine transformation. * @@ -185,35 +178,35 @@ public class AffineTransform implements Cloneable, Serializable { return type; } - public float getScaleX() { + public final float getScaleX() { return m00; } - public float getScaleY() { + public final float getScaleY() { return m11; } - public float getShearX() { + public final float getShearX() { return m01; } - public float getShearY() { + public final float getShearY() { return m10; } - public float getTranslateX() { + public final float getTranslateX() { return m02; } - public float getTranslateY() { + public final float getTranslateY() { return m12; } - public boolean isIdentity() { + public final boolean isIdentity() { return getType() == TYPE_IDENTITY; } - public void getMatrix(float[] matrix) { + public final void getMatrix(float[] matrix) { matrix[0] = m00; matrix[1] = m10; matrix[2] = m01; @@ -224,11 +217,11 @@ public class AffineTransform implements Cloneable, Serializable { } } - public float getDeterminant() { + public final float getDeterminant() { return m00 * m11 - m01 * m10; } - public void setTransform(float m00, float m10, float m01, float m11, float m02, float m12) { + public final void setTransform(float m00, float m10, float m01, float m11, float m02, float m12) { this.type = TYPE_UNKNOWN; this.m00 = m00; this.m10 = m10; @@ -238,18 +231,18 @@ public class AffineTransform implements Cloneable, Serializable { this.m12 = m12; } - public void setTransform(AffineTransform t) { + public final void setTransform(AffineTransform t) { type = t.type; setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12); } - public void setToIdentity() { + public final void setToIdentity() { type = TYPE_IDENTITY; m00 = m11 = 1.0f; m10 = m01 = m02 = m12 = 0.0f; } - public void setToTranslation(float mx, float my) { + public final void setToTranslation(float mx, float my) { m00 = m11 = 1.0f; m01 = m10 = 0.0f; m02 = mx; @@ -261,7 +254,7 @@ public class AffineTransform implements Cloneable, Serializable { } } - public void setToScale(float scx, float scy) { + public final void setToScale(float scx, float scy) { m00 = scx; m11 = scy; m10 = m01 = m02 = m12 = 0.0f; @@ -272,7 +265,7 @@ public class AffineTransform implements Cloneable, Serializable { } } - public void setToShear(float shx, float shy) { + public final void setToShear(float shx, float shy) { m00 = m11 = 1.0f; m02 = m12 = 0.0f; m01 = shx; @@ -284,7 +277,7 @@ public class AffineTransform implements Cloneable, Serializable { } } - public void setToRotation(float angle) { + public final void setToRotation(float angle) { float sin = FloatUtil.sin(angle); float cos = FloatUtil.cos(angle); if (FloatUtil.abs(cos) < ZERO) { @@ -302,7 +295,7 @@ public class AffineTransform implements Cloneable, Serializable { type = TYPE_UNKNOWN; } - public void setToRotation(float angle, float px, float py) { + public final void setToRotation(float angle, float px, float py) { setToRotation(angle); m02 = px * (1.0f - m00) + py * m10; m12 = py * (1.0f - m00) - px * m10; @@ -339,23 +332,23 @@ public class AffineTransform implements Cloneable, Serializable { return t; } - public void translate(float mx, float my) { + public final void translate(float mx, float my) { concatenate(AffineTransform.getTranslateInstance(pointFactory, mx, my)); } - public void scale(float scx, float scy) { + public final void scale(float scx, float scy) { concatenate(AffineTransform.getScaleInstance(pointFactory, scx, scy)); } - public void shear(float shx, float shy) { + public final void shear(float shx, float shy) { concatenate(AffineTransform.getShearInstance(pointFactory, shx, shy)); } - public void rotate(float angle) { + public final void rotate(float angle) { concatenate(AffineTransform.getRotateInstance(pointFactory, angle)); } - public void rotate(float angle, float px, float py) { + public final void rotate(float angle, float px, float py) { concatenate(AffineTransform.getRotateInstance(pointFactory, angle, px, py)); } @@ -377,15 +370,15 @@ public class AffineTransform implements Cloneable, Serializable { t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12 } - public void concatenate(AffineTransform t) { + public final void concatenate(AffineTransform t) { setTransform(multiply(t, this)); } - public void preConcatenate(AffineTransform t) { + public final void preConcatenate(AffineTransform t) { setTransform(multiply(this, t)); } - public AffineTransform createInverse() throws NoninvertibleTransformException { + public final AffineTransform createInverse() throws NoninvertibleTransformException { float det = getDeterminant(); if (FloatUtil.abs(det) < ZERO) { throw new NoninvertibleTransformException(determinantIsZero); @@ -401,33 +394,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 +440,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; @@ -444,19 +449,17 @@ public class AffineTransform implements Cloneable, Serializable { } } - public Vertex deltaTransform(Vertex src, Vertex dst) { + public final 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; } - public void deltaTransform(float[] src, int srcOff, float[] dst, int dstOff, int length) { + public final void deltaTransform(float[] src, int srcOff, float[] dst, int dstOff, int length) { while (--length >= 0) { float x = src[srcOff++]; float y = src[srcOff++]; @@ -465,23 +468,21 @@ public class AffineTransform implements Cloneable, Serializable { } } - public Vertex inverseTransform(Vertex src, Vertex dst) throws NoninvertibleTransformException { + public final Vertex inverseTransform(Vertex src, Vertex dst) throws NoninvertibleTransformException { float det = getDeterminant(); if (FloatUtil.abs(det) < ZERO) { 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; } - public void inverseTransform(float[] src, int srcOff, float[] dst, int dstOff, int length) + public final void inverseTransform(float[] src, int srcOff, float[] dst, int dstOff, int length) throws NoninvertibleTransformException { float det = getDeterminant(); @@ -497,12 +498,12 @@ public class AffineTransform implements Cloneable, Serializable { } } - public Path2D createTransformedShape(Path2D src) { + public final Path2D createTransformedShape(Path2D src) { if (src == null) { 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()); @@ -511,7 +512,7 @@ public class AffineTransform implements Cloneable, Serializable { } @Override - public String toString() { + public final String toString() { return getClass().getName() + "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ @@ -519,7 +520,7 @@ public class AffineTransform implements Cloneable, Serializable { } @Override - public AffineTransform clone() { + public final AffineTransform clone() { try { return (AffineTransform) super.clone(); } catch (CloneNotSupportedException e) { @@ -540,7 +541,7 @@ public class AffineTransform implements Cloneable, Serializable { } */ @Override - public boolean equals(Object obj) { + public final boolean equals(Object obj) { if (obj == this) { return true; } @@ -553,28 +554,5 @@ public class AffineTransform implements Cloneable, Serializable { } return false; } - - - /** - * Write AffineTrasform object to the output steam. - * @param stream - the output stream - * @throws IOException - if there are I/O errors while writing to the output strem - */ - private void writeObject(java.io.ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - } - - - /** - * Read AffineTransform object from the input stream - * @param stream - the input steam - * @throws IOException - if there are I/O errors while reading from the input strem - * @throws ClassNotFoundException - if class could not be found - */ - private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - type = TYPE_UNKNOWN; - } - } 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; |