Coder Social home page Coder Social logo

openglada's Introduction

OpenGLAda โ€“ OpenGL binding for Ada

Project Status: I do not have the time and energy to maintain this project anymore. Both this project and the corresponding Alire crates are unmaintained. I would be okay with someone taking over the project, feel free to contact me about it.

Overview

OpenGLAda is a thick OpenGL binding for the Ada 2005 programming language. Unlike other, thin, bindings (see the project's homepage for a list), OpenGLAda enriches the original API with concepts and features provided by Ada, like object orientation, type safety and generics.

OpenGLAda provides the following libraries:

Library name Alire crate name Description
opengl openglada The OpenGL binding itself
opengl-glfw openglada_glfw GLFW binding
opengl-text openglada_text Text rendering library
opengl-images openglada_images Image loading library

The library name is what you want to with in your .gpr file, e.g. with "opengl-glfw";. The Alire crate is how you refer to the library if you're using Alire, e.g. alr with openglada.

The GLFW binding requires the GLFW library. The Text rendering library requires the FreeType library. The Image loading library uses GID.

The GLFW and FreeType dependencies will be fetched automatically by Alire on Windows, Debian, Ubuntu and Arch Linux. On other systems, you need to make them available to the linker yourself.

OpenGLAda supports macOS, Windows and X11-based systems. API documentation can be found on the project's homepage.

Migrating from C

Compared to C, OpenGLAda provides the features of the following C libraries:

  • OpenGL

  • GLEW: OpenGLAda loads all post-OpenGL 1.1 subroutines dynamically via pointers, so that available features may be queried at runtime.

  • GLUT: Long deprecated, yet still referenced from articles about OpenGL. OpenGLAda provides an optional wrapper for the GLFW library that provides functionality similar to GLUT.

    Text rendering functionality superior to what GLUT provides are supplied by opengl-text.gpr with the help of the FreeType library.

  • Image loading: OpenGLAda includes the GID library for image loading.

Installation

OpenGLAda is designed to be used with the Alire package manager. You can instead install the projects via gprbuild + gprinstall. This needs to be done for each project you want to use.

Scenario Variables

OpenGLAda defines a number of scenario variables. Some are set automatically by Alire, others need to be changed manually with the -X command line parameter (either through alr or grpbuild).

The available variables are:

  • Auto_Exceptions: Configures exception handling:

    • enabled (default): After each call to OpenGL, OpenGLAda checks whether OpenGL has set an error flag and if it had, raises the corresponding exception.
    • disabled: The user has to query the error flag on their own.
  • mode: May take one of the following values:

    • debug (default): Compile the project with debugging symbols and without optimization.
    • release: Compile the project for a release environment.
  • Windowing_System: Automatically set by Alire. Sets the backend windowing system. Used for GLFW and also for system-dependent parts of the API (GLX, WGL, CGL):

    • x11: X Windowing System (Linux, BSD, etc)
    • windows: Microsoft Windows
    • quartz: Quartz Compositor (macOS)
  • GLFW_Linker_Param: Relevant for the GFLW binding. Define how you will link to GLFW. Default is -lglfw everywhere but on Windows with GLFW 3, in which case it is -lglfw3. No need to change this if the GLFW library is loaded via Alire.

  • FreeType_Linker_Param: Automatically set by Alire. Relevant for the text rendering library. Define how you will link to FreeType. Default is -lfreetype.

A typical Windows installation would be

$ cd opengl
$ gprbuild -p -XWindowing_System=windows -Xmode=release opengl.gpr
$ gprinstall -XWindowing_System=windows -Xmode=release opengl.gpr

Tests

The tests in this repository are small programs that are mainly used to check if the basic system is working. You can build them with

$ env GPR_PROJECT_PATH=opengl:opengl-glfw:opengl-images:opengl-text \
      alr build

The tests use Alire for fetching the dependencies, but do not use the Alire projects of the libraries. The Alire workspace for the tests is not meant to be published.

Examples

Examples are available in this repository.

Developer Documentation

I have written an article about the development of OpenGLAda on AdaCore's blog:

Binding Generation

OpenGL implementations do not necessarily provide the newest OpenGL version, but possibly some older one with some functionality of the newer versions provided as extensions. For OpenGLAda, this means that most OpenGL functionality cannot be linked against via the library loader, since loading the library would immediately fail if any function is not available, even if the user never calls it. Most notoriously, Windows does not provide any OpenGL functionality newer than 1.1 via library loading.

The remedy for this is that function pointers of newer OpenGL functions must be queried at runtime. This is a tedious process and similar for each function. For this reason, OpenGLAda uses a code generator to autogenerate the function pointer types and the code loading each function, as well as the code importing OpenGL 1.1 functions via library loading.

The code generator can be found in opengl/src/generator. It processes the files found in opengl/src/specs and creates the files found in opengl/src/generated. The generator is a tool used at compile-time for building OpenGLAda and of no interest to the general user. The generated files are checked in to version control. The generator also generates the markdown file which is the base for the function mapping list on the website.

The process of wrapping a new OpenGL function is:

  • Build the generator using gprbuild generator.gpr in the opengl directory.
  • Add the function specification to one of the *.spec files in opengl/src/specs.
  • Run ./generator in the opengl directory (or generator.exe on Windows), which runs the generator on the specs and generates the Ada code.
  • Check in the newly generated code along with the changed spec.

The *.spec files use a syntax similar to Ada.

License

OpenGLAda, as well as the Ada dependencies FreeTypeAda and GID, are distributed under the terms of the MIT License.

The Ada 2012 logo that is used in the images tests is distributed under the terms of the CC BY-ND 3.0 license, the original author is AdaCore.

openglada's People

Contributors

alkhimey avatar cre8or avatar flyx avatar jokesin avatar landgraf avatar onox avatar rashfael avatar rogermc2 avatar roldak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openglada's Issues

Lighting functions fail.

I can't get the following lighting functions to work:

if GL.Toggles.State (GL.Toggles.Lighting) = GL.Toggles.Enabled then
      GL.Toggles.Disable (GL.Toggles.Lighting);
end if; 
GL.Toggles.Enable (GL.Toggles.Lighting);

They fail with:

raised GL.ERRORS.INTERNAL_ERROR : gl-raise_exception_on_opengl_error.adb:30

The following from Mac OpenGL.Frameworks gl3.h seem OK?
GLAPI void APIENTRY glDisable (GLenum cap);
GLAPI void APIENTRY glEnable (GLenum cap);
From Mac OpenGL.Frameworks gl.h:
#define GL_LIGHTING_BIT 0x00000040
/* Enable /
/
GL_FOG /
/
GL_LIGHTING */
#define GL_LIGHTING 0x0B50

Project Builds Fail After Latest Git Pull

I updated my OpenGLAda with GitHub Desktop and later checked with git pull.
Seems to be a problem with OpenGL.Glfw
Now my builds fails with
Undefined symbols for architecture x86_64:
"_glfwCreateWindow", referenced from:
_glfw__windows__init in libGlfwAda.a(glfw-windows.o)
"_glfwDefaultWindowHints", referenced from:
_glfw__windows__hints__reset_to_defaults in libGlfwAda.a(glfw-windows-hints.o)
"_glfwDestroyWindow", referenced from:
_glfw__windows__destroy in libGlfwAda.a(glfw-windows.o)
etc.

GL.Types.Single_Pointers doesn't work

It seems OpenGLAda only supports VBO's with data of which each row has at most four elements. I'm trying to get it to accept arbitrary number (n) of elements. But so far it doesn't work.

I'm trying to port the gl_test-opengl3.adb example from using a Singles.Vector3_Pointers to a Single_Pointers type. In Load_Data I replace Triangle1 with:

Triangle1 : constant Single_Array
  := (-0.3,  0.5, -1.0,
      -0.8, -0.5, -1.0,
       0.2, -0.5, -1.0);

For now each row still has three elements, but I want to increase this later to six or eight.

In the body I have:

Load_Vectors (Array_Buffer, Triangle1, Static_Draw);
GL.Attributes.Set_Vertex_Attrib_Pointer (Attrib_Pos, 3, Single_Type, 3, 0);

What I get is a black screen instead of the colored triangle (I have removed the red triangle). Am I doing something wrong?

I have a second question: are the last two parameters of Set_Vertex_Attrib_Pointer the number of elements or the bit size of the rows? In C++ I have something like (with rows having eight elements, pointing at the last two elements, skipping the first six):

glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));

