Commits

Michael Ludwig committed 9bf00e4

Improve doc/spec with regards to naming and accessing array uniforms.
Update attribute type to support array attributes.
Fix bugs in pulling in variables in LWJGL.
Add method definitions to GlslRenderer for array variables (not implemented yet)

Comments (0)

Files changed (5)

ferox-renderer-jogl/src/main/java/com/ferox/renderer/impl/jogl/JoglShaderBuilder.java

             getGL(context)
                     .glGetActiveUniform(programID, i, maxUniformNameLength, nameLen, 0, len, 0, type, 0, name,
                                         0);
-            String uniformName = new String(name, 0, nameLen[0]);
+            // strip off [0] at the end of an array name
+            String uniformName = new String(name, 0, len[0] > 1 ? nameLen[0] - 3 : nameLen[0]);
 
             // get uniform location
             int location = getGL(context).glGetUniformLocation(programID, uniformName);
-
             ShaderImpl.UniformImpl u = new ShaderImpl.UniformImpl(handle, Utils.getVariableType(type[0]),
                                                                   len[0], uniformName, location);
             uniforms.add(u);
 
             int index = getGL(context).glGetAttribLocation(programID, attrName);
             ShaderImpl.AttributeImpl a = new ShaderImpl.AttributeImpl(handle, Utils.getVariableType(type[0]),
-                                                                      attrName, index);
+                                                                      attrName, len[0], index);
             attributes.add(a);
         }
 

ferox-renderer-lwjgl/src/main/java/com/ferox/renderer/impl/lwjgl/LwjglShaderBuilder.java

         IntBuffer type = BufferUtil.newByteBuffer(DataType.INT, 1).asIntBuffer();
         for (int i = 0; i < numUniforms; i++) {
             // read uniform properties
+            name.clear();
             GL20.glGetActiveUniform(programID, i, nameLen, len, type, name);
             byte[] bs = new byte[nameLen.get(0)];
             name.get(bs, 0, bs.length).position(0);
-            String uniformName = new String(bs);
+            // strip off [0] at the end of an array name
+            String uniformName = new String(bs, 0, len.get(0) > 1 ? bs.length - 3 : bs.length);
+
             int location = GL20.glGetUniformLocation(programID, uniformName);
-
             ShaderImpl.UniformImpl u = new ShaderImpl.UniformImpl(handle, Utils.getVariableType(type.get(0)),
                                                                   len.get(0), uniformName, location);
             uniforms.add(u);
         int programID = handle.programID;
         int numAttrs = GL20.glGetProgrami(programID, GL20.GL_ACTIVE_ATTRIBUTES);
         int maxAttributeNameLength = GL20.glGetProgrami(programID, GL20.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
+
         ByteBuffer name = BufferUtil.newByteBuffer(DataType.BYTE, maxAttributeNameLength);
 
         IntBuffer nameLen = BufferUtil.newByteBuffer(DataType.INT, 1).asIntBuffer();
         IntBuffer len = BufferUtil.newByteBuffer(DataType.INT, 1).asIntBuffer();
         IntBuffer type = BufferUtil.newByteBuffer(DataType.INT, 1).asIntBuffer();
+
         for (int i = 0; i < numAttrs; i++) {
             // read uniform properties
+            name.clear();
             GL20.glGetActiveAttrib(programID, i, nameLen, len, type, name);
             byte[] bs = new byte[nameLen.get(0)];
             name.get(bs, 0, bs.length);
             int index = GL20.glGetAttribLocation(programID, attrName);
             ShaderImpl.AttributeImpl a = new ShaderImpl.AttributeImpl(handle,
                                                                       Utils.getVariableType(type.get(0)),
-                                                                      attrName, index);
+                                                                      attrName, len.get(0), index);
             attributes.add(a);
         }
 

ferox-renderer/src/main/java/com/ferox/renderer/GlslRenderer.java

      * @throws NullPointerException     if var is null
      */
     public void setUniform(Shader.Uniform var, @Const ColorRGB color, boolean isHDR);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, VertexAttribute attr);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, int column, VertexAttribute attr);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, double val);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, double v1, double v2);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, @Const Vector3 v);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, @Const Vector4 v);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, double m00, double m01, double m10,
