Skip to content

OpenGL::Modern Development

devel-chm edited this page Feb 12, 2017 · 19 revisions

This page is a list of plans for development of OpenGL::Modern including the changes needed in the existing OpenGL modules to support the transition to modern OpenGL APIs and yet maintain the degree of back compatibility with the legacy implementation and to provide developers a reasonable upgrade path.


Legacy OpenGL issues

The current Perl OpenGL module implements bindings to the original OpenGL fixed-function rendering model. It includes support for modern API features such as buffers and shaders by the OpenGL extension mechanism. However, since OpenGL 3.1 the original OpenGL 1.x and 2.x functions have been deprecated and are only available in a compatibility mode which is unsupported and unsupportable for many new graphics devices such as cell phones and tablets. In addition, the OpenGL module includes a number of sub-modules that seemed necessary at the time. Now, it is clear that an implementation where these implicit dependencies become actual perl modules of their own will allow a cleaner implementation and allow legacy Perl OpenGL users to make use of OpenGL::Modern API features while keeping such implicit module functions available for use---at least until better options are implemented. Here is a list of issues by module.

OpenGL::Const

This provides XS bindings to the constants from OpenGL, GLU, and [Free]GLUT. The bindings for OpenGL constants can be replaced by the corresponding implementation from OpenGL::Modern which supports OpenGL APIs from 1.x through 4.x via its use of the GLEW library to generate the bindings code.

We need to split out the GLU and GLUT constants into OpenGL::GLU and OpenGL::GLUT.

OpenGL::GLU

The GLU library bindings have been released as their own package. CHM/OpenGL-GLU-0.01.tar.gz was released to CPAN on 12-Feb-2017.

OpenGL::GLUT

FreeGLUT/GLUT is the baseline GUI implementation for OpenGL application development. It was included in the Perl OpenGL module to provide symmetric support for Windows, Unix, and MacOS X platforms and simplify development. However, GLUT is still a GUI and not a requirement for OpenGL development. Perl OpenGL essentially forces a GLUT/FreeGLUT install as part of the OpenGL bindings. There are many other GUI libraries and toolkits that can use OpenGL for graphics. The implementation of the bindings is simplified by removing GUI specifics from OpenGL and placing them into their own package.

NOTE: We'll need to address the issues of getting a FreeGLUT install. I think it is finally time to get Alien::GLUT and Alien::FreeGLUT running.

OpenGL::Array, OpenGL::Matrix, and OpenGL::RPN

These three modules are implemented in the OpenGL module to provide helper routines to manage OpenGL buffer management, computation of ModelView matrix operations, and general computation with data buffers as may be required to implement buffer and shader operations.

To support forward compatibility, we will refactor these 3 modules into their own perl packages. That lets OpenGL users migrate to OpenGL::Modern while keeping the support structure from the existing OpenGL code base with the already implemented functionality.

For the future, it is clear that the functionality of these modules: data array objects, matrix computation, and buffer object computation are already provided by functionality in the Perl Data Language. The architecture and implementation for a Next Generation Perl Data Language (PDL::NG) is underway with goals of improved modularity, better type support, and a better implementation in performance and usability. At some point, I would expect that OpenGL::Modern users would use a module like PDL::Tiny or maybe an optimized PDL::OpenGL::Compute module with actual name TBD.


OpenGL::Modern

Object Oriented Implementation

For consistency and interoperability with current standards for Perl5 and Perl6 OO frameworks, I suggest using Moo and Moo::Role for OO rather than rolling our own implementation. Moo has the advantage of allowing Moose-ification to use the full meta-object protocol capabilities if needed. Moo[se] provides an OO framework which is very close to the Perl6 OO framework which might improve interoperability of Perl5 and Perl6 development and use of OpenGL::Modern and the related modules.

Buffer operations