Do I need to manually use 'Size or System.Storage_Unit?

Problem Initializing vertex array

I declare
Vertex_Array : GL.Objects.Vertex_Arrays.Vertex_Array_Object;

then either
GL.Objects.Vertex_Arrays.Initialize_Id(Vertex_Array);
or
Vertex_Array.Initialize_Id;

Project builds OK but running produces
constraint error: raised CONSTRAINT_ERROR : erroneous memory access

I have no problems with GL.Objects.Buffers.Buffer variables which initialize_id, bind and run without error.

Context is:
type tWindow is new Glfw.Windows.Window with null record;
Main_Window : aliased tWindow;
Main_Window_Access : access tWindow := Main_Window'Access;

Main_Window.Init(Window_Width, Window_Height, "HelloTriangle");
glfw.Windows.Context.Make_Current(Main_Window_Access);

What am I doing wrong?
Regards,
Roger

Release v0.5

There have been some major changes since v0.4 has been released. Notably the complete overhaul of runtime loading and a lot of added examples. To get more people interested in OpenGLAda, it would be good to make a release.

This issue is for tracking down things to do before the next release.

Tasks:

  • Make sure the new runtime loading stuff is properly documented.
  • Evaluate whether there is code in the examples that could be moved into OpenGLAda itself (this is an invitation to @rogermc2 to propose stuff) Post-0.5
  • Make sure all examples work on all supported platforms; document working compiler versions.
    • Test Windows
      • AdaCore GNAT GPL 2017
      • TDM-GCC-64 (since AdaCore only provides 32bit)
    • Test macOS
      • AdaCore GNAT GPL 2017
      • GNUAda GNAT GCC too much work; if GNAT GPL works, chances are good this one works too
    • Test Linux
      Would like to, but I do not have a native Linux system I can use, and trying to setup a VirtualBox that is able to run OpenGL has been proven too much of a pain.
    • Add instructions for each platform about how to install the compiler and dependencies (GLFW, FTGL).
  • Review API documentation and add missing stuff if necessary.

Unable to push new branch

I tried using your procedure but had a couple of problems and am stuck at the moment being unable to push.

if you do not already have my repo as remote

git remote add upstream https://github.com/flyx/OpenGLAda.git -- OK

switching git branches will remove commited files that do not exist

in the other branch. to carry over the files you want to commit from

your current branch, save them somewhere else

mkdir tmp && cp -r examples/durian/hello tmp

now make a new branch based on my master. It will not have all

your old commits in the history

git checkout -b hello-example upstream/master -- Failed
This command wouldn't work. It complained:
"fatal: Cannot update paths and switch to branch 'hello-example' at the same time."
I used git branch hello-example to generate the branch then git checkout hello-example which seems to have worked?

copy back the things you want to commit

cp -r tmp/hello examples/durian

commit them (you may want to change .gitignore before this)

git add examples/durian -- OK

After this I ran git commit (based on instructions from git-scm documentation)

push the branch to your GitHub to be able to make a PR

git push origin hello-example -- Failed
produced:
remote: Permission to flyx/OpenGLAda.git denied to rogermc2.
fatal: unable to access 'https://github.com/flyx/OpenGLAda.git/': The requested URL returned error: 403
Apparently I don't have write-acces to "origin"?

I deleted my rogermc2/OpenGLAda then forked a new one wjich is currently "clean".
I notice "push the branch to your GitHub" which doesn't seem consistent with "origin" which I understand to be flyx/OpenGLAda.
"your GitHub" seems to indicate rogermc2/OpenGLAda? In which case, how do I push to it?

I find the git-scm documentation quite good but difficult to find what to do in a particular situation.
Your procedure helped considerably as a guide to the relevant sections of the documentation.

If I can get this one sorted out, it will provide me with a good recipe for future PRs.
It turns out GitHub Desktop is definitely unsuitable from my point of view.
The command line approach provides a much more obvious indication of how things should be done.
I found the git status command particularly useful.
Currently git log produces:
commit c9c7e4fe93805ee6cd33f46b17f96e01541941ef
Author: Roger [email protected]
Date: Fri Mar 3 15:22:19 2017 +1100

Updated .gitignore to ignore Durian hello application file.

commit 189fa2d362a9bd5b4188990c0c4e3af871425aaf
Author: Roger [email protected]
Date: Fri Mar 3 15:18:15 2017 +1100

Add new example to Durian: hello

commit be86936
Author: Felix Krause [email protected]
Date: Wed Mar 1 18:40:33 2017 +0100

More generator improvements 

Problem with Texture_2D.Load_From_Data

I'm having a problem with Texture_2D.Load_From_Data which raises CONSTRAINT_ERROR : erroneous memory access
Attached is a minimal program that includes a local C interface to glTexImage2D
which also raises CONSTRAINT_ERROR : erroneous memory access

Minimal Tex Image C.zip

Geometric Algebra Examples

I originally got interested in OpenGL because of its use in the book, Geometric Algebra for Computer Science because of my interest in geometric algebra.
I have started using OpenGLAda to program the examples in the book and thought that it might be useful to include my solutions as OpenGLAda examples if this is OK with you.
I am developing the examples completely in OpenGLAda including developing the Geometric Algebra framework completely in Ada which will be based on the book's C++ framework (sandbox).
My idea for the directory structure is:
examples
geometric_algebra
sandbox 1_1_<example 1.1 name> 2_1_<example 2.1 name> ........
There are also exercises (exercise 2.1, etc.) associated with the chapters, but I haven't figured out how to include them yet.

Geometric Algebra for Computer Science website:
http://www.cgl.uwaterloo.ca/smann/GA/reference_impl.html

How do I get scroll data?

I have been unable to figure out how to get scroll x, y data as a replacement for the C callback routine

void scroll_callback(GLFWwindow* window, double x, double y);

How to implement?

Non-existing procedure Load_UV_Buffer in examples

There are multiple references to a procedure Utilities.Load_UV_Buffer which does not exist:

  • examples/geometric_algebra/reference_implementation/src/ga_draw.adb (2 mentions)
  • examples/durian/buffers_and_textures/src/my_buffers.adb (1 mention)

Please have a look @rogermc2 .

Problem with type Buffer_Target

Mac OSX 10.11.6
Xcode 8.0

GPS 2016 (20160515) hosted on x86_64-apple-darwin14.5.0
GNAT GPL 2016 (20160515-49)

OpenGLAda-master 30 June 2016

I am stuck with a problem trying to use gl.Objects.Buffers.Buffer_Target which I can't solve.

type tTarget is new gl.Objects.Buffers.Buffer_Target(gl.Low_Level.Enums.Element_Array_Buffer);
produces "type derived from tagged type must have extension" which makes sense.

However, when I try
type tTarget is new gl.Objects.Buffers.Buffer_Target(gl.Low_Level.Enums.Element_Array_Buffer) with null record;
GPS responds by opening System.ads and complaining:
system.ads:1:01: subtype mark required in this context

This also occurs for
type tTarget is new gl.Objects.Buffers.Buffer_Target(gl.Low_Level.Enums.Element_Array_Buffer) with
record

end record;

syntax check does not produce the problem:
gprbuild -c -gnatc -u -eL -P/OpenGL_Projects/GLFW Tutorial/Tutorial 1/glfw_tutorial_1.gpr -XLIBRARY_TYPE=static -XAuto_Exceptions=enabled -XMode=debug buffers.adb -s

The problem occurs when compiling:
gprbuild -c -u -eL -P/OpenGL_Projects/GLFW Tutorial/Tutorial 1/glfw_tutorial_1.gpr -XLIBRARY_TYPE=static -XAuto_Exceptions=enabled -XMode=debug buffers.adb -s

Bind various glDepth* and glStencil* functions

Following functions are not binded:

  1. glStencilFuncSeparate (OpenGL >= 2)
  2. glStencilOpSeparate (OpenGL >= 2)
  3. glStencilMaskSeparate (OpenGL >= 2)
  4. glDepthMask (OpenGL >= 1)
  5. glDepthFunc (OpenGL >= 1)
  6. glDepthRangeArray (OpenGL >= 4)
  7. glDepthRangeIndexed (OpenGL >= 4)

Note: glStencil* (is glStencil*Separate with face set to GL_FRONT_AND_BACK)

What would be a good (new) package to put this functions in? (With actual bindings in gl-api.ads)

How to stop gpr file importing scenario data?

Whenever GNAT GPS saves a .gpr file after its initial generation it includes scenario information apparently inherited from opengl-glfw.gpr, opengl.gpr and opengl_shared.gpr which means that before committing updates I have to manually edit .gpr files to remove the scenario data or regenerate the project which produces a .gpr file containing only the required data (that is, without scenario data).
Is there any way of preventing GNAT GPS from including scenario data in my .gpr files?

