Pages: 1
  Print  
Author Topic: [GL3.3] Multiple render targets (MRT)  (Read 8813 times)
Offline (Unknown gender) TheExDeus
Posted on: January 13, 2015, 03:38:48 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Wanted to try implementing deffered shading. Hit the wall that if I want to do it efficiently, then I should be able to render to several render targets ("surfaces") at once. Found out that GM:S can do it with an undocumented function called surface_set_target_ext(int index, int id); which takes the index for the "stage" (as Robert calls them) to bind and id is the surface itself. Sadly we make surfaces as individual framebuffer objects (FBO). OpenGL allows only one FBO to be bound at any one time. This means I cannot bind several of them at once, like GM does. GM can do it because it uses DX underneath (on Windows only I presume, where surface_set_target_ext only seems to work, and only HLSL shaders can render to MRT in GM:S as far as I can see) and it allows that (http://msdn.microsoft.com/en-us/library/windows/desktop/bb147221%28v=vs.85%29.aspx). In OGL you do it differently, you add all the required textures to the one FBO (http://ogldev.atspace.co.uk/www/tutorial35/tutorial35.html) which can then be bound and all the textures accessed.
So as I couldn't add surface_set_target_ext(), I planned to add surface_add_colorbuffer(), which would add a texture with specific formats to the FBO. Something like this:
Code: [Select]
surf = surface_create(640,480); //This create 640x480 RGBA texture with unsigned int type and BGRA format (this is how it's made default right now)
surface_add_colorbuffer(surf, 3, tx_rgb, tx_bgr, tx_float); //This adds 640x480 RGB texture with float type and BGR format (and binds it to GL_COLOR_ATTACHMENT0 + 3)
surface_add_depthbuffer(surf, tx_depth_component, tx_depth_component32f, tx_float); //This adds 640x480 depth texture with float type and 32f format (and binds it to GL_DEPTH_ATTACHMENT)
I intentionally bound it to color attachment 3 and skipped 2, so you would see where the number comes in later. Now we can do this in pixel shader:
Code: [Select]
layout(location = 0) out vec4 surfaceBufferOne;
layout(location = 3) out vec3 surfaceBufferThree;

void main()
{
    surfaceBufferOne = vec4(1.0,0.5,0.0,1.0); //This buffer actually holds unsigned integers, so this becomes 255, 127, 0, 255
    surfaceBufferThree = vec3(3.1415,2.4891,1.2345); //This holds floats
}
Depth is rendered automatically.

The problem with all of this is that I cannot make this work together with other systems. I need a new graphics_create_texture() function (I called it graphics_create_texture_custom) which I have no place to put. I need:
Code: [Select]
enum {
  //Formats and internal formats
  tx_rgba = GL_RGBA,
  tx_rgb = GL_RGB,
  tx_rg = GL_RG,
  tx_red = GL_RED,
  tx_bgra = GL_BGRA,
  tx_bgr =  GL_BGR,
  tx_depth_component = GL_DEPTH_COMPONENT
};

enum {
  //Internal formats only
  tx_rgb32f = GL_RGB32F,
  tx_depth_component32f = GL_DEPTH_COMPONENT32F,
  tx_depth_component24 = GL_DEPTH_COMPONENT24,
  tx_depth_component16 = GL_DEPTH_COMPONENT16,
};

enum {
  //Types
  tx_unsigned_byte = GL_UNSIGNED_BYTE,
  tx_byte = GL_BYTE,
  tx_unsigned_short = GL_UNSIGNED_SHORT,
  tx_short = GL_SHORT,
  tx_unsigned_int = GL_UNSIGNED_INT,
  tx_int = GL_INT,
  tx_float = GL_FLOAT;
};
which I cannot define in General, because I use GL_ enums. If I didn't, then I would still need to define them in General and then access them trough arrays, which is what GL3d3d file does which is garbage. And then I need to add surface_add_colorbuffer and surface_add_depthbuffer somewhere, but I cannot do it in General, because GL1 will never have it (and DX will probably not have it either). So I end up making a stupid header where all of this junk goes into.

I seriously consider forking ENIGMA to have only one graphics system, because GL1 is obsolete and I haven't really touched it forever, and DX9/11 are not worked on and are not required as far as I see. If we somehow manage to get GLES working then we would still have problems like these, but at least GLES is like 95% compatible, so problems would be a lot smaller.

I guess this is why most engines have only one graphics system. Or at least abstracts everything even more, so it becomes agnostic to it. We cannot easily do it, because we make a tool, which allows people writing their own code, which is already a layer on top of the graphics system.
« Last Edit: January 13, 2015, 03:42:20 pm by TheExDeus » Logged
Offline (Male) Goombert
Reply #1 Posted on: January 13, 2015, 05:57:05 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
First I would like to mention we don't just make a tool, we make a tool that is supposed to make it easy for newcomers. Maybe we should just accept the fact that we are too small of a group to writing our own graphics abstraction, it really is beyond the scope of this project and even YYG's uses ANGLE. There are many positives to using ANGLE:

1) ENIGMA would finally have its shit together in the graphics department and little duplicate graphics code, which despite my efforts we still have a lot of.
2) We can use HLSL and GLSL at the same time.
3) We would actually have working graphics for embedded systems and mobile.
4) Everybody could use surfaces, and there wouldn't be inconsistencies in the behavior of our graphics systems.

