Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / GL BlendModes For Sprites/RenderImages

Author
Message
Grizzlius_Maximus
7
Years of Service
User Offline
Joined: 16th Oct 2017
Location:
Posted: 25th Apr 2020 11:37
I am aware about SetSpriteTransparency() Having a additive blend but I want to access other GL BlendModes like GL_DST_ALPHA, GL_ONE, GL_ZERO, etc. I came from GameMaker:Studio which offered these and I utilized many of them to create shadows, lighting, silhouettes and many other complicated stuff. I've searched other threads and it seems like there is no easy solution but I'm hoping since it 2020 now, things have changed. I really think its essential that AppGameKit should have these blendmodes. I'm using Tier 2 btw so I may be able to access the OpenGL commands through C++ (I have no idea though)
xCept
21
Years of Service
User Offline
Joined: 15th Dec 2002
Location:
Posted: 25th Apr 2020 21:26
Yes, I had hoped for this feature since 2011 and especially with V2 when "Sprite Blending Modes" were promoted on the Kickstarter. I suppose one can argue that similar blending is possible via shaders, but it adds undue complexity to the system. I used to use Cocos2D and it had simple BlendFunc commands for doing any number of boolean operations and blends against two sprites. I've been unable to easily port certain apps to AppGameKit due to this limitation.
Raven
19
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 26th Apr 2020 03:53 Edited at: 26th Apr 2020 03:54
While AppGameKit does employ a OpenGL 2.0 Compatibility (OGL-ES 1.1) Specification... it's key to note that the Fixed-Function Support for OpenGL 2.0, was only retained to supported the Semi-Programmable and Fixed-Function Graphics Hardware.
From 2005 and later., all Graphics Hardware became Fully Programmable Pipeline; meaning that while Driver Support for Fixed-Function Features (like Blend Modes) were maintained, these are Software Emulated and can have less than desired results on Modern Hardware.

Instead of the Fixed-Function., you have Shader Support.
https://learnopengl.com/Advanced-OpenGL/Blending

This actually does an excellent job of explaining how the GL Blend can be achieved in Fragment Shaders., just be aware that the way that GL Blend worked... is that you're Queuing a Fixed-Function Post Process, for once the Render Pass has occurred.
Where-as with a Fragment Shader; you can actually do these at ANY time and with whatever elements of the output you want with a Per Object or Per Scene Draw.
As a note, this is actually why Transparency used to have "Weird" Artefacts in a lot of games from 2005 to 2010... as A LOT of Graphics Developers generally used the Fixed-Function Blend Modes without actually understanding HOW they worked in the Hardware Pipeline.

Getting it right can be quite tricky, especially if you're using a lot of Post-Process Effects that rely on Depth Buffer Information.
And AppGameKit doesn't exactly help with this because it doesn't support Multiple Render Image output from a Shader... so it's not like you can exactly bake the Transparency into the Depth Buffer without additional Passes.
There is no "Unified" Solution so-to-speak, because of how you approach Post-Processing in a Programmable Pipeline.

As you'll typically be fighting between Accuracy and Performance.
I've seen claims that Programmable it's "Slower" to achieve Blend Modes., but the reality is that performance wise there is very little difference *IF* you're actually doing the exact same Pipeline Steps that the Blend Modes would be doing in the Background.
That is to say... it's merely a "Last Step" for a given Draw Pass.

Now again a limitation of AppGameKit will rear it's head... in that you can't #include additional Shaders (for some reason AppGameKit just doesn't support Nestled Includes unlike DBP), so you'll always have to include the Blend Mode Functions manually; in your Fragment Shader.
Thus I'd recommend getting used to how to do each and comment it, so when you go back you understand that's what you're doing with glFragColor as a "Last Step" in your Shader.
Bengismo
7
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 26th Apr 2020 10:29 Edited at: 26th Apr 2020 11:14
Raven wrote: "This actually does an excellent job of explaining how the GL Blend can be achieved in Fragment Shaders., just be aware that the way that GL Blend worked... is that you're Queuing a Fixed-Function Post Process, for once the Render Pass has occurred."


Sorry but that is absolutely inaccurate. A lot of what you have stated above is just plain wrong.

Firstly: The example tutorial you have linked to actually uses the built in GL blend modes! It doesnt replace them in any shader ....it just uses them to do the blending as per what they are set to in the open gl functions.

Secondly: AppGameKit does have, and uses GL blend modes...these are used on everything that is drawn in AGK. Ive explained that below.

Thirdly: The equivalent of gl_blendmodes cant really be acheived in shaders as you dont have the destination colour or alpha in a shader to blend with.
All you do in a fragment shader is set the source colour and alpha (ie the fragment colour) - you dont know anything about what it is about to be applied to. You would have to render each sprite to a render target then pass the render target to the next sprite to be drawn just to get at the destination colour and destination alpha data which would be ludicrously slow and laborious. Especially when gl blendmodes are still used and available on any modern hardware.

