Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New: OpenGL Main Menu (for systems not supporting WinForms) #595

Merged
merged 53 commits into from
Jul 20, 2021
Merged

Conversation

leezer3
Copy link
Owner

@leezer3 leezer3 commented Mar 17, 2021

Unlikely to be merged / useful at the minute, but this is a WIP attempt to use the in-game menu for route loading etc.

#384

May also be usable on mobile, but needs considerable work to be anything more than a tech-demo.
Also has the problem that it doesn't allow access to any of the configuration etc.

TARGETS:

  • Release 1.7.5.0 with the new TrainManager setup. (next week or two)
  • Merge 64-bit code and let the community loose on it. (next month?)
  • Release 1.8.0.0 as first 64-bit build.
  • Finish / merge OpenGL menu code.
  • Implement non-default train chooser. Should be able to use the route chooser.
  • Add menu icon option, to use the existing pixel art. Ought to make the folder etc. selection a little clearer.
  • Add command line switch to use the GL menu. Can probably just hook into this in the OS-X launch script.
  • Add recent files option. Can we pull in the existing list, or is this stored in the mainform??

ISSUES:

  • Aspect ratio of imges isn't respected.
  • Manage OS-X expectations, any OpenGL menu will not be brilliant.
  • Set sensible defaults for the game, as unable to easily edit?
  • Check M1 compatability if possible. Requires a Mac user with an M1.......

@leezer3 leezer3 added this to the 1.9.0 milestone Mar 17, 2021
@leezer3
Copy link
Owner Author

leezer3 commented Mar 17, 2021

64-bit support (required for OS-X, thanks Apple.....) also depends on the following branch being integrated:
https://github.com/leezer3/OpenBVE/tree/WinPluginProxy

This needs to be rebased onto the new TrainManager, but is relatively usable.

@leezer3
Copy link
Owner Author

leezer3 commented Mar 18, 2021

openGLMenu

So, we now have a working route image and description display in the new GL main menu.
A lot of broken stuff (need to clip over-length strings when browsing folders amongst other things), and needs optimisation in many places, but the basic concept is working.
I think that the train browser will need to be implemented as a second screen, working in the same way as the first, so that we can either start immediately with the default train, or browse the train list in the same manner.

@leezer3
Copy link
Owner Author

leezer3 commented Mar 18, 2021

This is now at the stage where it'll succesfully launch a routefile, which is actually a major milestone!
At the minute, the game launches into this menu, which needs to be removed. Similarly, for testing purposes the train is fixed as opposed to user selectable / determined by the route.

TODO:

  • Add train browser using similar principles.
  • Add Menu Icon option. (Might also be useful in-game later on)
  • Restrict max file browser width to 50% (??) of the screen.
  • Make things look a little prettier, so stuff like a border around text boxes etc?
  • Add appropriate switch to the launcher so that this isn't default.
  • Add logic to check whether we're on a 64-bit Mac and to show this if so.
  • Test with anything other than my development box....

@leezer3
Copy link
Owner Author

leezer3 commented Mar 19, 2021

Added a slightly hacky rectangle overlay shader.
Should be able to use a similar hack to render text overlays without having to mess around with generating a new VAO for every string.

cc @LabRatAndy
I've seen your branch, this one avoids the VAO pain you've got. IMHO this is a neat little trick, although I'm not 100% fond of the switch statement in the shader.

@leezer3
Copy link
Owner Author

leezer3 commented Mar 20, 2021

Implemented text shader using the same principles.
This shares a fragment shader with the rectangle.

As an alternative, the text and rectangle shaders could be merged, and add a property UseTextureAtlas (or similar)
Probably much of a muchness.....
This also dumps the System.Drawing code from the font in favour of API based vectors. At present, this isn't especially interesting, but on mobile, it doesn't appear to be shipped by default, and is presumably a cut-down form anyway. Use our own code wherever possible, and future possible porting will be much easier.

@LabRatAndy
Copy link

At least you've managed to get rectangles to draw correctly, as I couldn't seam to get the projection matrix correct. I actually only used one VAO and VBO. I then used SubBufferData to replace the vertex positions before the draw call.

Whilst in general I think branching program structures in shaders is best avoided, as I understand that they can impact performance. However, as I understand it as long as the shader is able to complete before the rest of the pipeline tasks complete then it shouldn't impact performance; as we are waiting for them not the shader.

