flyx / OpenGLAda

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

New implementations #120

Closed rogermc2 closed 6 years ago

rogermc2 commented 6 years ago

Additional GL implementations that I need for a current project. Recommended changes will be appreciated.

rogermc2 commented 6 years ago

Thanks for your instructions. It might take me a day or two to investigate and fix things.

flyx commented 6 years ago

I updated the specs because glDrawArraysInstanced needed to be loaded dynamically. You should merge gl-api.spec into your branch and regenerate the generated files.

By the way, I commited some stuff that allows me to build a Windows installer for OpenGLAda :). I'd like to make a new release shortly and provide that installer, so that Windows folks can use this library more easily.

rogermc2 commented 6 years ago

I hope that I've merged gl-api.spec into this branch and regenerated files correctly. I'm never 100% confident with merging.

rogermc2 commented 6 years ago

I think of fixed everything except Transform_Feedback_Varyings for which I have not found a suitable implementation. Please provide details on how to "hand out pointers to the characters there" which I don't understand and, after many hours, haven't been able how to figure out how to implement. API.Transform_Feedback_Varyings seems to require a chars_ptr_array. I tried doing it with chars_ptr which compiled but the application crashed with a GL error message.

rogermc2 commented 6 years ago

I don't know what happened there! I thought I'd fixed fix the subtype thing! Fixed now.

rogermc2 commented 6 years ago

I'm having a problem with Texture_Buffer_Target The following worked with Texture_Buffer_Target as a subtype but doesn't seem to get inherited now.

   procedure Load_Texture_Buffer is new
     GL.Objects.Buffers.Load_To_Buffer (GL.Types.Singles.Matrix4_Pointers);

