Pages: « 1 2
  Print  
Author Topic: [OGL3] Shader Test  (Read 18092 times)
Offline (Male) Goombert
Reply #15 Posted on: December 29, 2014, 12:33:23 am

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

View Profile
Harri I still want to dig for lower level solutions to this. Mainly it seems that a lot of applications on the internet also just don't care, including some graphics abstraction API's. I am going to dig to see what ANGLE does about this, and see if I can figure out whether Studio has this issue if the user draws the surface themselves.

The first thing I'd like to roll out, is messing with the projection or matrices, I think me and you both hate that option, it's way too much math involved and it has too many caveats to work in all cases. I am open to the shader solution, if we provide a way to disable it. Another thing we could do is just flip the texture data the first time surface_get_texture is called on the surface after it was rendered to with surface_set_target, though I don't know what the cost of this is compared to doing it in the shader after upload, obviously more efficient for drawing the surface without changing it multiple times in a row which is the same concept applied to vertex buffers, a pixel buffer could be used to do this. This is actually similar to the correct way OpenGL would handle it, there should have been an extension to change the pixel upload origin since framebuffers were introduced. Take the following Nvidia extension which lets you specify this origin for blitting to the main window.

https://www.opengl.org/registry/specs/ARB/clip_control.txt

Quote from: OpenGL Spec
    When rendering Direct3D content into a framebuffer object in OpenGL, there
    is one complication -- how to get a correct image *out* of the related
    textures.  Direct3D applications would expect a texture coordinate of
    (0,0) to correspond to the upper-left corner of a rendered image, while
    OpenGL FBO conventions would map (0,0) to the lower-left corner of the
    rendered image.  For applications wishing to use Direct3D content with
    unmodified texture coordinates, the command

        glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);

    configures the OpenGL to invert geometry vertically inside the viewport.
    Content at the top of the viewport for Direct3D will be rendered to the
    bottom of the viewport from the point of view of OpenGL, but will have a
    <t> texture coordinate of zero in both cases.  When operating in this
    mode, applications need not invert the programmed viewport rectangle as
    recommended for windowed rendering above.

We would just call that function to flip the viewport when surface_set_target is called and then call the same function to undo that in surface_reset_target, it's only a two line fix. It looks like it's OpenGL 4.5 though.
https://www.opengl.org/sdk/docs/man/html/glClipControl.xhtml

Sadly, I don't even have this extension.
Quote from: GLEW Info
GL_ARB_clip_control:                                           MISSING
--------------------
  glClipControl:                                               MISSING

ANGLE does it in the shader, so this is also how it is done in GM: Studio. Search PDF for "Direct3D inverts the"
http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf

Here's the specific commit where they fixed FBO flipping in ANGLE
https://code.google.com/p/angleproject/source/detail?r=b31f532d7137039e73d5bbdcc0b54a9883718c58&path=/src/libGLESv2/mathutil.h

For the solution we find we should (if we can) offer a way to disable it, in which case all of our surface drawing functions draw with upside down coordinates and the user has to do the same when using the surface as a texture. But let me keep doing some additional research.
« Last Edit: December 29, 2014, 01:03:27 am 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 #16 Posted on: December 29, 2014, 08:41:59 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
I am open to the shader solution, if we provide a way to disable it.
The problem is that user shaders will have to take this account every time. This will also break all compatibility with GM shaders (which right now are about 99% compatible).

Quote
Another thing we could do is just flip the texture data the first time surface_get_texture is called on the surface after it was rendered to with surface_set_target, though I don't know what the cost of this is compared to doing it in the shader after upload, obviously more efficient for drawing the surface without changing it multiple times in a row which is the same concept applied to vertex buffers, a pixel buffer could be used to do this.
For most cases you don't need to do any flips in the pixel shader, as you can flip the texture coordinates in the vertex shader. That is extremely fast. Of course as the texture lookup can be independent of texture coordinates, then you must flip the GLSL texture lookup functions (like done in ANGLE). Flipping texture on the CPU will be A LOT slower. And doing it on some surface_get_texture() will basically ruin the surface for any later drawings on it, which would make surfaces quite unusable. Surfaces are not just for using once, draw once, clear surface. You often draw on them multiple times over many frames, like when drawing blood or bodies in a Crimsonland clone or something like that.

Quote
Here's the specific commit where they fixed FBO flipping in ANGLE
ANGLE translates GLSL to HLSL. In this translation they can do a lot of marvelous things. We on the other hand don't do any GLSL parsing. And I don't nominated myself to write a GLSL parser. So the solution doesn't work for us, because any user's shaders will have to manually do this inversion themselves. This means no compatibility with GM, no compatibility even with shaders found online. ANGLE had this quite easy actually, as they just flip all the textures in memory to be upside down just like FBO's, and then do the other flip in shaders. So in the end the fix is a lot easier. They don't differentiate between a regular texture and an FBO texture like we are trying to do.
Logged
Offline (Male) Goombert
Reply #17 Posted on: December 29, 2014, 08:47:46 am

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

View Profile
Yeah I hadn't considered that you may want to draw to the same surface again, so flipping on the CPU is out of the question.

What about doing what ANGLE does then, would that be compatible with GM Studio shaders? If not our only real option is to just use ANGLE. It however would be nice if we all had GL4.5 cards and could just use the proper fix.
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 #18 Posted on: December 29, 2014, 09:25:23 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
As I said - to replicate that what ANGLE does we will need a GLSL parser, that can replace all texture lookup functions with a custom one. In the simplest case it could be a find/replace kind of fix, but I don't think it would be that easy. And it must be done in run-time, probably in glsl_shader_compile().
I don't think using ANGLE is an option, as it just adds another layer of abstraction on top of one we already have. The idea of ANGLE is to be able to run GLES programs on Windows. It's not meant for GL3 or GL4 to run in Windows, as they technically can already do it. They have a shader validator which we could maybe use, but that's about it. Using ANGLE just to flip a freaking texture is an overkill.
Logged
Pages: « 1 2
  Print