Also, could a geometry shader help create the vertices for the rectangles? I'm not fully familier with how they fit in the pipeline or there exact usage.

@leezer3
Copy link
Owner Author

leezer3 commented Mar 21, 2021

Good point.
That's a somewhat complicated area, and not one I've got much expertise in.

However, as I understand it, this really depends on exactly how much the branch prediction can be done in advance. If your shader performs a variable result based calculation within the branch, then a misprediction can be nasty (as the shader can be being run for millions of pixels in paralell esentially)
In cases like this, each branch is hopefully going to be flattened into a single set of instructions and becomes essentially free.
https://stackoverflow.com/questions/4176247/efficiency-of-branching-in-shaders

(I'll probably cherry-pick the string / rectangle changes into the mainline branch after the next release)

@leezer3
Copy link
Owner Author

leezer3 commented Apr 29, 2021

UNTESTED:
This should now hopefully detect OS-X and fallback to the GL menu if appropriate.
Will try and get hold of an OS-X machine and see if things work later in the week hopefully.

There is also now a command-line switch controlling the GL menu:

openbve.exe /glmenu=true

@leezer3
Copy link
Owner Author

leezer3 commented Apr 30, 2021

openglmenu2

Added icons and a few more bits of plumbing into this.
Still heavy WIP, nothing implemented for trains yet.

Whilst this won't look mega pretty, once finished should be functional.

@leezer3
Copy link
Owner Author

leezer3 commented May 2, 2021

Train choosing is now complete, and seems to work quite acceptably.

The level of polish on this isn't exactly brilliant, and the code could probably do with a complete tidy up, but I think everything important is now primarily functional.
Next step is to try testing this on a Mac and Linux and see what that gives us.

@s520 you might be interested in this one too if you're available :)

@leezer3 leezer3 changed the title WIP: OpenGL Main Menu New: OpenGL Main Menu (for systems not supporting WinForms) May 2, 2021
@ginga81
Copy link
Contributor

ginga81 commented May 2, 2021

When the game start and press ESC key, Station Jump and more menu shows.
In this menu, if we press ESC key press more, must back to the game.
But, OpenBVE is back to route choose menu, and core dump and crash.

@leezer3
Copy link
Owner Author

leezer3 commented May 2, 2021

Thanks, fixed that and several other glitches.
Probably more we haven't yet found too.

I've also just discovered that an over-long description will overflow the textbox.
This is going to take a little more modification to fix (I think I'll have to hack together some scroll arrows somhow), as opposed to the simple scroll effect for long lines.

@leezer3
Copy link
Owner Author

leezer3 commented May 6, 2021

openglmenu3

Fixed a few glitches on GL1.3, and I've also now implemented a complete OpenGL picturebox class, so that we can actually maintain the image aspect ratios nicely, as opposed to stretching them to fit the square box.

TODO:

  • Make the casing of variable / parameter naming consistant in the new classes, it isn't at the minute....
  • Attempt to cleanup the code in the menu file a bit more.
  • Add recently used routes option.
  • Package install only?

@leezer3
Copy link
Owner Author

leezer3 commented May 7, 2021

Actually managed to do some Apple testing today.

Unfortunately, it's not very good news at least at first....
64-bit Apple crashes no mater what we do, complaining about an invalid window selector. I think this is because we've still got references to Windows.Forms stuff in the code, and it's flagging the process somehow.

If I understand it right, the 32-bit OpenTK backend is running under Carbon, wheras 64-bit is running under Cocoa.
opentk/opentk#119

From the looks of the linked issue (old, but I think still valid) WinForms will not play nice with anything else on 64-bit Apple.

Plan of action (?!?!):

  • Make the menu class a little more generic, so we can re-use in Object Viewer and Route Viewer.
  • Implement an OpenGL dialog box class- Basic OK / cancel popups are fine, but more than that dunno.....
  • Replace some of the Object Viewer / Route Viewer dialogs with the above?
  • Split the main form for OpenBVE into a launcher process (?)

WinForms usage:

Object Viewer

  • TrainSettings window
  • Open objects window
  • Errors window
  • Settings window

Route Viewer

  • Open route window
  • Errors window
  • Settings window

Main game

  • Some error popup dialogs
  • Reference due to the main form itself

Editors

  • All WinForms

Looks like the main game is going to be the easiest to deal with, at least at the start, although we might have to make some pretty fundamental plumbing changes to split out the main menu.

I'm also wondering about OpenTK 4.x
https://www.nuget.org/packages/OpenTK/
This completely replaces the OpenTK internal backends with GLFW. It might be interesting to attempt a port to this and see if that works any better.

@leezer3
Copy link
Owner Author

leezer3 commented May 7, 2021

Success!
Screen Shot 2021-05-07 at 14 58 46

It appears that if we call Toolkit.Init first before any WinForms code is present, it actually loads.
However, the default Apple graphics context doesn't seem to support GL3.2
I think we need to deliberately request a forwards compatible context in this case and specify that we want GL3.2

At least though we've got a functional menu.

@marcriera
Copy link
Contributor

Main game

* Some error popup dialogs

* Reference due to the main form itself

Input device plugins also have WinForms config forms.

@leezer3
Copy link
Owner Author

leezer3 commented May 7, 2021

Good point.
I think both input device plugins are a long-term aim at best though :/

Obviously, for polish reasons at the minute, this is nowhere close (or likely) to be made the default option, and AFAIK is only needed on 64-bit Apple, and presumably mobile (although I haven't even thought about that one yet)
Essentially, something that actually loads and has most of the common features available is better than nothing at all.

@marcriera
Copy link
Contributor

Good point.
I think both input device plugins are a long-term aim at best though :/

Obviously, for polish reasons at the minute, this is nowhere close (or likely) to be made the default option, and AFAIK is only needed on 64-bit Apple, and presumably mobile (although I haven't even thought about that one yet)
Essentially, something that actually loads and has most of the common features available is better than nothing at all.

Yes, just pointing them so we don't forget, as they are external and may not be initially obvious.

@leezer3
Copy link
Owner Author

leezer3 commented May 8, 2021

Forward compatible context is going to be a pain....

The commit above solves some of the issues involved, but it's nowhere close to working yet.
Known issues with a forward compatible GL3.2 context:

  • GL_QUADS are no longer valid- Need to re-write the rectangle and text shaders to use triangles instead.
  • GL.AlphaFunc is no longer valid. This breaks lots of stuff, and will need to be written into the shader instead. Likely to need a switch case in the fragment shader, unless I can think of something better.

@LabRatAndy
Copy link

For GL_Quads, the rectangle and text shaders in my stringshader branch use triangles which I've managed to get to work now. Although, I have used VAOs etc rather than a procedural shader. Feel free to use that if it helps.

For the glalphafunc problem, rather than having a switch statement in the shader you could use multiple different shaders and draw all objects with say shader 1 then bind shader 2 and draw all the objects that need to be drawn with this shader. However you would need to sort the objects into which shader to use to draws them which may or may not be slower than the shader with a switch statement.

Finally in the last commit there could be a potential problem in the useshader function. it links the shader again which could cause performance issues as useshader is used in the rendering loop to bind the shader and there is no check for this failing to link the shader; I don't know what opengl will do in this case. Also, does glbindfragmentdatalocation need to be called every time the shader is bound, would it not be better to do this in the shader constructor?

@leezer3
Copy link
Owner Author

leezer3 commented May 9, 2021

Interesting idea with different alpha shaders.

Sorting isn't going to work (see the two pass drawing method used), but testing is needed on that front.
We might actually be able to do the entire thing in a single shader pass (the draw result is the same, just different alpha test values)

I was having problems with this yesterday though; I've got the nasty suspicion the depth test buffer is interacting with the alpha function too.

@leezer3
Copy link
Owner Author

leezer3 commented May 10, 2021

Single pass shader unfortunately won't work, as we're using blend.

Either I've done something terminally stupid (quite likely) or it doesn't like doing things this way at all...
It's also possible that the shader state variables aren't consistant with the GL ones (due to shader switch), but I did try testing that with no good results.
Any ideas welcomed.

Terminally stupid mistake, it was falling through cases; Always look at things again a bit later on.

If / when this is got working, we probably want to think about a Uniform Buffer Object for storing the projection matrix and the alpha test values in, so that we eliminate a bit of uploading to the shaders.
It'll also want benchmarking, last thing we need is to kill performance or something.....

@leezer3
Copy link
Owner Author

leezer3 commented May 10, 2021

So, I've fixed the issue, and done some very rudimentary testing.

Using the Plymouth route, FPS with the alpha shader solution is currently down by ~20%
I'd guess there's somewhere about a 5% margin of error in there, so a not insignificant drop.

Some preliminary thoughts on optimisation:

  • Can probably get rid of the AlphaEnabled uniform, and just use always / never instead. (This is assuming the GPU evaluates all branches)
  • Eliminate all alpha test cases other than Equal, Greater and Less, as we don't use them at present.
  • Move the alpha into a second shader. There should be vastly less transparencies than solid faces, and there's clearly some sort of performance impact.

@leezer3
Copy link
Owner Author

leezer3 commented May 11, 2021

The alpha shader idea unfortunately doesn't work (at least without a redesign somewhere), as we need alpha for the polygon DNB.

The performance killer is definitely the discard statements in the shader.
Eliminating the unused ones gets the framerate much closer to what we expect, FPS with the latest commit seems to be 2-5% down.

Still need to think about eliminating quads in the rectangle / text shader, haven't looked at LabRatAndy's branch yet.
The discard performance issues above suggest that his might actually be the better approach, although this will require testing.

Some of this may also be hardware / OS & GL implementation dependant. For reference, I'm testing with a GTX1060 on Windows 10 at the minute.

@leezer3
Copy link
Owner Author

leezer3 commented May 13, 2021

Now that's interesting.

The geometry shader seems to give us a 20% odd FPS drop, over just doing it with the switch statement in the vertex shader.
This might be due to the triangles (more polys obviously), but it shouldn't be that many, especially as it's only the UI being drawn with these shaders.

Google suggests Intel hardware is much better with geometry shaders, but this might not be unexpected.
I'm almost tempted to do a Forward compatible only render path as a third option in render types.


Some stuff on the geometry shader issue, the first suggests that doing it in the vertex shader procedurally as per previously is going to be an order of magnitude faster....
Mac may also not support geometry shaders at all (Apple again...............)
http://www.joshbarczak.com/blog/?p=667
https://www.factorio.com/blog/post/fff-251

@leezer3
Copy link
Owner Author

leezer3 commented Jun 21, 2021

Some more hacking away.
Branch is now at ~132 - 135fps

Highlights:

  • Using a 1x1 pixel white texture (as opposed to disabling texturing) has a very marginal FPS gain. (2-3fps, may be more on mobile drivers and poor hardware)

@leezer3
Copy link
Owner Author

leezer3 commented Jul 16, 2021

Changed to use a forwards compatible context with GL3, although perhaps this wants restricting to OS-X only.
I think this has found all the unexpected bits..... although I'm seeing a possible glitch with panel elements overlapping. Need to investigate a bit

@leezer3
Copy link
Owner Author

leezer3 commented Jul 17, 2021

openGL on OS-X appears to be a seriously messed up situation.
I've done a lot of testing this morning, and we should now have a functioning GL3 renderer on OS-X.

This has the following caveats / changes / TODOs:

  • All shaders must be explicitly marked as GL3 core profile.
  • The host process for GL3 appears to need to be 64-bit. (This also means that GL3 must use the new menu, no way to get GL3 with the old menu); Need to disable the checkbox, or do a process restart in 64-bit (think about things....)
  • Drive selection on GL menu is broken and causes a crash. (I think this is Apple symlink related, need to investigate)
  • Possible glitch with route image picturebox, although this may be driver related.

@leezer3
Copy link
Owner Author

leezer3 commented Jul 19, 2021

Made a few more improvements, as follows:

  • Forwards compatible contexts may be deliberately set via the config file.
  • New menu now hides folders / files starting with a period on non-windows platforms.
  • Try / catch blocks around the filesystem operations. Probably fixes OmegaZeroKiller's crash and mine, although I haven't yet tested on the real thing.
  • Fixed the rectangle draw glitch (caused by the white pixel change and forgetting to set the last bound texture)

Assuming this doesn't crash, it's probably mergable as-is. Further improvements, basic package manager and options etc. really need to be in separate PRs, as this is getting rather oversize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants