Closed midwan closed 1 year ago
Related issue at Silk.NET: https://github.com/dotnet/Silk.NET/issues/1277
@Pyrdacor based on the replies on the Silk.NET issue, and from what I tested here, it seems that this library won't work on devices such as the RPI, due to the OpenGL minimum requirements (the lib is hardcoded to use OpenGL 3.1 as a minimum).
Considering there are no 3D functions being used, perhaps we could use something simpler like a pure SDL2 implementation? Not sure how much of a change that would be...
Well OpenGL 3.1 is explicitly required as the engine uses shaders. This is from 2009 so 14 years old already. But the Pi uses OpenGL ES which is a whole different story. See the Ambermoon.net project and there the GameWindow.cs file. Relevant code:
#if GLES
var api = new GraphicsAPI
(ContextAPI.OpenGLES, ContextProfile.Compatability, ContextFlags.Default, new APIVersion(3, 0));
#else
var api = GraphicsAPI.Default;
#endif
So to make it work with Pi you need to define GLES when compiling.
The Pi4 should support OpenGL ES 3.0 which is based on OpenGL 3.3. This is what I am aiming for. The Pi3 only has OpenGL ES 2.0 which won't work maybe. But I guess it also emulates some newer features as well.
But as I just now realize, it also supports at least fragment and vertex shaders which is all that is needed. So maybe just change new APIVersion(3, 0)
to new APIVersion(2, 0)
and compile with GLES defined. Might work.
Creating a new render backend with SDL is a huge task. But in theory I designed the projects to be able to support this. Basically the game works with interfaces defined in the Ambermoon.Core project in sub-folder "Render".
You could create your own render backend which implements those interfaces and provides the implementation.
Basically you have to take the project Ambermoon.Renderer.OpenGL as a reference and create a new similar project.
Still it is a lot of work. But this would be the way to go. As you can see in that project, there are many shader classes which won't work without OpenGL 3.1 or OpenGL ES 2 or 3.
The concept in a nutshell is:
If you implement them all, you should be fine in theory. The project grew a lot since the initial design so there might be some more things to take care of.
In general it should be enough to set the Visible property of a render node to true and ensure a valid position on the screen through the X and Y property. And of course a valid layer must be assigned. If those 4 properties are valid, the render node is drawn. This is the basic workflow for displaying stuff on the screen.
I could provide more info, but writing a new renderer might be much work.
I tried the configuration ReleaseWithAndroid
, which seems to define GLES
already, and that seems to go on a bit further, but eventually fails with a different error:
[Render] Unable to create layer 'Map3DBackground': 0:19(18): error: no matching function for call to `mod(int, int)'; candidates are:
0:19(18): error: float mod(float, float)
0:19(18): error: vec2 mod(vec2, float)
0:19(18): error: vec3 mod(vec3, float)
0:19(18): error: vec4 mod(vec4, float)
0:19(18): error: vec2 mod(vec2, vec2)
0:19(18): error: vec3 mod(vec3, vec3)
0:19(18): error: vec4 mod(vec4, vec4)
0:19(14): error: cannot construct `int' from a non-numeric data type
0:20(13): warning: `index' used uninitialized
0:20(27): warning: `index' used uninitialized
0:21(13): warning: `index' used uninitialized
at Ambermoon.Renderer.OpenGL.RenderView..ctor(IContextProvider contextProvider, IGameData gameData, IGraphicProvider graphicProvider, ITextProcessor textProcessor, Func`1 textureAtlasManagerProvider, Int32 framebufferWidth, Int32 framebufferHeight, Size windowSize, Boolean& useFrameBuffer, Boolean& useEffectFrameBuffer, Func`1 screenBufferModeProvider, Func`1 effectProvider, Graphic[] additionalPalettes, DeviceType deviceType, SizingPolicy sizingPolicy, OrientationPolicy orientationPolicy)
at Ambermoon.GameWindow.CreateRenderView(GameData gameData, IConfiguration configuration, GraphicProvider graphicProvider, FontProvider fontProvider, Graphic[] additionalPalettes, Func`1 textureAtlasManagerProvider)
at Ambermoon.GameWindow.ShowVersionSelector(BinaryReader builtinVersionReader, Action`4 selectHandler, TextureAtlasManager& createdTextureAtlasManager)
at Ambermoon.GameWindow.Window_Load()
at Silk.NET.Windowing.Internals.ViewImplementationBase.Initialize()
at Silk.NET.Windowing.WindowExtensions.Run(IView view)
at Ambermoon.GameWindow.Run(Configuration configuration)
at Ambermoon.Program.Main()
it seems that's the shader itself that fails now, but I don't have enough knowledge about shaders to fix that :)
BTW, the UseGLES
option you passed from PowerShell doesn't seem to work for me. It would never enable/define GLES
in the project, so I ended up using the ReleaseWithAndroid
configuration instead.
For the first shader error you could fix this with changing mod(x, y)
to mod(float(x), float(y))
.
Maybe you have to do int(mod(float(x), float(y)))
.
Maybe ES doesn't support some functions.
If this is the only error, this is no big deal.
@Pyrdacor Thanks! I managed to make some progress with your suggestions above, by changing one reference in the shader. Now the game starts up with no errors (besides the warning about the window as shown above), and I can get to the point where I start a new game, but the character selection screen is... problematic:
Any idea what this might be related to?
Also, I am probably missing something here, but I can't seem to be able to define GLES
as expected in the Ambermoon.net
project. For now I'm just commenting out the alternative to compile for the RPI, but ideally this should work properly...
You had an env variable being defined in your PS1 script, but that didn't seem to work. No matter what value it got (true/false) it would never define GLES
, even though you had that condition in the project file.
I used the ReleaseWithAndroid
config that the Ambermoon.Renderer.OpenGL
had, and that one defines GLES
when it's selected, so I tried creating that config in the Ambermoon.net
project as well:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithAndroid|AnyCPU'">
<DefineConstants>$(DefineConstants);GLES</DefineConstants>
<Optimize>True</Optimize>
</PropertyGroup>
However, it still does not define GLES
for me when I select that config, at least not in Ambermoon.net
- it does in Ambermoon.Renderer.OpenGL
as expected. :-/
Like I said, I'm probably missing something here, but I think this should have worked.
The Ambermoon.net project most likely has no such configuration. You would have to add it. You can see this in the configuration manager of the solution. I bet when the solution configuration "ReleaseWithAndroid" is selected, the Ambrrmoon.net project uses the "Release" config.
The configurations exist for each project and also for the whole solution. But a project can use a different configuration as the solution config. Especially when it doesn't have that config.
About the messed up UI. This can have multiple causes. One is the display layer (layer in the shader) which controls the Z order.
You can check in the debugger if the property Visible
of the sprites is true. If yes it is some shader issue. Might be rounding or something like that.
The Ambermoon.net project most likely has no such configuration. You would have to add it. You can see this in the configuration manager of the solution. I bet when the solution configuration "ReleaseWithAndroid" is selected, the Ambrrmoon.net project uses the "Release" config.
The configurations exist for each project and also for the whole solution. But a project can use a different configuration as the solution config. Especially when it doesn't have that config.
I think I have it correctly set up - The solution has the correct configs selected per project:
And then in Ambermoon.net
I added the new config:
<Configurations>Debug;Release;DebugAndroid;ReleaseNative;ReleaseWithAndroid</Configurations>
and finally tried to have it set the constant when it's selected:
<PropertyGroup Condition="'$(Configuration)'=='ReleaseWithAndroid'">
<DefineConstants>GLES</DefineConstants>
<Optimize>True</Optimize>
</PropertyGroup>
(tried both with just a Configuration and also a combination of Configuration/CPU)
While the same seems to work for the OpenGL project, it does not for the Ambermoon.net one. Weird...
I'll check for any clues regarding the character selection screen and get back.
Regarding the config issue above, perhaps you can take a look at my branch and see if you can notice something I missed: https://github.com/midwan/Ambermoon.net/tree/fix-rpi :)
How did you check if GLES is defined? As it is only evaluated in the renderer project it won't have an effect to define it in Ambermoon.net I guess.
In the configuration manager I see "ReleaseWithAndroid" but in the project file you added and also check for "ReleaseAndroid"
@Pyrdacor
It's also evaluated in GameWindow.cs
of the Ambermoon.net
project:
public void Run(Configuration configuration)
{
this.configuration = configuration;
var screenSize = configuration.GetScreenSize();
Width = screenSize.Width;
Height = screenSize.Height;
#if GLES
var api = new GraphicsAPI
(ContextAPI.OpenGLES, ContextProfile.Compatability, ContextFlags.Default, new APIVersion(3, 0));
#else
var api = GraphicsAPI.Default;
#endif
var version = Assembly.GetExecutingAssembly().GetName().Version;
gameVersion = $"Ambermoon.net v{version.Major}.{version.Minor}.{version.Build}";
var videoMode = new VideoMode(60);
var options = new WindowOptions(true, new WindowDimension(100, 100),
new WindowDimension(Width, Height), 60.0, 60.0, api, gameVersion,
WindowState.Normal, WindowBorder.Fixed, true, false, videoMode, 24);
options.WindowClass = "Ambermoon.net";
I didn't add that, it was already there. And you had a condition in the project file to define GLES
if the variable UseGLES
was used, but that didn't seem to work (at least not for me)...
Ok good catch. You saw my second reply? You used the wrong configuration name in the project file.
@Pyrdacor
I did a search for ReleaseWithAndroid
in all files and replaced any remaining occurrences now - but it still refuses to show GLES
as defined in that file. It's like something is undefining it, very strange.
If I add a #define GLES
at the top of the file, it works of course. But for some reason it doesn't pick it up from the project file.
I think you should instead have replaced "ReleaseAndroid" by "ReleaseWithAndroid" as this is the used solution configuration. If it works in the renderer project it should also work in the main project if the names are right.
Ok I saw you also renamed it inside the solution file so it should work. Did you restart VS? Sometimes it's just a visual issue and it actually works. I can test it tomorrow when I am back at my PC.
If you want to rule out the configuration you could just remove the condition in the project file for testing. If it then still does not work, something else is broken.
Ok I found the reason. The project has another condition <PropertyGroup Condition="'$(OS)' == 'Windows_NT'">
which adds the "WINDOWS" constant. But this overrides all other constants on Windows as it just sets this one constant. It should be <DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
there to keep the previous ones.
I updated the whole solutions and projects and added 2 new configs "ReleaseES" and "DebugES" to distinguish between Android and just ES (RPI etc).
Maybe you can just rebase against master again.
I already changed the ES context version to 2.0, upgraded some dependencies etc.
See a51b905b89df43f3cd21134f31bae46daa208812
Ah, good catch!
I'll rebase against master
again, sure. Just a note: OpenGLES 3.0 seemed to work on the RPI, so perhaps you don't need to take it down to 2.0. ;-)
How is the status? I saw on your screenshot in the background that it runs with the SDL backend which is not well supported. Were you able to run it with glow?
I didn't have a chance to do anything more with this, I'm afraid. Been busy with a few other projects lately...
Ok let me know when you continue with this.
Maybe we can try this with a Pull request, so we can comment/make changes in the code directly as well? I can send over what I have done so far, and we can continue on that.
PR submitted: https://github.com/Pyrdacor/Ambermoon.net/pull/346 - ignore that, I'll clean up the git mess and try again
Proper PR submitted: https://github.com/Pyrdacor/Ambermoon.net/pull/347 :)
Perhaps this issue should be closed, as we've moved on from the original problem/description? :)
Describe the bug Ambermoon fails to start on a Raspberry Pi running Manjaro (arm64/aarch64), with the following error:
The window opens up, but contains nothing. Pressing enter in the console shuts down the game.
Based on this related answer in StackOverflow: https://stackoverflow.com/questions/65531911/glx-context-creation-error-glxbadfbconfig, the specification of GLX_ARB_create_context is clear about when GLXBadFBConfig error may be returned:
It might be a case of Silk.NET requesting a major/minor version that is not supported on these devices, but I'm not 100% sure yet.
The output of
glxinfo | grep -e "OpenGL version" -e "Core" -e "Compatible"
on the device is the following:From what I could see so far, you don't explicitly request any GL version when initializing the window, so this may be internal to Silk.NET. I'll try opening an issue there to see if they have any feedback, and keep digging to see if there's a way to fix this.
Submitting this issue here for future reference, and in the case of any PR that fixes it. :)