Mojo2: compiling/linking shaders should not crash

Monkey Forums/Monkey Programming/Mojo2: compiling/linking shaders should not crash

Shinkiro1(Posted 2016) [#1]
When you have a glsl syntax error, that should not create an unrecoverable error.
This makes hotloading a shader impossible, which in case doesn't allow experimentation.

I suggest either throwing an exception or somehow indicate that the shader wasn't compiled/linked successfully.

---
Ps: Specifically, I am talking about the glCompile and glLink functions inside glutil.monkey


Shinkiro1(Posted 2016) [#2]
*push*


Dima(Posted 2016) [#3]
You bring up a very good point...

I wrote a simple Shadertoy.com loader when first discovering Mojo2, mainly to learn something about GLSL, but also because it seemed crazy simple to setup in Monkey. Sample code in 'modules/mojo2/bananas/shadereffect' is pretty much good to go with only a few tweaks, like drawing to full screen and exposing some of the uniforms. I ended up using only 2 of the uniforms; iResolution and iGlobalTime, which was enough for many of the shaders to work unmodified, while others only needed minor tweaks to hide unused uniforms.

Here's where I was heading with that... The thought to allow rudimentary "hotloading" did cross my mind, similar to Shadertoy, but I never bothered because loading existing shaders from text files seemed to do the trick, and I was simply content and moved on to other things.

Now I saw your post and started thinking again, how not having runtime error control can cause severe headaches and even prevent some of features. Editing and compiling shaders at runtime is a great example, probably not very common, but a clear demonstration of how the runtime error can prevent potentially required features.

I'm wondering if more like that exist in Monkey. I even went and tried to rename an existing text file as an image (renamed extension .txt to .png), thinking maybe there's a way to break Monkey with corrupt data. Monkey however refused to BUILD the project (html5) while TRANS complained that image.png could not be loaded. It must be copying files from build folder in some funny way, because simply having that file in the data folder prevented from compiling (no reference to that file in code anywhere, purely at build time if corrupt image exists in data, html5 target)

This is kinda where I stopped. I also tried dividing by zero on the HTML5 target and got an error only in Debug, while Release build didn't complain at all, and printed the result as "0". Dividing by zero in GLSL did not produce any errors, compiled and ran, but showed a white screen instead, so clearly something broke inside the shader.

At this point I don't know how realistic an updated error handling system for Monkey is, so i wouldn't get my hopes up, especially considering Monkey2 in development . I imagine there had to have been reasons, maybe something with having so many targets and language constraints per target or too much effort involved. I would think Monkey2 will address this, and be very surprised if it doesn't.

Wondering if you can fiddle with native target codes that generate GLSL build errors and throw an exception instead? Probably depends on the target, but you really only care about this one particular shader build error this much right? Someone around here who knows Monkey internals should probably know if this possible or the effort required.

Totally a valid concern about lacking runtime error control.

Regards,
Dmitriy


Shinkiro1(Posted 2016) [#4]
hey Dmitriy,
actually I know it's possible because i 'hacked' it into monkey.
all you have to do is replace the error() calls inside glCompile() and glLink with exceptions. (in mojo2/glutil.monkey)
now when i load a shader, i catch the exception and print it to the console.

this allows you to let the app running, while you can edit the shader in a texteditor:
make changes -> save -> reload shader

this is much better than having to recompile the whole application.

if someone wants to do the same, here is code (replace the last 2 functions).
Function glCompile:Int( type:Int,source:String )

	#If TARGET<>"glfw" Or GLFW_USE_ANGLE_GLES20
		source="precision mediump float;~n"+source
	#Endif

	Local shader:=glCreateShader( type )
	glShaderSource shader,source
	glCompileShader shader
	glGetShaderiv shader,GL_COMPILE_STATUS,tmpi
	If Not tmpi[0]
		Throw New glException("Failed compiling fragment shader: "+glGetShaderInfoLog( shader ))
	Endif
	Return shader

End

Function glLink:Void( program:Int )
	glLinkProgram program
	glGetProgramiv program,GL_LINK_STATUS,tmpi
	If Not tmpi[0]
		Throw New glException("Failed linking program: "+glGetProgramInfoLog( program ))
	End
End

Class glException Extends Throwable
	Method New(message:String)
	    Self.message = "glException: " + message
	End

    Method ToString:String()
        Return message
    End

	Private
	Field message:String
End



Nobuyuki(Posted 2016) [#5]
It's worth making a pull request, I think! Unfortunately since monkey2 dev has ramped up, mx releases seem to have slowed; I'm guessing that we just need to push a few more patches like this one to get a bugfix release with all of the latest updates..