Search code examples
scalaopengllwjgl

Setting Uniform yields blank screen


Consider the following basic (vertex-)shader:

#version 330 core

in vec3 position;
in vec2 textureCoords;

out vec2 passTextureCoords;

uniform mat4 transformationMatrix;

void main(void)
{
    gl_Position = transformationMatrix * vec4(position.x, position.y, position.z, 1.0);
    passTextureCoords = textureCoords;
}

All it does is display a texture (hence I omit the fragment-shader as nothing happens there)

Without the transformationMatrix (gl_Position = vec4(position.x, position.y, position.z, 1.0);

everything works fine and the texture is displayed. As soon as I want to bind a matrix though, things look differently.

My Matrix4.scala:

class Matrix4(var m00: Float, var m01: Float, var m02: Float, var m03: Float,
              var m10: Float, var m11: Float, var m12: Float, var m13: Float,
              var m20: Float, var m21: Float, var m22: Float, var m23: Float,
              var m30: Float, var m31: Float, var m32: Float, var m33: Float)
{
  def toFloatBuffer(): FloatBuffer =
  {
    val buffer: FloatBuffer = BufferUtils.createFloatBuffer(16)

  //  buffer.put(this.toArray) // Set manually for now to make sure no error in Array-creation

    buffer.put(this.m00)
    buffer.put(this.m01)
    buffer.put(this.m02)
    buffer.put(this.m03)

    buffer.put(this.m10)
    buffer.put(this.m11)
    buffer.put(this.m12)
    buffer.put(this.m13)

    buffer.put(this.m20)
    buffer.put(this.m21)
    buffer.put(this.m22)
    buffer.put(this.m23)

    buffer.put(this.m30)
    buffer.put(this.m31)
    buffer.put(this.m32)
    buffer.put(this.m33)

    buffer
  }
}

object Matrix4
{
  def Identity = new Matrix4(
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
  )
}

Shaders.scala

object Shaders
{
    def loadMatrix(uniformLocation: Int, value: Matrix4): Unit =
    {
      val matrixBuffer: FloatBuffer = value.toFloatBuffer
      matrixBuffer.flip
      glUniformMatrix4fv(uniformLocation, false, matrixBuffer)
    }

    def getUniformLocation(programID: Int, uniformName: String): Int =
    {
       glGetUniformLocation(programID, uniformName)
    }
}

Now for the main-loop:

val transformationMatrixLocation: Int = Shaders.getUniformLocation(shader, "transformationMatrix")

val transformationMatrix: Matrix4 = Matrix4.Identity

Shaders.loadMatrix(transformationMatrixLocation, transformationMatrix)

transformationMatrixLocation => 0

transformationMatrix = {

  1.0      0.0     0.0     0.0 

  0.0      1.0     0.0     0.0 

  0.0      0.0     1.0     0.0 

  0.0      0.0     0.0     1.0                                                                          
}

(Shader holds the id of the Shader-program)

So, my Matrix is created correctly and the Uniform is found (else it would return -1).

As I see it either my FloatBuffer-creation in Matrix4.scala is wrong or I send it incorrectly to OpenGL (Shaders.scala).

Or am I missing something else? Cracking my head on this one for about an hour now, to no avail :(

edit: To clear things up: Yes, the shader is bound (otherwise it wouldn't work as it does without the matrix ;)) and the method for binding a uniform is from lwjgl (version 3).


Solution

  • From your code snippets provided so far, it is not clear if your shader program is actually in use at the time of the glUniformMatrix4fv call. Uniforms are per-program state, and all glUniform*() calls apply to the currently bound program only.