+                                   double m11);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, @Const Matrix3 v);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, @Const Matrix4 v);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, int val);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, int v1, int v2);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, int v1, int v2, int v3);
+
+    public void bindAttributeArray(Shader.Attribute var, int index, int v1, int v2, int v3, int v4);
+
+    public void setUniformArray(Shader.Uniform var, int index, double val);
+
+    public void setUniformArray(Shader.Uniform var, int index, double v1, double v2);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const Vector3 v);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const Vector4 v);
+
+    public void setUniformArray(Shader.Uniform var, int index, double m00, double m01, double m10,
+                                double m11);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const Matrix3 val);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const Matrix4 val);
+
+    public void setUniformArray(Shader.Uniform var, int index, int val);
+
+    public void setUniformArray(Shader.Uniform var, int index, int v1, int v2);
+
+    public void setUniformArray(Shader.Uniform var, int index, int v1, int v2, int v3);
+
+    public void setUniformArray(Shader.Uniform var, int index, int v1, int v2, int v3, int v4);
+
+    public void setUniformArray(Shader.Uniform var, int index, boolean val);
+
+    public void setUniformArray(Shader.Uniform var, int index, boolean v1, boolean v2);
+
+    public void setUniformArray(Shader.Uniform var, int index, boolean v1, boolean v2, boolean v3);
+
+    public void setUniformArray(Shader.Uniform var, int index, boolean v1, boolean v2, boolean v3,
+                                boolean v4);
+
+    public void setUniformArray(Shader.Uniform var, int index, Sampler texture);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const ColorRGB color);
+
+    public void setUniformArray(Shader.Uniform var, int index, @Const ColorRGB color, boolean isHDR);
 }

ferox-renderer/src/main/java/com/ferox/renderer/Shader.java

     }
 
     /**
-     * Attribute represents a bindable vertex attribute declared in the vertex shader of the compiled program.
-     * If the attribute type is a matrix type, it encapsulates N underlying attributes where each low-level
-     * attribute maps to a column of the matrix.
+     * Abstract access to variable information exposed by GLSL shaders through OpenGL. The variables will be
+     * either uniforms or attributes to the vertex shader. Array access and declarations may not be supported
+     * depending on the GLSL version.
      */
