Port to Modern OpenGL#1296
Conversation
|
Please don't sacrifice support for old OpenGL. I have no objections if you move the current OpenGL 1.x/2.x rendering code into your abstracted interface and add OpenGL 3.x rendering as a second implementation. |
|
@s09bQ5 Thanks a lot for the review. I removed scaling the textures to power-of-two dimensions, under the assumption that all GPUs will have NPOT support (it's required in OpenGL 2.0 and later). Now that it's required to still support OpenGL 1.x, should I add support back for GPUs that don't support NPOT? Or can we make the extension mandatory for 1.x contexts? |
|
I personally am very much in favor of getting rid of the old fixed function based rendering. No need to keep that legacy code. All the other platforms will benefit from getting rid of it and switching to more current OGL. For example RaspberryPi will have much better performance even without us specifically adding GLES support. We got rid of 32-bit builds, that is much more of an issue for older setups than OpenGL 3 requirement. |
|
First off, sorry for merge-conflicting your branch, I only saw it was there at all after I already merged a bunch of things. With that out of the way, I did scroll through the branch diff a bit and I liked what I saw a lot. I remember messing around with the info bar (the one with all the rectangles when you're singing) and oscilloscopes some time ago and I also remember how often something was suddenly taking up half the screen, or invisible, etc. Bottom line: I am heavily interested in eventually merging this. As to what versions you should (or shouldn't) target, I'll defer to s09bQ5. Though personally, OpenGL 2.0 (or 1.x but requiring the NPOT extension) is perfectly valid. I can't comment on 2 vs 3 as a minimum, though I'm assuming NPOT is the biggest nightmare here anyway (but again I don't know much about this graphics internal stuff) Regarding merge conflicts, if you want to get some of the trivial renames done already (like the text one, but there's probably more) so that you don't have to constantly keep rebasing, I am okay with that. |
|
As a compromise, I could add support for OpenGL 2.0. 2.0 is at least somewhat modern in that it supports shaders and NPOT textures. I would have to adapt the code slightly, but way less than adding back the ancient 1.x fixed function stuff. Setting 2.0 as a minimum would give us at least 20 years of hardware compatibility for PCs. |
|
I'd like to again put emphasis on that we just recently dropped 32-bit support, requiring 64bit OS installs, and we just in the last release required that change. Adding the switch to OGL 3 would now fit perfectly. I checked again and from what I could find, all the typical hardware that typically comes with 64 bit OS also already supports OpenGL 3. So there would be no benefit in keeping 2.0 support around - it would just harm performance on some platforms. |
We didn't drop 32 bit support. We just stopped providing binaries for 32 bit OSes. And if I remember correctly, in the PR for that it was argued that users of 32 bit machines can still compile USDX for their systems.
Proof? Why do people think that the fixed function OpenGL API is bad? Just because Khronos renamed it to "legacy"? Why do we need shaders? Nobody has plans for visual changes that requires them. Machines that have support for OpenGL 3+ are fast enough to cope with any performance drawback of OpenGL 1.x/2.x. |
Here's an idea I have for how USDX could benefit from shader support. You've probably noticed that video decoding performance in USDX is not great. It often struggles with high resolution files. One of the reasons for this is the use of RGB textures for the video frames. Almost all video files use YUV colorspace, because it provides superior compression. But YUV data can't be displayed by the GPU. So we convert them to RGB format via the FFmpeg swresample library and then upload them to the GPU. With support for shaders, we could instead upload frames to the GPU in YUV format, and have the GPU do the YUV->RGB conversion. This would cut the memory bandwidth in half (1.5 bytes per pixel vs 3 bytes per pixel), and reduce the load on the CPU. This is one example of an optimization that can be made with shaders that isn't possible with the fixed function pipeline. |
|
The beauty of the legacy OpenGL API is that you don't have to use shaders. If they are supported, you can use them to speed things up. If not, you can continue to render the old way. |
|
This branch has reached feature parity with How to approach ProjectM will depend strongly on the versions of OpenGL that need to supported. The latest ProjectM 3.x/4.x releases require modern OpenGL (3.x). So this will be on hold until we can reach an agreement on the compatibility question. I remain in favor of dropping support for the OpenGL 1.x fixed function pipeline API in favor of the shader-based APIs. |
|
I still think that getting rid of glBegin / glEnd / fixed function pipeline would be worth it and switching to requiring OpenGL 3.3 or newer would be the best way to go forward. Any hardware released within the past 13+ years supports it. No need to maintain two rendering code paths (fixed function and shader based) concurrently. People with machines that are too old can still continue playing using previously released USDX versions. How much legacy code we decide to maintain has an impact on how fast new features and improvements of UltraStar Deluxe can be developed and tested+released. I'd like to force getting an agreement within the next few weeks, so that development on this very helpful PR can continue, and thus suggest we just vote on it. 🚀 Option 1: Maintain OpenGL 1.4+ and 2 and 3/4 compatibility for now Please vote via emoticon reaction within the next 7 days. |
|
I am on an ancient 2015 Intel Macbook Pro with an Intel Iris Graphics 6100 which fully supports OpenGL 3.3 and 4.1 Core Profile. In general, I am mostly in favor of supporting old hardware (because I am likely to be affected), but considering that even my ancient computer supports OpenGL 3, dropping support for 1.4+ and 2 is not exactly making a switch that requires brand-new hardware. |
|
You call that ancient? May I remind you of #1156, which was reported this year? That chipset is from 2008 and its GPU barely supports OpenGL 3.3. |
|
A bit of GPU history:
|
|
GPU History Continuation (2012–2026)
|
|
Thanks @s09bQ5 and @bohning for the history. That tracks closely with my estimate of ~15 years of hardware compatibility for this branch as it currently stands. As I previously mentioned, I could drop the minimum version down to OpenGL 2.0 with a little bit of added complexity to the code, but not too bad. That would get us another 5 years of hardware compatibility, to about 20 years total. Adding back the 1.X API would require a major restructuring of the code, and increase the maintenance burden in the long term. I would like to avoid that if possible. |
|
re: #1296 (comment) to add some explanation to why I picked "drop 1, keep 2.1 and above": Would a compromise be acceptable? That is:
My tertiary backup system (I hope I won't ever need it) has an X4500 HD. More pressing, until less than a year ago my main day-to-day system was a 3rd gen i3 with iGPU (~14 years old apparently), and only recently did I "upgrade" to ~9-year old hardware. But that upgrade was mostly because there's so much Personally, I'm actually fine with whatever comes out of the poll, because I have enough systems on GL3 and higher (and I really don't care about projectm at all) that it's not an issue for me. Dropping 1 seems like a sane idea to me, dropping 2 as well won't affect me personally but the "15 years of hardware compatability" is eerily close to my previous daily. |
|
@barbeque-squared Good points. I just switched my vote to Option 2. I think it's a fair compromise, and we should now have a final answer on this question. Last question I have is in regard to ProjectM. As I mentioned, we currently use very outdated ProjectM 2.x, which doesn't support OpenGL 3.x/4.x. The latest 4.x versions of ProjectM have dropped support for OpenGL 1.x/2.x. So they are mutually incompatible. I would really like to upgrade ProjectM to 4.x as there have been a lot of really good improvements to that library since 2.x, and it would greatly simplify our codebase. So users with 20 year old PCs running OpenGL 2.x would still be able to play the core game, but ProjectM would not be available. IMO this is fine since it's just an optional feature anyway. |
|
@complexlogic feel free to go ahead and switch it to ProjectM 4.x. |
I've been working on porting the game to modern OpenGL, which uses shaders instead of the fixed function pipeline. The port currently targets OpenGL 3.0, which was released in 2008. It should be compatibile with most PCs made in the last ~15 years.
The port is fully playable, with only a few minor features not implemented yet (see list at bottom). Before I do the work to finish it, I would like to get some feedback from the maintainers whether there is interest in eventually merging this.
This branch establishes a new abstract base class
TRendererfor doing drawing, with sub classes implemented by each rendering backend (currently only OpenGL 3.x). This is similar to how other systems work in USDX, such as the audio system.I have two motivations for doing this. The first is that it significantly improves the code quality of USDX. All of the OpenGL code is now contained within a single unit. No more having 100+ different pieces of code to draw a texture or quad scattered throughout various places in the codebase.
Now, this becomes
Renderer.DrawTexture,Renderer.DrawQuad,Renderer.DrawLine, etc. This is a nice abstraction, so you don't have be an OpenGL expert to work on the graphics anymore. The low level graphics code is hidden and contained.The second reason for doing this is that it improves the portablility of the program. The pluggable rendering interface provides the ability to add other rendering backends in the future if we need to. OpenGL is a legacy API, and is officially deprecated on Apple platforms. For example, if Apple eventually drops OpenGL, we could keep macOS support by adding a Metal backend.
This would also allow us to upgrade ProjectM to the latest 4.x release, instead of being stuck on unmaintained 2.x. With 4.x, the ProjectM library now provides a C API, so we wouldn't need the C Wrapper library anymore. That would greatly simplify the build system.
To keep compatibility with embedded systems such as Raspberry Pi, an OpenGL ES backend would need to be added. Embedded/mobile platforms generally don't support modern desktop OpenGL. However, because the graphics of USDX are so simple, this should be a relatively easy addition with only minor adaptation needed. Almost all of the code should be common with the existing desktop OpenGL renderer.
Here's a high level summary of the code changes:
TRendererclass introduced for drawing, with subclasses for each rendering backendTTextureUnitclass functionality (LoadTexture,GetTexture, etc.) are now part ofTRendererTTextureis now a class instead of a record. This was needed for polymorphism (ability to support multiple rendering backends)TTextureclass, instead of being implemented separately in each of the graphics classes (TMenuButton,TStatic, text, etc).TextGLunit is nowUTextglPrintfunction is nowPrintTextglTextWidthfunction is nowTextWidthTo Do