Răsfoiți Sursa

updated API of BO.

javasabr 7 ani în urmă
părinte
comite
54e3987022

+ 15 - 9
jme3-core/src/main/java/com/jme3/material/Material.java

@@ -669,19 +669,25 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
     }
 
     /**
-     * Pass a buffer object to the material shader.
+     * Pass an uniform buffer object to the material shader.
      *
      * @param name  the name of the buffer object defined in the material definition (j3md).
      * @param value the buffer object.
      */
-    public void setBufferObject(final String name, final BufferObject value) {
-        if (value instanceof UniformBufferObject) {
-            setParam(name, VarType.UniformBufferObject, value);
-        } else if (value instanceof ShaderStorageBufferObject) {
-            setParam(name, VarType.ShaderStorageBufferObject, value);
-        } else {
-            throw new IllegalArgumentException("Not expected value " + value);
-        }
+    public void setUniformBufferObject(final String name, final BufferObject value) {
+        value.setBufferType(BufferObject.BufferType.UniformBufferObject);
+        setParam(name, VarType.UniformBufferObject, value);
+    }
+
+    /**
+     * Pass a shader storage buffer object to the material shader.
+     *
+     * @param name  the name of the buffer object defined in the material definition (j3md).
+     * @param value the buffer object.
+     */
+    public void setShaderStorageBufferObject(final String name, final BufferObject value) {
+        value.setBufferType(BufferObject.BufferType.ShaderStorageBufferObject);
+        setParam(name, VarType.ShaderStorageBufferObject, value);
     }
 
     /**

+ 0 - 2
jme3-core/src/main/java/com/jme3/renderer/Renderer.java

@@ -38,8 +38,6 @@ import com.jme3.scene.VertexBuffer;
 import com.jme3.shader.BufferObject;
 import com.jme3.shader.Shader;
 import com.jme3.shader.Shader.ShaderSource;
-import com.jme3.shader.ShaderStorageBufferObject;
-import com.jme3.shader.UniformBufferObject;
 import com.jme3.system.AppSettings;
 import com.jme3.texture.FrameBuffer;
 import com.jme3.texture.Image;

+ 38 - 27
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -1229,15 +1229,24 @@ public final class GLRenderer implements Renderer {
         bindProgram(shader);
 
         final int shaderId = shader.getId();
+        final BufferObject.BufferType bufferType = bufferObject.getBufferType();
 
-        if (bufferObject instanceof ShaderStorageBufferObject) {
-            final int blockIndex = gl4.glGetProgramResourceIndex(shaderId, GL4.GL_SHADER_STORAGE_BLOCK, bufferBlock.getName());
-            gl4.glShaderStorageBlockBinding(shaderId, blockIndex, bufferObject.getBinding());
-            gl4.glBindBufferBase(GL4.GL_SHADER_STORAGE_BUFFER, bufferObject.getBinding(), bufferObject.getId());
-        } else if (bufferObject instanceof UniformBufferObject) {
-            final int blockIndex = gl3.glGetUniformBlockIndex(shaderId, bufferBlock.getName());
-            gl3.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bufferObject.getBinding(), bufferObject.getId());
-            gl3.glUniformBlockBinding(GL3.GL_UNIFORM_BUFFER, blockIndex, bufferObject.getBinding());
+        switch (bufferType) {
+            case UniformBufferObject: {
+                final int blockIndex = gl3.glGetUniformBlockIndex(shaderId, bufferBlock.getName());
+                gl3.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bufferObject.getBinding(), bufferObject.getId());
+                gl3.glUniformBlockBinding(GL3.GL_UNIFORM_BUFFER, blockIndex, bufferObject.getBinding());
+                break;
+            }
+            case ShaderStorageBufferObject: {
+                final int blockIndex = gl4.glGetProgramResourceIndex(shaderId, GL4.GL_SHADER_STORAGE_BLOCK, bufferBlock.getName());
+                gl4.glShaderStorageBlockBinding(shaderId, blockIndex, bufferObject.getBinding());
+                gl4.glBindBufferBase(GL4.GL_SHADER_STORAGE_BUFFER, bufferObject.getBinding(), bufferObject.getId());
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Doesn't support binding of " + bufferType);
+            }
         }
 
         bufferBlock.clearUpdateNeeded();
@@ -2577,16 +2586,10 @@ public final class GLRenderer implements Renderer {
 
         int maxSize = Integer.MAX_VALUE;
 
-        if (bo instanceof UniformBufferObject) {
-            if (!caps.contains(Caps.UniformBufferObject)) {
-                throw new IllegalArgumentException("The current video hardware doesn't support UBO.");
-            }
-        } else if (bo instanceof ShaderStorageBufferObject) {
-            if (!caps.contains(Caps.ShaderStorageBufferObject)) {
-                throw new IllegalArgumentException("The current video hardware doesn't support SSBO.");
-            }
-        } else {
-            throw new IllegalArgumentException("Not expected type of the BO " + bo);
+        final BufferObject.BufferType bufferType = bo.getBufferType();
+
+        if (!caps.contains(bufferType.getRequiredCaps())) {
+            throw new IllegalArgumentException("The current video hardware doesn't support " + bufferType);
         }
 
         final ByteBuffer data = bo.computeData(maxSize);
@@ -2609,14 +2612,22 @@ public final class GLRenderer implements Renderer {
 
         data.rewind();
 
-        if (bo instanceof UniformBufferObject) {
-            gl3.glBindBuffer(GL3.GL_UNIFORM_BUFFER, bufferId);
-            gl3.glBufferData(GL4.GL_UNIFORM_BUFFER, data, GL3.GL_DYNAMIC_DRAW);
-            gl3.glBindBuffer(GL4.GL_UNIFORM_BUFFER, 0);
-        } else {
-            gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, bufferId);
-            gl4.glBufferData(GL4.GL_SHADER_STORAGE_BUFFER, data, GL4.GL_DYNAMIC_COPY);
-            gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, 0);
+        switch (bufferType) {
+            case UniformBufferObject: {
+                gl3.glBindBuffer(GL3.GL_UNIFORM_BUFFER, bufferId);
+                gl3.glBufferData(GL4.GL_UNIFORM_BUFFER, data, GL3.GL_DYNAMIC_DRAW);
+                gl3.glBindBuffer(GL4.GL_UNIFORM_BUFFER, 0);
+                break;
+            }
+            case ShaderStorageBufferObject: {
+                gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, bufferId);
+                gl4.glBufferData(GL4.GL_SHADER_STORAGE_BUFFER, data, GL4.GL_DYNAMIC_COPY);
+                gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, 0);
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Doesn't support binding of " + bufferType);
+            }
         }
 
         bo.clearUpdateNeeded();
@@ -2644,7 +2655,7 @@ public final class GLRenderer implements Renderer {
         }
 
         intBuf1.clear();
-        intBuf1.put(0, bufferId);
+        intBuf1.put(bufferId);
         intBuf1.flip();
 
         gl.glDeleteBuffers(intBuf1);

+ 97 - 24
jme3-core/src/main/java/com/jme3/shader/BufferObject.java

@@ -1,6 +1,7 @@
 package com.jme3.shader;
 
 import com.jme3.math.*;
+import com.jme3.renderer.Caps;
 import com.jme3.renderer.Renderer;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.NativeObject;
@@ -23,11 +24,37 @@ public class BufferObject extends NativeObject {
         std430,
     }
 
+    public enum BufferType {
+        ShaderStorageBufferObject(Caps.ShaderStorageBufferObject),
+        UniformBufferObject(Caps.UniformBufferObject),
+        ;
+
+        private final Caps requiredCaps;
+
+        BufferType(final Caps requiredCaps) {
+            this.requiredCaps = requiredCaps;
+        }
+
+        /**
+         * Get the required caps.
+         *
+         * @return the required caps.
+         */
+        public Caps getRequiredCaps() {
+            return requiredCaps;
+        }
+    }
+
     /**
      * The fields of this BO.
      */
     private final Map<String, BufferObjectField> fields;
 
