Using Legacy OpenGL and Modern OpenGL in One Application

I have a working laptop that supports OpenGL 2.1, and I have a desktop in my house with OpenGL 4.4. I am working on a project on my desktop. Therefore, I am making my program compatible with Modern OpenGL. But I want to develop this project on my work laptop. My question is: can I make this project compatible with Legacy and Modern OpenGL?

Like this.

#ifdef MODERN_OPENGL some code.. glBegin(GL_TRIANGLES); ... glEnd(); #else glGenBuffers(&vbo); ... #endif 
+5
source share
3 answers

What you offer is possible, however, if you do this using preprocessor macros, you will end up in a conditional compilation hell. The best option for your approach is to compile into shared libraries, one of which is compiled for obsolete and one for the modern one, and loads the correct one on demand. However, when you approach this direction, you can just hinder the manipulation of the preprocessor and just move the transfer path options to your own compilation units.

Another approach is to choose which rendering path to use at runtime. This is my preferred approach, and I usually implement it through a function pointer table (vtable). For example, the volume rasterizer library that I offer has full support for OpenGL-2.x and modern kernel profiles and will dynamically adjust its code paths and GLSL shader code to match the capabilities of the OpenGL context in which it is used.

If you're worried about performance, keep in mind that literally every runtime that allows you to overwrite polymorphic functions must go through this bottleneck. Yes, it depends on some cost, but OTOH is so widespread that pre-sampling processors of modern processors and the indirect transition scheme are optimized to solve this problem.


EDIT: An important note on what "obsolete" OpenGL is and what not

So, here is something very important, I forgot to write first of all: Legacy OpenGL is not glBegin / glEnd . This is due to the presence of a pipeline with a fixed function by default, and vertex arrays on the client side.

Let me reiterate that: Legacy OpenGL-1.1 and later have vertex arrays! This effectively means that a large amount of code, which is associated with the layout and filling the contents of vertex arrays, will work for the whole OpenGL. The differences are in how vertex array data is actually passed to OpenGL.

In an obsolete pipeline with a fixed OpenGL function, you have several predefined attributes and functions that you use to point OpenGL to memory areas containing data for these attributes before calling glDraw…

When shaders were introduced (OpenGL-2.x or via the ARB extension earlier), they came to the same glVertexAttribPointer functions that are still used with modern OpenGL. And in fact, in OpenGL-2 you can still point them to client buffers.

The OpenGL-3.3 kernel forcibly used buffer objects. However, buffer objects are also available for older versions of OpenGL (kernel in OpenGL-1.5) or through the ARB extension; you can even use them for non-programmable GPUs (which means the efficient first generation Nvidia GeForce) of the last century.

The bottom line is that you can write fine code for OpenGL that is compatible with a huge range for version profiles, and only a very small version code is required to control an outdated / modern transistor.

+4
source

Depending on which library utility / extension loader you are using, at runtime you can check which version is supported by the current context by checking GLAD_GL_VERSION_X_X , glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR/MINOR) , etc. and creating an appropriate renderer.

0
source

I would start by writing your application using the new OpenGL 3/4 Core API, but limit myself to the subset supported in OpenGL 2.1. As datenwolf points out above, you have pointers to vertex attributes and buffers even in 2.1

Thus, no glBegin / End blocks, but also can not push / push the matrix, do not push / pop out the state attribute, there is no lighting. Do everything in vertex and fragment shaders with uniforms.

Limiting yourself to 2.1 will be a little more painful than using the new new material in OpenGL 4, but not by much. In my experience, switching from the matrix stack and recessed lighting is the hardest part, no matter which version of OpenGL it works, you still have to do it.

In the end, you will have one version of the code, and it will be easier to update if / when you decide to refuse support 2.1.

0
source

Source: https://habr.com/ru/post/1263817/


All Articles