-    public static interface Attribute {
+    public static interface Variable {
         /**
-         * @return The attribute's type
+         * Get the value type of this variable. If getLength() > 1, then this is the component type of the
+         * array.
+         *
+         * @return The type of this variable
          */
         public VariableType getType();
 
         /**
-         * @return The attribute's name as declared in the shader source
+         * Return the number of primitives of getType() used by this variable. If it's > 1, then the variable
+         * represents an array.
+         *
+         * @return Size of the variable, in units of getType()
+         */
+        public int getLength();
+
+        /**
+         * Return the name of the variable as declared in the glsl code of the uniform's owner. See {@link
+         * #getUniform(String)} for specifics on how names are formatted for complex variables.
+         *
+         * @return The name of the variable
          */
         public String getName();
 
         /**
-         * @return The compiled index of the attribute within the program
+         * @return The compiled index of the variable within the program
          */
         public int getIndex();
 
         /**
-         * @return True if the attribute name starts with 'gl_' and is one of the special or reserved GLSL
-         *         attribute variables
+         * @return True if the variable starts with 'gl_' and represents one of the special variables declared
+         *         in the (older) GLSL specs
          */
         public boolean isReserved();
     }
 
-    public static interface Uniform {
-        /**
-         * Get the value type of this uniform. If getLength() > 1, then this is the component type of the
-         * array for the uniform.
-         *
-         * @return The type of this uniform
-         */
-        public VariableType getType();
+    /**
+     * Variable type representing uniforms in a shader.
+     */
+    public static interface Uniform extends Variable {
+    }
 
-        /**
-         * Return the number of primitives of getType() used by this uniform. If it's > 1, then the uniform
-         * represents an array.
-         *
-         * @return Size of the uniform, in units of getType()
-         */
-        public int getLength();
-
-        /**
-         * Return the name of the uniform as declared in the glsl code of the uniform's owner.
-         *
-         * @return The name of the uniform
-         */
-        public String getName();
-
-        /**
-         * @return The compiled index of the uniform within the program
-         */
-        public int getIndex();
-
-        /**
-         * @return True if the uniform variable starts with 'gl_' and represents one of the special uniforms
-         *         declared in the (older) GLSL specs
-         */
-        public boolean isReserved();
-
-        /**
-         * @return True if the uniform is an array
-         */
-        public boolean isArray();
+    public static interface Attribute extends Variable {
     }
 
     /**
+     * Get the detected uniforms from the linked shader. These are the uniforms reported by OpenGL. Unused
+     * uniforms that have been compiled away will not be included. The returned list will have expanded out
+     * all struct members into individual uniform objects.
+     *
      * @return All uniforms used in the shader, ordered by their compiled index
      */
     public List<? extends Uniform> getUniforms();
 
     /**
      * Get the uniform object for the variable with the given {@code name}. This will return null if there is
-     * no matching uniform.
+     * no matching uniform. The variable name must be the full name of the uniform excluding any last array
+     * access. This is because intermediate struct and array accesses are hard-coded and expanded into uniform
+     * slots by OpenGL. As an example, the following uniform declaration:
+     * <pre>
+     *     struct MyType {
+     *         vec3 innerArray[2];
+     *         vec4 var;
+     *     }
+     *     uniform MyType outerArray[3];
+     * </pre>
+     * would produce the following uniform names (assuming the outer array indices were all used): <ul>
+     * <li>outerArray[0].innerArray (with a reported length of 2)</li> <li>outerArray[0].var</li>
+     * <li>outerArray[1].innerArray (ditto)</li> <li>outerArray[1].var</li> </ul>
+     * <p/>
+     * Uniforms of built-in types and arrays of built-in types can be accessed using their declared variable
+     * name.
      *
      * @param name The uniform variable name
      *
 
     /**
      * Get the attribute object for the variable with the given {@code name}. This will return null if there
-     * is no matching attribute.
+     * is no matching attribute. As with uniform names, the attribute name should not include any array
+     * index.
      *
      * @param name The attribute variable name
      *

ferox-renderer/src/main/java/com/ferox/renderer/impl/resources/ShaderImpl.java

         }
 
         @Override
-        public boolean isArray() {
-            return length > 1;
+        public String toString() {
+            if (length > 1) {
+                return String.format("uniform %s[%d] %s at %d", type, length, name, index);
+            } else {
+                return String.format("uniform %s %s at %d", type, name, index);
+            }
         }
     }
 
         private final VariableType type;
         private final String name;
         private final int index;
+        private final int length;
 
-        public AttributeImpl(ShaderHandle owner, VariableType type, String name, int index) {
+        public AttributeImpl(ShaderHandle owner, VariableType type, String name, int length, int index) {
             this.owner = owner;
             this.type = type;
             this.name = name;
             this.index = index;
+            this.length = length;
+        }
+
+        @Override
+        public int getLength() {
+            return length;
         }
 
         @Override
         public boolean isReserved() {
             return name.startsWith("gl_");
         }
+
+        @Override
+        public String toString() {
+            if (length > 1) {
+                return String.format("attribute %s[%d] %s at %d", type, length, name, index);
+            } else {
+                return String.format("attribute %s %s at %d", type, name, index);
+            }
+        }
     }
 
     public static class ShaderHandle extends ResourceHandle {