瀏覽代碼

GL implementations: Fix uploading of buffers with position != 0
* this is required for pregenerated mipmaps in e.g. DDS files
* others checks are added to make sure a zero-length buffer cannot be uploaded (that's an error for now)

shadowislord 10 年之前
父節點
當前提交
d3cbf7fbf2

+ 17 - 40
jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java

@@ -69,14 +69,14 @@ public class AndroidGL implements GL, GLExt {
     }
     
     private static void checkLimit(Buffer buffer) {
+        if (buffer == null) {
+            return;
+        }
         if (buffer.limit() == 0) {
-            throw new RendererException("Attempting to upload empty buffer, that's an error");
+            throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
         }
-    }
-    
-    private static void checkPosition(Buffer buffer) {
-        if (buffer.position() != 0) {
-            throw new RendererException("All buffers must have position set to zero");
+        if (buffer.remaining() == 0) {
+            throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
         }
     }
     
@@ -101,32 +101,26 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glBufferData(int target, FloatBuffer data, int usage) {
-        checkPosition(data);
         GLES20.glBufferData(target, getLimitBytes(data), data, usage);
     }
 
     public void glBufferData(int target, ShortBuffer data, int usage) {
-        checkPosition(data);
         GLES20.glBufferData(target, getLimitBytes(data), data, usage);
     }
 
     public void glBufferData(int target, ByteBuffer data, int usage) {
-        checkPosition(data);
         GLES20.glBufferData(target, getLimitBytes(data), data, usage);
     }
 
     public void glBufferSubData(int target, long offset, FloatBuffer data) {
-        checkPosition(data);
         GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
     }
 
     public void glBufferSubData(int target, long offset, ShortBuffer data) {
-        checkPosition(data);
         GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
     }
 
     public void glBufferSubData(int target, long offset, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data);
     }
 
@@ -147,12 +141,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glCompressedTexImage2D(target, level, internalformat, width, height, 0, getLimitBytes(data), data);
     }
 
     public void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, getLimitBytes(data), data);
     }
 
@@ -169,7 +161,7 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glDeleteBuffers(IntBuffer buffers) {
-        checkPosition(buffers);
+        checkLimit(buffers);
         GLES20.glDeleteBuffers(buffers.limit(), buffers);
     }
 
@@ -182,7 +174,7 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glDeleteTextures(IntBuffer textures) {
-        checkPosition(textures);
+        checkLimit(textures);
         GLES20.glDeleteTextures(textures.limit(), textures);
     }
 
@@ -227,12 +219,12 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glGenBuffers(IntBuffer buffers) {
-        checkPosition(buffers);
+        checkLimit(buffers);
         GLES20.glGenBuffers(buffers.limit(), buffers);
     }
 
     public void glGenTextures(IntBuffer textures) {
-        checkPosition(textures);
+        checkLimit(textures);
         GLES20.glGenTextures(textures.limit(), textures);
     }
 
@@ -250,12 +242,12 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glGetInteger(int pname, IntBuffer params) {
-        checkPosition(params);
+        checkLimit(params);
         GLES20.glGetIntegerv(pname, params);
     }
 
     public void glGetProgram(int program, int pname, IntBuffer params) {
-        checkPosition(params);
+        checkLimit(params);
         GLES20.glGetProgramiv(program, pname, params);
     }
 
@@ -264,7 +256,7 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glGetShader(int shader, int pname, IntBuffer params) {
-        checkPosition(params);
+        checkLimit(params);
         GLES20.glGetShaderiv(shader, pname, params);
     }
 
@@ -301,7 +293,6 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glReadPixels(x, y, width, height, format, type, data);
     }
 
@@ -325,7 +316,6 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glTexImage2D(target, level, format, width, height, 0, format, type, data);
     }
 
@@ -338,17 +328,14 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer data) {
-        checkPosition(data);
         GLES20.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
     }
 
     public void glUniform1(int location, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniform1fv(location, getLimitCount(value, 1), value);
     }
 
     public void glUniform1(int location, IntBuffer value) {
-        checkPosition(value);
         GLES20.glUniform1iv(location, getLimitCount(value, 1), value);
     }
 
@@ -361,12 +348,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glUniform2(int location, IntBuffer value) {
-        checkPosition(value);
         GLES20.glUniform2iv(location, getLimitCount(value, 2), value);
     }
 
     public void glUniform2(int location, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniform2fv(location, getLimitCount(value, 2), value);
     }
 
@@ -375,12 +360,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glUniform3(int location, IntBuffer value) {
-        checkPosition(value);
         GLES20.glUniform3iv(location, getLimitCount(value, 3), value);
     }
 
     public void glUniform3(int location, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniform3fv(location, getLimitCount(value, 3), value);
     }
 
@@ -389,12 +372,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glUniform4(int location, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniform4fv(location, getLimitCount(value, 4), value);
     }
 
     public void glUniform4(int location, IntBuffer value) {
-        checkPosition(value);
         GLES20.glUniform4iv(location, getLimitCount(value, 4), value);
     }
 
@@ -403,12 +384,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glUniformMatrix3(int location, boolean transpose, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniformMatrix3fv(location, getLimitCount(value, 3 * 3), transpose, value);
     }
 
     public void glUniformMatrix4(int location, boolean transpose, FloatBuffer value) {
-        checkPosition(value);
         GLES20.glUniformMatrix4fv(location, getLimitCount(value, 4 * 4), transpose, value);
     }
 
@@ -429,12 +408,10 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glBufferData(int target, IntBuffer data, int usage) {
-        checkPosition(data);
         GLES20.glBufferData(target, getLimitBytes(data), data, usage);
     }
 
     public void glBufferSubData(int target, long offset, IntBuffer data) {
-        checkPosition(data);
         GLES20.glBufferSubData(target, (int)offset, getLimitBytes(data), data);
     }
 
@@ -479,12 +456,12 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glDeleteFramebuffersEXT(IntBuffer param1) {
-        checkPosition(param1);
+        checkLimit(param1);
         GLES20.glDeleteFramebuffers(param1.limit(), param1);
     }
 
     public void glDeleteRenderbuffersEXT(IntBuffer param1) {
-        checkPosition(param1);
+        checkLimit(param1);
         GLES20.glDeleteRenderbuffers(param1.limit(), param1);
     }
 
@@ -497,12 +474,12 @@ public class AndroidGL implements GL, GLExt {
     }
 
     public void glGenFramebuffersEXT(IntBuffer param1) {
-        checkPosition(param1);
+        checkLimit(param1);
         GLES20.glGenFramebuffers(param1.limit(), param1);
     }
 
     public void glGenRenderbuffersEXT(IntBuffer param1) {
-        checkPosition(param1);
+        checkLimit(param1);
         GLES20.glGenRenderbuffers(param1.limit(), param1);
     }
 

+ 49 - 0
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java

@@ -1,8 +1,10 @@
 package com.jme3.renderer.lwjgl;
 
