private void modifyProjectionMatrix(final Vector4 clipPlane) { // Get the current projection matrix projectionMatrix = cam.getProjectionMatrix().toArray(projectionMatrix); // Get the inverse transpose of the current modelview matrix final ReadOnlyMatrix4 modelViewMatrixInvTrans = tRenderer.getCamera().getModelViewMatrix().invert(tmpMatrix).transposeLocal(); modelViewMatrixInvTrans.applyPre(clipPlane, clipPlane); // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix cornerPoint.setX((sign(clipPlane.getX()) + projectionMatrix[8]) / projectionMatrix[0]); cornerPoint.setY((sign(clipPlane.getY()) + projectionMatrix[9]) / projectionMatrix[5]); cornerPoint.setZ(-1.0); cornerPoint.setW((1.0 + projectionMatrix[10]) / projectionMatrix[14]); // Calculate the scaled plane vector final Vector4 scaledPlaneVector = clipPlane.multiply((2.0 / clipPlane.dot(cornerPoint)), cornerPoint); // Replace the third row of the projection matrix projectionMatrix[2] = scaledPlaneVector.getX(); projectionMatrix[6] = scaledPlaneVector.getY(); projectionMatrix[10] = scaledPlaneVector.getZ() + 1.0; projectionMatrix[14] = scaledPlaneVector.getW(); // Load it back into OpenGL final Matrix4 newProjectionMatrix = tmpMatrix.fromArray(projectionMatrix); tRenderer.getCamera().setProjectionMatrix(newProjectionMatrix); }
@Override public void draw(final Renderer r) { initialize(r); updateTranslations(); final double camWaterDist = waterPlane.pseudoDistance(cam.getLocation()); aboveWater = camWaterDist >= 0; if (isSupported()) { waterShader.setUniform("tangent", tangent); waterShader.setUniform("binormal", binormal); waterShader.setUniform("useFadeToFogColor", useFadeToFogColor); waterShader.setUniform("waterColor", waterColorStart); waterShader.setUniform("waterColorEnd", waterColorEnd); waterShader.setUniform("normalTranslation", (float) normalTranslation); waterShader.setUniform("refractionTranslation", (float) refractionTranslation); waterShader.setUniform("abovewater", aboveWater); if (useProjectedShader) { waterShader.setUniform("cameraPos", cam.getLocation()); waterShader.setUniform("waterHeight", (float) waterPlane.getConstant()); waterShader.setUniform("amplitude", (float) waterMaxAmplitude); waterShader.setUniform("heightFalloffStart", (float) heightFalloffStart); waterShader.setUniform("heightFalloffSpeed", (float) heightFalloffSpeed); } final double heightTotal = clipBias + waterMaxAmplitude - waterPlane.getConstant(); final Vector4 clipPlane = Vector4.fetchTempInstance(); if (useReflection) { clipPlane.set( waterPlane.getNormal().getX(), waterPlane.getNormal().getY(), waterPlane.getNormal().getZ(), heightTotal); renderReflection(clipPlane); } if (useRefraction && aboveWater) { clipPlane.set( -waterPlane.getNormal().getX(), -waterPlane.getNormal().getY(), -waterPlane.getNormal().getZ(), -waterPlane.getConstant()); renderRefraction(clipPlane); } } if (fallbackTextureState != null) { fallbackTextureStateMatrix.setM31(normalTranslation); fallbackTexture.setTextureMatrix(fallbackTextureStateMatrix); } super.draw(r); }
public void updateTextureMatrix(final Matrix4 matrixStore) { update(); final ReadOnlyMatrix4 projectorView = getModelViewMatrix(); final ReadOnlyMatrix4 projectorProjection = getProjectionMatrix(); matrixStore.set(projectorView).multiplyLocal(projectorProjection).multiplyLocal(BIAS); }
/** Load water textures. */ protected void setupTextures() { textureReflect = new Texture2D(); textureReflect.setWrap(Texture.WrapMode.EdgeClamp); textureReflect.setMagnificationFilter(Texture.MagnificationFilter.Bilinear); Matrix4 matrix = new Matrix4(); matrix.setM00(-1.0); matrix.setM30(1.0); textureReflect.setTextureMatrix(matrix); tRenderer.setupTexture(textureReflect); normalmapTexture = TextureManager.load( normalMapTextureString, Texture.MinificationFilter.Trilinear, TextureStoreFormat.GuessCompressedFormat, true); textureState.setTexture(normalmapTexture, 0); normalmapTexture.setWrap(Texture.WrapMode.Repeat); textureReflectBlur = new Texture2D(); textureReflectBlur.setWrap(Texture.WrapMode.EdgeClamp); textureReflectBlur.setMagnificationFilter(Texture.MagnificationFilter.Bilinear); textureReflectBlur.setTextureMatrix(matrix); tRenderer.setupTexture(textureReflectBlur); textureState.setTexture(textureReflectBlur, 1); dudvTexture = TextureManager.load( dudvMapTextureString, Texture.MinificationFilter.Trilinear, TextureStoreFormat.GuessNoCompressedFormat, true); matrix = new Matrix4(); matrix.setM00(0.8); matrix.setM11(0.8); dudvTexture.setTextureMatrix(matrix); textureState.setTexture(dudvTexture, 2); dudvTexture.setWrap(Texture.WrapMode.Repeat); if (useRefraction) { textureRefract = new Texture2D(); textureRefract.setWrap(Texture.WrapMode.EdgeClamp); textureRefract.setMagnificationFilter(Texture.MagnificationFilter.Bilinear); tRenderer.setupTexture(textureRefract); textureDepth = new Texture2D(); textureDepth.setWrap(Texture.WrapMode.EdgeClamp); textureDepth.setMagnificationFilter(Texture.MagnificationFilter.NearestNeighbor); textureDepth.setTextureStoreFormat(TextureStoreFormat.Depth24); tRenderer.setupTexture(textureDepth); textureState.setTexture(textureRefract, 3); textureState.setTexture(textureDepth, 4); } if (useProjectedShader) { foamTexture = TextureManager.load( foamMapTextureString, Texture.MinificationFilter.Trilinear, TextureStoreFormat.GuessCompressedFormat, true); if (useRefraction) { textureState.setTexture(foamTexture, 5); } else { textureState.setTexture(foamTexture, 3); } foamTexture.setWrap(Texture.WrapMode.Repeat); } reloadShader(); }
public void updateTextureMatrix(final Texture texture) { final Matrix4 texMat = Matrix4.fetchTempInstance(); updateTextureMatrix(texMat); texture.setTextureMatrix(texMat); Matrix4.releaseTempInstance(texMat); }