+    /**
+     * The field's array.
+     */
+    private final BufferObjectField[] fieldArray;
+
     /**
      * The buffer's data layout.
      */
@@ -38,19 +65,38 @@ public class BufferObject extends NativeObject {
      */
     private final int binding;
 
+    /**
+     * The buffer's type.
+     */
+    private BufferType bufferType;
+
     /**
      * The previous data buffer.
      */
     private ByteBuffer previousData;
 
-    public BufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
+    public BufferObject(final int binding, final Layout layout, final BufferType bufferType, final BufferObjectField... fields) {
         this.handleRef = new Object();
+        this.bufferType = bufferType;
         this.binding = binding;
         this.layout = layout;
         this.fields = new LinkedHashMap<>(fields.length);
         for (final BufferObjectField field : fields) {
             this.fields.put(field.getName(), field);
         }
+        this.fieldArray = fields;
+    }
+
+    public BufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
+        this(binding, layout, BufferType.UniformBufferObject, fields);
+    }
+
+    public BufferObject(final int binding, final BufferObjectField... fields) {
+        this(binding, Layout.std140, BufferType.UniformBufferObject, fields);
+    }
+
+    public BufferObject(final BufferObjectField... fields) {
+        this(1, Layout.std140, BufferType.UniformBufferObject, fields);
     }
 
     public BufferObject(final int id) {
@@ -58,6 +104,30 @@ public class BufferObject extends NativeObject {
         this.binding = -2;
         this.fields = null;
         this.layout = null;
+        this.fieldArray = null;
+    }
+
+    /**
+     * Gets the buffer's type.
+     *
+     * @return the buffer's type.
+     */
+    public BufferType getBufferType() {
+        return bufferType;
+    }
+
+    /**
+     * Sets the buffer's type.
+     *
+     * @param bufferType the buffer's type.
+     */
+    public void setBufferType(final BufferType bufferType) {
+
+        if (getId() != -1) {
+            throw new IllegalStateException("Can't change buffer's type when this buffer is already initialized.");
+        }
+
+        this.bufferType = bufferType;
     }
 
     /**
@@ -119,31 +189,34 @@ public class BufferObject extends NativeObject {
 
         int estimateSize = 0;
 
-        for (final Map.Entry<String, BufferObjectField> entry : fields.entrySet()) {
-            final BufferObjectField field = entry.getValue();
+        for (final BufferObjectField field : fieldArray) {
             estimateSize += estimateSize(field);
         }
 
         if(maxSize < estimateSize) {
             throw new IllegalStateException("The estimated size(" + estimateSize + ") of this BO is bigger than " +
-                "maximum available size " + maxSize);
+                    "maximum available size " + maxSize);
         }
 
         if (previousData != null) {
             if (previousData.capacity() < estimateSize) {
                 BufferUtils.destroyDirectBuffer(previousData);
                 previousData = null;
+            } else {
+                previousData.clear();
             }
         }
 
-        final ByteBuffer data = previousData == null ? BufferUtils.createByteBuffer((int) (estimateSize * 1.1F)) : previousData;
+        final ByteBuffer data = previousData == null ? BufferUtils.createByteBuffer(estimateSize) : previousData;
 
-        for (final Map.Entry<String, BufferObjectField> entry : fields.entrySet()) {
-            writeField(entry.getValue(), data);
+        for (final BufferObjectField field : fieldArray) {
+            writeField(field, data);
         }
 
         data.flip();
 
+        this.previousData = data;
+
         return data;
     }
 
@@ -510,25 +583,25 @@ public class BufferObject extends NativeObject {
 
             final Vector4f vec4 = (Vector4f) value;
             data.putFloat(vec4.getX())
-                .putFloat(vec4.getY())
-                .putFloat(vec4.getZ())
-                .putFloat(vec4.getW());
+                    .putFloat(vec4.getY())
+                    .putFloat(vec4.getZ())
+                    .putFloat(vec4.getW());
 
         } else if(value instanceof Quaternion) {
 
             final Quaternion vec4 = (Quaternion) value;
             data.putFloat(vec4.getX())
-                .putFloat(vec4.getY())
-                .putFloat(vec4.getZ())
-                .putFloat(vec4.getW());
+                    .putFloat(vec4.getY())
+                    .putFloat(vec4.getZ())
+                    .putFloat(vec4.getW());
 
         } else if(value instanceof ColorRGBA) {
 
             final ColorRGBA vec4 = (ColorRGBA) value;
             data.putFloat(vec4.getRed())
-                .putFloat(vec4.getGreen())
-                .putFloat(vec4.getBlue())
-                .putFloat(vec4.getAlpha());
+                    .putFloat(vec4.getGreen())
+                    .putFloat(vec4.getBlue())
+                    .putFloat(vec4.getAlpha());
         }
     }
 
@@ -541,8 +614,8 @@ public class BufferObject extends NativeObject {
     protected void write(final ByteBuffer data, final Vector3f value) {
 
         data.putFloat(value.getX())
-            .putFloat(value.getY())
-            .putFloat(value.getZ());
+                .putFloat(value.getY())
+                .putFloat(value.getZ());
 
         if (layout == Layout.std140) {
             data.putInt(0);
@@ -560,8 +633,8 @@ public class BufferObject extends NativeObject {
     protected void write(final ByteBuffer data, final float x, final float y, final float z) {
 
         data.putFloat(x)
-            .putFloat(y)
-            .putFloat(z);
+                .putFloat(y)
+                .putFloat(z);
 
         if (layout == Layout.std140) {
             data.putInt(0);
@@ -579,9 +652,9 @@ public class BufferObject extends NativeObject {
      */
     protected void write(final ByteBuffer data, final float x, final float y, final float z, final float w) {
         data.putFloat(x)
-            .putFloat(y)
-            .putFloat(z)
-            .putFloat(w);
+                .putFloat(y)
+                .putFloat(z)
+                .putFloat(w);
     }
 
     /**
@@ -592,7 +665,7 @@ public class BufferObject extends NativeObject {
      */
     protected void write(final ByteBuffer data, final Vector2f value) {
         data.putFloat(value.getX())
-            .putFloat(value.getY());
+                .putFloat(value.getY());
     }
 
     /**

+ 0 - 21
jme3-core/src/main/java/com/jme3/shader/ShaderStorageBufferObject.java

@@ -1,21 +0,0 @@
-package com.jme3.shader;
-
-/**
- * The implementation of SSBO.
- *
- * @author JavaSaBr
- */
-public class ShaderStorageBufferObject extends BufferObject {
-
-    public ShaderStorageBufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
-        super(binding, layout, fields);
-    }
-
-    public ShaderStorageBufferObject(final int binding, final BufferObjectField... fields) {
-        super(binding, Layout.std430, fields);
-    }
-
-    public ShaderStorageBufferObject(final int id) {
-        super(id);
-    }
-}

+ 0 - 17
jme3-core/src/main/java/com/jme3/shader/UniformBufferObject.java

@@ -1,17 +0,0 @@
-package com.jme3.shader;
-
-/**
- * The implementation of UBO.
- *
- * @author JavaSaBr
- */
-public class UniformBufferObject extends BufferObject {
-
-    public UniformBufferObject(final int binding, final BufferObjectField... fields) {
-        super(binding, Layout.std140, fields);
-    }
-
-    public UniformBufferObject(final int id) {
-        super(id);
-    }
-}

+ 3 - 4
jme3-core/src/main/java/com/jme3/system/NullRenderer.java

@@ -31,9 +31,6 @@
  */
 package com.jme3.system;
 
-import java.nio.ByteBuffer;
-import java.util.EnumSet;
-
 import com.jme3.light.LightList;
 import com.jme3.material.RenderState;
 import com.jme3.math.ColorRGBA;
@@ -47,11 +44,13 @@ import com.jme3.scene.VertexBuffer;
 import com.jme3.shader.BufferObject;
 import com.jme3.shader.Shader;
 import com.jme3.shader.Shader.ShaderSource;
-import com.jme3.shader.ShaderStorageBufferObject;
 import com.jme3.texture.FrameBuffer;
 import com.jme3.texture.Image;
 import com.jme3.texture.Texture;
+
+import java.nio.ByteBuffer;
 import java.util.EnumMap;
+import java.util.EnumSet;
 
 public class NullRenderer implements Renderer {