From 4e572605a8d195cf7f8dfe3b73be4b8f2086067e Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Sat, 12 Sep 2015 17:52:56 -0400 Subject: [PATCH] GLRenderer: merge changes from master --- .../com/jme3/renderer/opengl/GLRenderer.java | 126 ++++++++++-------- 1 file changed, 74 insertions(+), 52 deletions(-) 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 14da67de7..132fb4cd9 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 @@ -1816,7 +1816,7 @@ public class GLRenderer implements Renderer { } @SuppressWarnings("fallthrough") - private void setupTextureParams(Texture tex) { + private void setupTextureParams(int unit, Texture tex) { Image image = tex.getImage(); int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1); @@ -1829,32 +1829,23 @@ public class GLRenderer implements Renderer { // filter things if (image.getLastTextureState().magFilter != tex.getMagFilter()) { int magFilter = convertMagFilter(tex.getMagFilter()); + bindTextureAndUnit(target, image, unit); 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); + bindTextureAndUnit(target, image, unit); gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter); image.getLastTextureState().minFilter = tex.getMinFilter(); } - if (caps.contains(Caps.SeamlessCubemap) && tex.getType() == Texture.Type.CubeMap) { - if (haveMips && !context.seamlessCubemap) { - // We can enable seamless cubemap filtering. - gl.glEnable(GLExt.GL_TEXTURE_CUBE_MAP_SEAMLESS); - context.seamlessCubemap = true; - } else if (!haveMips && context.seamlessCubemap) { - // For skyboxes (no mipmaps), disable seamless cubemap filtering. - gl.glDisable(GLExt.GL_TEXTURE_CUBE_MAP_SEAMLESS); - context.seamlessCubemap = false; - } - } - - if (tex.getAnisotropicFilter() > 1) { - if (caps.contains(Caps.TextureFilterAnisotropic)) { - gl.glTexParameterf(target, - GLExt.GL_TEXTURE_MAX_ANISOTROPY_EXT, - tex.getAnisotropicFilter()); - } + if (caps.contains(Caps.TextureFilterAnisotropic) + && image.getLastTextureState().anisoFilter != tex.getAnisotropicFilter()) { + bindTextureAndUnit(target, image, unit); + gl.glTexParameterf(target, + GLExt.GL_TEXTURE_MAX_ANISOTROPY_EXT, + tex.getAnisotropicFilter()); + image.getLastTextureState().anisoFilter = tex.getAnisotropicFilter(); } // repeat modes @@ -1862,6 +1853,7 @@ public class GLRenderer implements Renderer { case ThreeDimensional: case CubeMap: // cubemaps use 3D coords if (gl2 != null && image.getLastTextureState().rWrap != tex.getWrap(WrapAxis.R)) { + bindTextureAndUnit(target, image, unit); gl2.glTexParameteri(target, GL2.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R))); image.getLastTextureState().rWrap = tex.getWrap(WrapAxis.R); } @@ -1869,10 +1861,12 @@ public class GLRenderer implements Renderer { case TwoDimensional: case TwoDimensionalArray: if (image.getLastTextureState().tWrap != tex.getWrap(WrapAxis.T)) { + bindTextureAndUnit(target, image, unit); 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)) { + bindTextureAndUnit(target, image, unit); gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); image.getLastTextureState().sWrap = tex.getWrap(WrapAxis.S); } @@ -1881,21 +1875,27 @@ public class GLRenderer implements Renderer { throw new UnsupportedOperationException("Unknown texture type: " + tex.getType()); } - if(tex.isNeedCompareModeUpdate() && gl2 != null){ + if (tex.isNeedCompareModeUpdate() && gl2 != null) { // R to Texture compare mode if (tex.getShadowCompareMode() != Texture.ShadowCompareMode.Off) { + bindTextureAndUnit(target, image, unit); gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_R_TO_TEXTURE); + gl2.glTexParameteri(target, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY); if (tex.getShadowCompareMode() == Texture.ShadowCompareMode.GreaterOrEqual) { gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_FUNC, GL.GL_GEQUAL); } else { gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_FUNC, GL.GL_LEQUAL); } - }else{ + } else { + bindTextureAndUnit(target, image, unit); //restoring default value gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL.GL_NONE); } tex.compareModeUpdated(); } + + // If at this point we didn't bind the texture, bind it now + bindTextureOnly(target, image, unit); } /** @@ -1953,6 +1953,50 @@ public class GLRenderer implements Renderer { } } + /** + * Ensures that the texture is bound to the given unit + * and that the unit is currently active (for modification). + * + * @param target The texture target, one of GL_TEXTURE_*** + * @param img The image texture to bind + * @param unit At what unit to bind the texture. + */ + private void bindTextureAndUnit(int target, Image img, int unit) { + if (context.boundTextureUnit != unit) { + gl.glActiveTexture(GL.GL_TEXTURE0 + unit); + context.boundTextureUnit = unit; + } + if (context.boundTextures[unit] != img) { + gl.glBindTexture(target, img.getId()); + context.boundTextures[unit] = img; + statistics.onTextureUse(img, true); + } else { + statistics.onTextureUse(img, false); + } + } + + /** + * Ensures that the texture is bound to the given unit, + * but does not care if the unit is active (for rendering). + * + * @param target The texture target, one of GL_TEXTURE_*** + * @param img The image texture to bind + * @param unit At what unit to bind the texture. + */ + private void bindTextureOnly(int target, Image img, int unit) { + if (context.boundTextures[unit] != img) { + if (context.boundTextureUnit != unit) { + gl.glActiveTexture(GL.GL_TEXTURE0 + unit); + context.boundTextureUnit = unit; + } + gl.glBindTexture(target, img.getId()); + context.boundTextures[unit] = img; + statistics.onTextureUse(img, true); + } else { + statistics.onTextureUse(img, false); + } + } + /** * Uploads the given image to the GL driver. * @@ -1974,19 +2018,10 @@ public class GLRenderer implements Renderer { statistics.onNewTexture(); } - // bind texture + // bind texture int target = convertTextureType(type, img.getMultiSamples(), -1); - if (context.boundTextures[unit] != img) { - if (context.boundTextureUnit != unit) { - gl.glActiveTexture(GL.GL_TEXTURE0 + unit); - context.boundTextureUnit = unit; - } - - gl.glBindTexture(target, texId); - context.boundTextures[unit] = img; - - statistics.onTextureUse(img, true); - } + + bindTextureAndUnit(target, img, unit); if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired()) { // Image does not have mipmaps, but they are required. @@ -2095,6 +2130,7 @@ public class GLRenderer implements Renderer { img.clearUpdateNeeded(); } + @Override public void setTexture(int unit, Texture tex) { Image image = tex.getImage(); if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { @@ -2121,24 +2157,7 @@ public class GLRenderer implements Renderer { int texId = image.getId(); assert texId != -1; - Image[] textures = context.boundTextures; - - int type = convertTextureType(tex.getType(), image.getMultiSamples(), -1); - if (textures[unit] != image) { - if (context.boundTextureUnit != unit) { - gl.glActiveTexture(GL.GL_TEXTURE0 + unit); - context.boundTextureUnit = unit; - } - - gl.glBindTexture(type, texId); - textures[unit] = image; - - statistics.onTextureUse(image, true); - } else { - statistics.onTextureUse(image, false); - } - - setupTextureParams(tex); + setupTextureParams(unit, tex); } public void modifyTexture(Texture tex, Image pixels, int x, int y) { @@ -2722,12 +2741,15 @@ public class GLRenderer implements Renderer { private void renderMeshLegacy(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { setupVertexBuffersLegacy(mesh, instanceData); VertexBuffer indices = getIndexBuffer(mesh, lod); + + clearVertexAttribs(); + if (indices != null) { drawTriangleList(indices, mesh, count); } else { drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount()); } - clearVertexAttribs(); + } public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) {