GP2X Trenki's Software Renderer Tutorial

Discussion in 'General Discussions' started by Trenki, Feb 9, 2008.

  1. dockthepod

    dockthepod Member

    Joined:
    Jun 15, 2006
    Messages:
    250
    Thanks Trenki! Texturing works just like I thought it would :) Those varyings are really handy.
     
  2. dockthepod

    dockthepod Member

    Joined:
    Jun 15, 2006
    Messages:
    250
    Hi Trenki. I was seeing some big slowdowns when I had fullscreen coverages (ie, I was drawing a lot of big triangles) so I stuck my single_fragment directly in the affine_span to avoid the function call overhead. My app went from 25 -> 45 fps with that one tiny change. I haven't really looked at optimizing beyond that but thought you might be interested.
     
  3. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    Interesting. This should normally not be the case since the compiler would inline the single_fragment function. Was the single_fragment function declared inline and/or defined inside the fragment shader class? How exactly did you move the function directly into affine_span? Are you sure you didn't change anything else?

    Please let me know and maybe have a look at both, the single_fragment and the new affine_span function. You can also PM me if you like.
     
    Last edited by a moderator: Dec 18, 2015
  4. Daid

    Daid Member

    Joined:
    Jun 13, 2006
    Messages:
    267
    Location:
    Netherlands
    Maybe his compile options won't allow any optimalizations?

    Got any pointers where I can learn a bit more about 3D stuff. All this 'pipeline' and 'shaders' is new for me. I'm also wondering what the '.w' part is in "out.w = 1 << 16;"
    I've played a bit with openGL, and understand a bit of 3D vector math. But that's about it. (Really interrested in seeing what I can do with your code, but it looks like it requires a bit more knowlage then basic openGL)
     
  5. dockthepod

    dockthepod Member

    Joined:
    Jun 15, 2006
    Messages:
    250
     
    Last edited by a moderator: Dec 18, 2015
  6. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    Yeah, compile options are very important. I always use -O3 and -funroll-loops and I noticed the open2x devkit with gcc 4.1.1 compiles better than devkitGP2X on Windows with gcc 4.0.2.

    The out.w coordinate is the fourth coordinate of a homogenous point in 3D. It is normally computed when you do modelview_projection_matrix * vertex where vertex normally is (x, y, z, 1). mvp * vertex gives you a homogenous vector (x', y', z', w) after transformation. This allows one to have perspective transformations. out.w = 1 << 16; simply sets w to 1 (in fixed point 16.16). w will end up beeing 1 whenever you do an orthographic projection whereas with a perspective projection w can become any value.

    The renderer requires substantions knowledge of the "Graphics Pipeline". To learn more anbout it you may try "Graphics Pipeline", "Rendering Pipeline", "3D Pipeline" in Google. Also the OpenGL specification describes the pipeline to some extent.
     
  7. efegea

    efegea Member

    Joined:
    Aug 8, 2005
    Messages:
    636
    Location:
    GP32Spain, Spain
    I'm playing with it and like it a lot. I'm understanding how it works and got a CAL3D model shown on the screen, well kind of, I'm still fighting with the matrices. At least I can see the model, and can scale it using a matrix, and apply the model view projection matrix...more or less. At least I'm improving :lol:

    <--------EDIT------->
    Well I got it working!

    But two problems:

    1- I have upside down textures. Inverted. Don't know how to spell it.
    2-There is some kind of...is it called clipping? Is like some polygons from the back overlaping polygons on the front.
     
  8. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    1. The Cal3D model probably has the texture coordinates stored in a way that suits OpenGL with (0, 0) at the bottom left corner while "normal" images are stored top down and thus have (0,0) in the upper left. The simplest way to fix this is to modify the t (y) texture coordinate y' = 1 - y. This can be done in the vertex shader or after loading the model.

    2. Polygons in the back overlapping polygons in the front indicates a wrong depth test. You need to have a depth surface and do the correct depth test in the fragment shader yourself. Look at the cow demo for a depth testing example.
     
    Last edited by a moderator: Dec 18, 2015
  9. dockthepod

    dockthepod Member

    Joined:
    Jun 15, 2006
    Messages:
    250
    I hacked on this a bit more last night. I can't figure out why my fragment shader is so slow. I profiled my game and I spend 90% (literally) of the time in affine_span. What compile options should I use? I've tried 02, 03, unroll-loops, etc. No dice.
     
  10. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    Have you confirmed that putting the fragment shader source directly into the affine_span function actually makes things faster? I doubt it does so. In the last source fragment you posted you had commented out the depth test which of course would have made it faster but also would not have given the same results.

    I always compile with -O3 and -funroll-loops. If you are using my sources as base you should also "#define GP2X" as this makes it use the mmuhack. You really want to use the mmuhack and probably also the ramhack (included in my cow demo) to make things as fast as possible.

    You can best test your fragment shader by drawing a fullscreen quad and see how long it takes. A single texture mapped quad takes 5.2ms with fixed texture size and 6.1ms with variable texture size. You can compare your numbers with this.

    You can also PM me your fragment shader and I will have a look at it.

    EDIT: You should also #define NDEBUG via the command line in a release build, so that all asserts are removed from the source.
     
    Last edited by a moderator: Dec 18, 2015
  11. dockthepod

    dockthepod Member

    Joined:
    Jun 15, 2006
    Messages:
    250
    Thanks Trenki :) I'll play around some more when I get home. I'm confident that it can go much faster with the right settings. The good news is your renderer has allowed me to make great progress on the game I've been kicking around in my head for a long while now. Thanks again for release it!
     
  12. efegea

    efegea Member

    Joined:
    Aug 8, 2005
    Messages:
    636
    Location:
    GP32Spain, Spain
    Thanks Trenki! :)

    That was so easy to fix. Now I can see the model without artifacts. Thanks!

    A small video of what I got :D
    http://personales.ya.com/efegea/cal3d_trenki_renderer.avi
    But that on my athlon64 3400, I have not GP2X. I got 75 fps as average.
     
    Last edited by a moderator: Dec 18, 2015
  13. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    Nice video! 75fps seems too low though on a AMD64 3400 as the gp2x is 10-15 times slower. Did you compile with full optimization? How many triangles does the model have? When you want good performance on the gp2x you should get at least 200-250fps on your system.
     
  14. Exophase

    Exophase Nothing good will ever come of Exophase.

    Joined:
    Sep 21, 2006
    Messages:
    10,308
    Location:
    Cleveland OH
    Is that possibly being limited by vsync? 75MHz is a pretty normal number for refresh rate.
     
    Last edited by a moderator: Dec 18, 2015
  15. efegea

    efegea Member

    Joined:
    Aug 8, 2005
    Messages:
    636
    Location:
    GP32Spain, Spain
    I was thinking so. My screen refresh rate is 75hz. But as far as I know there is not any code for enabling/disablig vsync in my code.


    Oh ok, SDL_flip waits for vsync. That was the bug. I have to use SDL_UpdateRect I think..


    EDIT: it's weird, changed it and the framerate is still the same
     
  16. Daid

    Daid Member

    Joined:
    Jun 13, 2006
    Messages:
    267
    Location:
    Netherlands
     
    Last edited by a moderator: Dec 17, 2015
  17. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    Oh ok, SDL_flip waits for vsync. That was the bug. I have to use SDL_UpdateRect I think..


    EDIT: it's weird, changed it and the framerate is still the same



    SDL (at least on Windows) does not give you a hardware surface, so I don't know if they even do vsync with SW_SURFACEs. I circumvented vsync by only requesting a single buffered surface and rendering to another SDL_Surface and blitting the result to the screen in the end. This also works on the gp2x and can make things a lot faster as you don't waste time waiting for vsync. The little tearing is actually pretty unnoticable.
     
    Last edited by a moderator: Dec 18, 2015
  18. efegea

    efegea Member

    Joined:
    Aug 8, 2005
    Messages:
    636
    Location:
    GP32Spain, Spain
    I do that. I use the same code as in your cow example. But it's still at 75fps. I think it's the vsync but perhaps it isn't.

    That when my cpu is at 2400Mhz, when I reduce the speed to 1000Mhz, the framerate drops to 45fps
     
    Last edited by a moderator: Dec 18, 2015
  19. Trenki

    Trenki Member

    Joined:
    Jun 15, 2006
    Messages:
    114
    Location:
    South Tyrol, Italy
    @efegea: I don't know what you are doing exactly but on Windows there should not be any vsync at all (at least not for my cow demo which you use as base code). What compiler are you using by the way? When I compile my cow demo with VC++ in Release mode I get 73-75fps on Windows Vista AMD Turion64 X2 2.2Ghz while I get 255-270fps when I compile with GCC 4.2.1 with -O3 -funroll-loops -DNDEBUG. This definitly shows that GCC is better.

    @Daid: Simply setting out.w to z may produce a perspective effect but probably one which you do not want. You should construct a normal perspective projection matrix and multiply the vertex with it and assign the result to out.w. You can use my vector_math library for that. It has all the necessary functions.
     
  20. efegea

    efegea Member

    Joined:
    Aug 8, 2005
    Messages:
    636
    Location:
    GP32Spain, Spain
    I'm on 64 bit gentoo linux, AMD Athlon64 3400 2.4Ghz, GCC 4.1.2 with -O3 -funroll-loops -DNDEBUG, 125fps on your cow demo
     

Share This Page

Loading...