From 9c71f276d1fcc87b69b413847fd1da34b30d0932 Mon Sep 17 00:00:00 2001
From: Sven Gothel
+ * A region is also dirty if other render attributes or parameters are changed!
+ * In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit
- * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.
+ * FIXME: Utilize 'ARB_Uniform_Buffer_Object' where available! + *
+ */ + public static class ProgramLocal { + public final GLUniformData gcu_PMVMatrix01; + public final GLUniformData gcu_Weight; + public final GLUniformData gcu_ColorStatic; + private int rsId = -1; + + public ProgramLocal() { + gcu_PMVMatrix01 = GLUniformData.creatEmptyMatrix(UniformNames.gcu_PMVMatrix01, 4, 4); + gcu_Weight = GLUniformData.creatEmptyVector(UniformNames.gcu_Weight, 1); + gcu_ColorStatic = GLUniformData.creatEmptyVector(UniformNames.gcu_ColorStatic, 4); + } + + public final int getRenderStateId() { return rsId; } + + /** + *+ * Since {@link RenderState} data is being used in multiple + * {@link ShaderProgram}s the data must always be written. + *
+ * @param gl + * @param updateLocation + * @param renderModes + * @param throwOnError TODO + * @return true if no error occurred, i.e. all locations found, otherwise false. + */ + public final boolean update(final GL2ES2 gl, final RenderState rs, final boolean updateLocation, final int renderModes, final boolean pass1, final boolean throwOnError) { + if( rs.id() != rsId ) { + gcu_PMVMatrix01.setData(rs.pmvMatrix.glGetPMvMatrixf()); + gcu_Weight.setData(rs.weightBuffer); + gcu_ColorStatic.setData(rs.colorStaticBuffer); + rsId = rs.id(); + } + boolean res = true; + if( null != rs.sp && rs.sp.inUse() ) { + if( !Region.isTwoPass(renderModes) || !pass1 ) { + final boolean r0 = rs.updateUniformDataLoc(gl, updateLocation, true, gcu_PMVMatrix01, throwOnError); + res = res && r0; + } + if( pass1 ) { + if( Region.hasVariableWeight( renderModes ) ) { + final boolean r0 = rs.updateUniformDataLoc(gl, updateLocation, true, gcu_Weight, throwOnError); + res = res && r0; + } + { + final boolean r0 = rs.updateUniformDataLoc(gl, updateLocation, true, gcu_ColorStatic, throwOnError); + res = res && r0; + } + } + } + return res; + } + + public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) { + if(null==sb) { + sb = new StringBuilder(); + } + sb.append("ProgramLocal[rsID ").append(rsId).append(Platform.NEWLINE); + // pmvMatrix.toString(sb, "%.2f"); + sb.append(gcu_PMVMatrix01).append(", ").append(Platform.NEWLINE); + sb.append(gcu_ColorStatic).append(", "); + sb.append(gcu_Weight).append("]"); + return sb; + } + + @Override + public String toString() { + return toString(null, false).toString(); + } + } + protected RenderState(Vertex.Factory extends Vertex> vertexFactory, PMVMatrix pmvMatrix) { + this.id = getNextID(); this.sp = null; this.vertexFactory = vertexFactory; this.pmvMatrix = null != pmvMatrix ? pmvMatrix : new PMVMatrix(); - this.gcu_PMVMatrix01 = new GLUniformData(UniformNames.gcu_PMVMatrix01, 4, 4, this.pmvMatrix.glGetPMvMatrixf()); - this.gcu_Weight = new GLUniformData(UniformNames.gcu_Weight, 1.0f); - this.gcu_ColorStatic = new GLUniformData(UniformNames.gcu_ColorStatic, 4, FloatBuffer.allocate(4)); + this.weight = new float[1]; + this.weightBuffer = FloatBuffer.wrap(weight); + this.colorStatic = new float[4]; + this.colorStaticBuffer = FloatBuffer.wrap(colorStatic); this.hintBitfield = 0; } + public final int id() { return id; } public final ShaderProgram getShaderProgram() { return sp; } public final boolean isShaderProgramInUse() { return null != sp ? sp.inUse() : false; } @@ -124,86 +209,46 @@ public class RenderState { public final Vertex.Factory extends Vertex> getVertexFactory() { return vertexFactory; } public final PMVMatrix getMatrix() { return pmvMatrix; } - public final PMVMatrix getMatrixMutable() { - gcu_PMVMatrix01_dirty = true; - return pmvMatrix; - } - public final GLUniformData getMatrixUniform() { return gcu_PMVMatrix01; } - public final void setMatrixDirty() { gcu_PMVMatrix01_dirty = true; } - public final boolean isMatrixDirty() { return gcu_PMVMatrix01_dirty;} public static boolean isWeightValid(float v) { return 0.0f <= v && v <= 1.9f ; } - public final float getWeight() { return gcu_Weight.floatValue(); } + public final float getWeight() { return weight[0]; } public final void setWeight(float v) { if( !isWeightValid(v) ) { throw new IllegalArgumentException("Weight out of range"); } - gcu_Weight_dirty = true; - gcu_Weight.setData(v); + weight[0] = v; } public final float[] getColorStatic(float[] rgbaColor) { - FloatBuffer fb = (FloatBuffer) gcu_ColorStatic.getBuffer(); - rgbaColor[0] = fb.get(0); - rgbaColor[1] = fb.get(1); - rgbaColor[2] = fb.get(2); - rgbaColor[3] = fb.get(3); + System.arraycopy(colorStatic, 0, rgbaColor, 0, 4); return rgbaColor; } public final void setColorStatic(float r, float g, float b, float a){ - final FloatBuffer fb = (FloatBuffer) gcu_ColorStatic.getBuffer(); - fb.put(0, r); - fb.put(1, g); - fb.put(2, b); - fb.put(3, a); - gcu_ColorStatic_dirty = true; + colorStatic[0] = r; + colorStatic[1] = g; + colorStatic[2] = b; + colorStatic[3] = a; } - /** - * - * @param gl - * @param updateLocation - * @param renderModes - * @return true if no error occurred, i.e. all locations found, otherwise false. - */ - public final boolean update(GL2ES2 gl, final boolean updateLocation, final int renderModes, final boolean pass1) { - boolean res = true; - if( null != sp && sp.inUse() ) { - if( ( !Region.isTwoPass(renderModes) || !pass1 ) && ( gcu_PMVMatrix01_dirty || updateLocation ) ) { - final boolean r0 = updateUniformDataLoc(gl, updateLocation, gcu_PMVMatrix01_dirty, gcu_PMVMatrix01); - res = res && r0; - gcu_PMVMatrix01_dirty = !r0; - } - if( pass1 ) { - if( Region.hasVariableWeight( renderModes ) && ( gcu_Weight_dirty || updateLocation ) ) { - final boolean r0 = updateUniformDataLoc(gl, updateLocation, gcu_Weight_dirty, gcu_Weight); - res = res && r0; - gcu_Weight_dirty = !r0; - } - if( gcu_ColorStatic_dirty || updateLocation ) { - final boolean r0 = updateUniformDataLoc(gl, updateLocation, gcu_ColorStatic_dirty, gcu_ColorStatic); - res = res && r0; - gcu_ColorStatic_dirty = false; - } - } - } - return res; - } - /** * * @param gl * @param updateLocation * @param data + * @param throwOnError TODO * @return true if no error occured, i.e. all locations found, otherwise false. */ - public final boolean updateUniformLoc(final GL2ES2 gl, final boolean updateLocation, final GLUniformData data) { + public final boolean updateUniformLoc(final GL2ES2 gl, final boolean updateLocation, final GLUniformData data, final boolean throwOnError) { if( updateLocation || 0 > data.getLocation() ) { - return 0 <= data.setLocation(gl, sp.program()); + final boolean ok = 0 <= data.setLocation(gl, sp.program()); + if( throwOnError && !ok ) { + throw new GLException("Could not locate "+data); + } + return ok; } else { return true; } @@ -215,12 +260,16 @@ public class RenderState { * @param updateLocation * @param updateData TODO * @param data + * @param throwOnError TODO * @return true if no error occured, i.e. all locations found, otherwise false. */ - public final boolean updateUniformDataLoc(final GL2ES2 gl, boolean updateLocation, boolean updateData, final GLUniformData data) { + public final boolean updateUniformDataLoc(final GL2ES2 gl, boolean updateLocation, boolean updateData, final GLUniformData data, final boolean throwOnError) { updateLocation = updateLocation || 0 > data.getLocation(); if( updateLocation ) { updateData = 0 <= data.setLocation(gl, sp.program()); + if( throwOnError && !updateData ) { + throw new GLException("Could not locate "+data); + } } if( updateData ){ gl.glUniform(data); @@ -233,11 +282,16 @@ public class RenderState { /** * @param gl * @param data + * @param throwOnError TODO * @return true if no error occured, i.e. all locations found, otherwise false. */ - public final boolean updateAttributeLoc(final GL2ES2 gl, final boolean updateLocation, final GLArrayDataServer data) { + public final boolean updateAttributeLoc(final GL2ES2 gl, final boolean updateLocation, final GLArrayDataServer data, boolean throwOnError) { if( updateLocation || 0 > data.getLocation() ) { - return 0 <= data.setLocation(gl, sp.program()); + final boolean ok = 0 <= data.setLocation(gl, sp.program()); + if( throwOnError && !ok ) { + throw new GLException("Could not locate "+data); + } + return ok; } else { return true; } @@ -274,21 +328,8 @@ public class RenderState { return false; } - public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) { - if(null==sb) { - sb = new StringBuilder(); - } - sb.append("RenderState[").append(sp).append(Platform.NEWLINE); - // pmvMatrix.toString(sb, "%.2f"); - sb.append(", dirty[pmv "+gcu_PMVMatrix01_dirty+", color "+gcu_ColorStatic_dirty+", weight "+gcu_Weight_dirty+"], ").append(Platform.NEWLINE); - sb.append(gcu_PMVMatrix01).append(", ").append(Platform.NEWLINE); - sb.append(gcu_ColorStatic).append(", "); - sb.append(gcu_Weight).append("]"); - return sb; - } - @Override public String toString() { - return toString(null, false).toString(); + return "RenderState["+sp+"]"; } } diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index f944843e9..aadbecc91 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -178,7 +178,7 @@ public class TextRegionUtil { final int special = 0; GLRegion region = getCachedRegion(font, str, pixelSize, special); if(null == region) { - region = GLRegion.create(renderModes); + region = GLRegion.create(renderModes, null); addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor, tempT1, tempT2); addCachedRegion(gl, font, str, pixelSize, special, region); } @@ -213,7 +213,7 @@ public class TextRegionUtil { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } - final GLRegion region = GLRegion.create(renderModes); + final GLRegion region = GLRegion.create(renderModes, null); addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor, temp1, temp2); region.draw(gl, renderer, sampleCount); region.destroy(gl); diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java index 6a4b13dfb..3ac17b0c5 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java @@ -56,7 +56,7 @@ public class ShaderProgram { /** * returns the uniq shader id as an integer */ - public int id() { return id; } + public int id() { return id; } /** * Detaches all shader codes and deletes the program. @@ -321,7 +321,7 @@ public class ShaderProgram { private int shaderProgram = 0; // non zero is valid! private final HashSet+ * Since multiple {@link Region}s may share one + * {@link ShaderProgram}, the uniform data must always be updated. + *
+ * + * @param gl + * @param renderer + * @param renderModes + * @param pass1 + * @param quality + * @param sampleCount + */ public void useShaderProgram(final GL2ES2 gl, final RegionRenderer renderer, final int renderModes, final boolean pass1, final int quality, final int sampleCount) { final RenderState rs = renderer.getRenderState(); - renderer.useShaderProgram(gl, renderModes, pass1, quality, sampleCount); + final boolean updateLocGlobal = renderer.useShaderProgram(gl, renderModes, pass1, quality, sampleCount); final ShaderProgram sp = renderer.getRenderState().getShaderProgram(); - final boolean updateLocation; + final boolean updateLocLocal; if( pass1 ) { - updateLocation = !sp.equals(spPass1); + updateLocLocal = !sp.equals(spPass1); spPass1 = sp; - rs.update(gl, updateLocation, renderModes, true); - rs.updateUniformLoc(gl, updateLocation, gcu_PMVMatrix02); - rs.updateAttributeLoc(gl, updateLocation, gca_VerticesAttr); - rs.updateAttributeLoc(gl, updateLocation, gca_CurveParamsAttr); - if( null != gca_ColorsAttr ) { - rs.updateAttributeLoc(gl, updateLocation, gca_ColorsAttr); + if( DEBUG ) { + System.err.println("XXX changedSP.p1 updateLocation loc "+updateLocLocal+" / glob "+updateLocGlobal); + } + if( updateLocLocal ) { + rs.updateAttributeLoc(gl, true, gca_VerticesAttr, true); + rs.updateAttributeLoc(gl, true, gca_CurveParamsAttr, true); + if( null != gca_ColorsAttr ) { + rs.updateAttributeLoc(gl, true, gca_ColorsAttr, true); + } + } + rsLocal.update(gl, rs, updateLocLocal, renderModes, true, true); + rs.updateUniformLoc(gl, updateLocLocal, gcu_PMVMatrix02, true); + if( null != gcu_ColorTexUnit ) { + rs.updateUniformLoc(gl, updateLocLocal, gcu_ColorTexUnit, true); + rs.updateUniformLoc(gl, updateLocLocal, gcu_ColorTexBBox, true); } } else { - updateLocation = !sp.equals(spPass2); + updateLocLocal = !sp.equals(spPass2); spPass2 = sp; - rs.update(gl, updateLocation, renderModes, false); - rs.updateAttributeLoc(gl, updateLocation, gca_FboVerticesAttr); - rs.updateAttributeLoc(gl, updateLocation, gca_FboTexCoordsAttr); - rs.updateUniformDataLoc(gl, updateLocation, true, gcu_FboTexUnit); - rs.updateUniformLoc(gl, updateLocation, gcu_FboTexSize); + if( DEBUG ) { + System.err.println("XXX changedSP.p2 updateLocation loc "+updateLocLocal+" / glob "+updateLocGlobal); + } + if( updateLocLocal ) { + rs.updateAttributeLoc(gl, true, gca_FboVerticesAttr, true); + rs.updateAttributeLoc(gl, true, gca_FboTexCoordsAttr, true); + } + rsLocal.update(gl, rs, updateLocLocal, renderModes, false, true); + rs.updateUniformDataLoc(gl, updateLocLocal, false /* updateData */, gcu_FboTexUnit, true); // FIXME always update if changing tex-unit + rs.updateUniformLoc(gl, updateLocLocal, gcu_FboTexSize, true); } } - public VBORegion2PVBAAES2(final int renderModes, final int textureUnit) { - super(renderModes); + public VBORegion2PVBAAES2(final int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit) { + super(renderModes, colorTexSeq); + + rsLocal = new RenderState.ProgramLocal(); + final int initialElementCount = 256; // Pass 1: @@ -154,14 +190,23 @@ public class VBORegion2PVBAAES2 extends GLRegion { } else { gca_ColorsAttr = null; } + if( hasColorTexture() ) { + gcu_ColorTexUnit = new GLUniformData(UniformNames.gcu_ColorTexUnit, colorTexSeq.getTextureUnit()); + colorTexBBox = new float[4]; + gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 4, FloatBuffer.wrap(colorTexBBox)); + } else { + gcu_ColorTexUnit = null; + colorTexBBox = null; + gcu_ColorTexBBox = null; + } FloatUtil.makeIdentityf(pmvMatrix02, 0); FloatUtil.makeIdentityf(pmvMatrix02, 16); gcu_PMVMatrix02 = new GLUniformData(UniformNames.gcu_PMVMatrix02, 4, 4, FloatBuffer.wrap(pmvMatrix02)); // Pass 2: - gcu_FboTexUnit = new GLUniformData(UniformNames.gcu_FboTexUnit, textureUnit); - gcu_FboTexSize = new GLUniformData(UniformNames.gcu_FboTexSize, 2, Buffers.newDirectFloatBuffer(2)); + gcu_FboTexUnit = new GLUniformData(UniformNames.gcu_FboTexUnit, pass2TexUnit); + gcu_FboTexSize = new GLUniformData(UniformNames.gcu_FboTexSize, 2, FloatBuffer.wrap(new float[2])); 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); @@ -250,8 +295,12 @@ public class VBORegion2PVBAAES2 extends GLRegion { gca_ColorsAttr.seal(gl, true); gca_ColorsAttr.enableBuffer(gl, false); } - - // update all bbox related data + if( null != gcu_ColorTexUnit ) { + colorTexBBox[0] = box.getMinX(); + colorTexBBox[1] = box.getMinY(); + colorTexBBox[2] = box.getMaxX(); + colorTexBBox[3] = box.getMaxY(); + } gca_FboVerticesAttr.seal(gl, false); { final FloatBuffer fb = (FloatBuffer)gca_FboVerticesAttr.getBuffer(); @@ -537,14 +586,30 @@ public class VBORegion2PVBAAES2 extends GLRegion { private void renderRegion(final GL2ES2 gl) { gl.glUniform(gcu_PMVMatrix02); + gca_VerticesAttr.enableBuffer(gl, true); gca_CurveParamsAttr.enableBuffer(gl, true); if( null != gca_ColorsAttr ) { gca_ColorsAttr.enableBuffer(gl, true); } indicesBuffer.bindBuffer(gl, true); // keeps VBO binding - - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + if( null != gcu_ColorTexUnit ) { + final TextureSequence.TextureFrame frame = colorTexSeq.getNextTexture(gl); + gl.glActiveTexture(GL.GL_TEXTURE0 + colorTexSeq.getTextureUnit()); + final Texture tex = frame.getTexture(); + tex.bind(gl); + tex.enable(gl); // nop on core + final int colorTexUnit = colorTexSeq.getTextureUnit(); + if( colorTexUnit != gcu_ColorTexUnit.intValue() ) { + gcu_ColorTexUnit.setData(colorTexUnit); + gl.glUniform(gcu_ColorTexUnit); + } + gl.glUniform(gcu_ColorTexBBox); // FIXME: Only if changed! + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + tex.disable(gl); // nop on core + } else { + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + } indicesBuffer.bindBuffer(gl, false); if( null != gca_ColorsAttr ) { diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index 8268394dd..0ec139a0f 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java @@ -27,26 +27,41 @@ */ package jogamp.graph.curve.opengl; +import java.nio.FloatBuffer; + import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLUniformData; import jogamp.graph.curve.opengl.shader.AttributeNames; +import jogamp.graph.curve.opengl.shader.UniformNames; +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.util.GLArrayDataServer; import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.texture.Texture; +import com.jogamp.opengl.util.texture.TextureSequence; public class VBORegionSPES2 extends GLRegion { + private final RenderState.ProgramLocal rsLocal; + private GLArrayDataServer gca_VerticesAttr = null; private GLArrayDataServer gca_CurveParamsAttr = null; private GLArrayDataServer gca_ColorsAttr; private GLArrayDataServer indicesBuffer = null; + private final GLUniformData gcu_ColorTexUnit; + private final float[] colorTexBBox; // x0, y0, x1, y1 + private final GLUniformData gcu_ColorTexBBox; private ShaderProgram spPass1 = null; - public VBORegionSPES2(final int renderModes) { - super(renderModes); + public VBORegionSPES2(final int renderModes, final TextureSequence colorTexSeq) { + super(renderModes, colorTexSeq); + + rsLocal = new RenderState.ProgramLocal(); + final int initialElementCount = 256; indicesBuffer = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); @@ -62,6 +77,15 @@ public class VBORegionSPES2 extends GLRegion { } else { gca_ColorsAttr = null; } + if( hasColorTexture() ) { + gcu_ColorTexUnit = new GLUniformData(UniformNames.gcu_ColorTexUnit, colorTexSeq.getTextureUnit()); + colorTexBBox = new float[4]; + gcu_ColorTexBBox = new GLUniformData(UniformNames.gcu_ColorTexBBox, 4, FloatBuffer.wrap(colorTexBBox)); + } else { + gcu_ColorTexUnit = null; + colorTexBBox = null; + gcu_ColorTexBBox = null; + } } @Override @@ -117,8 +141,6 @@ public class VBORegionSPES2 extends GLRegion { @Override protected void updateImpl(final GL2ES2 gl) { // seal buffers - indicesBuffer.seal(gl, true); - indicesBuffer.enableBuffer(gl, false); gca_VerticesAttr.seal(gl, true); gca_VerticesAttr.enableBuffer(gl, false); gca_CurveParamsAttr.seal(gl, true); @@ -127,6 +149,14 @@ public class VBORegionSPES2 extends GLRegion { gca_ColorsAttr.seal(gl, true); gca_ColorsAttr.enableBuffer(gl, false); } + if( null != gcu_ColorTexUnit ) { + colorTexBBox[0] = box.getMinX(); + colorTexBBox[1] = box.getMinY(); + colorTexBBox[2] = box.getMaxX(); + colorTexBBox[3] = box.getMaxY(); + } + indicesBuffer.seal(gl, true); + indicesBuffer.enableBuffer(gl, false); if(DEBUG_INSTANCE) { System.err.println("VBORegionSPES2 idx "+indicesBuffer); System.err.println("VBORegionSPES2 ver "+gca_VerticesAttr); @@ -134,22 +164,37 @@ public class VBORegionSPES2 extends GLRegion { } } + /** + *+ * Since multiple {@link Region}s may share one + * {@link ShaderProgram}, the uniform data must always be updated. + *
+ * + * @param gl + * @param renderer + * @param renderModes + * @param quality + */ public void useShaderProgram(final GL2ES2 gl, final RegionRenderer renderer, final int renderModes, final int quality) { final RenderState rs = renderer.getRenderState(); - final boolean updateLocation0 = renderer.useShaderProgram(gl, renderModes, true, quality, 0); + final boolean updateLocGlobal = renderer.useShaderProgram(gl, renderModes, true, quality, 0); final ShaderProgram sp = renderer.getRenderState().getShaderProgram(); - final boolean updateLocation = !sp.equals(spPass1); + final boolean updateLocLocal = !sp.equals(spPass1); spPass1 = sp; - - // update attribute-location and uniform data and location - rs.update(gl, updateLocation, renderModes, true); - rs.updateAttributeLoc(gl, updateLocation, gca_VerticesAttr); - rs.updateAttributeLoc(gl, updateLocation, gca_CurveParamsAttr); - if( null != gca_ColorsAttr ) { - rs.updateAttributeLoc(gl, updateLocation, gca_ColorsAttr); - } if( DEBUG ) { - System.err.println("XXX changedSP.p1 "+updateLocation+" / "+updateLocation0); + System.err.println("XXX changedSP.p1 updateLocation loc "+updateLocLocal+" / glob "+updateLocGlobal); + } + if( updateLocLocal ) { + rs.updateAttributeLoc(gl, true, gca_VerticesAttr, true); + rs.updateAttributeLoc(gl, true, gca_CurveParamsAttr, true); + if( null != gca_ColorsAttr ) { + rs.updateAttributeLoc(gl, true, gca_ColorsAttr, true); + } + } + rsLocal.update(gl, rs, updateLocLocal, renderModes, true, true); + if( null != gcu_ColorTexUnit ) { + rs.updateUniformLoc(gl, updateLocLocal, gcu_ColorTexUnit, true); + rs.updateUniformLoc(gl, updateLocLocal, gcu_ColorTexBBox, true); } } @@ -171,8 +216,23 @@ public class VBORegionSPES2 extends GLRegion { gca_ColorsAttr.enableBuffer(gl, true); } indicesBuffer.bindBuffer(gl, true); // keeps VBO binding - - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + if( null != gcu_ColorTexUnit ) { + final TextureSequence.TextureFrame frame = colorTexSeq.getNextTexture(gl); + gl.glActiveTexture(GL.GL_TEXTURE0 + colorTexSeq.getTextureUnit()); + final Texture tex = frame.getTexture(); + tex.bind(gl); + tex.enable(gl); // nop on core + final int colorTexUnit = colorTexSeq.getTextureUnit(); + if( colorTexUnit != gcu_ColorTexUnit.intValue() ) { + gcu_ColorTexUnit.setData(colorTexUnit); + gl.glUniform(gcu_ColorTexUnit); + } + gl.glUniform(gcu_ColorTexBBox); // FIXME: Only if changed! + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + tex.disable(gl); // nop on core + } else { + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + } indicesBuffer.bindBuffer(gl, false); if( null != gca_ColorsAttr ) { diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/AttributeNames.java b/src/jogl/classes/jogamp/graph/curve/opengl/shader/AttributeNames.java index b2c73a2e4..dff536645 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/AttributeNames.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/AttributeNames.java @@ -44,6 +44,7 @@ public class AttributeNames { public static final String COLOR_ATTR_NAME = "gca_Colors"; public static final String FBO_VERTEX_ATTR_NAME = "gca_FboVertices"; + public static final String FBO_TEXCOORDS_ATTR_NAME = "gca_FboTexCoords"; } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/UniformNames.java b/src/jogl/classes/jogamp/graph/curve/opengl/shader/UniformNames.java index f37025516..7244851ff 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/UniformNames.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/UniformNames.java @@ -4,6 +4,8 @@ public class UniformNames { public static final String gcu_PMVMatrix01 = "gcu_PMVMatrix01"; // gcu_PMVMatrix[3]; // P, Mv, and Mvi public static final String gcu_ColorStatic = "gcu_ColorStatic"; public static final String gcu_Weight = "gcu_Weight"; + public static final String gcu_ColorTexUnit = "gcu_ColorTexUnit"; + public static final String gcu_ColorTexBBox = "gcu_ColorTexBBox"; public static final String gcu_PMVMatrix02 = "gcu_PMVMatrix02"; // gcu_PMVMatrix[3]; // P, Mv, and Mvi public static final String gcu_FboTexUnit = "gcu_FboTexUnit"; diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl index 373e8d575..83b312a0b 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1-curve_simple.glsl @@ -1,7 +1,11 @@ if( gcv_CurveParam.x == 0.0 && gcv_CurveParam.y == 0.0 ) { // pass-1: Lines -#ifdef USE_COLOR_CHANNEL +#if defined(USE_COLOR_TEXTURE) && defined(USE_COLOR_CHANNEL) + mgl_FragColor = texture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st) * gcv_Color * gcu_ColorStatic; +#elif defined(USE_COLOR_TEXTURE) + mgl_FragColor = texture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st) * gcu_ColorStatic; +#elif defined(USE_COLOR_CHANNEL) mgl_FragColor = gcv_Color * gcu_ColorStatic; #else mgl_FragColor = gcu_ColorStatic; @@ -17,7 +21,13 @@ float position = rtex.y - (rtex.x * (1.0 - rtex.x)); float a = clamp(0.5 - ( position/length(f) ) * sign(gcv_CurveParam.y), 0.0, 1.0); -#ifdef USE_COLOR_CHANNEL +#if defined(USE_COLOR_TEXTURE) && defined(USE_COLOR_CHANNEL) + vec4 t = texture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st); + mgl_FragColor = vec4(t.rgb * gcv_Color.rgb * gcu_ColorStatic.rgb, t.a * gcv_Color.a * gcu_ColorStatic.a * a); +#elif defined(USE_COLOR_TEXTURE) + vec4 t = texture2D(gcu_ColorTexUnit, gcv_ColorTexCoord.st); + mgl_FragColor = vec4(t.rgb * gcu_ColorStatic.rgb, t.a * gcu_ColorStatic.a * a); +#elif defined(USE_COLOR_CHANNEL) mgl_FragColor = vec4(gcv_Color.rgb * gcu_ColorStatic.rgb, gcv_Color.a * gcu_ColorStatic.a * a); #else mgl_FragColor = vec4(gcu_ColorStatic.rgb, gcu_ColorStatic.a * a); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp index 46729cfd0..c6ed4ca58 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-pass1.vp @@ -11,7 +11,6 @@ void main(void) { - // gl_Position = gcu_PMVMatrix02[0] * gcu_PMVMatrix02[1] * vec4(gca_Vertices, 1); gl_Position = gcu_PMVMatrix02[0] * gcu_PMVMatrix02[1] * gca_Vertices; #if 1 gcv_CurveParam = gca_CurveParams; @@ -24,6 +23,10 @@ void main(void) gcv_CurveParam = gca_CurveParams; } #endif +#ifdef USE_COLOR_TEXTURE + vec2 dim = vec2(gcu_ColorTexBBox.z - gcu_ColorTexBBox.x, gcu_ColorTexBBox.w - gcu_ColorTexBBox.y); + gcv_ColorTexCoord = vec2(gca_Vertices.x - gcu_ColorTexBBox.x, gca_Vertices.y - gcu_ColorTexBBox.y) / dim; +#endif #ifdef USE_COLOR_CHANNEL gcv_Color = gca_Colors; #endif diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-single.vp b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-single.vp index 7598c23f8..14210be39 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-single.vp +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/curverenderer01-single.vp @@ -11,7 +11,6 @@ void main(void) { - // gl_Position = gcu_PMVMatrix01[0] * gcu_PMVMatrix01[1] * vec4(gca_Vertices, 1); gl_Position = gcu_PMVMatrix01[0] * gcu_PMVMatrix01[1] * gca_Vertices; #if 1 gcv_CurveParam = gca_CurveParams; @@ -24,6 +23,10 @@ void main(void) gcv_CurveParam = gca_CurveParams; } #endif +#ifdef USE_COLOR_TEXTURE + vec2 dim = vec2(gcu_ColorTexBBox.z - gcu_ColorTexBBox.x, gcu_ColorTexBBox.w - gcu_ColorTexBBox.y); + gcv_ColorTexCoord = vec2(gca_Vertices.x - gcu_ColorTexBBox.x, gca_Vertices.y - gcu_ColorTexBBox.y) / dim; +#endif #ifdef USE_COLOR_CHANNEL gcv_Color = gca_Colors; #endif 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 848c26819..ae7fa8490 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/uniforms.glsl @@ -6,6 +6,11 @@ uniform mat4 gcu_PMVMatrix01[3]; // P, Mv, and Mvi uniform vec4 gcu_ColorStatic; uniform float gcu_Weight; +#ifdef USE_COLOR_TEXTURE + uniform sampler2D gcu_ColorTexUnit; + uniform vec4 gcu_ColorTexBBox; +#endif + uniform mat4 gcu_PMVMatrix02[3]; // P, Mv, and Mvi uniform sampler2D gcu_FboTexUnit; @@ -14,11 +19,4 @@ uniform sampler2D gcu_FboTexUnit; */ uniform vec2 gcu_FboTexSize; -// const int MAX_TEXTURE_UNITS = 8; // <= gl_MaxTextureImageUnits -// const int MAX_LIGHTS = 8; -// uniform mat3 gcu_NormalMatrix; // transpose(inverse(ModelView)).3x3 -// uniform int gcu_ColorEnabled; -// uniform int gcu_TexCoordEnabled[MAX_TEXTURE_UNITS]; -// uniform int gcu_CullFace; - #endif // uniforms_glsl diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl b/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl index 2054c9c21..265ab6915 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl +++ b/src/jogl/classes/jogamp/graph/curve/opengl/shader/varyings.glsl @@ -6,6 +6,10 @@ varying vec3 gcv_CurveParam; varying vec2 gcv_FboTexCoord; +#ifdef USE_COLOR_TEXTURE + varying vec2 gcv_ColorTexCoord; +#endif + #ifdef USE_COLOR_CHANNEL varying vec4 gcv_Color; #endif -- cgit v1.2.3