Événements liés
  • Démo technique du samedi #3: 19 Mai 2007
Pages: [1] 2 3   Bas de page
Imprimer
Auteur Fil de discussion: [Demo] Screenshot et application 3D  (Lu 8218 fois)
0 Membres et 1 Invité sur ce fil de discussion.
Smealum Hors ligne
Assassin
Administrateur
*****
Messages: 590


Voir le profil WWW
Assassin

« 19 Mai 2007, 11:18:44 »

Dans cette démo, nous allons vous montrer comment prendre un screenshot en utilisant la technique "reg_capture", puis l'appliquer sur un objet en 3D.

Note : cette démo est entièrement codée sous libnds.

Code découpé et expliqué

Code
(c):
#include <nds.h>
#include <stdlib.h>
#include <stdio.h>
On commence simple, en incluant les headers qui nous seront utiles.

Code
(c):
#include "texture_bin.h"
On inclut la texture qui sera affichée sur le poly avant qu'aucun screenshot ne soit pris. Elle fait 256*256 et a été convertie avec gfx2gba en utilisant ces paramètres :
"gfx2gba -c32k *.bmp"

Code
(c):
u8* screenbuffer;
On déclare un buffer qui servira à stocker le screenshot. Pour l'instant, ce n'est qu'un pointeur, on lui allouera de la mémoire plus tard.

Code
(c):
float zoom=2.0f;
float rotateX = 0.0;
float rotateY = 0.0;
int textureID;
Diverses variables utiles pour la partie 3D de la démo.

Code
(c):
void screen(u8* buff) {
REG_DISPCAPCNT=DCAP_BANK(3)|DCAP_ENABLE|DCAP_SIZE(3);
while(REG_DISPCAPCNT & DCAP_ENABLE);
dmaCopy(VRAM_D, buff, 256*192*2);
}
Fonction servant à prendre une capture d'écran et à la stocker dans un buffer.
REG_DISPCAPCNT <= sert à prendre un screenshot; voici les paramètres qu'il requiert :
DCAP_BANK(x) : choix de la Vram utilisée pour la capture. Elle doit être en mode LCD. 0 : Vram A, 1 : B, 2 : C, 3 : D
J'utilise ici la D.
DCAP_SIZE(x) : taille de la capture.
0:128x128, 1:256x64, 2:256x128, 3:256x192
Ici, on veut tout l'écran, donc on met 3
dmaCopy <= La capture est enregistrée dans la Vram D, donc on la copie vers le buffer qui a été donné en argument à la fonction

