From eff6292d4714317ff6b5764e44221132982d40d0 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 16 Oct 2016 18:42:51 +1300 Subject: Lighting data calculations improved Positions are now correctly pre multiplied by MV, and the front material emmission value is sent through to the shaders, if requested --- .../java/org/jogamp/java3d/Jogl2es2Context.java | 3 + .../java/org/jogamp/java3d/Jogl2es2MatrixUtil.java | 24 ++++++++ .../java/org/jogamp/java3d/Jogl2es2Pipeline.java | 72 ++++++++++++++++------ 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2Context.java b/src/main/java/org/jogamp/java3d/Jogl2es2Context.java index 41c1511..cc8bdce 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2Context.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2Context.java @@ -264,6 +264,7 @@ public class Jogl2es2Context extends JoglContext public int glModelViewProjectionMatrix = -1; public int glNormalMatrix = -1; public int ignoreVertexColors = -1; + public int glFrontMaterialambient = -1; public int glFrontMaterialdiffuse = -1; public int glFrontMaterialemission = -1; public int glFrontMaterialspecular = -1; @@ -333,6 +334,7 @@ public class Jogl2es2Context extends JoglContext public float polygonOffset; public boolean ignoreVertexColors; + public Vector4f glFrontMaterialambient= new Vector4f(); public Vector4f glFrontMaterialdiffuse = new Vector4f(); public Vector3f glFrontMaterialemission = new Vector3f(); public Vector3f glFrontMaterialspecular = new Vector3f(); @@ -387,6 +389,7 @@ public class Jogl2es2Context extends JoglContext polygonOffsetFactor = -1; polygonOffset = -1; ignoreVertexColors = false; + glFrontMaterialambient.set(-999f, -999f, -999f, -999f); glFrontMaterialdiffuse.set(-999f, -999f, -999f, -999f); glFrontMaterialemission.set(-999f, -999f, -999f); glFrontMaterialspecular.set(-999f, -999f, -999f); diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java b/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java index 5237173..3fb6929 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2MatrixUtil.java @@ -7,6 +7,8 @@ import java.nio.FloatBuffer; import org.jogamp.vecmath.Matrix3d; import org.jogamp.vecmath.Matrix4d; import org.jogamp.vecmath.SingularMatrixException; +import org.jogamp.vecmath.Tuple4f; +import org.jogamp.vecmath.Vector4f; /** class that demands single threading and uses deburners, don't touch if you don't understand, it will be bad... * @@ -614,6 +616,19 @@ class Jogl2es2MatrixUtil } } + public final void transform(Matrix4d m, Tuple4f vecOut) + { + float x, y, z; + + x = (float) (m.m00 * vecOut.x + m.m01 * vecOut.y + m.m02 * vecOut.z + m.m03 * vecOut.w); + y = (float) (m.m10 * vecOut.x + m.m11 * vecOut.y + m.m12 * vecOut.z + m.m13 * vecOut.w); + z = (float) (m.m20 * vecOut.x + m.m21 * vecOut.y + m.m22 * vecOut.z + m.m23 * vecOut.w); + vecOut.w = (float) (m.m30 * vecOut.x + m.m31 * vecOut.y + m.m32 * vecOut.z + m.m33 * vecOut.w); + vecOut.x = x; + vecOut.y = y; + vecOut.z = z; + } + //Oh lordy lordy yo' betta swear yo' single freadin' !!! public double[] deburnV2 = null;//deburners @@ -768,6 +783,15 @@ class Jogl2es2MatrixUtil } //More single threaded death-defying gear + private Vector4f tmpV4f = new Vector4f();; + + public Vector4f transform(Matrix4d m1, Matrix4d m2, float tx, float ty, float tz, float tw) + { + tmpV4f.set(tx, ty, tz, tw); + transform(m1, tmpV4f); + transform(m2, tmpV4f); + return tmpV4f; + } private FloatBuffer matFB4x4; diff --git a/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java b/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java index 2aef9fa..65ed685 100644 --- a/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java +++ b/src/main/java/org/jogamp/java3d/Jogl2es2Pipeline.java @@ -32,6 +32,7 @@ import org.jogamp.java3d.Jogl2es2Context.LightData; import org.jogamp.java3d.Jogl2es2Context.LocationData; import org.jogamp.java3d.Jogl2es2Context.ProgramData; import org.jogamp.vecmath.SingularMatrixException; +import org.jogamp.vecmath.Vector3f; import org.jogamp.vecmath.Vector4f; import com.jogamp.common.nio.Buffers; @@ -1950,7 +1951,20 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline } } - // send material data through + // send material data through + if (locs.glFrontMaterialambient != -1) + { + if (!MINIMISE_NATIVE_CALLS_FFP + || (shaderProgramId != ctx.prevShaderProgram || !ctx.gl_state.glFrontMaterialambient.equals(ctx.materialData.ambient))) + { + gl.glUniform4f(locs.glFrontMaterialambient, ctx.materialData.ambient.x, ctx.materialData.ambient.y, + ctx.materialData.ambient.z, 1f); + if (DO_OUTPUT_ERRORS) + outputErrors(ctx); + if (MINIMISE_NATIVE_CALLS_FFP) + ctx.gl_state.glFrontMaterialambient.set(ctx.materialData.ambient); + } + } if (locs.glFrontMaterialdiffuse != -1) { if (!MINIMISE_NATIVE_CALLS_FFP @@ -2033,17 +2047,17 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline } } - /*dirLight - pointLight - spotLight*/ //currentEnabledLights - // For now using first point light, but gonna need to put em all in + // TODO: add the other attributes of spot and point light in + //For now using first point light, but gonna need to put em all in LightData l0 = null; if (ctx.pointLight[0] != null) l0 = ctx.pointLight[0]; else if (ctx.dirLight[0] != null) l0 = ctx.dirLight[0]; + else if (ctx.spotLight[0] != null) + l0 = ctx.spotLight[0]; if (l0 != null) { @@ -2224,6 +2238,7 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline locs.glModelViewProjectionMatrix = gl.glGetUniformLocation(shaderProgramId, "glModelViewProjectionMatrix"); locs.glNormalMatrix = gl.glGetUniformLocation(shaderProgramId, "glNormalMatrix"); locs.ignoreVertexColors = gl.glGetUniformLocation(shaderProgramId, "ignoreVertexColors"); + locs.glFrontMaterialambient = gl.glGetUniformLocation(shaderProgramId, "glFrontMaterialambient"); locs.glFrontMaterialdiffuse = gl.glGetUniformLocation(shaderProgramId, "glFrontMaterialdiffuse"); locs.glFrontMaterialemission = gl.glGetUniformLocation(shaderProgramId, "glFrontMaterialemission"); locs.glFrontMaterialspecular = gl.glGetUniformLocation(shaderProgramId, "glFrontMaterialspecular"); @@ -3263,7 +3278,8 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline void updateDirectionalLight(Context ctx, int lightSlot, float red, float green, float blue, float dirx, float diry, float dirz) { if (VERBOSE) - System.err.println("JoglPipeline.updateDirectionalLight()"); + System.err.println("JoglPipeline.updateDirectionalLight() " + lightSlot + " " + red + " " + green + " " + blue + " " + dirx + + " " + diry + " " + dirz); if (OUTPUT_PER_FRAME_STATS) ((Jogl2es2Context) ctx).perFrameStats.updateDirectionalLight++; @@ -3295,6 +3311,12 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline gl.glLightf(lightNum, GL2ES2.GL_SPOT_CUTOFF, 180.0f);*/ Jogl2es2Context joglesctx = ((Jogl2es2Context) ctx); + + // note can't use the modelview as it's calced late + + //TODO:? possibly directional should only take the view mat, but surely I'd get a blank model?? + Vector4f lightPos = joglesctx.matrixUtil.transform(joglesctx.currentModelMat, joglesctx.currentViewMat, -dirx, -diry, -dirz, 0f); + if (joglesctx.dirLight[lightSlot] == null) joglesctx.dirLight[lightSlot] = new LightData(); @@ -3306,9 +3328,9 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline joglesctx.dirLight[lightSlot].specular.y = green; joglesctx.dirLight[lightSlot].specular.z = blue; joglesctx.dirLight[lightSlot].specular.w = 1.0f; - joglesctx.dirLight[lightSlot].pos.x = -dirx; - joglesctx.dirLight[lightSlot].pos.y = -diry; - joglesctx.dirLight[lightSlot].pos.z = -dirz; + joglesctx.dirLight[lightSlot].pos.x = lightPos.x; + joglesctx.dirLight[lightSlot].pos.y = lightPos.y; + joglesctx.dirLight[lightSlot].pos.z = lightPos.z; joglesctx.dirLight[lightSlot].pos.w = 0.0f;// 0 means directional light joglesctx.dirLight[lightSlot].ambient = black;// odd // joglesctx.dirLight[lightSlot].GL_POSITION = 1.0f; // what is this? @@ -3336,8 +3358,6 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline /* GL2 gl = context(ctx).getGL().getGL2(); //GL2ES2 gl = context(ctx).getGL().getGL2ES2(); - // OK ES2 requires lights to be handed across manually - // so once again just force it in there and assume shader has it int lightNum = GL2ES2.GL_LIGHT0 + lightSlot; float[] values = new float[4]; @@ -3360,6 +3380,13 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline gl.glLightf(lightNum, GL2ES2.GL_SPOT_CUTOFF, 180.0f);*/ Jogl2es2Context joglesctx = ((Jogl2es2Context) ctx); + + // note the current state of MV MUST be used by the lights when setting position! + //https://www.opengl.org/discussion_boards/showthread.php/168706-Light-Position-in-eye-s-cordinate + + // note can't use the modelview as it's calced late + Vector4f lightPos = joglesctx.matrixUtil.transform(joglesctx.currentModelMat, joglesctx.currentViewMat, posx, posy, posz, 1.0f); + if (joglesctx.pointLight[lightSlot] == null) joglesctx.pointLight[lightSlot] = new LightData(); @@ -3371,9 +3398,9 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline joglesctx.pointLight[lightSlot].specular.y = green; joglesctx.pointLight[lightSlot].specular.z = blue; joglesctx.pointLight[lightSlot].specular.w = 1.0f; - joglesctx.pointLight[lightSlot].pos.x = posx; - joglesctx.pointLight[lightSlot].pos.y = posy; - joglesctx.pointLight[lightSlot].pos.z = posz; + joglesctx.pointLight[lightSlot].pos.x = lightPos.x; + joglesctx.pointLight[lightSlot].pos.y = lightPos.y; + joglesctx.pointLight[lightSlot].pos.z = lightPos.z; joglesctx.pointLight[lightSlot].pos.w = 1.0f;// 1 mean pos not dir joglesctx.pointLight[lightSlot].ambient = black;// odd joglesctx.pointLight[lightSlot].GL_CONSTANT_ATTENUATION = attenx; @@ -3400,8 +3427,6 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline /* GL2 gl = context(ctx).getGL().getGL2(); //GL2ES2 gl = context(ctx).getGL().getGL2ES2(); - // OK ES2 requires lights to be handed across manually - // so once again just force it in there and assume shader has it int lightNum = GL2ES2.GL_LIGHT0 + lightSlot; float[] values = new float[4]; @@ -3428,6 +3453,13 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline gl.glLightf(lightNum, GL2ES2.GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / Math.PI));*/ Jogl2es2Context joglesctx = ((Jogl2es2Context) ctx); + + // note the current state of MV MUST be used by the lights when setting position! + //https://www.opengl.org/discussion_boards/showthread.php/168706-Light-Position-in-eye-s-cordinate + + // note can't use the modelview as it's calced late + Vector4f lightPos = joglesctx.matrixUtil.transform(joglesctx.currentModelMat, joglesctx.currentViewMat, posx, posy, posz, 1.0f); + if (joglesctx.spotLight[lightSlot] == null) joglesctx.spotLight[lightSlot] = new LightData(); @@ -3439,9 +3471,9 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline joglesctx.spotLight[lightSlot].specular.y = green; joglesctx.spotLight[lightSlot].specular.z = blue; joglesctx.spotLight[lightSlot].specular.w = 1.0f; - joglesctx.spotLight[lightSlot].pos.x = posx; - joglesctx.spotLight[lightSlot].pos.y = posy; - joglesctx.spotLight[lightSlot].pos.z = posz; + joglesctx.spotLight[lightSlot].pos.x = lightPos.x; + joglesctx.spotLight[lightSlot].pos.y = lightPos.y; + joglesctx.spotLight[lightSlot].pos.z = lightPos.z; joglesctx.spotLight[lightSlot].pos.w = 1.0f;// 1 mean pos not dir joglesctx.spotLight[lightSlot].ambient = black;// odd joglesctx.spotLight[lightSlot].GL_CONSTANT_ATTENUATION = attenx; @@ -5312,6 +5344,8 @@ class Jogl2es2Pipeline extends Jogl2es2DEPPipeline JoglesMatrixUtil.transposeInvert(joglesctx.currentModelViewMat, joglesctx.currentNormalMat); */ + // note this MV MUST be used by the lights when setting position! + //https://www.opengl.org/discussion_boards/showthread.php/168706-Light-Position-in-eye-s-cordinate } // The native method for setting the Projection matrix. -- cgit v1.2.3