updated API of BO.

JavaSaBr-added_new_var_type
javasabr 7 years ago committed by Nehon
parent 2297441c13
commit 54e3987022
  1. 24
      jme3-core/src/main/java/com/jme3/material/Material.java
  2. 2
      jme3-core/src/main/java/com/jme3/renderer/Renderer.java
  3. 65
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  4. 121
      jme3-core/src/main/java/com/jme3/shader/BufferObject.java
  5. 21
      jme3-core/src/main/java/com/jme3/shader/ShaderStorageBufferObject.java
  6. 17
      jme3-core/src/main/java/com/jme3/shader/UniformBufferObject.java
  7. 7
      jme3-core/src/main/java/com/jme3/system/NullRenderer.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 name the name of the buffer object defined in the material definition (j3md).
* @param value the buffer object. * @param value the buffer object.
*/ */
public void setBufferObject(final String name, final BufferObject value) { public void setUniformBufferObject(final String name, final BufferObject value) {
if (value instanceof UniformBufferObject) { value.setBufferType(BufferObject.BufferType.UniformBufferObject);
setParam(name, VarType.UniformBufferObject, value); setParam(name, VarType.UniformBufferObject, value);
} else if (value instanceof ShaderStorageBufferObject) { }
setParam(name, VarType.ShaderStorageBufferObject, value);
} else { /**
throw new IllegalArgumentException("Not expected value " + 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);
} }
/** /**

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

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

@ -1,6 +1,7 @@
package com.jme3.shader; package com.jme3.shader;
import com.jme3.math.*; import com.jme3.math.*;
import com.jme3.renderer.Caps;
import com.jme3.renderer.Renderer; import com.jme3.renderer.Renderer;
import com.jme3.util.BufferUtils; import com.jme3.util.BufferUtils;
import com.jme3.util.NativeObject; import com.jme3.util.NativeObject;
@ -23,11 +24,37 @@ public class BufferObject extends NativeObject {
std430, 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. * The fields of this BO.
*/ */
private final Map<String, BufferObjectField> fields; private final Map<String, BufferObjectField> fields;
/**
* The field's array.
*/
private final BufferObjectField[] fieldArray;
/** /**
* The buffer's data layout. * The buffer's data layout.
*/ */
@ -38,19 +65,38 @@ public class BufferObject extends NativeObject {
*/ */
private final int binding; private final int binding;
/**
* The buffer's type.
*/
private BufferType bufferType;
/** /**
* The previous data buffer. * The previous data buffer.
*/ */
private ByteBuffer previousData; 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.handleRef = new Object();
this.bufferType = bufferType;
this.binding = binding; this.binding = binding;
this.layout = layout; this.layout = layout;
this.fields = new LinkedHashMap<>(fields.length); this.fields = new LinkedHashMap<>(fields.length);
for (final BufferObjectField field : fields) { for (final BufferObjectField field : fields) {
this.fields.put(field.getName(), field); 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) { public BufferObject(final int id) {
@ -58,6 +104,30 @@ public class BufferObject extends NativeObject {
this.binding = -2; this.binding = -2;
this.fields = null; this.fields = null;
this.layout = 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; int estimateSize = 0;
for (final Map.Entry<String, BufferObjectField> entry : fields.entrySet()) { for (final BufferObjectField field : fieldArray) {
final BufferObjectField field = entry.getValue();
estimateSize += estimateSize(field); estimateSize += estimateSize(field);
} }
if(maxSize < estimateSize) { if(maxSize < estimateSize) {
throw new IllegalStateException("The estimated size(" + estimateSize + ") of this BO is bigger than " + 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 != null) {
if (previousData.capacity() < estimateSize) { if (previousData.capacity() < estimateSize) {
BufferUtils.destroyDirectBuffer(previousData); BufferUtils.destroyDirectBuffer(previousData);
previousData = null; 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()) { for (final BufferObjectField field : fieldArray) {
writeField(entry.getValue(), data); writeField(field, data);
} }
data.flip(); data.flip();
this.previousData = data;
return data; return data;
} }
@ -510,25 +583,25 @@ public class BufferObject extends NativeObject {
final Vector4f vec4 = (Vector4f) value; final Vector4f vec4 = (Vector4f) value;
data.putFloat(vec4.getX()) data.putFloat(vec4.getX())
.putFloat(vec4.getY()) .putFloat(vec4.getY())
.putFloat(vec4.getZ()) .putFloat(vec4.getZ())
.putFloat(vec4.getW()); .putFloat(vec4.getW());
} else if(value instanceof Quaternion) { } else if(value instanceof Quaternion) {
final Quaternion vec4 = (Quaternion) value; final Quaternion vec4 = (Quaternion) value;
data.putFloat(vec4.getX()) data.putFloat(vec4.getX())
.putFloat(vec4.getY()) .putFloat(vec4.getY())
.putFloat(vec4.getZ()) .putFloat(vec4.getZ())
.putFloat(vec4.getW()); .putFloat(vec4.getW());
} else if(value instanceof ColorRGBA) { } else if(value instanceof ColorRGBA) {
final ColorRGBA vec4 = (ColorRGBA) value; final ColorRGBA vec4 = (ColorRGBA) value;
data.putFloat(vec4.getRed()) data.putFloat(vec4.getRed())
.putFloat(vec4.getGreen()) .putFloat(vec4.getGreen())
.putFloat(vec4.getBlue()) .putFloat(vec4.getBlue())
.putFloat(vec4.getAlpha()); .putFloat(vec4.getAlpha());
} }
} }
@ -541,8 +614,8 @@ public class BufferObject extends NativeObject {
protected void write(final ByteBuffer data, final Vector3f value) { protected void write(final ByteBuffer data, final Vector3f value) {
data.putFloat(value.getX()) data.putFloat(value.getX())
.putFloat(value.getY()) .putFloat(value.getY())
.putFloat(value.getZ()); .putFloat(value.getZ());
if (layout == Layout.std140) { if (layout == Layout.std140) {
data.putInt(0); 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) { protected void write(final ByteBuffer data, final float x, final float y, final float z) {
data.putFloat(x) data.putFloat(x)
.putFloat(y) .putFloat(y)
.putFloat(z); .putFloat(z);
if (layout == Layout.std140) { if (layout == Layout.std140) {
data.putInt(0); 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) { protected void write(final ByteBuffer data, final float x, final float y, final float z, final float w) {
data.putFloat(x) data.putFloat(x)
.putFloat(y) .putFloat(y)
.putFloat(z) .putFloat(z)
.putFloat(w); .putFloat(w);
} }
/** /**
@ -592,7 +665,7 @@ public class BufferObject extends NativeObject {
*/ */
protected void write(final ByteBuffer data, final Vector2f value) { protected void write(final ByteBuffer data, final Vector2f value) {
data.putFloat(value.getX()) data.putFloat(value.getX())
.putFloat(value.getY()); .putFloat(value.getY());
} }
/** /**

@ -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);
}
}

@ -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);
}
}

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

Loading…
Cancel
Save