Code
(c):
int main() {
Fonction principale.

Code
(c):
screenbuffer=(u8*)malloc(256*192*2);
On alloue de la mémoire au buffer avec un malloc.

Code
(c):
powerON(POWER_ALL);
 
/* On met l'écran du haut en mode 0 3D et celui du bas en mode 0 2D
parce que le blanc c'est moche et que la console ça rox */

videoSetMode(MODE_0_3D);
 
/* Vram A, B et C : textures (on n'a pas besoin d'autant d'espace, mais bon...);
Vram D : mode LCD (au moins une Vram doit être en mode LCD pour que la capture puisse fonctionner...
pas nécessairement la D comme dit plus haut) */

vramSetMainBanks(VRAM_A_TEXTURE,VRAM_B_TEXTURE,VRAM_C_TEXTURE,VRAM_D_LCD);
 
// On init l'IRQ
irqInit();
irqEnable(IRQ_VBLANK);
On init la console.

Code
(c):
glInit();
glEnable(GL_TEXTURE_2D);
glClearColor(0,0,0,31);
glViewPort(0,0,255,191);
gluLookAt(0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
On init la 3D.

Code
(c):
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_256 , TEXTURE_SIZE_256, 0, TEXGEN_TEXCOORD, (u8*)texture_bin);
On charge la texture qui va recouvrir notre poly au début.

Et, enfin, la boucle principale :         
Code
(c):
while(1) {
// Screenshot
if((keysUp() & KEY_A))
{
// On prend le screenshot
screen(screenbuffer);
// On reset les textures
glResetTextures();
// On charge la nouvelle texture
glBindTexture(0, textureID);
/* Comme vous pouvez le voir, la texture est en 256*256 alors que l'écran fait 256*192...
C'est un peu gênant mais pas un réel problème, il faudra juste faire attention
à bien adapter aux proportions lors du choix des coordonnées de la texture. */

glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_256 , TEXTURE_SIZE_256, 0, TEXGEN_TEXCOORD, (u8*)screenbuffer);
// On met un fond de couleur aléatoire pour changer un peu....
glClearColor(rand()&31,rand()&31,rand()&31,31);
/* Cette valeur est une valeur très approchée permettant dans cette scène d'avoir le quad
quasi-exactement aligné avec la caméra. Cependant, il changera pour chaque scène... */

zoom=1.09f;
// On met la rotation à 0
rotateX=0;
rotateY=0;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(35, 256.0 / 192.0, 0.1, 100);
glColor3f(1,1,1);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glMatrixMode(GL_MODELVIEW);
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
glPushMatrix();
glLoadIdentity();
 
// On met les touches à jour....
scanKeys();
// Rotations....
if((keysHeld() & KEY_UP)) rotateX += 3;
if((keysHeld() & KEY_DOWN)) rotateX -= 3;
if((keysHeld() & KEY_LEFT)) rotateY += 3;
if((keysHeld() & KEY_RIGHT)) rotateY -= 3;
// Déplacements....
if((keysHeld() & KEY_R)) zoom += 0.15;
if((keysHeld() & KEY_L)) zoom -= 0.15;
// Translation (pour le déplacement)
glTranslate3f32(0, 0, floattof32(-zoom));
// Rotation
glRotateX(rotateX);
glRotateY(rotateY);
 
// On applique notre texture
glBindTexture(0, textureID);
 
// On dessinne la face sur laquelle sera la texture
glBegin(GL_QUADS);
/* Un screen a été pris, alors on adapte la face aux proportions de l'écran de la DS
(la hauteur de l'écran est 75% de sa largeur) */

glTexCoord2f(0.0f, 0.75f); glVertex3f(-1.0f, -0.75f,  0.0f);
glTexCoord2f(1.0f, 0.75f); glVertex3f( 1.0f, -0.75f,  0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  0.75f,  0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  0.75f,  0.0f);
glEnd();
 
glPopMatrix(1);
glFlush(0);
 
swiWaitForVBlank();
}

Désolé si c'est un peu mal rédigé et peu explicite par moment, mais j'ai été pris par le temps...

Enfin, voici une archive avec les sources : http://www.dev-fr.org/screenshot.rar
Journalisée

birslip Hors ligne
Administrateur
*****
Messages: 513


Voir le profil WWW
« Réponse #1 : 20 Mai 2007, 13:15:35 »

Bonne explication! Je pense par contre que tu pourrais compléter un peu, surtout pour l'histoire de la 3D sur les deux écrans en même temps, grâce à ce fameux registre ^^. Bon sinon, ces démos du samedi elles sont géniales, vivement samedi prochain!
Journalisée

Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« Réponse #2 : 20 Mai 2007, 14:05:52 »

Roh, et la vidéo, elle est passé où ? ^^ Sinon va falloir que je regarde ça de plus prêt, ça m'a l'air bien sympa
Journalisée

xFlasH Hors ligne
Newbie
*
Messages: 21


Voir le profil
« Réponse #3 : 21 Mai 2007, 11:08:13 »

Très bonne démo!

Le seul hic que j'émettrais est la non-initialisation du seed. Les couleurs aléatoires qui nous sont renvoyés sont les memes, sur 2 lancements successifs. De l'ordre de la fioriture :-p
Sinon pour les personnes qui comme moi n'ont pas encore updaté la libnds, un workaround vite fait est de bypasser le nom de la macro REG_DISPCAPCNT n'existant pas encore, par DISP_CAPTURE
Code:
#define REG_DISPCAPCNT DISP_CAPTURE
Attention ceci est une bidouille qui permettra une compil vite fait sans avoir a updater, mais en aucun cas une solution viable a long terme.

Sinon +1 pour ces "démos du samedi" qui sont un vrai facteur de remotivation dans ces weekends pour se remettre a son code.


xf
Journalisée
Smealum Hors ligne
Assassin
Administrateur
*****
Messages: 590


Voir le profil WWW
Assassin

« Réponse #4 : 21 Mai 2007, 16:41:49 »

Très bonne démo!

Le seul hic que j'émettrais est la non-initialisation du seed. Les couleurs aléatoires qui nous sont renvoyés sont les memes, sur 2 lancements successifs. De l'ordre de la fioriture :-p
Sinon pour les personnes qui comme moi n'ont pas encore updaté la libnds, un workaround vite fait est de bypasser le nom de la macro REG_DISPCAPCNT n'existant pas encore, par DISP_CAPTURE
Code:
#define REG_DISPCAPCNT DISP_CAPTURE
Attention ceci est une bidouille qui permettra une compil vite fait sans avoir a updater, mais en aucun cas une solution viable a long terme.

Sinon +1 pour ces "démos du samedi" qui sont un vrai facteur de remotivation dans ces weekends pour se remettre a son code.


xf

Ah, oui, pour le changement de registre, j'aurais dû préciser.... D'ailleurs, pour ceux qui ne sont pas au courant, libnds aime bien changer le nom de ses registres, juste pour que les codeurs fassent un peu de gymnastique ;)
Journalisée

MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #5 : 21 Mai 2007, 17:32:57 »