The error report expectsBuffer_Target but objects to Texture_Buffer_Target. What do I need to do to get this to work? An additional generic or additional procedure Load_To_Buffer (Target : Texture_Buffer_Target; ... under the current generic or something else? Or, is there something missing from my Texture_Buffer_Target declaration?

A similar problem occurs with

   procedure Load_Vertex_Buffer is new
     GL.Objects.Buffers.Load_To_Buffer (GL.Types.Singles.Vector2_Pointers)
flyx commented 6 years ago

In the generic subroutines, simply substitute Target : Buffer_Target with Target : Buffer_Target'Class.

rogermc2 commented 6 years ago

That fixed it. Thanks.

flyx commented 6 years ago

Great! I will try and do away with those New_String allocations from Interfaces.C.Strings in the next days. I have unnecessarily used them myself in some places.

flyx commented 6 years ago

I pushed a modified Transform_Feedback_Varyings and on the way did away with other usages of New_String in the project, some of which caused serious memory leaks. Please check whether it works for you.

rogermc2 commented 6 years ago

Using

      Varyings       : constant String := "position_out,velocity_out";

In the following, Transform_Feedback_Varyings executes without failure but the subsequent link fails.

      GL.Objects.Programs.Use_Program  (Update_Program);
      Transform_Feedback_Varyings (Update_Program, Varyings, Interleaved_Attribs);
      Update_Program.Link;
      if not GL.Objects.Programs.Link_Status (Update_Program) then
         Put_Line ("Setup, Update_Program Link failed");
         Put_Line (GL.Objects.Programs.Info_Log (Update_Program));
      else
         Put_Line ("Setup, Update_Program Link ok");
      end if;

Error messages:

Setup, Update_Program Link failed
ERROR: Could not find transform feedback binding for 'position_out.'
ERROR: Could not find transform feedback binding for 'position_out.'
ERROR: Could not find transform feedback binding for 'velocity_out.'

raised GL.ERRORS.INVALID_OPERATION_ERROR : gl-raise_exception_on_opengl_error.adb:10

I'll try and find if this is caused by my code.

rogermc2 commented 6 years ago

While investigating the Transform_Feedback_Varyings procedure I came across a problem with Get_Transform_Feedback_Varying in that some parameters needed to be declared out which I have fixed. However, Get_Transform_Feedback_Varying now fails returning an invalid value error. The functions Transform_Feedback_Varyings and Transform_Feedback_Varying_Max_Length do not crash but both return the value 0 suggesting that Transform_Feedback_Varyings is not working properly. The function Transform_Feedback_Buffer_Mode returns INTERLEAVED_ATTRIBS which I suspect is the default buffer mode. I tested this by setting the mode to Separate_Attribs but Transform_Feedback_Buffer_Mode still returned INTERLEAVED_ATTRIBS I have circumvented Get_Transform_Feedback_Varying failure by incorporating Transform_Feedback_Varyings and Transform_Feedback_Varying_Max_Length tests as its possible that a Transform_Feedback_Varying having these parameters may be the cause of its failure. So far, I've not been able to discover other clues as to why linking following Transform_Feedback_Varyings is failing. Should I submit my proposed changes to Get_Transform_Feedback_Varying in my current open PR or leave it to my next (final) PR?

flyx commented 6 years ago

As the current PR does not touch these functions, please put the changes in the final PR.

flyx commented 6 years ago

I am unsure whether the points at the end of the varying's names are part of the error message or hint to an error in my code. The fact that position_out is mentioned twice hints to an error in my code, I'll investigate (later).

flyx commented 6 years ago

I pushed a fix for the wrong number of varyings. Not sure where the dot comes from though.

rogermc2 commented 6 years ago

I did not receive the usual e-mail advice and can't find any sign of the fix. However, merging updated master into my test program produces:

V_Type: SEPARATE_ATTRIBS   V_Length:  2   Max Length:  0
Setup, Update_Program Link failed
ERROR: Could not find transform feedback binding for 'position_out.'
ERROR: Could not find transform feedback binding for 'velocity_out.'

where,

Max_Length := Transform_Feedback_Varying_Max_Length (Update_Program);

So, by V_Type: SEPARATE_ATTRIBS and V_Length: 2, it looks like varyings are being at least partiallly loaded. I can't find any problem with Transform_Feedback_Varying_Max_Length which is supposed to give the " length of the longest varying name". Possibly 0, because of the "dots", Transform_Feedback_Varyings can't find the names its looking for? It would be nice to have a decent debugger to solve the "dot" problem.

flyx commented 6 years ago

Indeed. I have no idea where the dots come from, My code only replaces commas with null characters. There is no possibility of a dot getting inserted. Did this work previously for you with the New_String code?

flyx commented 6 years ago

I noticed that the error says „Could not find transform feedback binding“. Perhaps the error is not the varying's name, but the buffer binding?

rogermc2 commented 6 years ago

I can't remember if I had it working with the New_String code. Probably not. I also wondered about the buffer binding and am not sure what the message means. I checked everything that I could think of related to binding. I'll study your reference to buffer binding to try and understand just what is supposed to be bound to what. If really desperate, I'll try using the debugger which is always difficult.

flyx commented 6 years ago

Do you have corresponding C code that shows everything that needs to be done?

The documentation I linked mentions glBindBufferRange, which is currently not implemented by OpenGLAda. From what I understand, you need to create a Buffer object and bind it to Transform_Feedback_Buffer. Then you need to call glBindBufferRange for each varying output with the index parameter being whatever you specified in GLSL with xfb_buffer. That will tell the program linker where to store the values.

rogermc2 commented 6 years ago

The example that I am working on is from the red book examples code. It starts with:

    update_prog = glCreateProgram();
//  vertex and fragment shader code
    vglAttachShaderSource(update_prog, GL_VERTEX_SHADER, update_vs_source);
    vglAttachShaderSource(update_prog, GL_FRAGMENT_SHADER, white_fs);
    static const char * varyings[] =
    {
        "position_out", "velocity_out"
    };
    glTransformFeedbackVaryings(update_prog, 2, varyings, GL_INTERLEAVED_ATTRIBS);
    glLinkProgram(update_prog);
    glUseProgram(update_prog);

All array and buffer objects are declared, initialized and bound AFTER this code. The shader variables that we are trying to bind the string "position_out,velocity_out" with are:

out vec4 position_out;  
out vec3 velocity_out; 

I assume that bind refers to connecting the shader variables with the program created by glCreateProgram. I don't think that buffers are needed until after the TransformFeedbackVaryings have been linked. I have checked a couple of other examples and they all start like this. I've tried initializing and binding these objects at the beginning but the result was the same. I recoded using New_String and got the same results. During the recoding my first effort missed the second string. The resulting error message was:

ERROR: Could not find transform feedback binding for 'position_out.'
ERROR: Could not find transform feedback binding for '.'
rogermc2 commented 6 years ago

Attempting debugger use with the New_Strings version.

C_Varyings_Ptr : Interfaces.C.Strings.chars_ptr_array (1 .. Num_Strings);

C_Varyings_Ptr (1) is passed to API.Transform_Feedback_Varyings as "position_out["00"]" Unfortunately, while I can step through GL.Objects.Programs.Transform_Feedback_Varyings I can't step into API.Transform_Feedback_Varyings and hence the C code. Possibly because of the dynamic calling? Or because I don't have the C code?

rogermc2 commented 6 years ago

I now have some OpenGL code (Mesa) which I can look through to see if I can see the problem. Here is a typical Mesa error message:

 linker_error(prog,  "vertex shader does not write to `gl_Position'. \n");

So far I haven't found a transform feedback binding error message. The closest I have found is:

/* From GL_EXT_transform_feedback:
       *   A program will fail to link if:
       *   * any variable name specified in the <varyings> array is not
       *     declared as an output in the geometry shader (if present) or
       *     the vertex shader (if no geometry shader is present);
       */
      linker_error(prog, "Transform feedback varying %s undeclared.", this->orig_name);
rogermc2 commented 6 years ago

I have built the C example using Xcode. It runs without crashing but so far only a black window is displayed

flyx commented 6 years ago

Are you getting the error message you showed above or is that just an example?

btw, you cannot step into API.Transform_Feedback_Varyings because that is implemented in the OpenGL implementation, which certainly does not have any debugging symbols available.

rogermc2 commented 6 years ago

The error message is meaningless as I have discovered many errors in the program in that detected failures are neither reported nor acted on. The program is actually failing to initialise GLFW properly.

rogermc2 commented 6 years ago

I have discovered that the version of GLFW installed by brew no longer works with all programs. The latest master version needs to be downloaded from https://github.com/glfw/glfw, built and used. However, I this causes other build problems that I am now working on.

flyx commented 6 years ago

Can you give me more details here? Perhaps a link to a relevant GLFW issue or commit? Why does it no longer work, did you see an error in an example that was previously working? And do you know if this affects only macOS or all backends?

I would prefer not to tell the users they have to compile GLFW from scratch unless necessary. If this issue persists until I release the next version, I will put a note in the release notes or changelog that certain features need the newer GLFW code. However, GLFW 3.3 seems to get released soon, so I hope the problem fixes itself.

rogermc2 commented 6 years ago

This is the error ( https://github.com/glfw/glfw/issues/909):

2016-11-27 19:33:40.726198 GLFW[37260:6137830] [General] ERROR: 
Setting <GLFWContentView: 0x102a26000> as the first responder for window 
<GLFWWindow: 0x10071d510>, but it is in a different window ((null))! 
This would eventually crash when the view is freed. The first responder will be set to nil.

Currently, I OpenGLAda doesn't seem to be affected. It only seems to occur when I'm building C programs. The ogl_tutorials/misc05_picking_easy Ada example works but its C equivalent has the problem. Hopefully GLFW 3.3 will include the fixes. My current observations:

  1. brew no longer installs 'libglfw.a'. It only installs dylibs.
  2. the master version I referred to above builds 'libglfw3.a' which I need for building my C examples because it solves the problem.
  3. the current OpenGLAda examples need 'libglfw.a'.

So, OpenGLAda seems safe at the moment.

flyx commented 6 years ago

Thanks for the information. Generally, it should not be a problem that brew installs only dylibs. OpenGLAda should link to those dylibs just fine.

rogermc2 commented 6 years ago

I now have the the C version of the transform feedback example functioning without error. Instigating an error (leaving the "y" out of velocity) yields:

update_prog ProgramInfoLog: ERROR: Could not find transform feedback binding for 'velocit_out.'

So it looks like the dot is part of the error message. When spelt correctly,Get_Transform_Feedback_Varying returns the varying name as 'velocity_out' (no dot).

If no vertex array object has been previously bound Link succeeds but Validate fails.