diff --git a/jme3-core/src/main/java/com/jme3/material/Material.java b/jme3-core/src/main/java/com/jme3/material/Material.java index e2b030e93..ddd75ace7 100644 --- a/jme3-core/src/main/java/com/jme3/material/Material.java +++ b/jme3-core/src/main/java/com/jme3/material/Material.java @@ -46,10 +46,7 @@ import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.scene.Geometry; -import com.jme3.shader.Shader; -import com.jme3.shader.Uniform; -import com.jme3.shader.UniformBindingManager; -import com.jme3.shader.VarType; +import com.jme3.shader.*; import com.jme3.texture.Image; import com.jme3.texture.Texture; import com.jme3.texture.image.ColorSpace; @@ -412,6 +409,17 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { 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 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 null if the parameter is not set. @@ -660,6 +668,28 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { setParam(name, VarType.Vector4, value); } + /** + * 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 setUniformBufferObject(final String name, final BufferObject value) { + value.setBufferType(BufferObject.BufferType.UniformBufferObject); + setParam(name, VarType.BufferObject, 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.BufferObject, value); + } + /** * Pass a Vector2f to the material shader. * @@ -794,20 +824,29 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { } for (int i = 0; i < paramValues.size(); i++) { + MatParam param = paramValues.getValue(i); VarType type = param.getVarType(); - Uniform uniform = shader.getUniform(param.getPrefixedName()); - if (uniform.isSetByCurrentMaterial()) { - continue; - } + if (isBO(type)) { + + final ShaderBufferBlock bufferBlock = shader.getBufferBlock(param.getPrefixedName()); + bufferBlock.setBufferObject((BufferObject) param.getValue()); - if (type.isTextureType()) { - renderer.setTexture(unit, (Texture) param.getValue()); - uniform.setValue(VarType.Int, unit); - unit++; } else { - uniform.setValue(type, param.getValue()); + + Uniform uniform = shader.getUniform(param.getPrefixedName()); + if (uniform.isSetByCurrentMaterial()) { + continue; + } + + if (type.isTextureType()) { + renderer.setTexture(unit, (Texture) param.getValue()); + uniform.setValue(VarType.Int, unit); + unit++; + } else { + uniform.setValue(type, param.getValue()); + } } } @@ -815,6 +854,16 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return unit; } + /** + * Returns true if the type is Buffer Object's type. + * + * @param type the material parameter type. + * @return true if the type is Buffer Object's type. + */ + private boolean isBO(final VarType type) { + return type == VarType.BufferObject; + } + private void updateRenderState(RenderManager renderManager, Renderer renderer, TechniqueDef techniqueDef) { if (renderManager.getForcedRenderState() != null) { renderer.applyRenderState(renderManager.getForcedRenderState()); diff --git a/jme3-core/src/main/java/com/jme3/renderer/Caps.java b/jme3-core/src/main/java/com/jme3/renderer/Caps.java index d8e73a36e..0369517e2 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Caps.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Caps.java @@ -394,7 +394,15 @@ public enum Caps { /** * GPU can provide and accept binary shaders. */ - BinaryShader; + BinaryShader, + /** + * Supporting working with UniformBufferObject. + */ + UniformBufferObject, + /** + * Supporting working with ShaderStorageBufferObjects. + */ + ShaderStorageBufferObject; /** * Returns true if given the renderer capabilities, the texture diff --git a/jme3-core/src/main/java/com/jme3/renderer/Limits.java b/jme3-core/src/main/java/com/jme3/renderer/Limits.java index a7e737092..cd1bfec35 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Limits.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Limits.java @@ -62,4 +62,20 @@ public enum Limits { ColorTextureSamples, DepthTextureSamples, TextureAnisotropy, + + // UBO + UniformBufferObjectMaxVertexBlocks, + UniformBufferObjectMaxFragmentBlocks, + UniformBufferObjectMaxGeometryBlocks, + UniformBufferObjectMaxBlockSize, + + // SSBO + ShaderStorageBufferObjectMaxBlockSize, + ShaderStorageBufferObjectMaxVertexBlocks, + ShaderStorageBufferObjectMaxFragmentBlocks, + ShaderStorageBufferObjectMaxGeometryBlocks, + ShaderStorageBufferObjectMaxTessControlBlocks, + ShaderStorageBufferObjectMaxTessEvaluationBlocks, + ShaderStorageBufferObjectMaxComputeBlocks, + ShaderStorageBufferObjectMaxCombineBlocks, } diff --git a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java index 9f562ea61..201729da8 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java @@ -35,6 +35,7 @@ import com.jme3.material.RenderState; import com.jme3.math.ColorRGBA; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer; +import com.jme3.shader.BufferObject; import com.jme3.shader.Shader; import com.jme3.shader.Shader.ShaderSource; import com.jme3.system.AppSettings; @@ -267,12 +268,26 @@ public interface Renderer { */ public void updateBufferData(VertexBuffer vb); + /** + * 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. * @param vb The vertex buffer to delete */ public void deleteBuffer(VertexBuffer vb); + /** + * Deletes the buffer object from the GPU. + * + * @param bo the buffer object to delete. + */ + public void deleteBuffer(BufferObject bo); + /** * Renders count meshes, with the geometry data supplied and * per-instance data supplied. diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java index e0a1975c1..b2a57736f 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java @@ -45,156 +45,157 @@ import java.nio.ShortBuffer; */ public interface GL { - static final int GL_ALPHA = 0x1906; - static final int GL_ALWAYS = 0x207; - static final int GL_ARRAY_BUFFER = 0x8892; - static final int GL_BACK = 0x405; - static final int GL_BLEND = 0xBE2; - static final int GL_BLUE = 0x1905; - static final int GL_BYTE = 0x1400; - static final int GL_CLAMP_TO_EDGE = 0x812F; - static final int GL_COLOR_BUFFER_BIT = 0x4000; - static final int GL_COMPILE_STATUS = 0x8B81; - static final int GL_CULL_FACE = 0xB44; - static final int GL_DECR = 0x1E03; - static final int GL_DECR_WRAP = 0x8508; - static final int GL_DEPTH_BUFFER_BIT = 0x100; - static final int GL_DEPTH_COMPONENT = 0x1902; - static final int GL_DEPTH_COMPONENT16 = 0x81A5; - static final int GL_DEPTH_TEST = 0xB71; - static final int GL_DOUBLE = 0x140A; - static final int GL_DST_ALPHA = 0x0304; - static final int GL_DST_COLOR = 0x306; - static final int GL_DYNAMIC_DRAW = 0x88E8; - static final int GL_ELEMENT_ARRAY_BUFFER = 0x8893; - static final int GL_EQUAL = 0x202; - static final int GL_EXTENSIONS = 0x1F03; - static final int GL_FALSE = 0x0; - static final int GL_FLOAT = 0x1406; - static final int GL_FRAGMENT_SHADER = 0x8B30; - static final int GL_FRONT = 0x404; - static final int GL_FUNC_ADD = 0x8006; - static final int GL_FUNC_SUBTRACT = 0x800A; - static final int GL_FUNC_REVERSE_SUBTRACT = 0x800B; - static final int GL_FRONT_AND_BACK = 0x408; - static final int GL_GEQUAL = 0x206; - static final int GL_GREATER = 0x204; - static final int GL_GREEN = 0x1904; - static final int GL_INCR = 0x1E02; - static final int GL_INCR_WRAP = 0x8507; - static final int GL_INFO_LOG_LENGTH = 0x8B84; - static final int GL_INT = 0x1404; - static final int GL_INVALID_ENUM = 0x500; - static final int GL_INVALID_VALUE = 0x501; - static final int GL_INVALID_OPERATION = 0x502; - static final int GL_INVERT = 0x150A; - static final int GL_KEEP = 0x1E00; - static final int GL_LEQUAL = 0x203; - static final int GL_LESS = 0x201; - static final int GL_LINEAR = 0x2601; - static final int GL_LINEAR_MIPMAP_LINEAR = 0x2703; - static final int GL_LINEAR_MIPMAP_NEAREST = 0x2701; - static final int GL_LINES = 0x1; - static final int GL_LINE_LOOP = 0x2; - static final int GL_LINE_STRIP = 0x3; - static final int GL_LINK_STATUS = 0x8B82; - static final int GL_LUMINANCE = 0x1909; - static final int GL_LUMINANCE_ALPHA = 0x190A; - static final int GL_MAX = 0x8008; - static final int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; - static final int GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; - static final int GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; - static final int GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872; - static final int GL_MAX_TEXTURE_SIZE = 0xD33; - static final int GL_MAX_VERTEX_ATTRIBS = 0x8869; - static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; - static final int GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; - static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; - static final int GL_MIRRORED_REPEAT = 0x8370; - static final int GL_MIN = 0x8007; - static final int GL_NEAREST = 0x2600; - static final int GL_NEAREST_MIPMAP_LINEAR = 0x2702; - static final int GL_NEAREST_MIPMAP_NEAREST = 0x2700; - static final int GL_NEVER = 0x200; - static final int GL_NO_ERROR = 0x0; - static final int GL_NONE = 0x0; - static final int GL_NOTEQUAL = 0x205; - static final int GL_ONE = 0x1; - static final int GL_ONE_MINUS_DST_ALPHA = 0x0305; - static final int GL_ONE_MINUS_DST_COLOR = 0x307; - static final int GL_ONE_MINUS_SRC_ALPHA = 0x303; - static final int GL_ONE_MINUS_SRC_COLOR = 0x301; - static final int GL_OUT_OF_MEMORY = 0x505; - static final int GL_POINTS = 0x0; - static final int GL_POLYGON_OFFSET_FILL = 0x8037; - static final int GL_QUERY_RESULT = 0x8866; - static final int GL_QUERY_RESULT_AVAILABLE = 0x8867; - static final int GL_RED = 0x1903; - static final int GL_RENDERER = 0x1F01; - static final int GL_REPEAT = 0x2901; - static final int GL_REPLACE = 0x1E01; - static final int GL_RGB = 0x1907; - static final int GL_RGB565 = 0x8D62; - static final int GL_RGB5_A1 = 0x8057; - static final int GL_RGBA = 0x1908; - static final int GL_RGBA4 = 0x8056; - static final int GL_SCISSOR_TEST = 0xC11; - static final int GL_SHADING_LANGUAGE_VERSION = 0x8B8C; - static final int GL_SHORT = 0x1402; - static final int GL_SRC_ALPHA = 0x302; - static final int GL_SRC_ALPHA_SATURATE = 0x0308; - static final int GL_SRC_COLOR = 0x300; - static final int GL_STATIC_DRAW = 0x88E4; - static final int GL_STENCIL_BUFFER_BIT = 0x400; - static final int GL_STENCIL_TEST = 0xB90; - static final int GL_STREAM_DRAW = 0x88E0; - static final int GL_STREAM_READ = 0x88E1; - static final int GL_TEXTURE = 0x1702; - static final int GL_TEXTURE0 = 0x84C0; - static final int GL_TEXTURE1 = 0x84C1; - static final int GL_TEXTURE2 = 0x84C2; - static final int GL_TEXTURE3 = 0x84C3; - static final int GL_TEXTURE4 = 0x84C4; - static final int GL_TEXTURE5 = 0x84C5; - static final int GL_TEXTURE6 = 0x84C6; - static final int GL_TEXTURE7 = 0x84C7; - static final int GL_TEXTURE8 = 0x84C8; - static final int GL_TEXTURE9 = 0x84C9; - static final int GL_TEXTURE10 = 0x84CA; - static final int GL_TEXTURE11 = 0x84CB; - static final int GL_TEXTURE12 = 0x84CC; - static final int GL_TEXTURE13 = 0x84CD; - static final int GL_TEXTURE14 = 0x84CE; - static final int GL_TEXTURE15 = 0x84CF; - static final int GL_TEXTURE_2D = 0xDE1; - static final int GL_TEXTURE_CUBE_MAP = 0x8513; - static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; - static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; - static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; - static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; - static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; - static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; - static final int GL_TEXTURE_MAG_FILTER = 0x2800; - static final int GL_TEXTURE_MIN_FILTER = 0x2801; - static final int GL_TEXTURE_WRAP_S = 0x2802; - static final int GL_TEXTURE_WRAP_T = 0x2803; - static final int GL_TIME_ELAPSED = 0x88BF; - static final int GL_TRIANGLES = 0x4; - static final int GL_TRIANGLE_FAN = 0x6; - static final int GL_TRIANGLE_STRIP = 0x5; - static final int GL_TRUE = 0x1; - static final int GL_UNPACK_ALIGNMENT = 0xCF5; - static final int GL_UNSIGNED_BYTE = 0x1401; - static final int GL_UNSIGNED_INT = 0x1405; - static final int GL_UNSIGNED_SHORT = 0x1403; - static final int GL_UNSIGNED_SHORT_5_6_5 = 0x8363; - static final int GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034; - static final int GL_VENDOR = 0x1F00; - static final int GL_VERSION = 0x1F02; - static final int GL_VERTEX_SHADER = 0x8B31; - static final int GL_ZERO = 0x0; - - void resetStats(); + public static final int GL_ALPHA = 0x1906; + public static final int GL_ALWAYS = 0x207; + public static final int GL_ARRAY_BUFFER = 0x8892; + public static final int GL_BACK = 0x405; + public static final int GL_BLEND = 0xBE2; + public static final int GL_BLUE = 0x1905; + public static final int GL_BYTE = 0x1400; + public static final int GL_CLAMP_TO_EDGE = 0x812F; + public static final int GL_COLOR_BUFFER_BIT = 0x4000; + public static final int GL_COMPILE_STATUS = 0x8B81; + public static final int GL_CULL_FACE = 0xB44; + public static final int GL_DECR = 0x1E03; + public static final int GL_DECR_WRAP = 0x8508; + public static final int GL_DEPTH_BUFFER_BIT = 0x100; + public static final int GL_DEPTH_COMPONENT = 0x1902; + public static final int GL_DEPTH_COMPONENT16 = 0x81A5; + public static final int GL_DEPTH_TEST = 0xB71; + public static final int GL_DOUBLE = 0x140A; + public static final int GL_DST_ALPHA = 0x0304; + public static final int GL_DST_COLOR = 0x306; + public static final int GL_DYNAMIC_DRAW = 0x88E8; + public static final int GL_DYNAMIC_COPY = 0x88EA; + public static final int GL_ELEMENT_ARRAY_BUFFER = 0x8893; + public static final int GL_EQUAL = 0x202; + public static final int GL_EXTENSIONS = 0x1F03; + public static final int GL_FALSE = 0x0; + public static final int GL_FLOAT = 0x1406; + public static final int GL_FRAGMENT_SHADER = 0x8B30; + public static final int GL_FRONT = 0x404; + public static final int GL_FUNC_ADD = 0x8006; + public static final int GL_FUNC_SUBTRACT = 0x800A; + public static final int GL_FUNC_REVERSE_SUBTRACT = 0x800B; + public static final int GL_FRONT_AND_BACK = 0x408; + public static final int GL_GEQUAL = 0x206; + public static final int GL_GREATER = 0x204; + public static final int GL_GREEN = 0x1904; + public static final int GL_INCR = 0x1E02; + public static final int GL_INCR_WRAP = 0x8507; + public static final int GL_INFO_LOG_LENGTH = 0x8B84; + public static final int GL_INT = 0x1404; + public static final int GL_INVALID_ENUM = 0x500; + public static final int GL_INVALID_VALUE = 0x501; + public static final int GL_INVALID_OPERATION = 0x502; + public static final int GL_INVERT = 0x150A; + public static final int GL_KEEP = 0x1E00; + public static final int GL_LEQUAL = 0x203; + public static final int GL_LESS = 0x201; + public static final int GL_LINEAR = 0x2601; + public static final int GL_LINEAR_MIPMAP_LINEAR = 0x2703; + public static final int GL_LINEAR_MIPMAP_NEAREST = 0x2701; + public static final int GL_LINES = 0x1; + public static final int GL_LINE_LOOP = 0x2; + public static final int GL_LINE_STRIP = 0x3; + public static final int GL_LINK_STATUS = 0x8B82; + public static final int GL_LUMINANCE = 0x1909; + public static final int GL_LUMINANCE_ALPHA = 0x190A; + public static final int GL_MAX = 0x8008; + public static final int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; + public static final int GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; + public static final int GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; + public static final int GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872; + public static final int GL_MAX_TEXTURE_SIZE = 0xD33; + public static final int GL_MAX_VERTEX_ATTRIBS = 0x8869; + public static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; + public static final int GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; + public static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; + public static final int GL_MIRRORED_REPEAT = 0x8370; + public static final int GL_MIN = 0x8007; + public static final int GL_NEAREST = 0x2600; + public static final int GL_NEAREST_MIPMAP_LINEAR = 0x2702; + public static final int GL_NEAREST_MIPMAP_NEAREST = 0x2700; + public static final int GL_NEVER = 0x200; + public static final int GL_NO_ERROR = 0x0; + public static final int GL_NONE = 0x0; + public static final int GL_NOTEQUAL = 0x205; + public static final int GL_ONE = 0x1; + public static final int GL_ONE_MINUS_DST_ALPHA = 0x0305; + public static final int GL_ONE_MINUS_DST_COLOR = 0x307; + public static final int GL_ONE_MINUS_SRC_ALPHA = 0x303; + public static final int GL_ONE_MINUS_SRC_COLOR = 0x301; + public static final int GL_OUT_OF_MEMORY = 0x505; + public static final int GL_POINTS = 0x0; + public static final int GL_POLYGON_OFFSET_FILL = 0x8037; + public static final int GL_QUERY_RESULT = 0x8866; + public static final int GL_QUERY_RESULT_AVAILABLE = 0x8867; + public static final int GL_RED = 0x1903; + public static final int GL_RENDERER = 0x1F01; + public static final int GL_REPEAT = 0x2901; + public static final int GL_REPLACE = 0x1E01; + public static final int GL_RGB = 0x1907; + public static final int GL_RGB565 = 0x8D62; + public static final int GL_RGB5_A1 = 0x8057; + public static final int GL_RGBA = 0x1908; + public static final int GL_RGBA4 = 0x8056; + public static final int GL_SCISSOR_TEST = 0xC11; + public static final int GL_SHADING_LANGUAGE_VERSION = 0x8B8C; + public static final int GL_SHORT = 0x1402; + public static final int GL_SRC_ALPHA = 0x302; + public static final int GL_SRC_ALPHA_SATURATE = 0x0308; + public static final int GL_SRC_COLOR = 0x300; + public static final int GL_STATIC_DRAW = 0x88E4; + public static final int GL_STENCIL_BUFFER_BIT = 0x400; + public static final int GL_STENCIL_TEST = 0xB90; + public static final int GL_STREAM_DRAW = 0x88E0; + public static final int GL_STREAM_READ = 0x88E1; + public static final int GL_TEXTURE = 0x1702; + public static final int GL_TEXTURE0 = 0x84C0; + public static final int GL_TEXTURE1 = 0x84C1; + public static final int GL_TEXTURE2 = 0x84C2; + public static final int GL_TEXTURE3 = 0x84C3; + public static final int GL_TEXTURE4 = 0x84C4; + public static final int GL_TEXTURE5 = 0x84C5; + public static final int GL_TEXTURE6 = 0x84C6; + public static final int GL_TEXTURE7 = 0x84C7; + public static final int GL_TEXTURE8 = 0x84C8; + public static final int GL_TEXTURE9 = 0x84C9; + public static final int GL_TEXTURE10 = 0x84CA; + public static final int GL_TEXTURE11 = 0x84CB; + public static final int GL_TEXTURE12 = 0x84CC; + public static final int GL_TEXTURE13 = 0x84CD; + public static final int GL_TEXTURE14 = 0x84CE; + public static final int GL_TEXTURE15 = 0x84CF; + public static final int GL_TEXTURE_2D = 0xDE1; + public static final int GL_TEXTURE_CUBE_MAP = 0x8513; + public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; + public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; + public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; + public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; + public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; + public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; + public static final int GL_TEXTURE_MAG_FILTER = 0x2800; + public static final int GL_TEXTURE_MIN_FILTER = 0x2801; + public static final int GL_TEXTURE_WRAP_S = 0x2802; + public static final int GL_TEXTURE_WRAP_T = 0x2803; + public static final int GL_TIME_ELAPSED = 0x88BF; + public static final int GL_TRIANGLES = 0x4; + public static final int GL_TRIANGLE_FAN = 0x6; + public static final int GL_TRIANGLE_STRIP = 0x5; + public static final int GL_TRUE = 0x1; + public static final int GL_UNPACK_ALIGNMENT = 0xCF5; + public static final int GL_UNSIGNED_BYTE = 0x1401; + public static final int GL_UNSIGNED_INT = 0x1405; + public static final int GL_UNSIGNED_SHORT = 0x1403; + public static final int GL_UNSIGNED_SHORT_5_6_5 = 0x8363; + public static final int GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034; + public static final int GL_VENDOR = 0x1F00; + public static final int GL_VERSION = 0x1F02; + public static final int GL_VERTEX_SHADER = 0x8B31; + public static final int GL_ZERO = 0x0; + + public void resetStats(); /** *

Reference Page

@@ -204,7 +205,7 @@ public interface GL { * * @param texture which texture unit to make active. One of:
{@link #GL_TEXTURE0 TEXTURE0}GL_TEXTURE[1-31]
*/ - void glActiveTexture(int texture); + public void glActiveTexture(int texture); /** *

Reference Page

@@ -225,7 +226,7 @@ public interface GL { * @param program the program object to which a shader object will be attached. * @param shader the shader object that is to be attached. */ - void glAttachShader(int program, int shader); + public void glAttachShader(int program, int shader); /** *

Reference Page

@@ -235,7 +236,7 @@ public interface GL { * @param target the target type of query object established. * @param query the name of a query object. */ - void glBeginQuery(int target, int query); + public void glBeginQuery(int target, int query); /** *

Reference Page

@@ -245,7 +246,7 @@ public interface GL { * @param target the target to which the buffer object is bound. * @param buffer the name of a buffer object. */ - void glBindBuffer(int target, int buffer); + public void glBindBuffer(int target, int buffer); /** *

Reference Page

@@ -259,7 +260,7 @@ public interface GL { * @param target the texture target. * @param texture the texture object to bind. */ - void glBindTexture(int target, int texture); + public void glBindTexture(int target, int texture); /** *

Reference Page

@@ -269,7 +270,7 @@ public interface GL { * @param colorMode the RGB blend equation, how the red, green, and blue components of the source and destination colors are combined. * @param alphaMode the alpha blend equation, how the alpha component of the source and destination colors are combined */ - void glBlendEquationSeparate(int colorMode, int alphaMode); + public void glBlendEquationSeparate(int colorMode, int alphaMode); /** *

Reference Page

@@ -279,7 +280,7 @@ public interface GL { * @param sfactor the source weighting factor. * @param dfactor the destination weighting factor. */ - void glBlendFunc(int sfactor, int dfactor); + public void glBlendFunc(int sfactor, int dfactor); /** *

Reference Page

@@ -291,7 +292,7 @@ public interface GL { * @param sfactorAlpha how the alpha source blending factor is computed. The initial value is GL_ONE. * @param dfactorAlpha how the alpha destination blending factor is computed. The initial value is GL_ZERO. */ - void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha); + public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha); /** *

Reference Page

@@ -321,7 +322,7 @@ public interface GL { * @param dataSize the size in bytes of the buffer object's new data store * @param usage the expected usage pattern of the data store. */ - void glBufferData(int target, long dataSize, int usage); + public void glBufferData(int target, long dataSize, int usage); /** *

Reference Page

@@ -351,7 +352,7 @@ public interface GL { * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied. * @param usage the expected usage pattern of the data store. */ - void glBufferData(int target, FloatBuffer data, int usage); + public void glBufferData(int target, FloatBuffer data, int usage); /** *

Reference Page

@@ -381,7 +382,7 @@ public interface GL { * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied * @param usage the expected usage pattern of the data store. */ - void glBufferData(int target, ShortBuffer data, int usage); + public void glBufferData(int target, ShortBuffer data, int usage); /** *

Reference Page

@@ -411,7 +412,7 @@ public interface GL { * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied. * @param usage the expected usage pattern of the data store. */ - void glBufferData(int target, ByteBuffer data, int usage); + public void glBufferData(int target, ByteBuffer data, int usage); /** *

Reference Page

@@ -422,7 +423,7 @@ public interface GL { * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes. * @param data a pointer to the new data that will be copied into the data store. */ - void glBufferSubData(int target, long offset, FloatBuffer data); + public void glBufferSubData(int target, long offset, FloatBuffer data); /** *

Reference Page

@@ -433,7 +434,7 @@ public interface GL { * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes. * @param data a pointer to the new data that will be copied into the data store. */ - void glBufferSubData(int target, long offset, ShortBuffer data); + public void glBufferSubData(int target, long offset, ShortBuffer data); /** *

Reference Page

@@ -444,7 +445,7 @@ public interface GL { * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes. * @param data a pointer to the new data that will be copied into the data store. */ - void glBufferSubData(int target, long offset, ByteBuffer data); + public void glBufferSubData(int target, long offset, ByteBuffer data); /** *

Reference Page

@@ -454,7 +455,7 @@ public interface GL { * * @param mask Zero or the bitwise OR of one or more values indicating which buffers are to be cleared. */ - void glClear(int mask); + public void glClear(int mask); /** *

Reference Page

@@ -466,7 +467,7 @@ public interface GL { * @param blue the value to which to clear the B channel of the color buffer. * @param alpha the value to which to clear the A channel of the color buffer. */ - void glClearColor(float red, float green, float blue, float alpha); + public void glClearColor(float red, float green, float blue, float alpha); /** *

Reference Page

@@ -478,7 +479,7 @@ public interface GL { * @param blue whether B values are written or not. * @param alpha whether A values are written or not. */ - void glColorMask(boolean red, boolean green, boolean blue, boolean alpha); + public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha); /** *

Reference Page

@@ -487,7 +488,7 @@ public interface GL { * * @param shader the shader object to be compiled. */ - void glCompileShader(int shader); + public void glCompileShader(int shader); /** *

Reference Page

@@ -502,7 +503,7 @@ public interface GL { * @param border must be 0 * @param data a pointer to the compressed image data */ - void glCompressedTexImage2D(int target, int level, int internalFormat, int width, int height, int border, + public void glCompressedTexImage2D(int target, int level, int internalFormat, int width, int height, int border, ByteBuffer data); /** @@ -519,7 +520,7 @@ public interface GL { * @param format the format of the compressed image data stored at address {@code data}. * @param data a pointer to the compressed image data. */ - void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, + public void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ByteBuffer data); /** @@ -527,7 +528,7 @@ public interface GL { *

* Creates a program object. */ - int glCreateProgram(); + public int glCreateProgram(); /** *

Reference Page

@@ -536,7 +537,7 @@ public interface GL { * * @param shaderType the type of shader to be created. One of:
{@link #GL_VERTEX_SHADER VERTEX_SHADER}{@link #GL_FRAGMENT_SHADER FRAGMENT_SHADER}{@link GL3#GL_GEOMETRY_SHADER GEOMETRY_SHADER}{@link GL4#GL_TESS_CONTROL_SHADER TESS_CONTROL_SHADER}
{@link GL4#GL_TESS_EVALUATION_SHADER TESS_EVALUATION_SHADER}
*/ - int glCreateShader(int shaderType); + public int glCreateShader(int shaderType); /** *

Reference Page

@@ -547,7 +548,7 @@ public interface GL { * * @param mode the CullFace mode. One of:
{@link #GL_FRONT FRONT}{@link #GL_BACK BACK}{@link #GL_FRONT_AND_BACK FRONT_AND_BACK}
*/ - void glCullFace(int mode); + public void glCullFace(int mode); /** *

Reference Page

@@ -556,7 +557,7 @@ public interface GL { * * @param buffers an array of buffer objects to be deleted. */ - void glDeleteBuffers(IntBuffer buffers); + public void glDeleteBuffers(IntBuffer buffers); /** *

Reference Page

@@ -565,7 +566,7 @@ public interface GL { * * @param program the program object to be deleted. */ - void glDeleteProgram(int program); + public void glDeleteProgram(int program); /** *

Reference Page

@@ -574,7 +575,7 @@ public interface GL { * * @param shader the shader object to be deleted. */ - void glDeleteShader(int shader); + public void glDeleteShader(int shader); /** *

Reference Page

@@ -589,7 +590,7 @@ public interface GL { * * @param textures contains {@code n} names of texture objects to be deleted. */ - void glDeleteTextures(IntBuffer textures); + public void glDeleteTextures(IntBuffer textures); /** *

Reference Page

@@ -598,7 +599,7 @@ public interface GL { * * @param func the depth test comparison. One of:
{@link #GL_NEVER NEVER}{@link #GL_ALWAYS ALWAYS}{@link #GL_LESS LESS}{@link #GL_LEQUAL LEQUAL}{@link #GL_EQUAL EQUAL}{@link #GL_GREATER GREATER}{@link #GL_GEQUAL GEQUAL}{@link #GL_NOTEQUAL NOTEQUAL}
*/ - void glDepthFunc(int func); + public void glDepthFunc(int func); /** *

Reference Page

@@ -607,7 +608,7 @@ public interface GL { * * @param flag whether depth values are written or not. */ - void glDepthMask(boolean flag); + public void glDepthMask(boolean flag); /** *

Reference Page

@@ -617,7 +618,7 @@ public interface GL { * @param nearVal the near depth range. * @param farVal the far depth range. */ - void glDepthRange(double nearVal, double farVal); + public void glDepthRange(double nearVal, double farVal); /** *

Reference Page

@@ -627,7 +628,7 @@ public interface GL { * @param program the program object from which to detach the shader object. * @param shader the shader object to be detached. */ - void glDetachShader(int program, int shader); + public void glDetachShader(int program, int shader); /** *

Reference Page

@@ -636,7 +637,7 @@ public interface GL { * * @param cap the OpenGL state to disable. */ - void glDisable(int cap); + public void glDisable(int cap); /** *

Reference Page

@@ -645,7 +646,7 @@ public interface GL { * * @param index the index of the generic vertex attribute to be disabled. */ - void glDisableVertexAttribArray(int index); + public void glDisableVertexAttribArray(int index); /** *

Reference Page

@@ -660,7 +661,7 @@ public interface GL { * @param first the first vertex to transfer to the GL. * @param count the number of vertices after {@code first} to transfer to the GL. */ - void glDrawArrays(int mode, int first, int count); + public void glDrawArrays(int mode, int first, int count); /** *

Reference Page

@@ -700,7 +701,7 @@ public interface GL { * @param type the type of the values in {@code indices}. * @param indices a pointer to the location where the indices are stored. */ - void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices); /// GL2+ + public void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices); /// GL2+ /** *

Reference Page

@@ -709,7 +710,7 @@ public interface GL { * * @param cap the OpenGL state to enable. */ - void glEnable(int cap); + public void glEnable(int cap); /** *

Reference Page

@@ -718,7 +719,7 @@ public interface GL { * * @param index the index of the generic vertex attribute to be enabled. */ - void glEnableVertexAttribArray(int index); + public void glEnableVertexAttribArray(int index); /** *

Reference Page

@@ -727,7 +728,7 @@ public interface GL { * * @param target the query object target. */ - void glEndQuery(int target); + public void glEndQuery(int target); /** *

Reference Page

@@ -736,7 +737,7 @@ public interface GL { * * @param buffers a buffer in which the generated buffer object names are stored. */ - void glGenBuffers(IntBuffer buffers); + public void glGenBuffers(IntBuffer buffers); /** *

Reference Page

@@ -746,7 +747,7 @@ public interface GL { * * @param textures a scalar or buffer in which to place the returned texture names. */ - void glGenTextures(IntBuffer textures); + public void glGenTextures(IntBuffer textures); /** *

Reference Page

@@ -755,7 +756,7 @@ public interface GL { * * @param ids a buffer in which the generated query object names are stored. */ - void glGenQueries(int number, IntBuffer ids); + public void glGenQueries(int number, IntBuffer ids); /** *

Reference Page

@@ -765,7 +766,7 @@ public interface GL { * @param program the program object to be queried. * @param name a null terminated string containing the name of the attribute variable whose location is to be queried. */ - int glGetAttribLocation(int program, String name); + public int glGetAttribLocation(int program, String name); /** *

Reference Page

@@ -779,7 +780,7 @@ public interface GL { * @param pname the state variable. * @param params a scalar or buffer in which to place the returned data. */ - void glGetBoolean(int pname, ByteBuffer params); + public void glGetBoolean(int pname, ByteBuffer params); /** *

Reference Page

@@ -790,7 +791,7 @@ public interface GL { * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes. * @param data a pointer to the location where buffer object data is returned. */ - void glGetBufferSubData(int target, long offset, ByteBuffer data); + public void glGetBufferSubData(int target, long offset, ByteBuffer data); /** *

Reference Page

@@ -800,7 +801,7 @@ public interface GL { * further error will again record its code. If a call to {@code GetError} returns {@link #GL_NO_ERROR NO_ERROR}, then there has been no detectable error since * the last call to {@code GetError} (or since the GL was initialized). */ - int glGetError(); + public int glGetError(); /** *

Reference Page

@@ -814,7 +815,7 @@ public interface GL { * @param pname the state variable. * @param params a scalar or buffer in which to place the returned data. */ - void glGetInteger(int pname, IntBuffer params); + public void glGetInteger(int pname, IntBuffer params); /** *

Reference Page

@@ -825,7 +826,7 @@ public interface GL { * @param pname the object parameter. * @param params the requested object parameter. */ - void glGetProgram(int program, int pname, IntBuffer params); + public void glGetProgram(int program, int pname, IntBuffer params); /** *

Reference Page

@@ -835,7 +836,7 @@ public interface GL { * @param program the program object whose information log is to be queried. * @param maxSize the size of the character buffer for storing the returned information log. */ - String glGetProgramInfoLog(int program, int maxSize); + public String glGetProgramInfoLog(int program, int maxSize); /** * Unsigned version. @@ -843,7 +844,7 @@ public interface GL { * @param query the name of a query object * @param pname the symbolic name of a query object parameter */ - long glGetQueryObjectui64(int query, int pname); + public long glGetQueryObjectui64(int query, int pname); /** *

Reference Page

@@ -853,7 +854,7 @@ public interface GL { * @param query the name of a query object * @param pname the symbolic name of a query object parameter. One of:
{@link #GL_QUERY_RESULT QUERY_RESULT}{@link #GL_QUERY_RESULT_AVAILABLE QUERY_RESULT_AVAILABLE}
*/ - int glGetQueryObjectiv(int query, int pname); + public int glGetQueryObjectiv(int query, int pname); /** *

Reference Page

@@ -864,7 +865,7 @@ public interface GL { * @param pname the object parameter. * @param params the requested object parameter. */ - void glGetShader(int shader, int pname, IntBuffer params); + public void glGetShader(int shader, int pname, IntBuffer params); /** *

Reference Page

@@ -874,7 +875,7 @@ public interface GL { * @param shader the shader object whose information log is to be queried. * @param maxSize the size of the character buffer for storing the returned information log. */ - String glGetShaderInfoLog(int shader, int maxSize); + public String glGetShaderInfoLog(int shader, int maxSize); /** *

Reference Page

@@ -883,7 +884,7 @@ public interface GL { * * @param name the property to query. One of:
{@link #GL_RENDERER RENDERER}{@link #GL_VENDOR VENDOR}{@link #GL_EXTENSIONS EXTENSIONS}{@link #GL_VERSION VERSION}{@link GL2#GL_SHADING_LANGUAGE_VERSION SHADING_LANGUAGE_VERSION}
*/ - String glGetString(int name); + public String glGetString(int name); /** *

Reference Page

@@ -893,7 +894,7 @@ public interface GL { * @param program the program object to be queried. * @param name a null terminated string containing the name of the uniform variable whose location is to be queried. */ - int glGetUniformLocation(int program, String name); + public int glGetUniformLocation(int program, String name); /** *

Reference Page

@@ -902,7 +903,7 @@ public interface GL { * * @param cap the enable state to query. */ - boolean glIsEnabled(int cap); + public boolean glIsEnabled(int cap); /** *

Reference Page

@@ -911,7 +912,7 @@ public interface GL { * * @param width the line width. */ - void glLineWidth(float width); + public void glLineWidth(float width); /** *

Reference Page

@@ -920,7 +921,7 @@ public interface GL { * * @param program the program object to be linked. */ - void glLinkProgram(int program); + public void glLinkProgram(int program); /** *

Reference Page

@@ -930,7 +931,7 @@ public interface GL { * @param pname the pixel store parameter to set. * @param param the parameter value */ - void glPixelStorei(int pname, int param); + public void glPixelStorei(int pname, int param); /** *

Reference Page

@@ -944,7 +945,7 @@ public interface GL { * @param factor the maximum depth slope factor. * @param units the constant scale. */ - void glPolygonOffset(float factor, float units); + public void glPolygonOffset(float factor, float units); /** *

Reference Page

@@ -963,7 +964,7 @@ public interface GL { * @param type the pixel type. * @param data a buffer in which to place the returned pixel data. */ - void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data); + public void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data); /** @@ -983,7 +984,7 @@ public interface GL { * @param type the pixel type. * @param offset a buffer in which to place the returned pixel data/ */ - void glReadPixels(int x, int y, int width, int height, int format, int type, long offset); + public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset); /** *

Reference Page

@@ -998,7 +999,7 @@ public interface GL { * @param width the scissor rectangle width. * @param height the scissor rectangle height. */ - void glScissor(int x, int y, int width, int height); + public void glScissor(int x, int y, int width, int height); /** *

Reference Page

@@ -1013,7 +1014,7 @@ public interface GL { * @param shader the shader object whose source code is to be replaced, * @param strings an array of pointers to strings containing the source code to be loaded into the shader */ - void glShaderSource(int shader, String[] strings, IntBuffer length); + public void glShaderSource(int shader, String[] strings, IntBuffer length); /** *

Reference Page

@@ -1026,7 +1027,7 @@ public interface GL { * buffer. The initial value is 0. * @param mask a mask that is ANDed with both the reference value and the stored stencil value when the test is done. The initial value is all 1's. */ - void glStencilFuncSeparate(int face, int func, int ref, int mask); + public void glStencilFuncSeparate(int face, int func, int ref, int mask); /** *

Reference Page

@@ -1039,7 +1040,7 @@ public interface GL { * @param dppass the stencil action when both the stencil test and the depth test pass, or when the stencil test passes and either there is no depth buffer or depth * testing is not enabled. The initial value is GL_KEEP. */ - void glStencilOpSeparate(int face, int sfail, int dpfail, int dppass); + public void glStencilOpSeparate(int face, int sfail, int dpfail, int dppass); /** *

Reference Page

@@ -1056,7 +1057,7 @@ public interface GL { * @param type the texel data type. * @param data the texel data. */ - void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, + public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ByteBuffer data); /** @@ -1068,7 +1069,7 @@ public interface GL { * @param pname the parameter to set. * @param param the parameter value. */ - void glTexParameterf(int target, int pname, float param); + public void glTexParameterf(int target, int pname, float param); /** *

Reference Page

@@ -1079,7 +1080,7 @@ public interface GL { * @param pname the parameter to set. * @param param the parameter value. */ - void glTexParameteri(int target, int pname, int param); + public void glTexParameteri(int target, int pname, int param); /** *

Reference Page

@@ -1097,7 +1098,7 @@ public interface GL { * @param type the pixel data type. * @param data the pixel data. */ - void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, + public void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer data); /** @@ -1108,7 +1109,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform1(int location, FloatBuffer value); + public void glUniform1(int location, FloatBuffer value); /** *

Reference Page

@@ -1118,7 +1119,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform1(int location, IntBuffer value); + public void glUniform1(int location, IntBuffer value); /** *

Reference Page

@@ -1128,7 +1129,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param v0 the uniform value. */ - void glUniform1f(int location, float v0); + public void glUniform1f(int location, float v0); /** *

Reference Page

@@ -1138,7 +1139,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param v0 the uniform value. */ - void glUniform1i(int location, int v0); + public void glUniform1i(int location, int v0); /** *

Reference Page

@@ -1148,7 +1149,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform2(int location, IntBuffer value); + public void glUniform2(int location, IntBuffer value); /** *

Reference Page

@@ -1158,7 +1159,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform2(int location, FloatBuffer value); + public void glUniform2(int location, FloatBuffer value); /** *

Reference Page

@@ -1169,7 +1170,7 @@ public interface GL { * @param v0 the uniform x value. * @param v1 the uniform y value. */ - void glUniform2f(int location, float v0, float v1); + public void glUniform2f(int location, float v0, float v1); /** *

Reference Page

@@ -1179,7 +1180,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform3(int location, IntBuffer value); + public void glUniform3(int location, IntBuffer value); /** *

Reference Page

@@ -1189,7 +1190,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform3(int location, FloatBuffer value); + public void glUniform3(int location, FloatBuffer value); /** *

Reference Page

@@ -1201,7 +1202,7 @@ public interface GL { * @param v1 the uniform y value. * @param v2 the uniform z value. */ - void glUniform3f(int location, float v0, float v1, float v2); + public void glUniform3f(int location, float v0, float v1, float v2); /** *

Reference Page

@@ -1211,7 +1212,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform4(int location, FloatBuffer value); + public void glUniform4(int location, FloatBuffer value); /** *

Reference Page

@@ -1221,7 +1222,7 @@ public interface GL { * @param location the location of the uniform variable to be modified. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniform4(int location, IntBuffer value); + public void glUniform4(int location, IntBuffer value); /** *

Reference Page

@@ -1234,7 +1235,7 @@ public interface GL { * @param v2 the uniform z value. * @param v3 the uniform w value. */ - void glUniform4f(int location, float v0, float v1, float v2, float v3); + public void glUniform4f(int location, float v0, float v1, float v2, float v3); /** *

Reference Page

@@ -1245,7 +1246,7 @@ public interface GL { * @param transpose whether to transpose the matrix as the values are loaded into the uniform variable. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniformMatrix3(int location, boolean transpose, FloatBuffer value); + public void glUniformMatrix3(int location, boolean transpose, FloatBuffer value); /** *

Reference Page

@@ -1256,7 +1257,7 @@ public interface GL { * @param transpose whether to transpose the matrix as the values are loaded into the uniform variable. * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable. */ - void glUniformMatrix4(int location, boolean transpose, FloatBuffer value); + public void glUniformMatrix4(int location, boolean transpose, FloatBuffer value); /** *

Reference Page

@@ -1265,7 +1266,7 @@ public interface GL { * * @param program the program object whose executables are to be used as part of current rendering state. */ - void glUseProgram(int program); + public void glUseProgram(int program); /** *

Reference Page

@@ -1281,7 +1282,7 @@ public interface GL { * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer * currently bound to the {@link GL#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. */ - void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer); + public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer); /** *

Reference Page

@@ -1297,5 +1298,5 @@ public interface GL { * @param width the viewport width. * @param height the viewport height. */ - void glViewport(int x, int y, int width, int height); -} + public void glViewport(int x, int y, int width, int height); +} \ No newline at end of file diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java index 595f5ff85..dcf1d91eb 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java @@ -83,6 +83,46 @@ public interface GL3 extends GL2 { public static final int GL_RGB_INTEGER = 36248; public static final int GL_RGBA_INTEGER = 36249; + public static final int GL_UNIFORM_OFFSET = 0x8A3B; + + /** + * Accepted by the {@code target} parameters of BindBuffer, BufferData, BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, and GetBufferPointerv. + */ + public static final int GL_UNIFORM_BUFFER = 0x8A11; + + /** + * Accepted by the {@code pname} parameter of GetActiveUniformBlockiv. + */ + public static final int GL_UNIFORM_BLOCK_BINDING = 0x8A3F; + public static final int GL_UNIFORM_BLOCK_DATA_SIZE = 0x8A40; + public static final int GL_UNIFORM_BLOCK_NAME_LENGTH = 0x8A41; + public static final int GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42; + public static final int GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43; + public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44; + public static final int GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45; + 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, + * BindBufferRange, BindBufferOffset and BindBufferBase. + */ + public static final int GL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E; + /** *

Reference Page

*

@@ -128,4 +168,47 @@ public interface GL3 extends GL2 { * @param index the index of the particular element being queried. */ public String glGetString(int name, int index); /// GL3+ + + + /** + *

Reference Page

+ * + * Retrieves the index of a named uniform block. + * + * @param program the name of a program containing the uniform block. + * @param uniformBlockName an array of characters to containing the name of the uniform block whose index to retrieve. + * @return the block index. + */ + public int glGetUniformBlockIndex(int program, String uniformBlockName); + + /** + *

Reference Page

+ * + * Binds a buffer object to an indexed buffer target. + * + * @param target the target of the bind operation. One of:
{@link #GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link #GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL4#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL4#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}
+ * @param index the index of the binding point within the array specified by {@code target} + * @param buffer a buffer object to bind to the specified binding point + */ + public void glBindBufferBase(int target, int index, int buffer); + + /** + * Binding points for active uniform blocks are assigned using glUniformBlockBinding. Each of a program's active + * uniform blocks has a corresponding uniform buffer binding point. program is the name of a program object for + * which the command glLinkProgram has been issued in the past. + *

+ * If successful, glUniformBlockBinding specifies that program will use the data store of the buffer object bound + * to the binding point uniformBlockBinding to extract the values of the uniforms in the uniform block identified + * by uniformBlockIndex. + *

+ * When a program object is linked or re-linked, the uniform buffer object binding point assigned to each of its + * active uniform blocks is reset to zero. + * + * @param program The name of a program object containing the active uniform block whose binding to + * assign. + * @param uniformBlockIndex The index of the active uniform block within program whose binding to assign. + * @param uniformBlockBinding Specifies the binding point to which to bind the uniform block with index + * uniformBlockIndex within program. + */ + public void glUniformBlockBinding(int program, int uniformBlockIndex, int uniformBlockBinding); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java index 9afe4755b..821959aee 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java @@ -42,6 +42,32 @@ public interface GL4 extends GL3 { public static final int GL_TESS_EVALUATION_SHADER = 0x8E87; public static final int GL_PATCHES = 0xE; + /** + * Accepted by the {@code target} parameter of BindBufferBase and BindBufferRange. + */ + public static final int GL_ATOMIC_COUNTER_BUFFER = 0x92C0; + + /** + * Accepted by the {@code target} parameters of BindBuffer, BufferData, BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, and GetBufferPointerv. + */ + public static final int GL_SHADER_STORAGE_BUFFER = 0x90D2; + 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_BLOCK_SIZE = 0x90DE; + public static final int GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF; + /** *

Reference Page

*

@@ -50,4 +76,28 @@ public interface GL4 extends GL3 { * @param count the new value for the parameter given by {@code pname} */ public void glPatchParameter(int count); + + /** + * Returns the unsigned integer index assigned to a resource named name in the interface type programInterface of + * program object program. + * + * @param program the name of a program object whose resources to query. + * @param programInterface a token identifying the interface within program containing the resource named name. + * @param name the name of the resource to query the index of. + * @return the index of a named resource within a program. + */ + public int glGetProgramResourceIndex(int program, int programInterface, String name); + + /** + * Cchanges the active shader storage block with an assigned index of storageBlockIndex in program object program. + * storageBlockIndex must be an active shader storage block index in program. storageBlockBinding must be less + * than the value of {@code #GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS}. If successful, glShaderStorageBlockBinding specifies + * that program will use the data store of the buffer object bound to the binding point storageBlockBinding to + * read and write the values of the buffer variables in the shader storage block identified by storageBlockIndex. + * + * @param program the name of a program object whose resources to query. + * @param storageBlockIndex The index storage block within the program. + * @param storageBlockBinding The index storage block binding to associate with the specified storage block. + */ + public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java index a945a1d85..3dfd2a8ca 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java @@ -83,6 +83,19 @@ public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 { return result; } + @Override + public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { + final int result = gl3.glGetUniformBlockIndex(program, uniformBlockName); + checkError(); + return result; + } + + @Override + public void glBindBufferBase(final int target, final int index, final int buffer) { + gl3.glBindBufferBase(target, index, buffer); + checkError(); + } + @Override public void glDeleteVertexArrays(IntBuffer arrays) { gl3.glDeleteVertexArrays(arrays); @@ -95,8 +108,27 @@ public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 { checkError(); } + @Override + public int glGetProgramResourceIndex(int program, int programInterface, String name) { + final int result = gl4.glGetProgramResourceIndex(program, programInterface, name); + checkError(); + return result; + } + + @Override + public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding) { + gl4.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + checkError(); + } + public void glBlendEquationSeparate(int colorMode, int alphaMode) { gl.glBlendEquationSeparate(colorMode, alphaMode); checkError(); } + + @Override + public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { + gl3.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + checkError(); + } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index 746db4084..790e538f8 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -45,11 +45,9 @@ import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer.Format; import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.shader.Attribute; -import com.jme3.shader.Shader; +import com.jme3.shader.*; import com.jme3.shader.Shader.ShaderSource; import com.jme3.shader.Shader.ShaderType; -import com.jme3.shader.Uniform; import com.jme3.texture.FrameBuffer; import com.jme3.texture.FrameBuffer.RenderBuffer; import com.jme3.texture.Image; @@ -61,17 +59,17 @@ import com.jme3.util.BufferUtils; import com.jme3.util.ListMap; import com.jme3.util.MipMapGenerator; import com.jme3.util.NativeObjectManager; -import java.nio.*; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; +import jme3tools.shader.ShaderDebug; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import jme3tools.shader.ShaderDebug; public final class GLRenderer implements Renderer { @@ -480,6 +478,26 @@ public final class GLRenderer implements Renderer { } } + if (hasExtension("GL_ARB_shader_storage_buffer_object")) { + 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 logger.log(Level.INFO, "OpenGL Renderer Information\n" + " * Vendor: {0}\n" + @@ -1050,12 +1068,25 @@ public final class GLRenderer implements Renderer { } } + @Override public void postFrame() { objManager.deleteUnused(this); OpenCLObjectManager.getInstance().deleteUnusedObjects(); gl.resetStats(); } + protected void bindProgram(Shader shader) { + int shaderId = shader.getId(); + if (context.boundShaderProgram != shaderId) { + gl.glUseProgram(shaderId); + statistics.onShaderUse(shader, true); + context.boundShader = shader; + context.boundShaderProgram = shaderId; + } else { + statistics.onShaderUse(shader, false); + } + } + /*********************************************************************\ |* Shaders *| \*********************************************************************/ @@ -1070,18 +1101,6 @@ public final class GLRenderer implements Renderer { } } - protected void bindProgram(Shader shader) { - int shaderId = shader.getId(); - if (context.boundShaderProgram != shaderId) { - gl.glUseProgram(shaderId); - statistics.onShaderUse(shader, true); - context.boundShader = shader; - context.boundShaderProgram = shaderId; - } else { - statistics.onShaderUse(shader, false); - } - } - protected void updateUniform(Shader shader, Uniform uniform) { int shaderId = shader.getId(); @@ -1187,6 +1206,58 @@ public final class GLRenderer implements Renderer { } } + /** + * Updates the buffer block for the shader. + * + * @param shader the shader. + * @param bufferBlock the storage block. + */ + protected void updateShaderBufferBlock(final Shader shader, final ShaderBufferBlock bufferBlock) { + + assert bufferBlock.getName() != null; + assert shader.getId() > 0; + + final BufferObject bufferObject = bufferBlock.getBufferObject(); + if (bufferObject.getUniqueId() == -1 || bufferObject.isUpdateNeeded()) { + updateBufferData(bufferObject); + } + + if (!bufferBlock.isUpdateNeeded()) { + return; + } + + bindProgram(shader); + + final int shaderId = shader.getId(); + final BufferObject.BufferType bufferType = bufferObject.getBufferType(); + + bindBuffer(bufferBlock, bufferObject, shaderId, bufferType); + + bufferBlock.clearUpdateNeeded(); + } + + private void bindBuffer(final ShaderBufferBlock bufferBlock, final BufferObject bufferObject, final int shaderId, + final BufferObject.BufferType bufferType) { + + 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); + } + } + } + protected void updateShaderUniforms(Shader shader) { ListMap uniforms = shader.getUniformMap(); for (int i = 0; i < uniforms.size(); i++) { @@ -1197,6 +1268,18 @@ public final class GLRenderer implements Renderer { } } + /** + * Updates all shader's buffer blocks. + * + * @param shader the shader. + */ + protected void updateShaderBufferBlocks(final Shader shader) { + final ListMap bufferBlocks = shader.getBufferBlockMap(); + for (int i = 0; i < bufferBlocks.size(); i++) { + updateShaderBufferBlock(shader, bufferBlocks.getValue(i)); + } + } + protected void resetUniformLocations(Shader shader) { ListMap uniforms = shader.getUniformMap(); for (int i = 0; i < uniforms.size(); i++) { @@ -1415,6 +1498,7 @@ public final class GLRenderer implements Renderer { assert shader.getId() > 0; updateShaderUniforms(shader); + updateShaderBufferBlocks(shader); bindProgram(shader); } } @@ -2503,6 +2587,58 @@ public final class GLRenderer implements Renderer { vb.clearUpdateNeeded(); } + @Override + public void updateBufferData(final BufferObject bo) { + + int maxSize = Integer.MAX_VALUE; + + 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); + if (data == null) { + throw new IllegalArgumentException("Can't upload BO without data."); + } + + int bufferId = bo.getId(); + if (bufferId == -1) { + + // create buffer + intBuf1.clear(); + gl.glGenBuffers(intBuf1); + bufferId = intBuf1.get(0); + + bo.setId(bufferId); + + objManager.registerObject(bo); + } + + data.rewind(); + + 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(); + } + public void deleteBuffer(VertexBuffer vb) { int bufId = vb.getId(); if (bufId != -1) { @@ -2516,6 +2652,23 @@ public final class GLRenderer implements Renderer { } } + @Override + public void deleteBuffer(final BufferObject bo) { + + int bufferId = bo.getId(); + if (bufferId == -1) { + return; + } + + intBuf1.clear(); + intBuf1.put(bufferId); + intBuf1.flip(); + + gl.glDeleteBuffers(intBuf1); + + bo.resetObject(); + } + public void clearVertexAttribs() { IDList attribList = context.attribIndexList; for (int i = 0; i < attribList.oldLen; i++) { diff --git a/jme3-core/src/main/java/com/jme3/shader/BufferObject.java b/jme3-core/src/main/java/com/jme3/shader/BufferObject.java new file mode 100644 index 000000000..886f4a1ab --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/shader/BufferObject.java @@ -0,0 +1,828 @@ +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; +import com.jme3.util.SafeArrayList; + +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The base implementation of BO. + * + * @author JavaSaBr + */ +public class BufferObject extends NativeObject { + + private static final Map, VarType> CLASS_TO_VAR_TYPE = new HashMap<>(); + + static { + CLASS_TO_VAR_TYPE.put(Float.class, VarType.Float); + CLASS_TO_VAR_TYPE.put(Integer.class, VarType.Int); + CLASS_TO_VAR_TYPE.put(Boolean.class, VarType.Boolean); + CLASS_TO_VAR_TYPE.put(Vector2f.class, VarType.Vector2); + CLASS_TO_VAR_TYPE.put(Vector3f.class, VarType.Vector3); + CLASS_TO_VAR_TYPE.put(ColorRGBA.class, VarType.Vector4); + CLASS_TO_VAR_TYPE.put(Quaternion.class, VarType.Vector4); + CLASS_TO_VAR_TYPE.put(Vector4f.class, VarType.Vector4); + + CLASS_TO_VAR_TYPE.put(Vector2f[].class, VarType.Vector2Array); + CLASS_TO_VAR_TYPE.put(Vector3f[].class, VarType.Vector3Array); + CLASS_TO_VAR_TYPE.put(Vector4f[].class, VarType.Vector4Array); + CLASS_TO_VAR_TYPE.put(ColorRGBA[].class, VarType.Vector4Array); + CLASS_TO_VAR_TYPE.put(Quaternion[].class, VarType.Vector4Array); + + CLASS_TO_VAR_TYPE.put(Matrix3f.class, VarType.Matrix3); + CLASS_TO_VAR_TYPE.put(Matrix4f.class, VarType.Matrix4); + CLASS_TO_VAR_TYPE.put(Matrix3f[].class, VarType.Matrix3Array); + CLASS_TO_VAR_TYPE.put(Matrix4f[].class, VarType.Matrix4Array); + } + + protected static VarType getVarTypeByValue(final Object value) { + + final VarType varType = CLASS_TO_VAR_TYPE.get(value.getClass()); + if (varType != null) { + return varType; + } else if (value instanceof Collection && ((Collection) value).isEmpty()) { + throw new IllegalArgumentException("Can't calculate a var type for the empty collection value[" + value + "]."); + } else if (value instanceof List) { + return getVarTypeByValue(((List) value).get(0)); + } else if (value instanceof Collection) { + return getVarTypeByValue(((Collection) value).iterator().next()); + } + + throw new IllegalArgumentException("Can't calculate a var type for the value " + value); + } + + public enum Layout { + std140, + /** unsupported yet */ + @Deprecated + 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 fields; + + /** + * The field's array. + */ + private final SafeArrayList fieldArray; + + /** + * The buffer's data layout. + */ + private final Layout layout; + + /** + * The binding number. + */ + 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 BufferType bufferType) { + this.handleRef = new Object(); + this.bufferType = bufferType; + this.binding = binding; + this.layout = layout; + this.fields = new HashMap<>(); + this.fieldArray = new SafeArrayList<>(BufferObjectField.class); + } + + public BufferObject(final int binding, final Layout layout) { + this(binding, layout, BufferType.UniformBufferObject); + } + + public BufferObject(final int binding, final BufferType bufferType) { + this(binding, Layout.std140, bufferType); + } + + public BufferObject(final BufferType bufferType) { + this(1, Layout.std140, bufferType); + } + + public BufferObject(final Layout layout) { + this(1, layout, BufferType.UniformBufferObject); + } + + public BufferObject(final int binding) { + this(binding, Layout.std140, BufferType.UniformBufferObject); + } + + public BufferObject() { + this(1, Layout.std140, BufferType.UniformBufferObject); + } + + private BufferObject(final Void unused, final int id) { + super(id); + this.fieldArray = null; + this.fields = null; + this.layout = null; + this.binding = 0; + } + + /** + * Declares a filed in this BO. + * + * @param name the field's name. + * @param varType the field's type. + */ + public void declareField(final String name, final VarType varType) { + + if (fields.containsKey(name)) { + throw new IllegalArgumentException("The field " + name + " is already declared."); + } + + final BufferObjectField field = new BufferObjectField(name, varType); + + fields.put(name, field); + fieldArray.add(field); + } + + /** + * 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; + } + + /** + * Sets the value to the filed by the field's name. + * + * @param name the field's name. + * @param value the value. + */ + public void setFieldValue(final String name, final Object value) { + + BufferObjectField field = fields.get(name); + + if (field == null) { + declareField(name, getVarTypeByValue(value)); + field = fields.get(name); + } + + field.setValue(value); + setUpdateNeeded(); + } + + /** + * Gets the current value of the field by the name. + * + * @param name the field name. + * @param the value's type. + * @return the current value. + */ + public T getFieldValue(final String name) { + + final BufferObjectField field = fields.get(name); + if (field == null) { + throw new IllegalArgumentException("Unknown a field with the name " + name); + } + + return (T) field.getValue(); + } + + /** + * Get the binding number. + * + * @return the binding number. + */ + public int getBinding() { + return binding; + } + + @Override + public void resetObject() { + this.id = -1; + setUpdateNeeded(); + } + + /** + * Computes the current binary data of this BO. + * + * @param maxSize the max data size. + * @return the current binary data of this BO. + */ + public ByteBuffer computeData(final int maxSize) { + + int estimateSize = 0; + + 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); + } + + if (previousData != null) { + if (previousData.capacity() < estimateSize) { + BufferUtils.destroyDirectBuffer(previousData); + previousData = null; + } else { + previousData.clear(); + } + } + + final ByteBuffer data = previousData == null ? BufferUtils.createByteBuffer(estimateSize) : previousData; + + for (final BufferObjectField field : fieldArray) { + writeField(field, data); + } + + data.flip(); + + this.previousData = data; + + return data; + } + + /** + * Estimates size of the field. + * + * @param field the field. + * @return the estimated size. + */ + protected int estimateSize(final BufferObjectField field) { + + switch (field.getType()) { + case Float: + case Int: { + if (layout == Layout.std140) { + return 16; + } + return 4; + } + case Boolean: { + if (layout == Layout.std140) { + return 16; + } + return 1; + } + case Vector2: { + return 4 * 2; + } + case Vector3: { + final int multiplier = layout == Layout.std140 ? 4 : 3; + return 4 * multiplier; + } + case Vector4: + return 16; + case IntArray: { + return estimate((int[]) field.getValue()); + } + case FloatArray: { + return estimate((float[]) field.getValue()); + } + case Vector2Array: { + return estimateArray(field.getValue(), 8); + } + case Vector3Array: { + final int multiplier = layout == Layout.std140 ? 16 : 12; + return estimateArray(field.getValue(), multiplier); + } + case Vector4Array: { + return estimateArray(field.getValue(), 16); + } + case Matrix3: { + final int multiplier = layout == Layout.std140 ? 16 : 12; + return 3 * 3 * multiplier; + } + case Matrix4: { + return 4 * 4 * 4; + } + case Matrix3Array: { + int multiplier = layout == Layout.std140 ? 16 : 12; + multiplier = 3 * 3 * multiplier; + return estimateArray(field.getValue(), multiplier); + } + case Matrix4Array: { + final int multiplier = 4 * 4 * 16; + return estimateArray(field.getValue(), multiplier); + } + default: { + throw new IllegalArgumentException("The type of BO field " + field.getType() + " doesn't support."); + } + } + } + + /** + * Estimates bytes count to present the value on GPU. + * + * @param value the value. + * @param multiplier the multiplier. + * @return the estimated bytes cunt. + */ + protected int estimateArray(final Object value, final int multiplier) { + + if (value instanceof Object[]) { + return ((Object[]) value).length * multiplier; + } else if (value instanceof Collection) { + return ((Collection) value).size() * multiplier; + } + + throw new IllegalArgumentException("Unexpected value " + value); + } + + /** + * Estimates bytes count to present the values on GPU. + * + * @param values the values. + * @return the estimated bytes cunt. + */ + protected int estimate(final float[] values) { + return values.length * 4; + } + + /** + * Estimates bytes count to present the values on GPU. + * + * @param values the values. + * @return the estimated bytes cunt. + */ + protected int estimate(final int[] values) { + return values.length * 4; + } + + /** + * Writes the field to the data buffer. + * + * @param field the field. + * @param data the data buffer. + */ + protected void writeField(final BufferObjectField field, final ByteBuffer data) { + + final Object value = field.getValue(); + + switch (field.getType()) { + case Int: { + data.putInt(((Number) value).intValue()); + if (layout == Layout.std140) { + data.putInt(0); + data.putLong(0); + } + break; + } + case Float: { + data.putFloat(((Number) value).floatValue()); + if (layout == Layout.std140) { + data.putInt(0); + data.putLong(0); + } + break; + } + case Boolean: + data.put((byte) (((Boolean) value) ? 1 : 0)); + if (layout == Layout.std140) { + data.putInt(0); + data.putLong(0); + data.putShort((short) 0); + data.put((byte) 0); + } + break; + case Vector2: + write(data, (Vector2f) value); + break; + case Vector3: + write(data, (Vector3f) value); + break; + case Vector4: + writeVec4(data, value); + break; + case IntArray: { + write(data, (int[]) value); + break; + } + case FloatArray: { + write(data, (float[]) value); + break; + } + case Vector2Array: { + writeVec2Array(data, value); + break; + } + case Vector3Array: { + writeVec3Array(data, value); + break; + } + case Vector4Array: { + writeVec4Array(data, value); + break; + } + case Matrix3: { + write(data, (Matrix3f) value); + break; + } + case Matrix4: { + write(data, (Matrix4f) value); + break; + } + case Matrix3Array: { + writeMat3Array(data, value); + break; + } + case Matrix4Array: { + writeMat4Array(data, value); + break; + } + default: { + throw new IllegalArgumentException("The type of BO field " + field.getType() + " doesn't support."); + } + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeMat3Array(final ByteBuffer data, final Object value) { + + if (value instanceof Matrix3f[]) { + + final Matrix3f[] values = (Matrix3f[]) value; + for (final Matrix3f mat : values) { + write(data, mat); + } + + } else if(value instanceof SafeArrayList) { + + final SafeArrayList values = (SafeArrayList) value; + for (final Matrix3f mat : values.getArray()) { + write(data, mat); + } + + } else if(value instanceof Collection) { + + final Collection values = (Collection) value; + for (final Matrix3f mat : values) { + write(data, mat); + } + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeMat4Array(final ByteBuffer data, final Object value) { + + if (value instanceof Matrix4f[]) { + + final Matrix4f[] values = (Matrix4f[]) value; + for (final Matrix4f mat : values) { + write(data, mat); + } + + } else if(value instanceof SafeArrayList) { + + final SafeArrayList values = (SafeArrayList) value; + for (final Matrix4f mat : values.getArray()) { + write(data, mat); + } + + } else if(value instanceof Collection) { + + final Collection values = (Collection) value; + for (final Matrix4f mat : values) { + write(data, mat); + } + } + } + + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeVec4Array(final ByteBuffer data, final Object value) { + + if (value instanceof Object[]) { + + final Object[] values = (Object[]) value; + for (final Object vec : values) { + writeVec4(data, vec); + } + + } else if(value instanceof SafeArrayList) { + + final SafeArrayList values = (SafeArrayList) value; + for (final Object vec : values.getArray()) { + writeVec4(data, vec); + } + + } else if(value instanceof Collection) { + + final Collection values = (Collection) value; + for (final Object vec : values) { + writeVec4(data, vec); + } + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeVec3Array(final ByteBuffer data, final Object value) { + + if (value instanceof Vector3f[]) { + + final Vector3f[] values = (Vector3f[]) value; + for (final Vector3f vec : values) { + write(data, vec); + } + + } else if(value instanceof SafeArrayList) { + + final SafeArrayList values = (SafeArrayList) value; + for (final Vector3f vec : values.getArray()) { + write(data, vec); + } + + } else if(value instanceof Collection) { + + final Collection values = (Collection) value; + for (final Vector3f vec : values) { + write(data, vec); + } + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeVec2Array(final ByteBuffer data, final Object value) { + + if (value instanceof Vector2f[]) { + + final Vector2f[] values = (Vector2f[]) value; + for (final Vector2f vec : values) { + write(data, vec); + } + + } else if(value instanceof SafeArrayList) { + + final SafeArrayList values = (SafeArrayList) value; + for (final Vector2f vec : values.getArray()) { + write(data, vec); + } + + } else if(value instanceof Collection) { + + final Collection values = (Collection) value; + for (final Vector2f vec : values) { + write(data, vec); + } + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final float[] value) { + for (float val : value) { + data.putFloat(val); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final int[] value) { + for (int val : value) { + data.putInt(val); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void writeVec4(final ByteBuffer data, final Object value) { + + if (value == null) { + data.putLong(0).putLong(0); + } else if (value instanceof Vector4f) { + + final Vector4f vec4 = (Vector4f) value; + data.putFloat(vec4.getX()) + .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()); + + } else if(value instanceof ColorRGBA) { + + final ColorRGBA vec4 = (ColorRGBA) value; + data.putFloat(vec4.getRed()) + .putFloat(vec4.getGreen()) + .putFloat(vec4.getBlue()) + .putFloat(vec4.getAlpha()); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final Vector3f value) { + + if (value == null) { + data.putLong(0).putInt(0); + } else { + data.putFloat(value.getX()) + .putFloat(value.getY()) + .putFloat(value.getZ()); + } + + if (layout == Layout.std140) { + data.putInt(0); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param x the x value. + * @param y the y value. + * @param z the z value. + */ + protected void write(final ByteBuffer data, final float x, final float y, final float z) { + + data.putFloat(x) + .putFloat(y) + .putFloat(z); + + if (layout == Layout.std140) { + data.putInt(0); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param x the x value. + * @param y the y value. + * @param z the z value. + * @param w the w value. + */ + 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); + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final Vector2f value) { + if (value == null) { + data.putLong(0); + } else { + data.putFloat(value.getX()).putFloat(value.getY()); + } + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final Matrix3f value) { + write(data, value.get(0, 0), value.get(1, 0), value.get(2, 0)); + write(data, value.get(0, 1), value.get(1, 1), value.get(2, 1)); + write(data, value.get(0, 2), value.get(1, 2), value.get(2, 2)); + } + + /** + * Writes the value to the data buffer. + * + * @param data the data buffer. + * @param value the value. + */ + protected void write(final ByteBuffer data, final Matrix4f value) { + write(data, value.get(0, 0), value.get(1, 0), value.get(2, 0), value.get(3, 0)); + write(data, value.get(0, 1), value.get(1, 1), value.get(2, 1), value.get(3, 1)); + write(data, value.get(0, 2), value.get(1, 2), value.get(2, 2), value.get(3, 2)); + write(data, value.get(0, 3), value.get(1, 3), value.get(2, 3), value.get(3, 3)); + } + + @Override + public void deleteObject(final Object rendererObject) { + + if (!(rendererObject instanceof Renderer)) { + throw new IllegalArgumentException("This bo can't be deleted from " + rendererObject); + } + + ((Renderer) rendererObject).deleteBuffer(this); + } + + @Override + public NativeObject createDestructableClone() { + return new BufferObject(null, getId()); + } + + @Override + protected void deleteNativeBuffers() { + super.deleteNativeBuffers(); + if (previousData != null) { + BufferUtils.destroyDirectBuffer(previousData); + previousData = null; + } + } + + @Override + public long getUniqueId() { + return ((long) OBJTYPE_BO << 32) | ((long) id); + } +} diff --git a/jme3-core/src/main/java/com/jme3/shader/BufferObjectField.java b/jme3-core/src/main/java/com/jme3/shader/BufferObjectField.java new file mode 100644 index 000000000..798b418fc --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/shader/BufferObjectField.java @@ -0,0 +1,77 @@ +package com.jme3.shader; + +import static java.util.Objects.requireNonNull; + +/** + * The class to describe a filed in BO. + * + * @author JavaSaBr + */ +public class BufferObjectField { + + + /** + * The field name. + */ + private final String name; + + /** + * The field type. + */ + private final VarType type; + + /** + * The field value. + */ + private Object value; + + public BufferObjectField(final String name, final VarType type) { + this.name = name; + this.type = type; + } + + /** + * Get the field name. + * + * @return the field name. + */ + public String getName() { + return name; + } + + /** + * Gets the field type. + * + * @return the field type. + */ + public VarType getType() { + return type; + } + + /** + * Gets the field value. + * + * @return the field value. + */ + public Object getValue() { + return value; + } + + /** + * Sets the field value. + * + * @param value the field value. + */ + public void setValue(final Object value) { + this.value = requireNonNull(value, "The field's value can't be null."); + } + + @Override + public String toString() { + return "BufferObjectField{" + + "name='" + name + '\'' + + ", type=" + type + + ", value=" + value + + '}'; + } +} diff --git a/jme3-core/src/main/java/com/jme3/shader/Shader.java b/jme3-core/src/main/java/com/jme3/shader/Shader.java index 72ecbca17..05264f8db 100644 --- a/jme3-core/src/main/java/com/jme3/shader/Shader.java +++ b/jme3-core/src/main/java/com/jme3/shader/Shader.java @@ -51,6 +51,11 @@ public final class Shader extends NativeObject { * Maps uniform name to the uniform variable. */ private final ListMap uniforms; + + /** + * Maps storage block name to the buffer block variables. + */ + private final ListMap bufferBlocks; /** * Uniforms bound to {@link UniformBinding}s. @@ -220,10 +225,11 @@ public final class Shader extends NativeObject { */ public Shader(){ super(); - shaderSourceList = new ArrayList(); - uniforms = new ListMap(); - attribs = new IntMap(); - boundUniforms = new ArrayList(); + shaderSourceList = new ArrayList<>(); + uniforms = new ListMap<>(); + bufferBlocks = new ListMap<>(); + attribs = new IntMap<>(); + boundUniforms = new ArrayList<>(); } /** @@ -240,6 +246,7 @@ public final class Shader extends NativeObject { } uniforms = null; + bufferBlocks = null; boundUniforms = null; attribs = null; } @@ -288,10 +295,40 @@ public final class Shader extends NativeObject { return uniform; } + /** + * Gets or creates a buffer block by the name. + * + * @param name the buffer block's name. + * @return the buffer block. + */ + public ShaderBufferBlock getBufferBlock(final String name) { + + assert name.startsWith("m_"); + + ShaderBufferBlock block = bufferBlocks.get(name); + + if (block == null) { + block = new ShaderBufferBlock(); + block.name = name; + bufferBlocks.put(name, block); + } + + return block; + } + public void removeUniform(String name){ uniforms.remove(name); } + /** + * Removes a buffer block by the name. + * + * @param name the buffer block's name. + */ + public void removeBufferBlock(final String name){ + bufferBlocks.remove(name); + } + public Attribute getAttribute(VertexBuffer.Type attribType){ int ordinal = attribType.ordinal(); Attribute attrib = attribs.get(ordinal); @@ -306,7 +343,16 @@ public final class Shader extends NativeObject { public ListMap getUniformMap(){ return uniforms; } - + + /** + * Get the buffer blocks map. + * + * @return the buffer blocks map. + */ + public ListMap getBufferBlockMap() { + return bufferBlocks; + } + public ArrayList getBoundUniforms() { return boundUniforms; } @@ -320,6 +366,7 @@ public final class Shader extends NativeObject { return getClass().getSimpleName() + "[numSources=" + shaderSourceList.size() + ", numUniforms=" + uniforms.size() + + ", numBufferBlocks=" + bufferBlocks.size() + ", shaderSources=" + getSources() + "]"; } @@ -343,7 +390,7 @@ public final class Shader extends NativeObject { * Resets all uniforms that do not have the "set-by-current-material" flag * to their default value (usually all zeroes or false). * When a uniform is modified, that flag is set, to remove the flag, - * use {@link #clearUniformsSetByCurrent() }. + * use {@link #clearUniformsSetByCurrentFlag() }. */ public void resetUniformsNotSetByCurrent() { int size = uniforms.size(); @@ -366,6 +413,11 @@ public final class Shader extends NativeObject { uniform.reset(); // fixes issue with re-initialization } } + if (bufferBlocks != null) { + for (ShaderBufferBlock shaderBufferBlock : bufferBlocks.values()) { + shaderBufferBlock.reset(); + } + } if (attribs != null) { for (Entry entry : attribs) { entry.getValue().location = ShaderVariable.LOC_UNKNOWN; diff --git a/jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java b/jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java new file mode 100644 index 000000000..27b44d18b --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2009-2018 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.shader; + +/** + * Implementation of shader's buffer block. + * + * @author JavaSaBr + */ +public class ShaderBufferBlock extends ShaderVariable { + + /** + * Current used buffer object. + */ + protected BufferObject bufferObject; + + /** + * Set the new buffer object. + * + * @param bufferObject the new buffer object. + */ + public void setBufferObject(final BufferObject bufferObject) { + + if (bufferObject == null) { + throw new IllegalArgumentException("for storage block " + name + ": storageData cannot be null"); + } + + this.bufferObject = bufferObject; + + updateNeeded = true; + } + + /** + * Return true if need to update this storage block. + * + * @return true if need to update this storage block. + */ + public boolean isUpdateNeeded(){ + return updateNeeded; + } + + /** + * Clear the flag {@link #isUpdateNeeded()}. + */ + public void clearUpdateNeeded(){ + updateNeeded = false; + } + + /** + * Reset this storage block. + */ + public void reset(){ + updateNeeded = true; + } + + /** + * Get the current storage data. + * + * @return the current storage data. + */ + public BufferObject getBufferObject() { + return bufferObject; + } +} diff --git a/jme3-core/src/main/java/com/jme3/shader/VarType.java b/jme3-core/src/main/java/com/jme3/shader/VarType.java index 7300294d4..2319e7903 100644 --- a/jme3-core/src/main/java/com/jme3/shader/VarType.java +++ b/jme3-core/src/main/java/com/jme3/shader/VarType.java @@ -57,7 +57,8 @@ public enum VarType { Texture3D(false,true,"sampler3D"), TextureArray(false,true,"sampler2DArray|sampler2DArrayShadow"), TextureCubeMap(false,true,"samplerCube"), - Int("int"); + Int("int"), + BufferObject(false, false, "custom"); private boolean usesMultiData = false; private boolean textureType = false; diff --git a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java index 1eb2b1533..3c289ecc3 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java +++ b/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; @@ -44,12 +41,16 @@ import com.jme3.renderer.Renderer; import com.jme3.renderer.Statistics; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer; +import com.jme3.shader.BufferObject; import com.jme3.shader.Shader; import com.jme3.shader.Shader.ShaderSource; 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 { @@ -148,9 +149,17 @@ public class NullRenderer implements Renderer { public void updateBufferData(VertexBuffer vb) { } + @Override + public void updateBufferData(BufferObject bo) { + } public void deleteBuffer(VertexBuffer vb) { } + @Override + public void deleteBuffer(BufferObject bo) { + + } + public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { } diff --git a/jme3-core/src/main/java/com/jme3/util/NativeObject.java b/jme3-core/src/main/java/com/jme3/util/NativeObject.java index 508e6623d..426e4c9e0 100644 --- a/jme3-core/src/main/java/com/jme3/util/NativeObject.java +++ b/jme3-core/src/main/java/com/jme3/util/NativeObject.java @@ -52,7 +52,8 @@ public abstract class NativeObject implements Cloneable { OBJTYPE_SHADERSOURCE = 5, OBJTYPE_AUDIOBUFFER = 6, OBJTYPE_AUDIOSTREAM = 7, - OBJTYPE_FILTER = 8; + OBJTYPE_FILTER = 8, + OBJTYPE_BO = 9; /** * The object manager to which this NativeObject is registered to. diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java index e6435e5c5..545bd9c64 100644 --- a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java @@ -4,12 +4,11 @@ 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.*; - import com.jme3.renderer.opengl.GL4; import com.jogamp.opengl.GLContext; +import java.nio.*; + public class JoglGL implements GL, GL2, GL3, GL4 { private static int getLimitBytes(ByteBuffer buffer) { @@ -628,10 +627,36 @@ public class JoglGL implements GL, GL2, GL3, GL4 { public void glPatchParameter(int count) { GLContext.getCurrentGL().getGL3().glPatchParameteri(com.jogamp.opengl.GL3.GL_PATCH_VERTICES, count); } - + @Override public void glDeleteVertexArrays(IntBuffer arrays) { checkLimit(arrays); GLContext.getCurrentGL().getGL2ES3().glDeleteVertexArrays(arrays.limit(), arrays); } + + @Override + public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { + return GLContext.getCurrentGL().getGL3bc().glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(final int target, final int index, final int buffer) { + GLContext.getCurrentGL().getGL3bc().glBindBufferBase(target, index, buffer); + } + + @Override + public int glGetProgramResourceIndex(final int program, final int programInterface, final String name) { + throw new UnsupportedOperationException(); + //return GLContext.getCurrentGL().getGL4bc().glGetProgramResourceIndex(program, programInterface, name); + } + + @Override + public void glShaderStorageBlockBinding(final int program, final int storageBlockIndex, final int storageBlockBinding) { + GLContext.getCurrentGL().getGL4bc().glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + } + + @Override + public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { + GLContext.getCurrentGL().getGL3bc().glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } } diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index 5a74e06f0..bca6d0dbb 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -4,16 +4,12 @@ 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; -import java.nio.ShortBuffer; - import com.jme3.renderer.opengl.GL4; import com.jme3.util.BufferUtils; import org.lwjgl.opengl.*; +import java.nio.*; + public final class LwjglGL implements GL, GL2, GL3, GL4 { IntBuffer tmpBuff = BufferUtils.createIntBuffer(1); @@ -487,10 +483,35 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 { public void glPatchParameter(int count) { GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count); } - + + @Override + public int glGetProgramResourceIndex(final int program, final int programInterface, final String name) { + return GL43.glGetProgramResourceIndex(program, programInterface, name); + } + + @Override + public void glShaderStorageBlockBinding(final int program, final int storageBlockIndex, final int storageBlockBinding) { + GL43.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + } + @Override public void glDeleteVertexArrays(IntBuffer arrays) { checkLimit(arrays); ARBVertexArrayObject.glDeleteVertexArrays(arrays); } + + @Override + public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { + return GL31.glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(final int target, final int index, final int buffer) { + GL30.glBindBufferBase(target, index, buffer); + } + + @Override + public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { + GL31.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } } diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index e87bdf20a..0d8c32a8d 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -616,9 +616,34 @@ public class LwjglGL extends LwjglRender implements GL, GL2, GL3, GL4 { GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES, count); } + @Override + public int glGetProgramResourceIndex(final int program, final int programInterface, final String name) { + return GL43.glGetProgramResourceIndex(program, programInterface, name); + } + + @Override + public void glShaderStorageBlockBinding(final int program, final int storageBlockIndex, final int storageBlockBinding) { + GL43.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + } + @Override public void glDeleteVertexArrays(final IntBuffer arrays) { checkLimit(arrays); ARBVertexArrayObject.glDeleteVertexArrays(arrays); } + + @Override + public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { + return GL31.glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(final int target, final int index, final int buffer) { + GL30.glBindBufferBase(target, index, buffer); + } + + @Override + public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { + GL31.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } }