#165063 - AntonioND - Mon Dec 08, 2008 4:03 pm
Hello!
I was bored this morning and I did this rtt example, I hope you like it. Source code is included (I used the Textured_Cube example of libnds) but it's a bit messy.
Controls:
A/B: Scale small cube.
Pad: Rotate small cube.
Download:
http://antoniond.drunkencoders.com/files/rtt_example.rar
Capture:
http://antoniond.drunkencoders.com/files/rtt.png
Bye!
PS: Ti-Ra-Nog, here you are. :P
Last edited by AntonioND on Wed Dec 10, 2008 4:44 pm; edited 3 times in total
#165064 - TiRaNog - Mon Dec 08, 2008 4:24 pm
Yeah!! I love it!!
Many thanks AntonioND :D
See you!! ;-)
#165091 - Maximus32 - Tue Dec 09, 2008 7:57 pm
Very interesting!
I see you're using VSYNC for both the texture and the real scene, doesn't this reduce the framerate from 60 to 30 fps? If so, would it be possible to capture the texture without using VSYNC?
Does every rendered texture require an entire VRAM bank?
_________________
Bricks-OS, Operating System for Game Consoles
#165095 - AntonioND - Tue Dec 09, 2008 8:43 pm
I think you can't do it run at 60 fps. If you want to capture anything, you have to display it first. If you do so, you need to use a VRAM bank to save the image displayed on the screen and another one for the texture. If you want more textures, you don't need to use an entire bank, just tell the display capture register to save the data in another location inside the same bank.
If I am wrong, please tell me.
#165097 - Maximus32 - Tue Dec 09, 2008 9:19 pm
I don't think you need to actually display it first, it just needs to be rendered. The SourceA bit from the capture register selects: 0) the display, or 1) the 3D engine.
_________________
Bricks-OS, Operating System for Game Consoles
#165105 - AntonioND - Tue Dec 09, 2008 9:53 pm
Maximus32 wrote: |
I don't think you need to actually display it first, it just needs to be rendered. The SourceA bit from the capture register selects: 0) the display, or 1) the 3D engine. |
gbatek wrote: |
24 Source A (0=Graphics Screen BG+3D+OBJ, 1=3D Screen) |
What I understand from reading this is that if I enable that bit, only the 3D image displayed on the screen is captured.
#165117 - DiscoStew - Wed Dec 10, 2008 5:06 am
I wonder. What if using a single screen (the main screen) with BG0 and BG2 active, having BG2 "over" BG0 so BG0 is "hid", then alternating frames as you have it AntonioND with drawing cube to capture into VRAM_B to be used as a texture, then drawing cube using captured texture, and capturing the real scene into VRAM_C, and displaying the VRAM_C content onto BG2? BG0 will continue to alternate the 3D data, but BG2 will be in front of it, hiding that alternating sequence, and it will show the final result.
_________________
DS - It's all about DiscoStew
#165129 - AntonioND - Wed Dec 10, 2008 4:43 pm
Yeah, that's a good idea. New version in the first post ^^.
#165134 - DiscoStew - Wed Dec 10, 2008 8:22 pm
Cool. Looks much cleaner now, hehe.
I congratulate you on getting this to work, but the one thing that is bugging me about it is that it's running at 15FPS, not 30FPS. My assumption behind this is that you not only do a combined glFlush and swiWaitForVBlank to make sure that the 3D data gets rendered for the texture, which takes a frame, but afterwards, you use the capture hardware, and wait for that to go full circle, which takes up another frame, totaling 2. Combine this with that same method with rendering the real scene and capturing it, and that takes up another 2 for a total of 4 frames per completion. Hence, 15FPS.
I'm looking at your code now to see if there is a way around this.
EDIT:
Heh, I "sorta" got it fixed by making a little change. The previous code was...
Code: |
swiWaitForVBlank();
vramSetBankC(VRAM_C_LCD); //Scene goes to VRAM_C
REG_DISPCAPCNT=DCAP_BANK(2)|DCAP_ENABLE|DCAP_SIZE(3)|DCAP_SRC(1);
while(REG_DISPCAPCNT & DCAP_ENABLE);
vramSetBankC(VRAM_C_MAIN_BG_0x06000000); |
What I did was removed waiting for the capture hardware to finish, and moved the swiWaitForVBlank into that position to now have...
Code: |
vramSetBankC(VRAM_C_LCD); //Scene goes to VRAM_C
REG_DISPCAPCNT=DCAP_BANK(2)|DCAP_ENABLE|DCAP_SIZE(3)|DCAP_SRC(1);
swiWaitForVBlank();
vramSetBankC(VRAM_C_MAIN_BG_0x06000000); |
I did the same change to portion with the cube getting captured to be used as a texture, and now, it all runs at 30FPS. The side-effect to this is that the "outer" color from the use of ClearColor seem to have swapped as well, so even though clearing with green for use with the captured cubed to texture is now showing blue instead of green, and vice versa for the actual scene. It's probably because glClearColor is not tied in to glFlush as actual geometry is, and is most likely linked to the H-Blank.
_________________
DS - It's all about DiscoStew
Last edited by DiscoStew on Wed Dec 10, 2008 8:47 pm; edited 2 times in total
#165136 - Maxxie - Wed Dec 10, 2008 8:34 pm
AntonioND wrote: |
What I understand from reading this is that if I enable that bit, only the 3D image displayed on the screen is captured. |
If you take a look at the block diagram
You will notice that the capture will work (at least if gbatek is right there) with the 3d as source, even if BG0 is disabled for display in the layering process.
_________________
Trying to bring more detail into understanding the wireless hardware
#165137 - DiscoStew - Wed Dec 10, 2008 8:39 pm
Maxxie wrote: |
AntonioND wrote: |
What I understand from reading this is that if I enable that bit, only the 3D image displayed on the screen is captured. |
If you take a look at the block diagram
You will notice that the capture will work (at least if gbatek is right there) with the 3d as source, even if BG0 is disabled for display in the layering process. |
So its just a matter of not using MODE_5_3D, and going with MODE_5_2D | ENABLE_3D then?
_________________
DS - It's all about DiscoStew
#165138 - Maxxie - Wed Dec 10, 2008 8:44 pm
That's at least what i read out of gbatek. Haven't tried tho :p
_________________
Trying to bring more detail into understanding the wireless hardware
#165139 - AntonioND - Wed Dec 10, 2008 8:52 pm
Maxxie wrote: |
That's at least what i read out of gbatek. Haven't tried tho :p |
I tried with MODE_5_2D and it works, but only half of frames the image is displayed. The rest of frames the screen is black. I'll try with framebuffer mode.
EDIT: Framebuffer mode OK. ;) Thank you both. I'm trying to fix that thing about clear colors.
#165143 - DiscoStew - Wed Dec 10, 2008 9:20 pm
I believe I got the ClearColor portion fixed (this is still using MODE_5_3D), but I did quite a bit of rearranging with the code to get it to work fine. This is what I came up with...
Code: |
if(framecount & 1) //--------'real' scene-----------
{
swiWaitForVBlank();
vramSetBankB(VRAM_B_LCD); //Texture goes to VRAM_B
vramSetBankC(VRAM_C_MAIN_BG_0x06000000);
REG_DISPCAPCNT=DCAP_BANK(1)|DCAP_ENABLE|DCAP_SIZE(3)|DCAP_SRC(1);
glClearColor(0,0,31,31);
glViewport(0,0,255,192);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//---------------------------------------------------------------------
gluLookAt( 0.0, 0.0, 1.0, //camera possition
0.0, 0.0, 0.0, //look at
0.0, 1.0, 0.0); //up
//move it away from the camera
glTranslate3f32(0, 0, floattof32(-1));
glRotateX(rx);
glRotateY(ry);
GFX_TEX_FORMAT = (GL_RGBA<<26) | ((TEXTURE_SIZE_128)<<20) |
((TEXTURE_SIZE_128)<<23) | (((int)VRAM_B) >> 3);
DrawCube();
glFlush(0);
}
else //---------texture scene---------
{
swiWaitForVBlank();
vramSetBankB(VRAM_B_TEXTURE);
vramSetBankC(VRAM_C_LCD); //Scene goes to VRAM_C
REG_DISPCAPCNT=DCAP_BANK(2)|DCAP_ENABLE|DCAP_SIZE(3)|DCAP_SRC(1);
glClearColor(0,31,0,31);
glViewport(0,64,128,192);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 128/128, 0.1, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//---------------------------------------------------------------------
gluLookAt( 0.0, 0.0, 1.0, //camera possition
0.0, 0.0, 0.0, //look at
0.0, 1.0, 0.0); //up
//move it away from the camera
glTranslate3f32(0, 0, floattof32(-1));
glRotateX(rotateX);
glRotateY(rotateY);
glScalef(scale,scale,scale);
glBindTexture(0, textureID);
DrawCube();
glFlush(0);
} |
It looks odd from what it originally looked like, but it makes sense to me. Basically, each section starts right at the VBlank, and right afterwards, the display capture hardware is set up to deal with everything that was set up "in the last frame", while afterwards, the current frame is being dealt with.
_________________
DS - It's all about DiscoStew
#165150 - AntonioND - Wed Dec 10, 2008 10:36 pm
Yeah, I understand. ;)
Fixed and uploaded (again). I've put a define to change between framebuffer mode and mode 5+3D. Thanks for your help, DiscoStew.
BTW, at the begining I didn't notice it was running at 15 fps. XD
EDIT: Updated to work with latest libnds.