-
Notifications
You must be signed in to change notification settings - Fork 5
OpenGL::Modern Development
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.
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.
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 (or OpenGL::GLU::Const and OpenGL::GLUT::Const) respectively. Another idea was to use the perl constant pragma which should allow the perl interpreter to optimize the constants away. I'm not sure this is reasonable since I don't know what happens to the unused constant values on compile...do they stay around leading larger executables or is the memory returned to the system keeping the perl runtime size small and lean?
The GLU library bindings need to be split into their own module. They should have been a separate package all along. Now that the tessellation support is in the core via tessellation shaders, it is clear that it is a separate functionality and deserves a package of its own.
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.
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, I propose factoring these 3 modules into separate perl modules. That lets OpenGL users to migrate to OpenGL::Modern while keeping the support structure from the existing OpenGL code base.
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::NextGen) 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.
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.
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.
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.
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 before, I have been unable to reach the maintainer of OpenGL::Shader for feedback or planning purposes.
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.
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.
OpenGL4.pm and other files use the experimental perl 'signatures' feature and appear to have support for older perl versions through the use of the Filter::signatures source filter. Is the use of signatures actually required for the implementation or is it mainly a convenience to simplify writing subs? If the use is not structural to the bindings, it would reduce the number of dependencies for the OpenGL::Modern bindings which could simplify the use and testing of the module.