From a71b418c521b48099485be73018ff925f1ad0ce2 Mon Sep 17 00:00:00 2001 From: JavaSaBr Date: Thu, 8 Feb 2018 14:32:16 +0300 Subject: [PATCH] refactoring. --- .../main/java/com/jme3/material/Material.java | 16 ++++-- .../main/java/com/jme3/renderer/Renderer.java | 7 --- .../java/com/jme3/renderer/opengl/GL3.java | 20 +++++++ .../jme3/renderer/opengl/GLDebugDesktop.java | 6 +++ .../com/jme3/renderer/opengl/GLRenderer.java | 49 +++++++++-------- .../src/main/java/com/jme3/shader/Shader.java | 52 +++++++++---------- ...orageBlock.java => ShaderBufferBlock.java} | 20 +++---- .../java/com/jme3/system/NullRenderer.java | 7 +-- .../src/test/java/com/jme3/SetupTest.java | 21 ++++++++ .../java/com/jme3/renderer/jogl/JoglGL.java | 5 ++ .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 5 ++ .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 5 ++ 12 files changed, 143 insertions(+), 70 deletions(-) rename jme3-core/src/main/java/com/jme3/shader/{StorageBlock.java => ShaderBufferBlock.java} (84%) 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 72b09ae86..c6279240a 100644 --- a/jme3-core/src/main/java/com/jme3/material/Material.java +++ b/jme3-core/src/main/java/com/jme3/material/Material.java @@ -822,10 +822,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { MatParam param = paramValues.getValue(i); VarType type = param.getVarType(); - if(type == VarType.ShaderStorageBufferObject) { + if(isBO(type)) { - final StorageBlock storageBlock = shader.getStorageBlock(param.getPrefixedName()); - storageBlock.setStorageData(param.getValue()); + final ShaderBufferBlock bufferBlock = shader.getBufferBlock(param.getPrefixedName()); + bufferBlock.setBufferObject((BufferObject) param.getValue()); } else { @@ -848,6 +848,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.ShaderStorageBufferObject || type == VarType.UniformBufferObject; + } + 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/Renderer.java b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java index 690acd743..88dcb8456 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java @@ -270,13 +270,6 @@ public interface Renderer { */ public void updateBufferData(VertexBuffer vb); - /** - * Uploads a shader storage buffer object to the GPU. - * - * @param ssbo the shader storage buffer object to upload. - */ - public void updateBufferData(ShaderStorageBufferObject ssbo); - /** * Uploads data of the buffer object on the GPU. * 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 661014138..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 @@ -191,4 +191,24 @@ public interface GL3 extends GL2 { * @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/GLDebugDesktop.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java index 085d9cadd..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 @@ -125,4 +125,10 @@ public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 { 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 6611a82a5..266cea2ea 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 @@ -1207,33 +1207,40 @@ public final class GLRenderer implements Renderer { } /** - * Update the storage block for the shader. + * Updates the buffer block for the shader. * * @param shader the shader. - * @param storageBlock the storage block. + * @param bufferBlock the storage block. */ - protected void updateShaderStorageBlock(final Shader shader, final StorageBlock storageBlock) { + protected void updateShaderBufferBlock(final Shader shader, final ShaderBufferBlock bufferBlock) { - assert storageBlock.getName() != null; + assert bufferBlock.getName() != null; assert shader.getId() > 0; - final ShaderStorageBufferObject storageData = (ShaderStorageBufferObject) storageBlock.getStorageData(); - if (storageData.getUniqueId() == -1 || storageData.isUpdateNeeded()) { - updateBufferData(storageData); + final BufferObject bufferObject = bufferBlock.getBufferObject(); + if (bufferObject.getUniqueId() == -1 || bufferObject.isUpdateNeeded()) { + updateBufferData(bufferObject); } - if (storageBlock.isUpdateNeeded()) { - - bindProgram(shader); + if (!bufferBlock.isUpdateNeeded()) { + return; + } - final int shaderId = shader.getId(); - final int blockIndex = gl4.glGetProgramResourceIndex(shaderId, GL4.GL_SHADER_STORAGE_BLOCK, storageBlock.getName()); + bindProgram(shader); - gl4.glShaderStorageBlockBinding(shaderId, blockIndex, storageData.getBinding()); - gl4.glBindBufferBase(GL4.GL_SHADER_STORAGE_BUFFER, storageData.getBinding(), storageData.getId()); + final int shaderId = shader.getId(); - storageBlock.clearUpdateNeeded(); + if (bufferObject instanceof ShaderStorageBufferObject) { + final int blockIndex = gl4.glGetProgramResourceIndex(shaderId, GL4.GL_SHADER_STORAGE_BLOCK, bufferBlock.getName()); + gl4.glShaderStorageBlockBinding(shaderId, blockIndex, bufferObject.getBinding()); + gl4.glBindBufferBase(GL4.GL_SHADER_STORAGE_BUFFER, bufferObject.getBinding(), bufferObject.getId()); + } else if (bufferObject instanceof UniformBufferObject) { + final int blockIndex = gl3.glGetUniformBlockIndex(shaderId, bufferBlock.getName()); + gl3.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bufferObject.getBinding(), bufferObject.getId()); + gl3.glUniformBlockBinding(GL3.GL_UNIFORM_BUFFER, blockIndex, bufferObject.getBinding()); } + + bufferBlock.clearUpdateNeeded(); } protected void updateShaderUniforms(Shader shader) { @@ -1247,14 +1254,14 @@ public final class GLRenderer implements Renderer { } /** - * Updates all shader's storage blocks. + * Updates all shader's buffer blocks. * * @param shader the shader. */ - protected void updateShaderStorageBlocks(final Shader shader) { - final ListMap storageBlocks = shader.getStorageBlockMap(); - for (int i = 0; i < storageBlocks.size(); i++) { - updateShaderStorageBlock(shader, storageBlocks.getValue(i)); + protected void updateShaderBufferBlocks(final Shader shader) { + final ListMap bufferBlocks = shader.getBufferBlockMap(); + for (int i = 0; i < bufferBlocks.size(); i++) { + updateShaderBufferBlock(shader, bufferBlocks.getValue(i)); } } @@ -1476,7 +1483,7 @@ public final class GLRenderer implements Renderer { assert shader.getId() > 0; updateShaderUniforms(shader); - updateShaderStorageBlocks(shader); + updateShaderBufferBlocks(shader); bindProgram(shader); } } 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 c599051cd..05264f8db 100644 --- a/jme3-core/src/main/java/com/jme3/shader/Shader.java +++ b/jme3-core/src/main/java/com/jme3/shader/Shader.java @@ -53,9 +53,9 @@ public final class Shader extends NativeObject { private final ListMap uniforms; /** - * Maps storage block name to the storage block variable. + * Maps storage block name to the buffer block variables. */ - private final ListMap storageBlocks; + private final ListMap bufferBlocks; /** * Uniforms bound to {@link UniformBinding}s. @@ -227,7 +227,7 @@ public final class Shader extends NativeObject { super(); shaderSourceList = new ArrayList<>(); uniforms = new ListMap<>(); - storageBlocks = new ListMap<>(); + bufferBlocks = new ListMap<>(); attribs = new IntMap<>(); boundUniforms = new ArrayList<>(); } @@ -246,7 +246,7 @@ public final class Shader extends NativeObject { } uniforms = null; - storageBlocks = null; + bufferBlocks = null; boundUniforms = null; attribs = null; } @@ -296,24 +296,24 @@ public final class Shader extends NativeObject { } /** - * Get or create a storage block by the name. + * Gets or creates a buffer block by the name. * - * @param name the storage block's name. - * @return the storage block. + * @param name the buffer block's name. + * @return the buffer block. */ - public StorageBlock getStorageBlock(final String name) { + public ShaderBufferBlock getBufferBlock(final String name) { assert name.startsWith("m_"); - StorageBlock storageBlock = storageBlocks.get(name); + ShaderBufferBlock block = bufferBlocks.get(name); - if (storageBlock == null) { - storageBlock = new StorageBlock(); - storageBlock.name = name; - storageBlocks.put(name, storageBlock); + if (block == null) { + block = new ShaderBufferBlock(); + block.name = name; + bufferBlocks.put(name, block); } - return storageBlock; + return block; } public void removeUniform(String name){ @@ -321,12 +321,12 @@ public final class Shader extends NativeObject { } /** - * Remove a storage block by the name. + * Removes a buffer block by the name. * - * @param name the storage block's name. + * @param name the buffer block's name. */ - public void removeStorageBlock(final String name){ - storageBlocks.remove(name); + public void removeBufferBlock(final String name){ + bufferBlocks.remove(name); } public Attribute getAttribute(VertexBuffer.Type attribType){ @@ -345,12 +345,12 @@ public final class Shader extends NativeObject { } /** - * Get the storage blocks map. + * Get the buffer blocks map. * - * @return the storage blocks map. + * @return the buffer blocks map. */ - public ListMap getStorageBlockMap() { - return storageBlocks; + public ListMap getBufferBlockMap() { + return bufferBlocks; } public ArrayList getBoundUniforms() { @@ -366,7 +366,7 @@ public final class Shader extends NativeObject { return getClass().getSimpleName() + "[numSources=" + shaderSourceList.size() + ", numUniforms=" + uniforms.size() + - ", numStorageBlocks=" + storageBlocks.size() + + ", numBufferBlocks=" + bufferBlocks.size() + ", shaderSources=" + getSources() + "]"; } @@ -413,9 +413,9 @@ public final class Shader extends NativeObject { uniform.reset(); // fixes issue with re-initialization } } - if (storageBlocks != null) { - for (StorageBlock storageBlock : storageBlocks.values()) { - storageBlock.reset(); + if (bufferBlocks != null) { + for (ShaderBufferBlock shaderBufferBlock : bufferBlocks.values()) { + shaderBufferBlock.reset(); } } if (attribs != null) { diff --git a/jme3-core/src/main/java/com/jme3/shader/StorageBlock.java b/jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java similarity index 84% rename from jme3-core/src/main/java/com/jme3/shader/StorageBlock.java rename to jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java index fd386d498..27b44d18b 100644 --- a/jme3-core/src/main/java/com/jme3/shader/StorageBlock.java +++ b/jme3-core/src/main/java/com/jme3/shader/ShaderBufferBlock.java @@ -32,29 +32,29 @@ package com.jme3.shader; /** - * Implementation of shader's storage block. + * Implementation of shader's buffer block. * * @author JavaSaBr */ -public class StorageBlock extends ShaderVariable { +public class ShaderBufferBlock extends ShaderVariable { /** * Current used buffer object. */ - protected Object storageData; + protected BufferObject bufferObject; /** - * Set the new storage data. + * Set the new buffer object. * - * @param storageData the new storage data + * @param bufferObject the new buffer object. */ - public void setStorageData(final Object storageData) { + public void setBufferObject(final BufferObject bufferObject) { - if (storageData == null) { + if (bufferObject == null) { throw new IllegalArgumentException("for storage block " + name + ": storageData cannot be null"); } - this.storageData = storageData; + this.bufferObject = bufferObject; updateNeeded = true; } @@ -87,7 +87,7 @@ public class StorageBlock extends ShaderVariable { * * @return the current storage data. */ - public Object getStorageData() { - return storageData; + public BufferObject getBufferObject() { + return bufferObject; } } 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 6b39e2879..63c3735eb 100644 --- a/jme3-core/src/main/java/com/jme3/system/NullRenderer.java +++ b/jme3-core/src/main/java/com/jme3/system/NullRenderer.java @@ -44,6 +44,7 @@ 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.shader.ShaderStorageBufferObject; @@ -150,14 +151,14 @@ public class NullRenderer implements Renderer { } @Override - public void updateBufferData(ShaderStorageBufferObject ssbo) { + public void updateBufferData(BufferObject bo) { } - public void deleteBuffer(VertexBuffer vb) { } @Override - public void deleteBuffer(ShaderStorageBufferObject ssbo) { + public void deleteBuffer(BufferObject bo) { + } public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { diff --git a/jme3-core/src/test/java/com/jme3/SetupTest.java b/jme3-core/src/test/java/com/jme3/SetupTest.java index fdf35dbf3..a9969e179 100644 --- a/jme3-core/src/test/java/com/jme3/SetupTest.java +++ b/jme3-core/src/test/java/com/jme3/SetupTest.java @@ -31,6 +31,13 @@ */ package com.jme3; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.shader.BufferObject; +import com.jme3.shader.BufferObject.Layout; +import com.jme3.shader.BufferObjectField; +import com.jme3.shader.UniformBufferObject; +import com.jme3.shader.VarType; import org.junit.Test; /** @@ -41,6 +48,20 @@ public class SetupTest { @Test(expected=AssertionError.class) public void testAssertionEnabled() { + + Material material; + + final UniformBufferObject ubo = new UniformBufferObject(3, Layout.std140, + new BufferObjectField("light_1", VarType.Vector4), + new BufferObjectField("light_2", VarType.Vector4), + new BufferObjectField("array", VarType.FloatArray) + ); + ubo.setValue("light_1", ColorRGBA.Black); + ubo.setValue("light_2", ColorRGBA.Gray); + ubo.setValue("array", new float[] {1F, 2F, 3F}); + + material.setBufferObject("uboTest", ubo); + assert false; } } 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 5cc7b091c..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 @@ -654,4 +654,9 @@ public class JoglGL implements GL, GL2, GL3, GL4 { 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 68d974520..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 @@ -509,4 +509,9 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 { 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 e535ee141..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 @@ -641,4 +641,9 @@ public class LwjglGL extends LwjglRender implements GL, GL2, GL3, GL4 { 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); + } }