Page 1 of 1

Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Thu Nov 26, 2020 3:25 pm
by dmitry.grigoryev
Hello,

I'm trying to build an old game which is written using SDL and procedural OpenGL. I understand that switch-glad only supports OpenGL 4.3, without legacy APIs such as glBegin() / glEnd().

What options do I have, besides rewriting the game engine with VAOs/VBOs? Is there a reason why procedural OpenGL is not supported on Switch? Or is there a package I have missed which provides such support?

Re: Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Thu Nov 26, 2020 8:47 pm
by fincs
switch-mesa does support legacy OpenGL. The version of glad we package as switch-glad is only offered as courtesy so that most people don't need to do it on their own; but it is perfectly possible to generate a version of glad that loads an older version of OpenGL (select e.g. GL version 2.1 in Compatibility profile, and uncheck "Generate a loader" since that only works on Windows/Linux/macOS), and change the EGL initialization code likewise.

Re: Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Fri Nov 27, 2020 10:02 am
by dmitry.grigoryev
Thank you, generating a custom GLAD solved the compilation problems. However, I'm still stuck with unsupported functions at runtime. I ran a few lines of OpenGL code with GL_DEBUG_OUTPUT enabled, and this is what I get:

Code: Select all

	glEnable(GL_TEXTURE_2D); //GL CALLBACK: type = GL_ERROR, severity = 37190, message = GL_INVALID_ENUM in glEnable(GL_TEXTURE_2D)
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClearDepth(1.0);	 //GL CALLBACK: type = GL_ERROR, severity = 37190, message = GL_INVALID_OPERATION in unsupported function called (unsupported extension or deprecated function?)
	glDisable(GL_CULL_FACE);
	glLoadIdentity();	 //GL CALLBACK: type = GL_ERROR, severity = 37190, message = GL_INVALID_OPERATION in unsupported function called (unsupported extension or deprecated function?)
	glFinish();
Now I'm left wondering whether GL_TEXTURE_2D, glClearDepth, glLoadIdentity etc. are unsupported, or perhaps I screwed up somewhere in my build. Is there a way to verify a function / feature is supported on Switch, preferably in bulk at compile time?

PS. I'm pretty sure I screwed up, because I overlooked your advice on EGL initialization settings. I'm still figuring out how to do it in my case. Currently I have:

Code: Select all

scr = SDL_CreateWindow(..., SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN)
glc = SDL_GL_CreateContext(scr);
As such, I don't call eglCreateContext() so I have to find out where the call is made and how to modify the parameters.

Re: Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Fri Nov 27, 2020 12:49 pm
by fincs
Since you're using SDL and not EGL directly, that means you're locked out of using legacy GL APIs (SDL2 does not support creating legacy GL contexts as far as I can tell). You'll have to switch over to using EGL directly, unfortunately.

Re: Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Sun Nov 29, 2020 11:47 am
by dmitry.grigoryev
Thanks, your suggestion worked just fine!
I'm still fighting some minor bugs, one of them seems to come from glRasterPos. I'm using GLAD for OpenGL 2.1 compatibility profile with all extensions, and have modified initEgl accordingly. Then I changed the EGL example to have only this GL code, which crashes.

Code: Select all

                initEgl(nwindowGetDefault());
                gladLoadGL();
		glClearColor(1,0,0,1);
		glClear(GL_COLOR_BUFFER_BIT);
		glRasterPos2i(0, 0);
                eglSwapBuffers(s_display, s_surface);
                // Wait for user input
                deinitEgl();
Removing glRasterPos2i(0, 0); heals the crash. Is glRasterPos problematic on the Switch, or am I doing something wrong?

Re: Legacy OpenGL code (glBegin/glEnd) on Switch

Posted: Mon Nov 30, 2020 12:49 pm
by fincs
glRasterPos2i is indeed a problematic function in legacy GL, since there is no hardware accelerated support for it in certain modern GPUs such as the one the Switch uses. Under normal circumstances a GL implementation has to fall back on software rendering, which is what upstream mesa implements. However, this software renderer is fairly costly in terms of code size and also defeats the purpose of providing a GPU driver library (not to mention it is very rarely used and since mesa is not optimized for static linking, *every* single homebrew application would need to pay the price), so it was disabled/removed in switch-mesa. Unfortunately we aren't able to offer an alternative that doesn't involve advising you to rewrite/adapt the code you're working with as to not rely on this feature.