OpenGL.Soil build failure under OSX El Capitan, XCode 8.0

Compilation of the file : /System/Library/Frameworks/CoreGraphics.framework/Headers/CGFont.h
fails on my system with:
CGFont.h:53:40: error: initializer element is not constant
static const CGFontIndex kCGGlyphMax = kCGFontIndexMax;

but kCGFontIndexMax certainly (to me) looks like a constant:
typedef unsigned short CGFontIndex;
static const CGFontIndex kCGFontIndexMax = ((1 << 16) - 2);
static const CGFontIndex kCGGlyphMax = kCGFontIndexMax;

Googling indicates that this failure is not specific to my system.
I see that there are two Frameworks/CoreGraphics.framework/Headers/CGFont.h on my system.
One in /Library/Developer/CommandLineTools and one in /System/Library
with header files dated 8 Feb 2016 in the first and 2 Nov 2016.
I am aware that Apple are forever reorganizing there system file structures but haven't been able to find what their current preferred organization is.
However, a comparison of the two CGFont.h files indicates no difference at least up to line 53.

Any ideas welcome.

Linking gl functions that are not available during compilation

PS D:\My Documents\Code\OpenGLAda> gprbuild -P glfw_test.gpr   -XWindowing_System=windows -XGLFW_Version=3
gprbind glfw_test-monitors.bexch
gnatbind glfw_test-monitors.ali
gcc -c b__glfw_test-monitors.adb
gprbind glfw_test-windows.bexch
gnatbind glfw_test-windows.ali
gcc -c b__glfw_test-windows.adb
gprbind glfw_test-clipboard.bexch
gnatbind glfw_test-clipboard.ali
gcc -c b__glfw_test-clipboard.adb
gprbind glfw_test-mouse.bexch
gnatbind glfw_test-mouse.ali
gcc -c b__glfw_test-mouse.adb
gcc glfw_test-monitors.o -lglfw3 -lwinmm -lgdi32 -lOpenGL32 -lOpenGL32 -lGdi32 -o glfw_test-monitors.exe
gcc glfw_test-windows.o -lglfw3 -lwinmm -lgdi32 -lOpenGL32 -lOpenGL32 -lGdi32 -o glfw_test-windows.exe
gcc glfw_test-clipboard.o -lglfw3 -lwinmm -lgdi32 -lOpenGL32 -lOpenGL32 -lGdi32 -o glfw_test-clipboard.exe
gcc glfw_test-mouse.o -lglfw3 -lwinmm -lgdi32 -lOpenGL32 -lOpenGL32 -lGdi32 -o glfw_test-mouse.exe
D:\My Documents\Code\OpenGLAda\lib\libOpenGLAda.a(gl-blending.o): In function `gl__blending__set_blend_equation':
D:/My Documents/Code/OpenGLAda/src/gl/implementation/gl-blending.adb:99: undefined reference to `glBlendEquation@4'

Windows with the libre Ada 2016 toolchain. (OpenGL 4.4+ is available on the system)

Problem Clearing Framebuffer

I am trying to implement:
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, 512, 512);
glClearBufferfv(GL_COLOR, 0, sb7::color::Green);
By:
Read_And_Draw_Target.Bind(Frame_Buffer);
GL.Window.Set_Viewport(0, 0, 512, 512);
gl.Buffers.Clear((True, False, True, True));
gl.Buffers.Set_Color_Clear_Value(Green);
but
gl.Buffers.Clear((True, False, True, True)); raises the exception
GL.ERRORS.INVALID_FRAMEBUFFER_OPERATION_ERROR : gl-raise_exception_on_opengl_error.adb:26
I have declared:
subtype tFrame_Buffer is GL.Objects.Framebuffers.Framebuffer;
Frame_Buffer : tFrame_Buffer;
Green : GL.Types.Colors.Color := (0.0, 1.0, 0.0, 1.0);

gl.Buffers.Set_Color_Clear_Value(Green); seems OK as no error occurs when I comment out the gl.Buffers.Clear line.
This code works OK for the default framebuffer (Read_And_Draw_Target.Bind(Default_Framebuffer))
I have also tried
gl.Buffers.Clear_Color_Buffers(gl.Buffers.Back, Green);
but this also raises an error.

Many examples are choking

On windows 10, every ogl_tutorials gives the following:

OpenGL version supported: 3. 2
Renderer: GeForce GTX 750 Ti/PCIe/SSE2
Primary_Shading_Language_Version: 1.50 NVIDIA via Cg compiler

An exception occurred in Setup.
An exception occurred in Render.
An exception occurred in Main_Loop.
Tutorial_03 returned a constraint error: Exception name: CONSTRAINT_ERROR
Message: gl-objects-programs.adb:274 access check failed

Note: Actually, gl_test-immediate.exe works but every other gl-test-xxxxx returns an acces check failed.

Am I doing something wrong?

Thx.

GL.Objects.Shaders.Source doesn't like being called twice on the same list item.

Attached is a program that I've simplified as much as possible to demonstrate that GL.Objects.Shaders.Source doesn't like being called twice on the same list item.
When the procedure Show_All_Shader_Program_Data contains both calls to GL.Objects.Shaders.Source, the program terminates with:

/OpenGL_Projects/GLFW Tutorial/Test/test
#version 400
in vec3 vp;
void main()
{
gl_Position = vec4(vp, 1.0);
}
Leaving Show_All_Shader_Program_Data.
An exceptiom occurred in Tutorial_1.
raised PROGRAM_ERROR : my_buffers.adb:49 finalize/adjust raised exception
raised PROGRAM_ERROR : finalize/adjust raised exception
[2016-12-07 18:24:41] process exited with status 1, elapsed time: 02.14s

When the procedure Show_All_Shader_Program_Data contains only one call to GL.Objects.Shaders.Source, the program terminates successfully.
Test.zip

In need of glCompressedTexImage2D

I'm in need of glCompressedTexImage2D which is declared in OpenGL.frameworks gl3.h.
SOIL seems to provide a dead end, I think:
typedef void (APIENTRY * P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data);
P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC soilGlCompressedTexImage2D = NULL;
which I don't fully understand.

In the meantime I've made a thin binding based on your API procedure Tex_Image_2D.

High-Level API for text rendering

Using the FTGL binding is not flexible enough and should be deprecated. Instead, we should implement an own high-level text rendering API based on the new FreeType binding.

I started implementing this and got it to a level where text is rendered onto a texture. However, it is not completely working and I hope @rogermc2 can be of some assistance since my OpenGL is a bit rusty.

Current test program can be compiled with opengl-freetype-test.gpr. It depends on Strings_Edit for parsing UTF-8 input (so that we can render arbitrary unicode characters). TODOs:

  • figure out why the example only renders the text correctly after resizing the window once.
  • figure out how to properly color the texture the text is rendered into.
  • do some renaming. GL.FreeType should probably be simply GL.Text. Some types therein are also in need of renaming.
  • provide a way for the user to configure text size (currently hardcoded).
  • maybe do not render to a color texture, but instead to a red-only texture like the original character bitmaps are.
  • catch the case that a character is not available in the font. Maybe render a ? instead.
  • documentation

I look forward to your comments, @rogermc2 .

glTexSubImage2D needed

glTexSubImage2D does not appear to have been implemented.
glIsTexture would also be nice to have.
I will try following the Readme instructions on autogeneration to implement glTexSubImage2D.

Problem Drawing Quads

I am trying to draw quads, but the following code fails:
Draw_Elements (GL.Types.Quads, GL.Types.Size (Vertex_Data.Num_Elements), UInt_Type);
with "raised GL.ERRORS.INTERNAL_ERROR : gl-raise_exception_on_opengl_error.adb:30"

It runs without error when Quads is replaced with Points, Lines, Line_Loop, Line_Strip, Triangles, Triangle_Strip, Triangle_Fan, Lines_Adjacency, Line_Strip_Adjacency, Triangles_Adjacency or Triangle_Strip_Adjacency.

It also fails with Quad_Strip, Polygon and Patches.

Trouble reading pixel data

I am having a problem trying to "read pixels" with the following code:

   type Pixels_Array is array (Positive range <>) of aliased Integer;
   procedure Read_Pix is new
     GL.Framebuffer.Read_Pixels (Element_Type => Integer,
                                 Index_Type   => Positive,
                                 Array_Type   => Pixels_Array);

...

      Pixel_Data      : Pixels_Array (1 .. 4);

.....

Read_Pix (1, 1, 1024 / 2, 768 / 2, GL.Pixels.RGBA, GL.Pixels.Unsigned_Byte, Pixel_Data);

The above code produces the warning:

main_loop.adb:145:07: warning: variable "Pixel_Data" is read but never assigned

This suggests that Read_Pix is reading from Pixel_Data instead of writing to it as glReadPixels is specified to do.
OpenGLAda declarations for Read_Pixels appear OK.
Am I doing something wrong?

Unable to build OpenGLAda libraries.

Suddenly my builds are failing when attempting to build OpenGLAda libraries.
I tried on a couple of my branches with the same result.

gprbuild -d -eL -P/Ada_Source/OpenGLAda/opengl.gpr -XLIBRARY_TYPE=static -XAuto_Exceptions=enabled -XMode=release -XWindowing_System=quartz -s -XWindowing_System=quartz --create-missing-dirs --config=/Ada_Source/config.cgpr
Build Libraries
[gprlib] OpenGLAda.lexch
gprlib: unknown section: [PROJECT DIRECTORY]
gprbuild: could not build library for project opengl

opengl-glfw.gpr does not link with libdl

I got the following error:

$make tests
mkdir -p bin
gprbuild  -p -P glfw_test.gpr -XWindowing_System=x11 -XGLFW_Version=3
gcc-4.6 glfw_test-monitors.o -lglfw3 -pthread -lm -lXcursor -lXxf86vm -lXrandr -lXinerama -lXi -lGL -lX11 -o glfw_test-monitors
/usr/bin/ld: //usr/local/lib/libglfw3.a(glx_context.c.o): undefined reference to symbol 'dlopen@@GLIBC_2.1'
//lib/i386-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: ld returned 1 exit status
gprbuild: link of glfw_test-monitors.adb failed

Adding "-ldl" flag to linker options of opengl-glfw.gpr file solved the problem.

Make runtime loading more efficient

runtime loading is the process of loading pointers to OpenGL functions at runtime. This is done for multiple reasons:

  • Different implementations provide different portions of the OpenGL API. Linking and executing an OpenGL program should be possible even if unused functions are not available.
  • It should be possible for an application to switch to some backup implementation if a fancy feature is not available.
  • On Windows, all functionality not available in OpenGL 1.1 must be loaded dynamically because there are no symbols for newer functions available.

The currently implemented runtime loading in OpenGLAda works as following:

  1. All OpenGL functions beyond OpenGL 1.1 are wrapped with generic subroutines from GL.Runtime_Loading.
  2. Each time such a subroutine is called, it looks up a string containing the actual OpenGL function name in a hashmap.
  3. If no such key exists, it asks the OS for a function pointer to that OpenGL function and inserts that function pointer into the hashmap.
  4. Finally, it fetches the function pointer from the hashmap, calls it, and returns the result (if any).