The only real downside is that it is not fully 100% native, and we have just a little added overhead, but this day and age, who cares? Additionally Harri I don't think you should be mapping the enumerators to OpenGL constants because that pollutes the enigma_user namespace, thus why we mapped them to arrays in the other systems. In the end, do we want to continue banging our heads against the wall over these abstraction issues or do we want to just make good games and have a solid game engine?

Anyway, did you even bother to Google search Harri? Why can't you swap the color attachments?
https://www.opengl.org/discussion_boards/showthread.php/183185-Multiple-FBOs-or-attachment-swapping

PS: Also I see that it is still and undocumented function, they must have just forgot.
http://gmc.yoyogames.com/index.php?showtopic=602766
« Last Edit: January 13, 2015, 05:59:26 pm by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) TheExDeus
Reply #2 Posted on: January 13, 2015, 06:42:58 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
1) ENIGMA would finally have its shit together in the graphics department and little duplicate graphics code, which despite my efforts we still have a lot of.
2) We can use HLSL and GLSL at the same time.
3) We would actually have working graphics for embedded systems and mobile.
4) Everybody could use surfaces, and there wouldn't be inconsistencies in the behavior of our graphics systems.
1 is only because of the number of systems we try to support. 2 I don't care about. 3 is potential plus. 4 is a myth. Besides polygone and his 1990's PC, nobody ever has any problems with it. I have tested it on so many PC's (new, old, laptops, desktop etc.) and zero problems.

Quote
Anyway, did you even bother to Google search Harri? Why can't you swap the color attachments?
That doesn't do what I need. I need to use 3 attachments AT THE SAME TIME, so I can render to them all in one pass. The forum post talks about changing one attachment to another just so you wouldn't need to bind a framebuffer, which is something totally different.

You are free to try ANGLE and see how hard it would be to add to ENIGMA as another graphics engine (or to replace all of them). I personally don't want it or have any reason to want it. For all desktop platforms >=GL3.3 is just fine. For embedded stuff there would have to be differences (when targeting GLES2.0, not GLES3.0), but in most cases those are just resource limitations (like in GLES2.0 you can have only one framebuffer object, so FBO's themselves are quite useless). I just think we should stop supporting 3 graphics systems people don't use. I personally haven't done anything for DX at all, so i'm sure it's already broken because of changes I have done elsewhere.
Logged
Offline (Male) Goombert
Reply #3 Posted on: January 13, 2015, 07:16:09 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
1) The number of graphics systems we try to support is less than or equivalent to that supported by other abstraction API's. Direct3D11 is necessary for Xbox 360 and modern Windows platforms including Windows Phone. Direct3D9 is necessary for older Windows version which still have at least 25% of the market share, and Steam/Valve hardware surveys are useless in this regard because they don't differentiate between casual and hardcore gamers so the market is probably under-represented in their statistics. OpenGL1 is not really a must anymore, we could honestly get rid of that, if their hardware doesn't support OGL3 features they will likely rather have Direct3D9 than use such an old OGL version, I doubt there's a single Linux computer out there that doesn't have framebuffer support. But to get rid of OpenGL1 means to get rid of what has been our most stable graphics system.

2) You may not care about it but potential users do when a lot of the Studio examples include shaders written in both languages. But I'll cede that I always cared more about CG.

3) Is not that big of a plus, we'd get it with GLES anyway. The only real reason it is a plus because it brings support for also other windows platforms where we haven't finished implementing the graphics, like Direct3D11/Xbox 360.

4) Windows Vista and XP still have a lot of market share, and polygonz computer don't work right because the default Vista drivers have poor OpenGL support, most of the time users can update the driver to get the support but polygonz is just a fail.

Quote from: TheExDeus
I personally haven't done anything for DX at all, so i'm sure it's already broken because of changes I have done elsewhere.
That's really a poor position to take on the issue considering before and after changes to OpenGL3, Direct3D9 still gets better performance on some systems including mine.

At any rate I do not have the time, I am starting discrete math and chemistry this semester so I have to be cracking the books. I do not really know what ANGLE would entail, from what DaSpirit has told me it seems to be that you can only use GLES 2.0 and they are adding GLES 3.0 support soon, which means the code still has to be written in OpenGL3, it would just take our OpenGL3 system port it to GLES 2.0 and plug in ANGLE and it would work everywhere. In fact, we could write all the GLES in one abstract GLES system and allow you to optionally run it with ANGLE. So in other words we only support OpenGL3 natively and you can optionally turn on ANGLE for other platforms.

So in other words we just make ANGLE optional, we get the best of both worlds including fully native GL where it will run and optionally building with a little overhead for older platforms or platforms like Xbox 360.
« Last Edit: January 13, 2015, 07:18:22 pm by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Pages: 1
  Print