diff options
author | Sven Gothel <[email protected]> | 2014-04-02 04:41:48 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-04-02 04:41:48 +0200 |
commit | e8a5a1cbb988670ca206ab1ac633e19a91bfa478 (patch) | |
tree | 5b9f17a06ad350150375a2a0e38daa3d6dd11251 /src/jogl/classes/com/jogamp | |
parent | 6f5686696b1e9085a759774056c7be9887a9e34f (diff) |
Bug 801: WIP 2/2 - Add color attribute; Switch Shader instead of branching in shader; Update attributes and uniforms manually, drop ShaderState;
- Due to shader-switching,
'renderModes' are now local to Region, e.g. UIShape etc
- Remove RegionRenderer.renderModes
- VBORegion2P*:
- Use simple 2x float matrix for orthogonal P+Mv
- Cleanup shader
Diffstat (limited to 'src/jogl/classes/com/jogamp')
9 files changed, 246 insertions, 163 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index 2cd68a806..7edd2f572 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -51,7 +51,7 @@ public abstract class Region { public static final boolean DEBUG_INSTANCE = Debug.debug("graph.curve.Instance"); /** - * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * Rendering-Mode bit for {@link #getRenderModes() Region} * <p> * MSAA based Anti-Aliasing, a two pass region rendering, slower and more * resource hungry (FBO), but providing fast MSAA in case @@ -61,7 +61,7 @@ public abstract class Region { public static final int MSAA_RENDERING_BIT = 1 << 0; /** - * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * Rendering-Mode bit for {@link #getRenderModes() Region} * <p> * View based Anti-Aliasing, a two pass region rendering, slower and more * resource hungry (FBO), but AA is perfect. Otherwise the default fast one @@ -71,7 +71,7 @@ public abstract class Region { public static final int VBAA_RENDERING_BIT = 1 << 1; /** - * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * Rendering-Mode bit for {@link #getRenderModes() Region} * <p> * Use non uniform weights [0.0 .. 1.9] for curve region rendering. * Otherwise the default weight 1.0 for uniform curve region rendering is @@ -81,7 +81,7 @@ public abstract class Region { public static final int VARWEIGHT_RENDERING_BIT = 1 << 8; /** - * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * Rendering-Mode bit for {@link #getRenderModes() Region} * <p> * If set, a color channel attribute per vertex is added to the stream, * otherwise only the @@ -92,13 +92,16 @@ public abstract class Region { public static final int COLORCHANNEL_RENDERING_BIT = 1 << 9; /** - * Rendering-Mode bit for {@link Region#getRenderModes() Region} and {@link com.jogamp.graph.curve.opengl.RegionRenderer#getRenderModes() RegionRenderer}. + * Rendering-Mode bit for {@link #getRenderModes() Region} * <p> * If set, a color texture is used to determine the color. * </p> */ public static final int COLORTEXTURE_RENDERING_BIT = 1 << 10; + /** Default maximum {@link #getQuality() quality}, {@value}. */ + public static final int MAX_QUALITY = 1; + public static final int TWO_PASS_DEFAULT_TEXTURE_UNIT = 0; private final int renderModes; @@ -162,7 +165,7 @@ public abstract class Region { protected Region(int regionRenderModes) { this.renderModes = regionRenderModes; - this.quality = 99; + this.quality = MAX_QUALITY; } // FIXME: Better handling of impl. buffer growth .. ! @@ -176,7 +179,10 @@ public abstract class Region { */ public final int getRenderModes() { return renderModes; } + /** See {@link #MAX_QUALITY} */ public final int getQuality() { return quality; } + + /** See {@link #MAX_QUALITY} */ public final void setQuality(int q) { quality=q; } protected void clearImpl() { diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java index e305cc336..9505f2a9d 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java @@ -78,26 +78,26 @@ public abstract class GLRegion extends Region { * <p>Allocates the ogl related data and initializes it the 1st time.<p>
* <p>Called by {@link #draw(GL2ES2, RenderState, int, int, int)}.</p>
*/
- protected abstract void updateImpl(GL2ES2 gl, RegionRenderer renderer);
+ protected abstract void updateImpl(final GL2ES2 gl);
- protected abstract void destroyImpl(GL2ES2 gl, RegionRenderer renderer);
+ protected abstract void destroyImpl(final GL2ES2 gl);
- protected abstract void clearImpl(final GL2ES2 gl, final RegionRenderer renderer);
+ protected abstract void clearImpl(final GL2ES2 gl);
/**
* Clears all data, i.e. triangles, vertices etc.
*/
- public void clear(final GL2ES2 gl, final RegionRenderer renderer) {
- clearImpl(gl, renderer);
+ public void clear(final GL2ES2 gl) {
+ clearImpl(gl);
clearImpl();
}
/**
* Delete and clear the associated OGL objects.
*/
- public final void destroy(GL2ES2 gl, RegionRenderer renderer) {
- clear(gl, renderer);
- destroyImpl(gl, renderer);
+ public final void destroy(GL2ES2 gl) {
+ clear(gl);
+ destroyImpl(gl);
}
/**
@@ -120,7 +120,7 @@ public abstract class GLRegion extends Region { * The <i>alpha</i> component shall be set to zero.
* Note: If {@link GL#GL_BLEND blending} is enabled, the
* {@link RegionRenderer} might need to be
- * {@link RegionRenderer#create(RenderState, int, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) created}
+ * {@link RegionRenderer#create(RenderState, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) created}
* with the appropriate {@link {@link RegionRenderer.GLCallback callbacks}.
* </p>
* @param matrix current {@link PMVMatrix}.
@@ -129,13 +129,13 @@ public abstract class GLRegion extends Region { * The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched.
* @see RegionRenderer#enable(GL2ES2, boolean)
*/
- public final void draw(GL2ES2 gl, RegionRenderer renderer, int[/*1*/] sampleCount) {
+ public final void draw(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount) {
if(isDirty()) {
- updateImpl(gl, renderer);
+ updateImpl(gl);
setDirty(false);
}
drawImpl(gl, renderer, sampleCount);
}
- protected abstract void drawImpl(GL2ES2 gl, RegionRenderer renderer, int[/*1*/] sampleCount);
+ protected abstract void drawImpl(final GL2ES2 gl, final RegionRenderer renderer, final int[/*1*/] sampleCount);
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java index 8df34ead5..ade6098e1 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -70,7 +70,7 @@ public class RegionRenderer { * <p> * Implementation also sets {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}. * </p> - * @see #create(RenderState, int, GLCallback, GLCallback) + * @see #create(RenderState, GLCallback, GLCallback) * @see #enable(GL2ES2, boolean) */ public static final GLCallback defaultBlendEnable = new GLCallback() { @@ -89,7 +89,7 @@ public class RegionRenderer { * <p> * Implementation also clears {@link RegionRenderer#getRenderState() RenderState}'s {@link RenderState#BITHINT_BLENDING_ENABLED blending bit-hint}. * </p> - * @see #create(RenderState, int, GLCallback, GLCallback) + * @see #create(RenderState, GLCallback, GLCallback) * @see #enable(GL2ES2, boolean) */ public static final GLCallback defaultBlendDisable = new GLCallback() { @@ -109,20 +109,18 @@ public class RegionRenderer { * can be utilized to enable and disable {@link GL#GL_BLEND}. * </p> * @param rs the used {@link RenderState} - * @param renderModes bit-field of modes, e.g. {@link Region#VARWEIGHT_RENDERING_BIT}, {@link Region#VBAA_RENDERING_BIT} * @param enableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at - * {@link #init(GL2ES2) init(gl)} and {@link #enable(GL2ES2, boolean) enable(gl, true)}. + * {@link #init(GL2ES2, int) init(gl)} and {@link #enable(GL2ES2, boolean) enable(gl, true)}. * @param disableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at * {@link #enable(GL2ES2, boolean) enable(gl, false)}. * @return an instance of Region Renderer * @see #enable(GL2ES2, boolean) */ - public static RegionRenderer create(final RenderState rs, final int renderModes, - final GLCallback enableCallback, final GLCallback disableCallback) { - return new RegionRenderer(rs, renderModes, enableCallback, disableCallback); + public static RegionRenderer create(final RenderState rs, final GLCallback enableCallback, + final GLCallback disableCallback) { + return new RegionRenderer(rs, enableCallback, disableCallback); } - private final int renderModes; private final RenderState rs; private final GLCallback enableCallback; @@ -149,30 +147,13 @@ public class RegionRenderer { /** * @param rs the used {@link RenderState} - * @param renderModes bit-field of modes */ - protected RegionRenderer(final RenderState rs, final int renderModes, final GLCallback enableCallback, final GLCallback disableCallback) { + protected RegionRenderer(final RenderState rs, final GLCallback enableCallback, final GLCallback disableCallback) { this.rs = rs; - this.renderModes = renderModes; this.enableCallback = enableCallback; this.disableCallback = disableCallback; } - public final int getRenderModes() { - return renderModes; - } - - public final boolean usesVariableCurveWeight() { return Region.hasVariableWeight(renderModes); } - - /** - * @return true if Region's renderModes contains all bits as this Renderer's renderModes - * except {@link Region#VARWEIGHT_RENDERING_BIT}, otherwise false. - */ - public final boolean areRenderModesCompatible(final Region region) { - final int cleanRenderModes = getRenderModes() & ( Region.VARWEIGHT_RENDERING_BIT ); - return cleanRenderModes == ( region.getRenderModes() & cleanRenderModes ); - } - public final boolean isVBOSupported() { return vboSupported; } /** @@ -182,9 +163,10 @@ public class RegionRenderer { * <p>Shall be called by a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region, int)}</p> * * @param gl referencing the current GLContext to which the ShaderState is bound to + * @param renderModes TODO * @throws GLException if initialization failed */ - public final void init(GL2ES2 gl) throws GLException { + public final void init(final GL2ES2 gl, final int renderModes) throws GLException { if(initialized){ return; } @@ -227,6 +209,7 @@ public class RegionRenderer { final ShaderProgram sp = (ShaderProgram) i.next().getValue(); sp.destroy(gl); } + shaderPrograms.clear(); rs.destroy(gl); initialized = false; } @@ -237,10 +220,10 @@ public class RegionRenderer { * Enabling or disabling the {@link #getRenderState() RenderState}'s * {@link RenderState#getShaderProgram() shader program}. * <p> - * In case enable and disable {@link GLCallback}s are setup via {@link #create(RenderState, int, GLCallback, GLCallback)}, + * In case enable and disable {@link GLCallback}s are setup via {@link #create(RenderState, GLCallback, GLCallback)}, * they will be called before toggling the shader program. * </p> - * @see #create(RenderState, int, GLCallback, GLCallback) + * @see #create(RenderState, GLCallback, GLCallback) */ public final void enable(GL2ES2 gl, boolean enable) { if( enable ) { diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java index f915b7d49..c7083a41b 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java @@ -104,17 +104,20 @@ public class RenderState { * Set a {@link ShaderProgram} and enable it. If the given {@link ShaderProgram} is new, * method returns true, otherwise false. * @param gl - * @param sp + * @param spNext * @return true if a new shader program is being used and hence external uniform-data and -location, * as well as the attribute-location must be updated, otherwise false. */ - public final boolean setShaderProgram(final GL2ES2 gl, final ShaderProgram sp) { - if( sp.equals(this.sp) ) { - sp.useProgram(gl, true); + public final boolean setShaderProgram(final GL2ES2 gl, final ShaderProgram spNext) { + if( spNext.equals(this.sp) ) { + spNext.useProgram(gl, true); return false; } - this.sp = sp; - sp.useProgram(gl, true); + if( null != this.sp ) { + this.sp.notifyNotInUse(); + } + this.sp = spNext; + spNext.useProgram(gl, true); return true; } @@ -129,13 +132,6 @@ public class RenderState { public final void setMatrixDirty() { gcu_PMVMatrix01_dirty = true; } public final boolean isMatrixDirty() { return gcu_PMVMatrix01_dirty;} - public final void updateMatrix(GL2ES2 gl) { - if( gcu_PMVMatrix01_dirty && sp.inUse() ) { - gl.glUniform( gcu_PMVMatrix01 ); - gcu_PMVMatrix01_dirty = false; - } - } - public static boolean isWeightValid(float v) { return 0.0f <= v && v <= 1.9f ; } @@ -179,20 +175,17 @@ public class RenderState { 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); - System.err.println("XXX gcu_PMVMatrix01.update: "+r0); 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); - System.err.println("XXX gcu_Weight.update: "+r0); res = res && r0; gcu_Weight_dirty = !r0; } if( gcu_ColorStatic_dirty || updateLocation ) { final boolean r0 = updateUniformDataLoc(gl, updateLocation, gcu_ColorStatic_dirty, gcu_ColorStatic); - System.err.println("XXX gcu_ColorStatic.update: "+r0); res = res && r0; gcu_ColorStatic_dirty = false; } 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 6d9fdab0b..16b1224bd 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -48,10 +48,10 @@ import com.jogamp.graph.geom.Vertex.Factory; */ public class TextRegionUtil { - public final RegionRenderer renderer; + public final int renderModes; - public TextRegionUtil(final RegionRenderer renderer) { - this.renderer = renderer; + public TextRegionUtil(final int renderModes) { + this.renderModes = renderModes; } public static interface ShapeVisitor { @@ -144,6 +144,7 @@ public class TextRegionUtil { * Cached {@link GLRegion}s will be destroyed w/ {@link #clear(GL2ES2)} or to free memory. * </p> * @param gl the current GL state + * @param renderer TODO * @param font {@link Font} to be used * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. * @param str text to be rendered @@ -153,15 +154,15 @@ public class TextRegionUtil { * @throws Exception if TextRenderer not initialized */ public void drawString3D(final GL2ES2 gl, - final Font font, final float pixelSize, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount) { + final RegionRenderer renderer, final Font font, final float pixelSize, + final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount) { if( !renderer.isInitialized() ) { throw new GLException("TextRendererImpl01: not initialized!"); } final int special = 0; GLRegion region = getCachedRegion(font, str, pixelSize, special); if(null == region) { - region = GLRegion.create(renderer.getRenderModes()); + region = GLRegion.create(renderModes); addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); addCachedRegion(gl, font, str, pixelSize, special, region); } @@ -174,10 +175,11 @@ public class TextRegionUtil { * <p> * In case of a multisampling region renderer, i.e. {@link Region#VBAA_RENDERING_BIT}, recreating the {@link GLRegion} * is a huge performance impact. - * In such case better use {@link #drawString3D(GLRegion, RegionRenderer, GL2ES2, Font, float, CharSequence, float[], int[])} + * In such case better use {@link #drawString3D(GL2ES2, GLRegion, RegionRenderer, Font, float, CharSequence, float[], int[])} * instead. * </p> * @param gl the current GL state + * @param renderModes TODO * @param font {@link Font} to be used * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. * @param str text to be rendered @@ -186,21 +188,21 @@ public class TextRegionUtil { * The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched. * @throws Exception if TextRenderer not initialized */ - public static void drawString3D(final RegionRenderer renderer, final GL2ES2 gl, - final Font font, final float pixelSize, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount) { + public static void drawString3D(final GL2ES2 gl, final int renderModes, + final RegionRenderer renderer, final Font font, final float pixelSize, + final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } - final GLRegion region = GLRegion.create(renderer.getRenderModes()); + final GLRegion region = GLRegion.create(renderModes); addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); region.draw(gl, renderer, sampleCount); - region.destroy(gl, renderer); + region.destroy(gl); } /** * Render the string in 3D space w.r.t. the font and pixelSize - * using the given {@link GLRegion}, which will {@link GLRegion#clear(GL2ES2, RegionRenderer) cleared} beforehand. + * using the given {@link GLRegion}, which will {@link GLRegion#clear(GL2ES2) cleared} beforehand. * @param gl the current GL state * @param font {@link Font} to be used * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. @@ -210,13 +212,13 @@ public class TextRegionUtil { * The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched. * @throws Exception if TextRenderer not initialized */ - public static void drawString3D(final GLRegion region, final RegionRenderer renderer, final GL2ES2 gl, + public static void drawString3D(final GL2ES2 gl, final GLRegion region, final RegionRenderer renderer, final Font font, final float pixelSize, final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } - region.clear(gl, renderer); + region.clear(gl); addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); region.draw(gl, renderer, sampleCount); } @@ -229,7 +231,7 @@ public class TextRegionUtil { final Iterator<GLRegion> iterator = stringCacheMap.values().iterator(); while(iterator.hasNext()){ final GLRegion region = iterator.next(); - region.destroy(gl, renderer); + region.destroy(gl); } stringCacheMap.clear(); stringCacheArray.clear(); @@ -295,7 +297,7 @@ public class TextRegionUtil { final String key = getKey(font, str, pixelSize, special); final GLRegion region = stringCacheMap.remove(key); if(null != region) { - region.destroy(gl, renderer); + region.destroy(gl); } stringCacheArray.remove(key); } @@ -305,7 +307,7 @@ public class TextRegionUtil { if( null != key ) { final GLRegion region = stringCacheMap.remove(key); if(null != region) { - region.destroy(gl, renderer); + region.destroy(gl); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java index 9d3ee412b..cf56ff0a4 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java @@ -29,6 +29,8 @@ package com.jogamp.opengl.math; import java.nio.FloatBuffer; +import javax.media.opengl.GLException; + import jogamp.opengl.Debug; import com.jogamp.common.os.Platform; @@ -199,6 +201,123 @@ public class FloatUtil { } /** + * Make given matrix the orthogonal matrix based on given parameters. + * + * @param a 4x4 matrix in column-major order (also result) + * @param a_off + * @param initA if true, given matrix will be initialized w/ identity matrix. + * @param left + * @param right + * @param bottom + * @param top + * @param zNear + * @param zFar + * @return given matrix for chaining + */ + public static final float[] makeOrthof(final float[] a, final int a_off, final boolean initA, + final float left, final float right, + final float bottom, final float top, + final float zNear, final float zFar) { + if( initA ) { + FloatUtil.makeIdentityf(a, a_off); + } + // Ortho matrix (Column Order): + // 2/dx 0 0 0 + // 0 2/dy 0 0 + // 0 0 2/dz 0 + // tx ty tz 1 + final float dx=right-left; + final float dy=top-bottom; + final float dz=zFar-zNear; + final float tx=-1.0f*(right+left)/dx; + final float ty=-1.0f*(top+bottom)/dy; + final float tz=-1.0f*(zFar+zNear)/dz; + + a[a_off+0+4*0] = 2.0f/dx; + a[a_off+1+4*1] = 2.0f/dy; + a[a_off+2+4*2] = -2.0f/dz; + a[a_off+0+4*3] = tx; + a[a_off+1+4*3] = ty; + a[a_off+2+4*3] = tz; + + return a; + } + + /** + * Make given matrix the frustum matrix based on given parameters. + * + * @param a 4x4 matrix in column-major order (also result) + * @param a_off + * @param initA if true, given matrix will be initialized w/ identity matrix. + * @param left + * @param right + * @param bottom + * @param top + * @param zNear + * @param zFar + * @return given matrix for chaining + */ + public static final float[] makeFrustumf(final float[] a, final int a_off, final boolean initA, + final float left, final float right, + final float bottom, final float top, + final float zNear, final float zFar) { + if(zNear<=0.0f||zFar<0.0f) { + throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0"); + } + if(left==right || top==bottom) { + throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal"); + } + if( initA ) { + FloatUtil.makeIdentityf(a, a_off); + } + // Frustum matrix (Column Order): + // 2*zNear/dx 0 0 0 + // 0 2*zNear/dy 0 0 + // A B C -1 + // 0 0 D 0 + final float zNear2 = 2.0f*zNear; + final float dx=right-left; + final float dy=top-bottom; + final float dz=zFar-zNear; + final float A=(right+left)/dx; + final float B=(top+bottom)/dy; + final float C=-1.0f*(zFar+zNear)/dz; + final float D=-2.0f*(zFar*zNear)/dz; + + a[a_off+0+4*0] = zNear2/dx; + a[a_off+1+4*1] = zNear2/dy; + a[a_off+2+4*2] = C; + + a[a_off+0+4*2] = A; + a[a_off+1+4*2] = B; + + a[a_off+2+4*3] = D; + a[a_off+3+4*2] = -1.0f; + return a; + } + + /** + * Make given matrix the perspective matrix based on given parameters. + * + * @param a 4x4 matrix in column-major order (also result) + * @param a_off + * @param initA if true, given matrix will be initialized w/ identity matrix. + * @param fovy angle in radians + * @param aspect + * @param zNear + * @param zFar + * @return given matrix for chaining + */ + public static final float[] makePerspective(final float[] a, final int a_off, final boolean initA, + final float fovy, final float aspect, final float zNear, final float zFar) { + float top=(float)Math.tan(fovy)*zNear; + float bottom=-1.0f*top; + float left=aspect*bottom; + float right=aspect*top; + return makeFrustumf(a, a_off, initA, left, right, bottom, top, zNear, zFar); + } + + /** * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order @@ -840,4 +959,47 @@ public class FloatUtil { public static float sqrt(final float a) { return (float) java.lang.Math.sqrt(a); } + /** + * Returns resolution of Z buffer of given parameter, + * see <a href="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html">Love Your Z-Buffer</a>. + * <pre> + * return z * z / ( zNear * (1<<zBits) - z ) + * </pre> + * @param zBits number of bits of Z precision, i.e. z-buffer depth + * @param z distance from the eye to the object + * @param zNear distance from eye to near clip plane + * @return smallest resolvable Z separation at this range. + */ + public static float getZBufferEpsilon(final int zBits, final float z, final float zNear) { + return z * z / ( zNear * ( 1 << zBits ) - z ); + } + + /** + * Returns Z buffer value of given parameter, + * see <a href="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html">Love Your Z-Buffer</a>. + * <pre> + * float a = zFar / ( zFar - zNear ) + * float b = zFar * zNear / ( zNear - zFar ) + * return (int) ( (1<<zBits) * ( a + b / z ) ) + * </pre> + * @param zBits number of bits of Z precision, i.e. z-buffer depth + * @param z distance from the eye to the object + * @param zNear distance from eye to near clip plane + * @param zFar distance from eye to far clip plane + * @return z buffer value + */ + public static int getZBufferValue(final int zBits, final float z, final float zNear, final float zFar) { + final float a = zFar / ( zFar - zNear ); + final float b = zFar * zNear / ( zNear - zFar ); + return (int) ( (1<<zBits) * ( a + b / z ) ); + } + + /** + * Returns orthogonal distance + * (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar); + */ + public static float getOrthoWinZ(final float orthoZ, final float zNear, final float zFar) { + return (1f/zNear-1f/orthoZ)/(1f/zNear-1f/zFar); + } + }
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java index 44288256a..8f5beeebe 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java +++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java @@ -686,61 +686,12 @@ public class PMVMatrix implements GLMatrixFunc { @Override public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) { - // Ortho matrix (Column Order): - // 2/dx 0 0 0 - // 0 2/dy 0 0 - // 0 0 2/dz 0 - // tx ty tz 1 - final float dx=right-left; - final float dy=top-bottom; - final float dz=zFar-zNear; - final float tx=-1.0f*(right+left)/dx; - final float ty=-1.0f*(top+bottom)/dy; - final float tz=-1.0f*(zFar+zNear)/dz; - - matrixOrtho[0+4*0] = 2.0f/dx; - matrixOrtho[1+4*1] = 2.0f/dy; - matrixOrtho[2+4*2] = -2.0f/dz; - matrixOrtho[0+4*3] = tx; - matrixOrtho[1+4*3] = ty; - matrixOrtho[2+4*3] = tz; - - glMultMatrixf(matrixOrtho, 0); + glMultMatrixf( FloatUtil.makeOrthof(matrixOrtho, 0, false, left, right, bottom, top, zNear, zFar), 0 ); } @Override public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) { - if(zNear<=0.0f||zFar<0.0f) { - throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0"); - } - if(left==right || top==bottom) { - throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal"); - } - // Frustum matrix (Column Order): - // 2*zNear/dx 0 0 0 - // 0 2*zNear/dy 0 0 - // A B C -1 - // 0 0 D 0 - final float zNear2 = 2.0f*zNear; - final float dx=right-left; - final float dy=top-bottom; - final float dz=zFar-zNear; - final float A=(right+left)/dx; - final float B=(top+bottom)/dy; - final float C=-1.0f*(zFar+zNear)/dz; - final float D=-2.0f*(zFar*zNear)/dz; - - matrixFrustum[0+4*0] = zNear2/dx; - matrixFrustum[1+4*1] = zNear2/dy; - matrixFrustum[2+4*2] = C; - - matrixFrustum[0+4*2] = A; - matrixFrustum[1+4*2] = B; - - matrixFrustum[2+4*3] = D; - matrixFrustum[3+4*2] = -1.0f; - - glMultMatrixf(matrixFrustum, 0); + glMultMatrixf( FloatUtil.makeFrustumf(matrixFrustum, 0, false, left, right, bottom, top, zNear, zFar), 0 ); } // @@ -751,11 +702,7 @@ public class PMVMatrix implements GLMatrixFunc { * {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} with the perspective/frustum matrix. */ public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) { - float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear; - float bottom=-1.0f*top; - float left=aspect*bottom; - float right=aspect*top; - glFrustumf(left, right, bottom, top, zNear, zFar); + glMultMatrixf( FloatUtil.makePerspective(matrixFrustum, 0, false, fovy*((float)Math.PI)/360.0f, aspect, zNear, zFar), 0 ); } /** @@ -840,24 +787,12 @@ public class PMVMatrix implements GLMatrixFunc { * using a {@link AABBox#intersectsRay(Ray, float[]) bounding box}. * <p> * Notes for picking <i>winz0</i> and <i>winz1</i>: + * <ul> + * <li>see {@link FloatUtil#getZBufferEpsilon(int, float, float)}</li> + * <li>see {@link FloatUtil#getZBufferValue(int, float, float, float)}</li> + * <li>see {@link FloatUtil#getOrthoWinZ(float, float, float)}</li> + * </ul> * </p> - * <p> - * <a href="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html">Love Your Z-Buffer</a> - * <pre> - * delta = z * z / ( zNear * (1<<N) - z ) - * - * Where: - * N = number of bits of Z precision - * zNear = distance from eye to near clip plane - * z = distance from the eye to the object - * delta = the smallest resolvable Z separation at this range. - * </pre> - * Another equation to determine winZ for 'orthoDist' > 0 - * <pre> - * winZ = (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar); - * </pre> - * </p> - * * @param winx * @param winy * @param winz0 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 b289b41e2..6a4b13dfb 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderProgram.java @@ -312,17 +312,20 @@ public class ShaderProgram { gl.glUseProgram( on ? shaderProgram : 0 ); programInUse = on; } + public synchronized void notifyNotInUse() { + programInUse = false; + } - protected boolean programLinked = false; - protected boolean programInUse = false; - protected int shaderProgram = 0; // non zero is valid! - protected HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>(); - protected HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>(); - protected int id = -1; + private boolean programLinked = false; + private boolean programInUse = false; + private int shaderProgram = 0; // non zero is valid! + private final HashSet<ShaderCode> allShaderCode = new HashSet<ShaderCode>(); + private final HashSet<ShaderCode> attachedShaderCode = new HashSet<ShaderCode>(); + private int id = -1; private static synchronized int getNextID() { return nextID++; } - protected static int nextID = 1; + private static int nextID = 1; } diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java index ce4c2615d..64dd589b8 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/ShaderState.java @@ -176,8 +176,7 @@ public class ShaderState { } if(shaderProgram.inUse()) { if(null != prog && enable) { - // new program will issue glUseProgram(..) - shaderProgram.programInUse = false; + shaderProgram.notifyNotInUse(); } else { // no new 'enabled' program - disable useProgram(gl, false); |