While hashmaps are almost O(1), this process is certainly not ideal, since every function call will result in a hashmap lookup. Since OpenGL applications typically care for performance, this should be improved. A possible solution is as follows:

  • Every non-OpenGL-1.1 function in GL.API will be transformed into a variable of the respective function pointer type.
  • The code currently calling these functions will call the function pointers.
  • At some point of program execution, OpenGLAda shall query the function pointers from the OS and fill them in to those variables. After that, every call will go direct to the OpenGL function.

The question is where these function pointer variables shall be assigned a value. There are two feasible solutions I can think of:

  1. All function pointers are assigned an appropriate loader subroutine at elaboration time. This will cause the GL package and all dependent packages to lose pragma Preelaborate;. This may break existing code. The loader subroutines will, when called, query the actual function pointer from the OS, overwrite the function pointer variable, and then call it. So only the first call results in a slowdown; after that, the OpenGL implementation is called directly. This solution is safer than the second one because it ensures that there are no uninitialized pointer variables that may be dereferenced.
  2. GL gains a procedure Initialize which will load the function pointers. This will keep pragma Preelaborate;, but requires the user to explicitly call it once after they created an OpenGL context.
    The library GLEW which does runtime loading for C/C++ goes this way. However, a call to it may be integrated into GLFW.Create_Window which seems to be used by most OpenGLAda users. This solution is simpler and more straight-forward; it also makes sure that all workload is placed into the Initialize procedure and no lazy loading occurs during the execution.

Since I have no real preference, I'd like to have some opinions on this from current OpenGLAda users (@rogermc2, @onox, @alkhimey, @WickedShell).

Unable to make on Mac OS X Lion (Missing libs)

Hi, I just cloned this repo and I got these errors during the "make test":

gcc glfw_test-monitors.o -lglfw3 -Wl,-framework,Cocoa,-framework,IOKit -Wl,-framework,OpenGL,-framework,CoreFoundation -o glfw_test-monitors
ld: library not found for -lglfw3
collect2: error: ld returned 1 exit status
gprbuild: link of glfw_test-monitors.adb failed
make: *** [tests] Error 4

Any ideas how I could fix this? Where can I find lglfw3 libraries?
Im using Mac OS X 10.9.1 with command line tools and gnatmake installed.
Thank you for all the hard work that you have done! ๐Ÿ‘

glNormal3fv not implemented?

glNormal3dv seems to be the only glNormal3 implemented.
glNormal3dv is implemented as GL.Immediate.Set_Normal via GL.API.Normal.
Probably not a problem if I use this GL.Immediate.Set_Normal.
However, I notices from Immediate API in GL-API.spec that Immediate functions are deprecated so I'll try and figure out the current way of using normals.

Tessellation Patches Not Implemented.

I am trying to learn OpenGL from the book OpenGL Superbible which introduces Tessellation quite early.
However, OpenGLAda doesn't seem to support tessellation shader programming as, for example, there is no Patches Connection_Mode item which, apparently, is needed when calling Draw_Arrays for a GSL program incorporating tessellation shaders.
Is there a way around this?
If not I'll skip the section on tessellation as I don't really need it for my own purposes at the moment.

The GL.Objects.Shaders documentation on the web page doesn't mention Initialize_Id

Problem page: https://flyx.github.io/OpenGLAda/gl-objects-shaders.html

This caused me a bit of a headache to track down. As far as I can tell by looking at the examples in this repo, both shaders and GL programs need to be initialised by calling Initialize_Id on them before use, but that page of the GitHub site doesn't mention this at all. It's not in the text nor the code example.

It has this (shortened):

declare
   Vertex_Shader   : GL.Objects.Shaders.Shader (Kind => GL.Objects.Shaders.Vertex_Shader);
   Fragment_Shader : GL.Objects.Shaders.Shader (Kind => GL.Objects.Shaders.Fragment_Shader);
   Program         : GL.Objects.Programs.Program;
begin
   -- load and compile shaders
   GL.Files.Load_Shader_Source_From_File (Vertex_Shader, "vertex.glsl");
   GL.Files.Load_Shader_Source_From_File (Fragment_Shader, "fragment.glsl");
   ...

This exact code causes a constraint error in Raw_Id when it's called by Load_Shader_Source_From_File. I suppose that's because the ID defaults to -1 and its type is UInt, but I don't know specifically.

The example code should be amended to at least have something like this:

declare
   ...
begin
   -- initialise
   Vertex_Shader.Initialize_Id;
   Fragment_Shader.Initialize_Id;
   Program.Initialize_Id;

   -- load and compile shaders
   GL.Files.Load_Shader_Source_From_File (Vertex_Shader, "vertex.glsl");
   GL.Files.Load_Shader_Source_From_File (Fragment_Shader, "fragment.glsl");
   ...

The actual text on that page also describes a step-by-step process for using shaders, and it completely fails to mention Initialize_Id, so I think that should be updated too.

As far as I can tell that GitHub site doesn't have a public repo, so I'm putting this issue here.

GL.Objects.Shaders.Info_Log returns Constraint_Error

Mac OSX 10.11.6
XCode 8.0
GPS 2016 (20160515) hosted on x86_64-apple-darwin14.5.0
GNAT GPL 2016 (20160515-49)
Build Command:
gprbuild -d -eL -P/OpenGL_Projects/GLFW Tutorial/Tutorial 1/glfw_tutorial_1.gpr -XLIBRARY_TYPE=static -XAuto_Exceptions=enabled -XMode=debug -s -XWindowing_System=quartz
Build Libraries

GLFW Version: 3.2.1 Cocoa NSGL chdir menubar retina dynamic
OpenGL version supported: 3. 3
Renderer: Intel HD Graphics 3000 OpenGL Engine
Primary_Shading_Language_Version: 3.30

In the attached file:
if Compile_Shader(Vertex_Shader) then
Put_Line("Vertex shader compiled.");
Put_Line(GL.Objects.Shaders.Info_Log(Vertex_Shader));
produces:
Vertex shader compiled.
Load_Buffer returned constraint error: raised CONSTRAINT_ERROR : gl-objects-shaders.adb:77 range check failed