...ce qui influe aussi sur Palib non ? suivez mon regard Wink
Journalisée

Pitt Hors ligne
Administrateur
*****
Messages: 575


Voir le profil WWW
« Réponse #6 : 21 Mai 2007, 22:06:24 »

Vraiment sympa comme démo ! Enfin c'est du repompé sur EI0, mais c'est intéressant d'avoir le comment du pourquoi. Cheesy
Journalisée
MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #7 : 22 Mai 2007, 00:19:37 »

Citation
c'est du repompé sur EI0

hum, y avait surtout une démo des drunken-coders ...

mais celle là est mieux !  Wink

mais pourrais tu aller à la ligne, dans tes commentaires de code, le scroll horizontal en plus du vertical, à force, c'est pénible... Smiley
Journalisée

Alekmaul Hors ligne
Papi codeur et
Administrateur
*****
Messages: 1229


Voir le profil WWW
Out of memory error ...

« Réponse #8 : 22 Mai 2007, 08:23:26 »

Plus que les drunken coders, c'est surtout sur GBADEV  que l'on a parlé de cela pour, comme l'a dit birslip, la 3D sur les 2 écrans de la DS. http://forum.gbadev.org/viewtopic.php?t=11364
Journalisée

Mon site PortableDev : l'émulation sur GBA et sur DS
Smealum Hors ligne
Assassin
Administrateur
*****
Messages: 590


Voir le profil WWW
Assassin

« Réponse #9 : 23 Mai 2007, 21:41:59 »

Citation
c'est du repompé sur EI0

hum, y avait surtout une démo des drunken-coders ...

mais celle là est mieux !  Wink

mais pourrais tu aller à la ligne, dans tes commentaires de code, le scroll horizontal en plus du vertical, à force, c'est pénible... Smiley
Hmmmm... Ferais tu référence à cette démo ?
http://www.dev-fr.org/Smea/screen_done.PNG
Si oui, bien qu'elle utilise une texture drunken coders, elle est de moi Wink
Et c'est pas pompé d'EI0....c'est EI0 qui est pompé de la démo  Tongue
Journalisée

morukutsu Hors ligne
Sr. Member
****
Messages: 437


Voir le profil
Noctambule

« Réponse #10 : 16 Mai 2008, 11:59:00 »

Je voulais savoir, dans le cas ou on travaille que sur un seul écran. Est-ce qu'on peut se permettre de faire une capture par frame tout en conservant un framerate acceptable (60 fps Langue) ?
J'aimerai bien faire des effets sur l'écran du blur, glow, etc...

Merci d'avance !
Journalisée
MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #11 : 16 Mai 2008, 13:48:15 »

Smealum : c'etait ça... bien vu !! (ouch, un an de retard pour répondre  whistle )
Journalisée

Smealum Hors ligne
Assassin
Administrateur
*****
Messages: 590


Voir le profil WWW
Assassin

« Réponse #12 : 16 Mai 2008, 15:44:43 »

Je voulais savoir, dans le cas ou on travaille que sur un seul écran. Est-ce qu'on peut se permettre de faire une capture par frame tout en conservant un framerate acceptable (60 fps Langue) ?
J'aimerai bien faire des effets sur l'écran du blur, glow, etc...

Merci d'avance !
Si je me souviens bien, utiliser la capture à chaque frame fera automatiquement tomber le framerate à 30 FPS.
Journalisée

morukutsu Hors ligne
Sr. Member
****
Messages: 437


Voir le profil
Noctambule

« Réponse #13 : 16 Mai 2008, 15:47:32 »

Ah, je pensais que c'était juste si on veut faire un affichage 3D sur les deux écrans.

Je viens d'essayer et ça fait vraiment baisser le framerate (je passe à 50% d'utillisation CPU).
Faut que je trouve un autre moyen de faire mes effets maintenant  Cry
Journalisée
Noda Hors ligne
Full Member
***
Messages: 208


Voir le profil WWW
« Réponse #14 : 16 Mai 2008, 16:55:54 »

Je voulais savoir, dans le cas ou on travaille que sur un seul écran. Est-ce qu'on peut se permettre de faire une capture par frame tout en conservant un framerate acceptable (60 fps Langue) ?
J'aimerai bien faire des effets sur l'écran du blur, glow, etc...

Merci d'avance !
Si je me souviens bien, utiliser la capture à chaque frame fera automatiquement tomber le framerate à 30 FPS.

non, on peut faire du blur/bloom/ce que tu veux à 60fps Wink seulement faut au minimum faire du double-buffering de l'écran

D'ailleurs, la dernière version (internal) de Marble permet de faire du motion blur sur tout l'écran en mode 3D double screen et toujours à 30fps Langue
« Dernière édition: 16 Mai 2008, 16:57:36 par Noda » Journalisée
Pages: [1] 2 3   Haut de page
Imprimer

Aller à: