added limits, caps, working with buffer objects in renderer.
This commit is contained in:
parent
4d42e4b624
commit
b342b1ede1
@ -409,6 +409,17 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
return paramValues.get(name);
|
return paramValues.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current parameter's value.
|
||||||
|
*
|
||||||
|
* @param name the parameter name to look up.
|
||||||
|
* @return current value or null if the parameter wasn't set.
|
||||||
|
*/
|
||||||
|
public <T> T getParamValue(final String name) {
|
||||||
|
final MatParam param = paramValues.get(name);
|
||||||
|
return param == null ? null : (T) param.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the texture parameter set on this material with the given name,
|
* Returns the texture parameter set on this material with the given name,
|
||||||
* returns <code>null</code> if the parameter is not set.
|
* returns <code>null</code> if the parameter is not set.
|
||||||
@ -657,6 +668,22 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
setParam(name, VarType.Vector4, value);
|
setParam(name, VarType.Vector4, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass a 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass a Vector2f to the material shader.
|
* Pass a Vector2f to the material shader.
|
||||||
*
|
*
|
||||||
|
@ -395,6 +395,10 @@ public enum Caps {
|
|||||||
* GPU can provide and accept binary shaders.
|
* GPU can provide and accept binary shaders.
|
||||||
*/
|
*/
|
||||||
BinaryShader,
|
BinaryShader,
|
||||||
|
/**
|
||||||
|
* Supporting working with UniformBufferObject.
|
||||||
|
*/
|
||||||
|
UniformBufferObject,
|
||||||
/**
|
/**
|
||||||
* Supporting working with ShaderStorageBufferObjects.
|
* Supporting working with ShaderStorageBufferObjects.
|
||||||
*/
|
*/
|
||||||
|
@ -62,4 +62,20 @@ public enum Limits {
|
|||||||
ColorTextureSamples,
|
ColorTextureSamples,
|
||||||
DepthTextureSamples,
|
DepthTextureSamples,
|
||||||
TextureAnisotropy,
|
TextureAnisotropy,
|
||||||
|
|
||||||
|
// UBO
|
||||||
|
UniformBufferObjectMaxVertexBlocks,
|
||||||
|
UniformBufferObjectMaxFragmentBlocks,
|
||||||
|
UniformBufferObjectMaxGeometryBlocks,
|
||||||
|
UniformBufferObjectMaxBlockSize,
|
||||||
|
|
||||||
|
// SSBO
|
||||||
|
ShaderStorageBufferObjectMaxBlockSize,
|
||||||
|
ShaderStorageBufferObjectMaxVertexBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxFragmentBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxGeometryBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxTessControlBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxTessEvaluationBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxComputeBlocks,
|
||||||
|
ShaderStorageBufferObjectMaxCombineBlocks,
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ 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.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;
|
||||||
@ -276,19 +277,19 @@ public interface Renderer {
|
|||||||
*/
|
*/
|
||||||
public void updateBufferData(ShaderStorageBufferObject ssbo);
|
public void updateBufferData(ShaderStorageBufferObject ssbo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads data of the buffer object on the GPU.
|
||||||
|
*
|
||||||
|
* @param bo the buffer object to upload.
|
||||||
|
*/
|
||||||
|
public void updateBufferData(BufferObject bo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a vertex buffer from the GPU.
|
* Deletes a vertex buffer from the GPU.
|
||||||
* @param vb The vertex buffer to delete
|
* @param vb The vertex buffer to delete
|
||||||
*/
|
*/
|
||||||
public void deleteBuffer(VertexBuffer vb);
|
public void deleteBuffer(VertexBuffer vb);
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a shader storage buffer object from the GPU.
|
|
||||||
*
|
|
||||||
* @param ssbo the shader storage buffer object to delete.
|
|
||||||
*/
|
|
||||||
public void deleteBuffer(ShaderStorageBufferObject ssbo);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the buffer object from the GPU.
|
* Deletes the buffer object from the GPU.
|
||||||
*
|
*
|
||||||
|
@ -102,6 +102,21 @@ public interface GL3 extends GL2 {
|
|||||||
public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45;
|
public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45;
|
||||||
public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
|
public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
|
||||||
|
* GetFloatv, and GetDoublev:
|
||||||
|
*/
|
||||||
|
public static final int GL_MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B;
|
||||||
|
public static final int GL_MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C;
|
||||||
|
public static final int GL_MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D;
|
||||||
|
public static final int GL_MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E;
|
||||||
|
public static final int GL_MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F;
|
||||||
|
public static final int GL_MAX_UNIFORM_BLOCK_SIZE = 0x8A30;
|
||||||
|
public static final int GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31;
|
||||||
|
public static final int GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32;
|
||||||
|
public static final int GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33;
|
||||||
|
public static final int GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepted by the {@code target} parameters of BindBuffer, BufferData, BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, GetBufferPointerv,
|
* Accepted by the {@code target} parameters of BindBuffer, BufferData, BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, GetBufferPointerv,
|
||||||
* BindBufferRange, BindBufferOffset and BindBufferBase.
|
* BindBufferRange, BindBufferOffset and BindBufferBase.
|
||||||
|
@ -52,7 +52,21 @@ public interface GL4 extends GL3 {
|
|||||||
*/
|
*/
|
||||||
public static final int GL_SHADER_STORAGE_BUFFER = 0x90D2;
|
public static final int GL_SHADER_STORAGE_BUFFER = 0x90D2;
|
||||||
public static final int GL_SHADER_STORAGE_BLOCK = 0x92E6;
|
public static final int GL_SHADER_STORAGE_BLOCK = 0x92E6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepted by the <pname> parameter of GetIntegerv, GetBooleanv,
|
||||||
|
* GetInteger64v, GetFloatv, and GetDoublev:
|
||||||
|
*/
|
||||||
|
public static final int GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = 0x90D6;
|
||||||
|
public static final int GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS = 0x90D7;
|
||||||
|
public static final int GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS = 0x90D8;
|
||||||
|
public static final int GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS = 0x90D9;
|
||||||
|
public static final int GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = 0x90DA;
|
||||||
|
public static final int GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = 0x90DB;
|
||||||
|
public static final int GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = 0x90DC;
|
||||||
public static final int GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD;
|
public static final int GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD;
|
||||||
|
public static final int GL_MAX_SHADER_STORAGE_BLOCK_SIZE = 0x90DE;
|
||||||
|
public static final int GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><a target="_blank" href="http://docs.gl/gl4/glPatchParameteri">Reference Page</a></p>
|
* <p><a target="_blank" href="http://docs.gl/gl4/glPatchParameteri">Reference Page</a></p>
|
||||||
|
@ -480,6 +480,22 @@ public final class GLRenderer implements Renderer {
|
|||||||
|
|
||||||
if (hasExtension("GL_ARB_shader_storage_buffer_object")) {
|
if (hasExtension("GL_ARB_shader_storage_buffer_object")) {
|
||||||
caps.add(Caps.ShaderStorageBufferObject);
|
caps.add(Caps.ShaderStorageBufferObject);
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxBlockSize, getInteger(GL4.GL_MAX_SHADER_STORAGE_BLOCK_SIZE));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxComputeBlocks, getInteger(GL4.GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxGeometryBlocks, getInteger(GL4.GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxFragmentBlocks, getInteger(GL4.GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxVertexBlocks, getInteger(GL4.GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxTessControlBlocks, getInteger(GL4.GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxTessEvaluationBlocks, getInteger(GL4.GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS));
|
||||||
|
limits.put(Limits.ShaderStorageBufferObjectMaxCombineBlocks, getInteger(GL4.GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasExtension("GL_ARB_uniform_buffer_object")) {
|
||||||
|
caps.add(Caps.UniformBufferObject);
|
||||||
|
limits.put(Limits.UniformBufferObjectMaxBlockSize, getInteger(GL3.GL_MAX_UNIFORM_BLOCK_SIZE));
|
||||||
|
limits.put(Limits.UniformBufferObjectMaxGeometryBlocks, getInteger(GL3.GL_MAX_GEOMETRY_UNIFORM_BLOCKS));
|
||||||
|
limits.put(Limits.UniformBufferObjectMaxFragmentBlocks, getInteger(GL3.GL_MAX_FRAGMENT_UNIFORM_BLOCKS));
|
||||||
|
limits.put(Limits.UniformBufferObjectMaxVertexBlocks, getInteger(GL3.GL_MAX_VERTEX_UNIFORM_BLOCKS));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print context information
|
// Print context information
|
||||||
@ -2550,18 +2566,28 @@ public final class GLRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBufferData(final ShaderStorageBufferObject ssbo) {
|
public void updateBufferData(final BufferObject bo) {
|
||||||
|
|
||||||
if (!caps.contains(Caps.ShaderStorageBufferObject)) {
|
int maxSize = Integer.MAX_VALUE;
|
||||||
throw new IllegalArgumentException("The current video hardware doesn't support SSBO.");
|
|
||||||
|
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 ByteBuffer data = ssbo.getData();
|
final ByteBuffer data = bo.computeData(maxSize);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
throw new IllegalArgumentException("Can't upload SSBO without data.");
|
throw new IllegalArgumentException("Can't upload BO without data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int bufferId = ssbo.getId();
|
int bufferId = bo.getId();
|
||||||
if (bufferId == -1) {
|
if (bufferId == -1) {
|
||||||
|
|
||||||
// create buffer
|
// create buffer
|
||||||
@ -2569,19 +2595,24 @@ public final class GLRenderer implements Renderer {
|
|||||||
gl.glGenBuffers(intBuf1);
|
gl.glGenBuffers(intBuf1);
|
||||||
bufferId = intBuf1.get(0);
|
bufferId = intBuf1.get(0);
|
||||||
|
|
||||||
ssbo.setId(bufferId);
|
bo.setId(bufferId);
|
||||||
|
|
||||||
objManager.registerObject(ssbo);
|
objManager.registerObject(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, bufferId);
|
|
||||||
|
|
||||||
data.rewind();
|
data.rewind();
|
||||||
|
|
||||||
gl4.glBufferData(GL4.GL_SHADER_STORAGE_BUFFER, data, GL4.GL_DYNAMIC_COPY);
|
if (bo instanceof UniformBufferObject) {
|
||||||
gl4.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, 0);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
ssbo.clearUpdateNeeded();
|
bo.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteBuffer(VertexBuffer vb) {
|
public void deleteBuffer(VertexBuffer vb) {
|
||||||
@ -2598,9 +2629,9 @@ public final class GLRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteBuffer(final ShaderStorageBufferObject ssbo) {
|
public void deleteBuffer(final BufferObject bo) {
|
||||||
|
|
||||||
int bufferId = ssbo.getId();
|
int bufferId = bo.getId();
|
||||||
if (bufferId == -1) {
|
if (bufferId == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2611,12 +2642,7 @@ public final class GLRenderer implements Renderer {
|
|||||||
|
|
||||||
gl.glDeleteBuffers(intBuf1);
|
gl.glDeleteBuffers(intBuf1);
|
||||||
|
|
||||||
ssbo.resetObject();
|
bo.resetObject();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteBuffer(BufferObject bo) {
|
|
||||||
//TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearVertexAttribs() {
|
public void clearVertexAttribs() {
|
||||||
|
@ -40,7 +40,7 @@ public class BufferObject extends NativeObject {
|
|||||||
/**
|
/**
|
||||||
* The previous data buffer.
|
* The previous data buffer.
|
||||||
*/
|
*/
|
||||||
private ByteBuffer previosData;
|
private ByteBuffer previousData;
|
||||||
|
|
||||||
public BufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
|
public BufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
|
||||||
this.handleRef = new Object();
|
this.handleRef = new Object();
|
||||||
@ -128,14 +128,14 @@ public class BufferObject extends NativeObject {
|
|||||||
"maximum available size " + maxSize);
|
"maximum available size " + maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previosData != null) {
|
if (previousData != null) {
|
||||||
if (previosData.capacity() < estimateSize) {
|
if (previousData.capacity() < estimateSize) {
|
||||||
BufferUtils.destroyDirectBuffer(previosData);
|
BufferUtils.destroyDirectBuffer(previousData);
|
||||||
previosData = null;
|
previousData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ByteBuffer data = previosData == null ? BufferUtils.createByteBuffer((int) (estimateSize * 1.1F)) : previosData;
|
final ByteBuffer data = previousData == null ? BufferUtils.createByteBuffer((int) (estimateSize * 1.1F)) : previousData;
|
||||||
|
|
||||||
for (final Map.Entry<String, BufferObjectField> entry : fields.entrySet()) {
|
for (final Map.Entry<String, BufferObjectField> entry : fields.entrySet()) {
|
||||||
writeField(entry.getValue(), data);
|
writeField(entry.getValue(), data);
|
||||||
@ -481,9 +481,9 @@ public class BufferObject extends NativeObject {
|
|||||||
@Override
|
@Override
|
||||||
protected void deleteNativeBuffers() {
|
protected void deleteNativeBuffers() {
|
||||||
super.deleteNativeBuffers();
|
super.deleteNativeBuffers();
|
||||||
if (previosData != null) {
|
if (previousData != null) {
|
||||||
BufferUtils.destroyDirectBuffer(previosData);
|
BufferUtils.destroyDirectBuffer(previousData);
|
||||||
previosData = null;
|
previousData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,144 +1,17 @@
|
|||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.renderer.Renderer;
|
|
||||||
import com.jme3.util.BufferUtils;
|
|
||||||
import com.jme3.util.NativeObject;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of SSBO.
|
* The implementation of SSBO.
|
||||||
*
|
*
|
||||||
* @author JavaSaBr
|
* @author JavaSaBr
|
||||||
*/
|
*/
|
||||||
public class ShaderStorageBufferObject extends NativeObject {
|
public class ShaderStorageBufferObject extends BufferObject {
|
||||||
|
|
||||||
/**
|
public ShaderStorageBufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
|
||||||
* The buffer's data.
|
super(binding, layout, fields);
|
||||||
*/
|
|
||||||
private ByteBuffer data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The binding number.
|
|
||||||
*/
|
|
||||||
private int binding;
|
|
||||||
|
|
||||||
public ShaderStorageBufferObject() {
|
|
||||||
this.handleRef = new Object();
|
|
||||||
this.binding = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderStorageBufferObject(final int id) {
|
public ShaderStorageBufferObject(final int id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the binding number.
|
|
||||||
*
|
|
||||||
* @param binding the binding number.
|
|
||||||
*/
|
|
||||||
public void setBinding(final int binding) {
|
|
||||||
this.binding = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the binding number.
|
|
||||||
*
|
|
||||||
* @return the binding number.
|
|
||||||
*/
|
|
||||||
public int getBinding() {
|
|
||||||
return binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to initialize the data in the {@link ShaderStorageBufferObject}. Must only
|
|
||||||
* be called once.
|
|
||||||
*
|
|
||||||
* @param data the native byte buffer.
|
|
||||||
*/
|
|
||||||
public void setupData(final ByteBuffer data) {
|
|
||||||
|
|
||||||
if (id != -1) {
|
|
||||||
throw new UnsupportedOperationException("Data has already been sent. Cannot setupData again.");
|
|
||||||
} else if (data.isReadOnly()) {
|
|
||||||
throw new IllegalArgumentException("VertexBuffer data cannot be read-only.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
setUpdateNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to update the data in the buffer with new data. Can only
|
|
||||||
* be called after {@link #setupData(java.nio.ByteBuffer) }
|
|
||||||
* has been called. Note that it is fine to call this method on the
|
|
||||||
* data already set, e.g. ssbo.updateData(ssbo.getData()), this will just
|
|
||||||
* set the proper update flag indicating the data should be sent to the GPU
|
|
||||||
* again.
|
|
||||||
* <p>
|
|
||||||
* It is allowed to specify a buffer with different capacity than the
|
|
||||||
* originally set buffer.
|
|
||||||
*
|
|
||||||
* @param data the native data buffer to set.
|
|
||||||
*/
|
|
||||||
public void updateData(final ByteBuffer data) {
|
|
||||||
|
|
||||||
if (data == null) {
|
|
||||||
throw new IllegalArgumentException("SSBO can't be without data buffer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the data buffer is read-only which is a sign
|
|
||||||
// of a bug on the part of the caller
|
|
||||||
if (data.isReadOnly()) {
|
|
||||||
throw new IllegalArgumentException("SSBO's data cannot be read-only.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
setUpdateNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the buffer's data.
|
|
||||||
*
|
|
||||||
* @return the buffer's data.
|
|
||||||
*/
|
|
||||||
public ByteBuffer getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetObject() {
|
|
||||||
this.id = -1;
|
|
||||||
setUpdateNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteObject(final Object rendererObject) {
|
|
||||||
|
|
||||||
if (!(rendererObject instanceof Renderer)) {
|
|
||||||
throw new IllegalArgumentException("This ssbo can't be deleted from " + rendererObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
((Renderer) rendererObject).deleteBuffer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void deleteNativeBuffers() {
|
|
||||||
super.deleteNativeBuffers();
|
|
||||||
if (data != null) {
|
|
||||||
BufferUtils.destroyDirectBuffer(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NativeObject createDestructableClone() {
|
|
||||||
return new ShaderStorageBufferObject(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getUniqueId() {
|
|
||||||
return ((long) OBJTYPE_SSBO << 32) | ((long) id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.jme3.shader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementation of UBO.
|
||||||
|
*
|
||||||
|
* @author JavaSaBr
|
||||||
|
*/
|
||||||
|
public class UniformBufferObject extends BufferObject {
|
||||||
|
|
||||||
|
public UniformBufferObject(final int binding, final Layout layout, final BufferObjectField... fields) {
|
||||||
|
super(binding, layout, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniformBufferObject(final int id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
}
|
@ -58,6 +58,7 @@ public enum VarType {
|
|||||||
TextureArray(false,true,"sampler2DArray|sampler2DArrayShadow"),
|
TextureArray(false,true,"sampler2DArray|sampler2DArrayShadow"),
|
||||||
TextureCubeMap(false,true,"samplerCube"),
|
TextureCubeMap(false,true,"samplerCube"),
|
||||||
Int("int"),
|
Int("int"),
|
||||||
|
UniformBufferObject(false, false, "dynamic"),
|
||||||
ShaderStorageBufferObject(false, false, "dynamic");
|
ShaderStorageBufferObject(false, false, "dynamic");
|
||||||
|
|
||||||
private boolean usesMultiData = false;
|
private boolean usesMultiData = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user