updated API of BO.
This commit is contained in:
parent
2297441c13
commit
54e3987022
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
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 {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user