+import com.jme3.renderer.RendererException;
 import com.jme3.renderer.opengl.GL;
 import com.jme3.renderer.opengl.GL2;
 import com.jme3.renderer.opengl.GL3;
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
@@ -16,6 +18,18 @@ import org.lwjgl.opengl.GL30;
 
 public class LwjglGL implements GL, GL2, GL3 {
     
+    private static void checkLimit(Buffer buffer) {
+        if (buffer == null) {
+            return;
+        }
+        if (buffer.limit() == 0) {
+            throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
+        }
+        if (buffer.remaining() == 0) {
+            throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
+        }
+    }
+    
     public void glActiveTexture(int param1) {
         GL13.glActiveTexture(param1);
     }
@@ -41,26 +55,32 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glBufferData(int param1, FloatBuffer param2, int param3) {
+        checkLimit(param2);
         GL15.glBufferData(param1, param2, param3);
     }
 
     public void glBufferData(int param1, ShortBuffer param2, int param3) {
+        checkLimit(param2);
         GL15.glBufferData(param1, param2, param3);
     }
 
     public void glBufferData(int param1, ByteBuffer param2, int param3) {
+        checkLimit(param2);
         GL15.glBufferData(param1, param2, param3);
     }
 
     public void glBufferSubData(int param1, long param2, FloatBuffer param3) {
+        checkLimit(param3);
         GL15.glBufferSubData(param1, param2, param3);
     }
 
     public void glBufferSubData(int param1, long param2, ShortBuffer param3) {
+        checkLimit(param3);
         GL15.glBufferSubData(param1, param2, param3);
     }
 
     public void glBufferSubData(int param1, long param2, ByteBuffer param3) {
+        checkLimit(param3);
         GL15.glBufferSubData(param1, param2, param3);
     }
 
@@ -81,18 +101,22 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glCompressedTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) {
+        checkLimit(param7);
         GL13.glCompressedTexImage2D(param1, param2, param3, param4, param5, param6, param7);
     }
 
     public void glCompressedTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) {
+        checkLimit(param8);
         GL13.glCompressedTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8);
     }
 
     public void glCompressedTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) {
+        checkLimit(param8);
         GL13.glCompressedTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8);
     }
 
     public void glCompressedTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) {
+        checkLimit(param10);
         GL13.glCompressedTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
     }
 
@@ -109,6 +133,7 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glDeleteBuffers(IntBuffer param1) {
+        checkLimit(param1);
         GL15.glDeleteBuffers(param1);
     }
 
@@ -121,6 +146,7 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glDeleteTextures(IntBuffer param1) {
+        checkLimit(param1);
         GL11.glDeleteTextures(param1);
     }
 
@@ -169,14 +195,17 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glGenBuffers(IntBuffer param1) {
+        checkLimit(param1);
         GL15.glGenBuffers(param1);
     }
 
     public void glGenTextures(IntBuffer param1) {
+        checkLimit(param1);
         GL11.glGenTextures(param1);
     }
 
     public void glGetBoolean(int param1, ByteBuffer param2) {
+        checkLimit(param2);
         GL11.glGetBoolean(param1, param2);
     }
 
@@ -185,14 +214,17 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
     
     public void glGetInteger(int param1, IntBuffer param2) {
+        checkLimit(param2);
         GL11.glGetInteger(param1, param2);
     }
 
     public void glGetProgram(int param1, int param2, IntBuffer param3) {
+        checkLimit(param3);
         GL20.glGetProgram(param1, param2, param3);
     }
 
     public void glGetShader(int param1, int param2, IntBuffer param3) {
+        checkLimit(param3);
         GL20.glGetShader(param1, param2, param3);
     }
 
@@ -233,6 +265,7 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) {
+        checkLimit(param7);
         GL11.glReadPixels(param1, param2, param3, param4, param5, param6, param7);
     }
 
@@ -249,10 +282,12 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) {
+        checkLimit(param9);
         GL11.glTexImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9);
     }
 
     public void glTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) {
+        checkLimit(param10);
         GL12.glTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
     }
 
@@ -265,18 +300,22 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) {
+        checkLimit(param9);
         GL11.glTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9);
     }
 
     public void glTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10, ByteBuffer param11) {
+        checkLimit(param11);
         GL12.glTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11);
     }
 
     public void glUniform1(int param1, FloatBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform1(param1, param2);
     }
 
     public void glUniform1(int param1, IntBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform1(param1, param2);
     }
 
@@ -289,10 +328,12 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glUniform2(int param1, IntBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform2(param1, param2);
     }
 
     public void glUniform2(int param1, FloatBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform2(param1, param2);
     }
 
@@ -301,10 +342,12 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glUniform3(int param1, IntBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform3(param1, param2);
     }
 
     public void glUniform3(int param1, FloatBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform3(param1, param2);
     }
 
@@ -313,10 +356,12 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glUniform4(int param1, FloatBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform4(param1, param2);
     }
 
     public void glUniform4(int param1, IntBuffer param2) {
+        checkLimit(param2);
         GL20.glUniform4(param1, param2);
     }
 
@@ -325,10 +370,12 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glUniformMatrix3(int param1, boolean param2, FloatBuffer param3) {
+        checkLimit(param3);
         GL20.glUniformMatrix3(param1, param2, param3);
     }
 
     public void glUniformMatrix4(int param1, boolean param2, FloatBuffer param3) {
+        checkLimit(param3);
         GL20.glUniformMatrix4(param1, param2, param3);
     }
 
@@ -355,6 +402,7 @@ public class LwjglGL implements GL, GL2, GL3 {
     }
 
     public void glShaderSource(int param1, String[] param2, IntBuffer param3) {
+        checkLimit(param3);
         GL20.glShaderSource(param1, param2);
     }
 
@@ -378,6 +426,7 @@ public class LwjglGL implements GL, GL2, GL3 {
 
     @Override
     public void glGenVertexArrays(IntBuffer param1) {
+        checkLimit(param1);
         GL30.glGenVertexArrays(param1);
     }
 }

+ 22 - 0
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java

@@ -1,6 +1,8 @@
 package com.jme3.renderer.lwjgl;
 
+import com.jme3.renderer.RendererException;
 import com.jme3.renderer.opengl.GLExt;
+import java.nio.Buffer;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
 import org.lwjgl.opengl.ARBDrawInstanced;
@@ -14,15 +16,29 @@ import org.lwjgl.opengl.GL20;
 
 public class LwjglGLExt implements GLExt {
 
+    private static void checkLimit(Buffer buffer) {
+        if (buffer == null) {
+            return;
+        }
+        if (buffer.limit() == 0) {
+            throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
+        }
+        if (buffer.remaining() == 0) {
+            throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
+        }
+    }
+    
     public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
         EXTFramebufferBlit.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
     }
 
     public void glBufferData(int target, IntBuffer data, int usage) {
+        checkLimit(data);
         GL15.glBufferData(target, data, usage);
     }
 
     public void glBufferSubData(int target, long offset, IntBuffer data) {
+        checkLimit(data);
         GL15.glBufferSubData(target, offset, data);
     }
 
@@ -31,6 +47,7 @@ public class LwjglGLExt implements GLExt {
     }
 
     public void glDrawBuffers(IntBuffer bufs) {
+        checkLimit(bufs);
         GL20.glDrawBuffers(bufs);
     }
 
@@ -39,6 +56,7 @@ public class LwjglGLExt implements GLExt {
     }
 
     public void glGetMultisample(int pname, int index, FloatBuffer val) {
+        checkLimit(val);
         ARBTextureMultisample.glGetMultisample(pname, index, val);
     }
 
@@ -67,10 +85,12 @@ public class LwjglGLExt implements GLExt {
     }
 
     public void glDeleteFramebuffersEXT(IntBuffer param1) {
+        checkLimit(param1);
         EXTFramebufferObject.glDeleteFramebuffersEXT(param1);
     }
 
     public void glDeleteRenderbuffersEXT(IntBuffer param1) {
+        checkLimit(param1);
         EXTFramebufferObject.glDeleteRenderbuffersEXT(param1);
     }
 
@@ -83,10 +103,12 @@ public class LwjglGLExt implements GLExt {
     }
 
     public void glGenFramebuffersEXT(IntBuffer param1) {
+        checkLimit(param1);
         EXTFramebufferObject.glGenFramebuffersEXT(param1);
     }
 
     public void glGenRenderbuffersEXT(IntBuffer param1) {
+        checkLimit(param1);
         EXTFramebufferObject.glGenRenderbuffersEXT(param1);
     }