I have tried GL.Objects.Shaders.Info_Log in many locations with the same result.

I had to change the file extension from adb to txt to get the file to upload.
my_buffers.txt

`Renderer.To_Texture` Problem

Since merging the latest Develop branch, programs calling Renderer.To_Texture fail with:

Texture_Management.Render_Text calling Renderer.To_Texture
An exception occurred in Texture_Management.Render_Text.
An exception occurred in Main_Loop.
Render_Text returned a constraint error: 
raised CONSTRAINT_ERROR : gl-objects-framebuffers.adb:256 access check failed

The exception occurred in Texture_Management.Render_Text message appears to have been generated by a call to Renderer.To_Texture.
This problem occurs both in the example program Text_Rendering_2 and another project.
I inserted the Texture_Management.Render_Text calling Renderer.To_Texture message for debugging purposes, a similar line also being added following the call to Renderer.To_Texture which, of course, did not execute.

Problem with Load_Empty_Texture

I'm trying to implement
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
in which GL_UNSIGNED_BYTE specifies the data type of the pixel data (GL_RGB).

Texture_2D.Load_Empty_Texture
(Level => 0, Internal_Format => GL.Pixels.RGB,
Width => 1024, Height => 768);
raised GL.ERRORS.INTERNAL_ERROR : gl-raise_exception_on_opengl_error.adb:30

gl-raise_exception_on_opengl_error.adb:30 indicates that INTERNAL_ERROR is due to an Invalid_Enum:
when Errors.Invalid_Enum => raise Errors.Internal_Error;

The pixel data type specified by API.Tex_Image_2D is Pixels.Data_Type'First which appears to me to be Byte not Unsigned_Byte (Pixels.Data_Type second).

My investigations indicate that GL_RGB can take that values 0..255 indicating that pixel data type for RGB in this context should be Unsigned_Byte.

Is this the problem?
Probably not; I tried changing Pixels.Data_Type'First to Pixels.Unsigned_Byte in GL.Objects.Textures.With_2D_Loader.Load_Empty_Texture's call to API.Tex_Image_2D but the same error occurred.
As usual, am I misunderstanding something?

Problem extracting elements from Shaders.Lists.List lists due to discriminated list elements

The program builds OK but fails when run with:
Load_Buffer returned constraint error: raised CONSTRAINT_ERROR : gl-objects-shaders.adb:50 length check failed
This occurs only when I include
Utilities.Show_All_Shader_Program_Data(Shader_Program);
at the end of the Load_Buffer procedure which builds the shader program then draws the main window.
Utilities.Show_All_Shader_Program_Data(Shader_Program) runs after I close the main window.

I've cut much out of the Show_All_Shader_Program_Data procedure to simplify debugging.
The program runs OK to completion when I delete
Shader_Source : String := Shaders.Source(Shaders.Lists.Element(List_Cursor));
which I hoped to use to get the current shader's Shader_Type and also seemed (to me so far) to be the simplest way to demonstrate the problem.

procedure Show_All_Shader_Program_Data(aProgram : gl.Objects.Programs.Program) is
use GL.Objects;
Shaders_List : Shaders.Lists.List := Programs.Attached_Shaders(aProgram);
List_Cursor : Shaders.Lists.Cursor := Shaders_List.First;
Shader_Source : String := Shaders.Source(Shaders.Lists.Element(List_Cursor));
begin
Put_Line("GL_ATTACHED_SHADERS: ");
while Shaders.Lists.Has_Next(List_Cursor) loop
List_Cursor := Shaders.Lists.Next(List_Cursor);
end loop;
exception
when anError : Constraint_Error =>
Put("Show_All_Shader_Program_Data returned constraint error: ");
Put_Line(Exception_Information(anError));
when anError : GL.Errors.Invalid_Operation_Error =>
Put_Line("Show_All_Shader_Program_Data returned an invalid operation error: ");
Put_Line(Exception_Information(anError));
when anError : others =>
Put_Line("An exceptiom occurred in Show_All_Shader_Program_Data.");
Put_Line(Exception_Information(anError));
end Show_All_Shader_Program_Data;

I'm surprised the problem doesn't raise a Show_All_Shader_Program_Data exception?
I actually want to print out the Attached_Shaders list but can't see how to process out the different type of shaders.

Is this enough or do you need the complete Load_Buffer procedure?

Get_Cursor_Mode not fully implemented?

Set_Cursor_Mode is implemented in Glfw.Windows but not Get_Cursor_Mode although Get_Input_Mode does appear in glfw-api.
I have now implemented Get_Cursor_Mode in my wave_example branch as:

function Get_Cursor_Mode (Object : not null access Window)
                             return Input.Mouse.Cursor_Mode is
   begin
      return API.Get_Input_Mode (Object.Handle, Enums.Mouse_Cursor);
   end Get_Cursor_Mode;

glfw puzzle

  1. Instructions on how to install glfw would be great. Right now I am on windows.

a) glfw 2.x.x is not available for download at official site anymore. Maybe remove binding to version 2.
b) if I am not mistaken, in all case, we need the mingw 32 bits version of the bins. Like 4 others type of bins are hand out in the distribution zip archive.
c) the simpler I found was to c&p the glfw bins right next to ld.exe used by my gnat installation. Probably there is better way but never learned how.
d) In opengl_glfw.gpr this snippet does not work:
when "3" =>
GLFW_Sources := GLFW_Sources & "src\glfw\v3";
Shared_Test_Sources := Shared_Test_Sources & "tests/shared/glfw3_backend";
GLFW_Lib := "-lglfw";

We should read GLFW_Lib := "-lglfw3";

Thx.