The current implementation of data buffers and perl bindings in OpenGL::Modern (as from the original OpenGL::Glew in app-shadertoy is in the form of a packed string representation and data type. While this approach leads to simple coding, there are some potential problems with interoperability with other perl modules such as SDL and PDL.

While each may use a packed string representation "under the hood", it would seem to be clearer to have the buffer pointers be to some blessed object instead. That blessed type could then implement the appropriate interface as needed. This approach would also be completely general and flexible and could easily be extended to JIT compilation or other types of data creation and operations.

API function naming

There are a number of considerations in the perl subs of an OpenGL library binding. The bindings should be easy to understand, well documented, efficiently implemented, and simple to use but there is no requirement that they be the same as the native C function API. For example, there are many variants of OpenGL routines corresponding to differing input data types, and whether they are specified individually or as a vector. From the perl level, the interpreter can know the types and number of each of the arguments so having a perl-ish binding that just "does the right thing" is appealing. Unfortunately, such a high level "smart" implementation could be complicated to develop and verify. It might not perform as well and the difference from the standard could lead to confusion in usage.

The OpenGL module implemented the 1.x-2.x bindings with separate functions for each type of arguments. "_p" for perl type arguments, "_c" for direct C pointers to buffers, and "_s" for packed string representation as used by libSDL perl bindings and the Perl Data Language (PDL). This had the advantage that, aside from the "_[cps]" in the sub name, the routine names exactly matched the reference C API naming which meant existing OpenGL programmers could directly translate their code to perl. In addition, the on-line OpenGL documentation could be used to document the module routines with only the high level issues of "_c", "_p", and "_s" needing to be explained in the POD.

For the OpenGL::Modern bindings, I believe that the base perl subs can be implemented efficiently enough that the general user will not need to use function specializations for C pointers, SDL buffers, PDL data, or common perl-ish usages as was done in the OpenGL module implementation.

OpenGL::Texture and OpenGL::Image

These two modules appear to do similar things. It seems reasonable to merge the two into a single module which could maintain an appropriate degree of compatibility (is 100% possible?) while supporting OpenGL::Modern APIs. I have been unable to reach the maintainer of OpenGL::Image but maybe the new module could be OpenGL::Modern::Image or OpenGL::Modern::Texture or whatever. One idea that is worth maintaining from OpenGL::Image is the use of pluggable modules for different options for image support. The basic framework would be generic but the actual implementation could be whatever is appropriate or desired.

OpenGl::Shader::OpenGL4.pm and OpenGL::Shader

This is a similar story to the above: both modules make a more friendly perl-ish interface for working with shaders. Merging the best of both, maintaining compatibility as best possible into a new OpenGL::Modern::Shader seems like a reasonable plan. As above, I have been unable to reach the maintainer of OpenGL::Shader for feedback or planning purposes.

OpenGL::Modern::Types types support

From the high level perl view, the details of the OpenGL types used for rendering don't matter since a value is just a perl scalar. A buffer is just a data block of some size, etc. However, the reality is that hardware limitations and performance requirements mean that it does matter what data types are being used. For example, a compute shader computing values in GLdouble type would take twice as much memory per element and much longer to compute than one useing GLfloat values. I propose abstracting the type information into a module. Ideally, it would be compatible with Moo[se] types.


Update to baseline GUI from GLUT to GLFW

OpenGL::GLFW bindings

With support for so called "modern opengl" (i.e. OpenGL API versions 3.1 and higher which correspond to the shader-based rendering pipeline), we need to update the standard baseline GUI as well. GLUT/FreeGLUT bindings will continue to be supported but for cross-platform support of OpenGL, EGL, and Vulkan graphics, bindings for the GLFW library are needed. This will provide a lean, efficient, portable baseline window/context creation and basis user interaction features.

Truetype Font Support

As GLFW does not include font support, I propose implementing bindings to some type of text rendering library to enable users transitioning from GLUT to GLFW. One possibility is the FTGL library but there may be other possibilities. The idea is that there be an easy way to display text in their OpenGL applications.

Clone this wiki locally