flyx / OpenGLAda

Thick Ada binding for OpenGL and GLFW
flyx.github.io/OpenGLAda/
MIT License
95 stars 13 forks source link

Problem setting Singles.Vector3 uniform #105

Closed rogermc2 closed 6 years ago

rogermc2 commented 6 years ago

The following code fails

   Light_Position_ID        : GL.Uniforms.Uniform;
      Light_Position    : constant Singles.Vector3 := (4.0, 4.0, 4.0);
      GL.Uniforms.Set_Single (Light_Position_ID, Light_Position);
raised GL.ERRORS.INVALID_OPERATION_ERROR : gl-raise_exception_on_opengl_error.adb:10

However, the following does not fail

      GL.Uniforms.Set_Single (Light_Position_ID, 4.0, 4.0, 4.0);

Am I doing something wrong?

flyx commented 6 years ago

I'd assume that the wrapper has an error. API.Singles.Uniform3v takes a Types.Singles.Vector3_Array which I am sure about whether it maps properly to a GLint*. However, this should not lead to an Invalid_Operation_Error since that is only defined for wrong values of the count parameter (hidden in the outer API, always set to 3).

Here are the causes for Invalid_Operation_Error according to OpenGL spec:

GL_INVALID_OPERATION is generated if there is no current program object.

GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.

GL_INVALID_OPERATION is generated if one of the signed or unsigned integer variants of this function is used to load a uniform variable of type float, vec2, vec3, vec4, or an array of these, or if one of the floating-point variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4, or an array of these.

GL_INVALID_OPERATION is generated if one of the signed integer variants of this function is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these.

GL_INVALID_OPERATION is generated if one of the unsigned integer variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, or an array of these.

GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.

Could you check that your code & shader meets all the requirements for not getting that error?

rogermc2 commented 6 years ago

An initial check seems OK but I'll try and have a closer look detailing my results. I'm not sure what the -1 in the last one means:

GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.

It seems to be saying that an invalid uniform location should be OK if its set to -1?

The preceding matrix uniform settings work OK:

      GL.Uniforms.Set_Single (Model_Matrix_ID, Model_Matrix);
      GL.Uniforms.Set_Single (View_Matrix_ID, View_Matrix);
      GL.Uniforms.Set_Single (MVP_Matrix_ID, MVP_Matrix);
      GL.Uniforms.Set_Single (Light_Position_ID, Light_Position);
rogermc2 commented 6 years ago

Accidentally pressed the wrong button!

rogermc2 commented 6 years ago

GL_INVALID_OPERATION is generated if there is no current program object. A current program object is confirmed by the correct operation of preceding commands:

GL.Uniforms.Set_Single (Model_Matrix_ID, Model_Matrix);
 GL.Uniforms.Set_Single (View_Matrix_ID, View_Matrix);
 GL.Uniforms.Set_Single (MVP_Matrix_ID, MVP_Matrix);

I further confirmed this by placing before the failing 'Set_Single' command:

GL.Objects.Programs.Use_Program (Render_Program);

GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command. Shader uniform variable:

uniform vec3 Light_Position_Worldspace;

glUniform command invocation:

Light_Position    : constant Singles.Vector3 := (4.0, 4.0, 4.0);
GL.Uniforms.Set_Single (Light_Position_ID, Light_Position);

GL_INVALID_OPERATION is generated if one of the signed or unsigned integer variants of this function is used to load a uniform variable of type float, vec2, vec3, vec4, or an array of these, or if one of the floating-point variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4, or an array of these. Using correct type seems to be automatically done by OpenGLAda. Shader code:

uniform mat4 MVP;
uniform mat4 V;
uniform mat4 M;
uniform vec3 Light_Position_Worldspace;

Location setting:

      Light_Position_ID := GL.Objects.Programs.Uniform_Location
        (Render_Program, "Light_Position_Worldspace");

GL_INVALID_OPERATION is generated if one of the signed integer variants of this function is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these. Type is Single, Set_Single is used with 'constant Singles.Vector3'

GL_INVALID_OPERATION is generated if one of the unsigned integer variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, or an array of these. OpenGLAda determines function variant? According to GLSL specification,

vec2 , vec3 , vec4 : 2, 3, and 4-component floating point vectors.

GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1. Uniform location, Light_Position_ID appears valid.

All appears OK to me.