Translation Problem With Vertex Shader

square_test_minimal.zip
I have run into a problem involving the drawing of vertical square (plane) using a translation transformation (MV) followed by an orthographic transformation (P). (MVP = P * MV)
The problem is that the translated square is rendered as a trapezoid instead of a square.
When translating along the x axis, the vertical sides of the rendered object are parallel as expected but, in the horizontal direction, the vertical size decreases from left to right.
This occurs when the matrix multiplication is done in the Ada program and also when it is done in the shader program.
However, when done in the shader program the effect is worse.
I have checked, using Mathematica, that the MVP matrix generated should transform a square to a square.
The MVP matrix generated by the Ada program also seems correct has it has the scaling factors for both X and Y are equal.
No problem occurs when rotating the square using a rotation transformation followed by an orthographic projection.
I also checked that the scaling transformation works correctly.
Also if I change the square's coordinates to the required translated coordinates then perform only an orthographic projection the square renders correctly.
It is as if the MVP matrix is getting corrupted in being provided to the shader or that the shader operation is faulty. This seems unlikely as so many other operations occur correctly.
A minimal version of my program is #attached.
square_test_minimal.zip

glBindFragDataLocation needed?

I came across glBindFragDataLocation in the source code for a tutorial.
However, glBindFragDataLocation was not mentioned in the tutorial itself so, at the moment, I'm not absolutly sure whether it's needed or not.
I tried making a thin bind but it didn't work.
If it is needed, I think it needs to be incorporated into common/program_loader Program_From ahead of Shader_Program.Link;

Program requires gnat2012

My example durian/buffers_and_textures no longer compiles under GNAT 2017, failing with:

Compile
   [Ada]          my_buffers.adb
my_buffers.adb:98:19: iterator is an Ada 2012 feature
my_buffers.adb:98:19: unit must be compiled with -gnat2012 switch

However, I cannot set this switch.

Problem setting Singles.Vector3 uniform

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?

glPointSize Not Implemented

glPointSize is not implemented.
This is not a problem for simple programs as point size can be specified in vertex shader programs.
However, if possible, implementation might be nice for completeness?

How to render text via modern shader method?

After considerable effort I remain unable to figure out how to obtain access to bitmap glyph image data:

face->glyph->bitmap.buffer

which I need for:

Texture_2D.Load_From_Data  (0, RGB, GL.Types.Int (Data.Width),
                                  GL.Types.Int (Data.Height), Red,
                                  Unsigned_Byte, Image_Address);

Image_Address being the address of a bitmapped character glyph.
FTGL provides access to necessary character parameters, such as width and height, but doesn't seem to provide access to character glyphs which is available in C++ via the FTGlyphContainer function:

const FTGlyph* const Glyph(const unsigned int characterCode) const;

This seems to be an appropriate function for obtaining the glyph of a character for use in a modern OpenGL shader texture which I would like to provide by means of a FTGL function such as ~~~ function Get_Glyph (char : Character) return System.Address ~~~

The FTGL C interface seems designed only for the deprecated immediate pipeline use.
Advice on solving this problem will be greatly appreciated.

The code I am trying to implement is based on https://learnopengl.com/#!In-Practice/Text-Rendering. My initial need is for bitmapped characters.
The relevant code is:

  glTexImage2D
         (  GL_TEXTURE_2D,
            0,
            GL_RED,
            face->glyph->bitmap.width,
            face->glyph->bitmap.rows,
            0,
            GL_RED,
            GL_UNSIGNED_BYTE,
            face->glyph->bitmap.buffer
         );

I am close to completion but am stopped by my inability to access glyphs.

Problem Binding Texture

Initially a problem for me but I found a way which may or may not be right.
GL.Objects.Textures.Bind (Target : Texture_Target; Object : Texture'Class);
Is this the correct way of declaring a Texture_Target?
Texture_2D_Target : GL.Objects.Textures.Texture_Target(GL.Low_Level.Enums.Texture_2D);

Vector 5 arrays

Some examples use arrays of vector 5 singles.
3 elements are for position and 2 for texture (UV).
Can vector5 arrays be provided to support this?

Problem with GL.Objects.Buffers.Get_Sub_Data

GL.Objects.Buffers.Get_Sub_Data implements glBufferSubData via API.Buffer_Sub_Data.

GL.API.Buffer_Sub_Data := Load_T107("glBufferSubData");

According to my reading, glBufferSubData "Replaces a subset of a buffer object's data store with new data" suggesting that Get_Sub_Data should be Set_Sub_Data or Load_Sub_Data.
When I attempted to use Get_Sub_Data, compilation failed complaining that the target, GL_ARRAY_BUFFER, needs to be a variable.
I managed to get my program to compile by deleting "in out" from "Target : in out Buffer_Target".
This compares with the declaration for Load_To_Buffer.
The line of code that I am trying to implement is:

 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); 

As I still haven't been able to get my program to work, I'm not sure whether or not this is a problem.

Matrix Multiplication

After working with right multiplication for a while I've realized that left multiplication could probably be implemented by reversing the order of multiplication in the matrix multiplication routines. That is, implement * (left, right) by right * left multiplication.
This would then provide for left multiplication which is generally conventional in mathematics, physics and engineering as well as computer graphics theory. That is, R(object) rather than (object)R.
This would also be consistent with GLSL as, when coding shaders, multiplication is left right even though the matrix convention is column, row order.
For example, projection * view in shaders whereas in OpenGLAda I have to use view*projection.
Therefore, if possible, can the matrix multiplication routines be changed to implement this?

file "strings_edit.ads" not found

This package is mentioned several times but not implemented in this project.
I guess it's some third party stuff (there is a such named project on sourceforge by dmitry-kazakov, but how to guess).
Some clarification should be done on this cause no example compiles without it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.