Even when using Fragment shaders and vertex shaders...the blending using GL_BlendModes occurs after them both. Blending is a per sample operation (see image below) that occurs last in the open GL process. This is still the case in the latter versions of open GL and even in vulcan too.

See: https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview



Even Vulkan has settable blend modes that occur outside of the shaders:
https://vulkan.lunarg.com/doc/view/1.0.26.0/linux/vkspec.chunked/ch26s01.html

You can do a lot with shaders but overwriting the built in GL blend modes isnt really one of them without using largenumbers of render targets for everything you draw.

Grizzlius_Maximus wrote: " I want to access other GL BlendModes like GL_DST_ALPHA, GL_ONE, GL_ZERO, etc."


All app game kit objects allow you to set the blend modes per object...
See: https://www.appgamekit.com/documentation/Reference/3D/SetObjectBlendModes.htm

So you can set the source and destination blend modes as you want them to be. (any of those you listed)

This is for 3d objects only though.... So to use these, you could render your sprites as planes with an orthographic camera setup and do exactly what you want to with blend modes. Which is a little awkward as it involves using 3d items even just for sprite drawing.

In the case of sprites there are only 3 transparency modes (0=off, 1=alpha transparency, 2=additive blending)

internally these use the following GL blend modes
0 - Off: Source GL_ONE, Destination GL_ZERO (destination is replaced by the source)
1 - Alpha: Source (sourceAlpha) , Destination (1-sourcealpha)
2 - Additive: Source GL_ONE, Destination GL_ONE (both are added together)

These are the only built in modes for sprites unfortunately. This is the case as sprites can be batched in agk and drawn in less operations, the batching currently doesn't take into account individual blend modes. In theory a per sprite belndmode setting could be added to agk. Its already the case for 3d objects.

As you are using teir 2 there is a way to do this with sprites. Set the sprite transparency to mode 3 (Mode 3 has no effect) then use these function

agk:: PlatformSetBlendEnabled( int mode )
Set mode 1 to turn it on

agk:: PlatformSetBlendFunc( int mode1, int mode2 )
Mode1 = source blendmode
Mode 2 = destination blendmode

There you go...blend modes fully set.

Then manually draw your sprites. Manually drawing it is important though as AppGameKit can batch together sprite drawing. Meaning the changes to blend modes for individual sprites wouldnt get made halfway through a batch draw. So the results wouldnt be right if you let agk draw them as part of a Render() call.


As you are capable in C++ you could modify the AGK2 source and add a source and destination blend mode to the sprite class. Then modify agk:latformSetBlendMode( int mode ) to set them every time a sprite is drawn. It would work for small numbers of sprites with individual textures or if you manually draw them. The batching functions would need to be updated so that individual sprites could have their own blend functions and still be used in a normal Render() or sync() call.

Using the 3d drawing version may be easier if you are still getting to grips with AppGameKit teir 2 and involves no modification to the source. Approximating the blend modes in a shader might also be possible but it wont be really be correct unless you pass the contents of the back buffer to the sprite being rendered to get at the destination colour and alpha inside the shader. Its not necessary to do this just to set GL blend modes.

Edited: for horrific spelling mistakes
Grizzlius_Maximus
7
Years of Service
User Offline
Joined: 16th Oct 2017
Location:
Posted: 26th Apr 2020 13:19
Thanks Bengismo for the elaborate explanation!

I tried using agk:: PlatformSetBlendEnabled( int mode ) and agk:: PlatformSetBlendFunc( int mode1, int mode2 ) but these functions were internal and made inaccessible. I could meddle around with the source code but I am not too confident in myself.

I happen to find this work around by using #include <gl\gl.h> with its functions glEnable(GL_BLEND) and glBlendFunc (GLenum sfactor, GLenum dfactor) and it works! It does seem to override AppGameKit defined blendmodes which i'm fine with. Just like the internal AppGameKit blend functions, they do not work with Render() and the sprites need to be drawn manually. I actually prefer declaring the blendmode on the spot and drawing the sprites manually than setting the blendmode per sprite .

I am not too sure if this solution is proper especially when dealing with cross-platforms but it seems to be working the way I want it.
Bengismo
7
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 26th Apr 2020 14:06 Edited at: 26th Apr 2020 14:08
Good work...

You can make the app class a friend of agk:: and get access to just abouut everything. In any case, the platformSetblendMode functions internally call the GL functions that you have called above (like you have used them) so its doing the exact same thing in the end. At least on open gl it is.

It isnt totally cross platform anymore (like you said)but that doesnt matter at all unless you plan on cross compiling for android. Even then a small change would make it work.

Glad you got it working.

Login to post a reply

Server time is: 2024-11-22 05:39:29
Your offset time is: 2024-11-22 05:39:29