Retera / WarsmashModEngine

An emulation engine to improve Warcraft III modding
GNU Affero General Public License v3.0
192 stars 37 forks source link

Unable to run on AMD graphics cards #17

Open Kashouryo opened 1 year ago

Kashouryo commented 1 year ago

This engine runs fine on intel graphics card but can not run on AMD graphics card. GPU: AMD Radeon RX6900XT 22.5.1 windows driver

LwjglGraphics: OpenGL 3.3+ core profile (GLES 3.0) not supported.
Exception in thread "LWJGL Application" java.lang.NullPointerException: Cannot invoke "com.badlogic.gdx.graphics.GL30.glGenVertexArrays(int, java.nio.IntBuffer)" because "com.badlogic.gdx.Gdx.gl30" is null
    at com.etheller.warsmash.WarsmashGdxMenuScreen.show(WarsmashGdxMenuScreen.java:94)
    at com.badlogic.gdx.Game.setScreen(Game.java:61)
    at com.etheller.warsmash.desktop.DesktopLauncher$1.run(DesktopLauncher.java:122)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.executeRunnables(LwjglApplication.java:309)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:236)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:138)
Retera commented 1 year ago

OpenGL 3.3 is currently the minimum requirement. I experimented with a version that would compile for Android where I tried to backport some of the shaders and some of the stuff... it still was using GL30 even in the more Android/LibGDX compliant version. That project also become unrecognizably different and had differently organized code (basically an unpublished one-off experiment), because I did not have an Android BLP parser and opted to convert all game assets to PNG instead. It probably would not help you.

If you want to run this on older hardware that cannot use the OpenGL 3.3 spec, you will need to reinvent the project using older APIs and designs. I do not see a way around it. If you find a way around it, feel free to contribute your changes to the repo using a Pull Request! :)

v4dkou commented 1 year ago

@Retera Same error on AMD® Radeon RX 570 series on Linux, which is fairly recent and should support up to OpenGL 4.6.

From my experience with libGDX projects, this looks like an issue with Lwjgl 2, as it has reached EOL and these days throwing all sorts of nonsensical errors. Lwjgl 3 projects don't throw such errors for me.

Meanwhile, to get the project to compile and run up to that point, I've had to download specifically Oracle's JDK 1.8 (as per README.md and due to the fact that later JDKs don't support Lwjgl 2 and would throw Exception in thread "LWJGL Application" java.lang.NoClassDefFoundError: Could not initialize class org.lwjgl.Sys). However, the experimental branch has been merged into main and now it uses java.util.zip.CRC32C, which was not available until Java 9, which means I was not supposed to use 1.8. 🤷 (I've changed them for CRC32 locally as it should return same results as CRC32C, but who knows what other issues might arise in runtime).

Have you considered upgrading the project to com.badlogic.gdx.backends.lwjgl3? Generally it's not that hard, but there's a lot of small changes in API that make this change fairly disruptive (albeit localized in the desktop package), so I'd rather not get into that unless there's a possibility to get my changes upstream.

In the end we'd get a project that runs properly under JDK 17 (as is suggested by experimental branch merged in), Linux, and hopefully, AMD GPUs.

Relevant link: https://gist.github.com/crykn/eb37cb4f7a03d006b3a0ecad27292a2d

Retera commented 1 year ago

If your computer cannot support OpenGL 3.3 then changing to lwjgl3 would not fix your computer in any way that I understand. The lwjgl version has been basically entirely independent of the OpenGL version in any case that I have tested so far.

My use of LibGDX is gross and spaghetti-code-ish. I use them as a convenience to access LWJGL but my 3D model render pipeline is copied from the Hive Workshop 3D viewer javascript project and ported to Java. In the process of porting that, I was liberally just copying everything and copied over Ghostwolf's ("flowtsohg" github user's) concept of Scene and Camera and such that he had invented. Rather than being compliant with LibGDX, these are invented to match thematically with how Warcraft 3 formats and paradigms would work. One of the conflicts this introduced also was the concept of spacial 3D audio. In this kind of RTS game, we want the sound of ingame combat or unit responses to be spacially passed to the left or right ear based upon the camera's 3D location compared with the game unit's 3D location. The LibGDX bindings for lwjgl2 are based on top of OpenAL but do not expose the spacial listener controls and instead reduce it to a single sound balance floating point number where -1.0 is left ear and 1.0 is the right ear or something like that. I didn't want to reinvent the math and I didnt do that. Instead, I hacked the Lwjgl2 bindings in LibGDX and created a hole in the LibGDX API where I could talk to OpenAL directly and tell the system the 3D coordinates of my units and camera and allow the sound driver to figure this out. The OpenAL stuff already supported all that, but it wasn't exposed in LibGDX presumably because they aim to be cross platform and some platforms can't do it.

So, the last time I made a local reworked version of Warsmash where I wanted to compile to my Android phone, I ended up using LWJGL3 to do it and did have to port Warsmash to run on that. LibGDX is nice about it, but the problem and why I don't just do that for the whole repo here is that I don't want to give up my 3D spacial audio bindings hack for desktop.

I already started using Java 17 after someone recommended it (sorry that the readme still says Java 8) and typically for me when I do these kind of upgrades I end up losing features. For example, LWJGL2 is broken and doesnt seem to handle the Swing UI scaling correctly when Java 9+ bring in the UI scaling functions that cause queries to the window size to report incorrect scaled values inconsistent with what OpenGL expects. So, now on this Java 17 version, if you run the MdxEditorMain even though that was just a test, it no longer can draw 3d stuff fit to its entire window, and it just squashes to the corner if you have % UI scale turned on in your window manager (at least on Windows).

So, for me, when we talk about doing version upgrades, this usually entails me losing features and gaining ostensibly nothing. This is not because it has to be that way, but because of limits on my development time. Can you make a pull request of an LWJGL3 version of Warsmash that I can rigorously confirm has full feature parity with this repo in absolutely every way? LWJGL3 is also incapable of spinning up a 3D view in a Swing window like the MdxEditorMain test program. I do not actually care greatly about that test program, but not being able to use convenient desktop UI components combined with the 3D view would prohibit me from making a World Editor in the future, probably. Maybe society will force me to use DearImGui instead of Swing, but I consider that annoying. Retera Model Studio repo already has an implementation of the Object Editor for making custom units that is generally fully functional as a Swing based application, and is based on the same unit data subsystem copied into Warsmash. Some day it would be nice to combine that with Warsmash and make a full on map editor, but the HiveWE repo might get so good by then that it is not worth it. So, I am undecided whether I will do that. It depends on how beneficial the code overlap between Warsmash and a map editor might be -- for example if Warsmash diverged from Warcraft 3 but HiveWE focused into being a Warcraft 3 specific editor in the future or something.

But why should I spend half a dozen hours on code changes that take away the possibility of that future, and offer me no new features, only then in the end to find that your computer hardware was still unable to run OpenGL 3.3 so you still weren't going to use my updated version? I am not opposed to code changes but I want to make sure the outcome is worth the effort.

Have you tried running a Lwjgl3 LibGDX app on your computer where you enable the experimental OpenGL 3.3 stuff? It is still not enabled by default on Lwjgl3 as far as I know.

v4dkou commented 1 year ago

Can you make a pull request of an LWJGL3 version of Warsmash that I can rigorously confirm has full feature parity with this repo in absolutely every way?

Yes, that's why I am here, I wanted to ask whether there's a chance of this pull request getting pulled upstream (same as you, I want to make sure the outcome is worth the effort)

Of course, this is not something that could be done in a day, might take some time (reworking 3D spacial audio, for instance)

Do you have that local reworked version with LWJGL3 (that is not as feature complete as the main repo ofc)? If so, would you mind pushing it to a new branch or a brand new repo, so I could branch off it and start tinkering, so that somewhere in the future it'd be possible to merge our repos?

Have you tried running a Lwjgl3 LibGDX app on your computer where you enable the experimental OpenGL 3.3 stuff? It is still not enabled by default on Lwjgl3 as far as I know.

What experimental stuff exactly?

P.S. as for using LWJGL3 with Swing, there are workarounds I could test. https://stackoverflow.com/questions/59174586/opengl-and-awt-swing-user-interface/59206923#59206923

Retera commented 1 year ago

If so, would you mind pushing it to a new branch or a brand new repo, so I could branch off it and start tinkering, so that somewhere in the future it'd be possible to merge our repos?

Unfortunately for that version, basically it was the result of a time when there was a weekend where I decided to try to see if I could get Warsmash to play on my phone that weekend with no design contraints. So I allowed myself to just use the LibGDX project generator and generate an Android-centric wholly new project with a ton of the code from this repo shoveled into it. In the end, to actually get to the point where I could train a hero and go creeping on my phone I had edit a ton of stuff literally everywhere and make the end result into more of a LibGDX game compliant with a little more of the idea of LibGDX. The desktop Java concepts copied from the Retera Model Studio project mostly had to be dropped, including the Warcraft 3 archive loading stuff, so instead of the Warsmash INI it would basically load all the assets using LibGDX FileHandle types from the LibGDX internal files system. This meant that the process of packaging this to an APK app file reconstructed something containing the entirety of the Warcraft 3 game inside that, because the game was in the repo. Especially given that Blizzard is now predominantly a mobile gaming company, publishing anything to do with that experiment would probably be the quickest way to a takedown notice from Blizzard. Maybe thinking about that is not good.

v4dkou commented 1 year ago

You can avoid packaging W3 assets into APK by providing a Gdx.files.external-based loader and some UI for user to provide a path to a valid W3 installation on their SD card.