From 1e8b5ef338063b87a5f50c1a06e2da28b73383ba Mon Sep 17 00:00:00 2001 From: shadowislord Date: Sat, 31 Jan 2015 14:26:42 -0500 Subject: [PATCH] Avoid glTexParameter calls if not neccessary by storing last texture state in the Image object --- .../com/jme3/renderer/opengl/GLRenderer.java | 31 ++++++---- .../src/main/java/com/jme3/texture/Image.java | 14 +++++ .../jme3/texture/image/LastTextureState.java | 60 +++++++++++++++++++ 3 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 jme3-core/src/main/java/com/jme3/texture/image/LastTextureState.java diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index e9029ec21..5a714d205 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -1799,11 +1799,17 @@ public class GLRenderer implements Renderer { } // filter things - int minFilter = convertMinFilter(tex.getMinFilter(), haveMips); - int magFilter = convertMagFilter(tex.getMagFilter()); - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter); - gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, magFilter); - + if (image.getLastTextureState().magFilter != tex.getMagFilter()) { + int magFilter = convertMagFilter(tex.getMagFilter()); + gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, magFilter); + image.getLastTextureState().magFilter = tex.getMagFilter(); + } + if (image.getLastTextureState().minFilter != tex.getMinFilter()) { + int minFilter = convertMinFilter(tex.getMinFilter(), haveMips); + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter); + image.getLastTextureState().minFilter = tex.getMinFilter(); + } + if (tex.getAnisotropicFilter() > 1) { if (caps.contains(Caps.TextureFilterAnisotropic)) { gl.glTexParameterf(target, @@ -1820,16 +1826,21 @@ public class GLRenderer implements Renderer { switch (tex.getType()) { case ThreeDimensional: case CubeMap: // cubemaps use 3D coords - if (gl2 != null) { + if (gl2 != null && image.getLastTextureState().rWrap != tex.getWrap(WrapAxis.R)) { gl2.glTexParameteri(target, GL2.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R))); + image.getLastTextureState().rWrap = tex.getWrap(WrapAxis.R); } //There is no break statement on purpose here case TwoDimensional: case TwoDimensionalArray: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T))); - // fall down here is intentional.. -// case OneDimensional: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); + if (image.getLastTextureState().tWrap != tex.getWrap(WrapAxis.T)) { + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T))); + image.getLastTextureState().tWrap = tex.getWrap(WrapAxis.T); + } + if (image.getLastTextureState().sWrap != tex.getWrap(WrapAxis.S)) { + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); + image.getLastTextureState().sWrap = tex.getWrap(WrapAxis.S); + } break; default: throw new UnsupportedOperationException("Unknown texture type: " + tex.getType()); diff --git a/jme3-core/src/main/java/com/jme3/texture/Image.java b/jme3-core/src/main/java/com/jme3/texture/Image.java index 2229e168f..3fded4f80 100644 --- a/jme3-core/src/main/java/com/jme3/texture/Image.java +++ b/jme3-core/src/main/java/com/jme3/texture/Image.java @@ -40,6 +40,7 @@ import com.jme3.math.FastMath; import com.jme3.renderer.Caps; import com.jme3.renderer.Renderer; import com.jme3.texture.image.ColorSpace; +import com.jme3.texture.image.LastTextureState; import com.jme3.util.BufferUtils; import com.jme3.util.NativeObject; import java.io.IOException; @@ -374,7 +375,19 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { // attributes relating to GL object protected boolean mipsWereGenerated = false; protected boolean needGeneratedMips = false; + protected final LastTextureState lastTextureState = new LastTextureState(); + /** + * Internal use only. + * The renderer stores the texture state set from the last texture + * so it doesn't have to change it unless necessary. + * + * @return The image parameter state. + */ + public LastTextureState getLastTextureState() { + return lastTextureState; + } + /** * Internal use only. * The renderer marks which images have generated mipmaps in VRAM @@ -429,6 +442,7 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { public void resetObject() { this.id = -1; this.mipsWereGenerated = false; + this.lastTextureState.reset(); setUpdateNeeded(); } diff --git a/jme3-core/src/main/java/com/jme3/texture/image/LastTextureState.java b/jme3-core/src/main/java/com/jme3/texture/image/LastTextureState.java new file mode 100644 index 000000000..e7f2a2a14 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/texture/image/LastTextureState.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009-2015 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 THE COPYRIGHT OWNER 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. + */ +package com.jme3.texture.image; + +import com.jme3.renderer.Renderer; +import com.jme3.texture.Texture; + +/** + * Stores / caches texture state parameters so they don't have to be set + * each time by the {@link Renderer}. + * + * @author Kirill Vainer + */ +public final class LastTextureState { + + public Texture.WrapMode sWrap, tWrap, rWrap; + public Texture.MagFilter magFilter; + public Texture.MinFilter minFilter; + + public LastTextureState() { + // All parameters initialized to null (meaning unset). + } + + public void reset() { + sWrap = null; + tWrap = null; + rWrap = null; + magFilter = null; + minFilter = null; + } +}