dockthepod
Member
- Joined
- Jun 15, 2006
- Messages
- 250
Thanks Trenki! Texturing works just like I thought it would Those varyings are really handy.
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?dockthepod said: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.
Trenki said: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?dockthepod said: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.
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.
I'm using your example code as a starting point so my single_fragment is inside of my shader class. To move it over, i just did something like this ->
CODE
#if 0
unsigned short d = fd.z >> 16;
// if (depth16 < d) return 0;
depth16 = d;
int s = std::min(std::max(fd.varyings[0] >> 16, 0), 31);
color16 = (s << 11) | (s << 6) | s;
const int write_mask = 3; // FragmentShader::single_fragment(fd, color16, depth16);
#else
const int write_mask = FragmentShader::single_fragment(fd, color16, depth16);
#endif
I made two builds just flipping that #if to check the difference. I'll play around with it some more tonight after work.
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.efegea said: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.
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.dockthepod said: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.
Thanks Trenki!Trenki said: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.
Is that possibly being limited by vsync? 75MHz is a pretty normal number for refresh rate.Trenki said: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.
Trenki said: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.
Does -O3 always generate correct code? (I've had some issues with it with some GCC 4)
QUOTE
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.
Ok thanks. Silly question from my side I guess, but if you set out.w to the same as z (limit from 1 to 0xFFFF, in 16.16 format) would you get simple perspective projection then? Or do I need to calculate the projection matrix for that? (My matrix math knowlage is very low )
QUOTE
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.
I'm reading this one right now: http://www.extremetech.com/article2/0,1697,9722,00.asp seems to cover quite a bit (to much for the GP2x I recon ) just letting anyone else with interrest know.
Oh ok, SDL_flip waits for vsync. That was the bug. I have to use SDL_UpdateRect I think..efegea said: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.
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.Trenki said: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.