Voir la version complète : [DEV] Redimensionner une image
Dr.Vince
18/01/2006, 13h00
Je me posais une question tout bête : dans les émulateurs pour nos chères consoles portables, quels algos sont utilisés pour redimensionner l'image à la taille de la machine cible ???
D'ailleurs Nrx et Alekmaul, quel technique utilisé vous ????
Alekmaul
18/01/2006, 13h28
Pour ma part, aucun algo car je ne redimensionne pas :p sous MarcaDS :)
Sinon, sur DS comme GBA, tu peux utiliser les registres de scalling / zoom pour réaliser ces opérations.
Donc, sur DS, avec les registres du type :
BG3_XDX,BG3_XDY,BG3_YDX,BG3_YDY,BG3_CX,BG3_CY et les équivalents pour le SUB screen.
Après, en mode vectoriel, tu peux toujours utiliser la règle de 3 pour passer d'une coord X vers X*ZOOM avec ZOOM en coef multiplicateur (0.5 pour 2 fois moins grands), mais cela ne sera pas terrible ...
Dr.Vince
18/01/2006, 13h37
Comment ça tu redimensionne pas ??? l'écran de la DS ne fait pas la même taille qu'une borne d'arcade me semble-t-il ???
et effectivement, ce serait pour utiliser le mode 3 sur GBA donc du vectoriel
Alekmaul
18/01/2006, 13h38
Double post car ce qui vient n'est pas de moi :ph34r: :
VOici la technique alpha lerp tirée de pocketheaven pour l'émulateur nes sur GBA et DS je crois.
avec le source :
http://pinocchio.jk0.org/gbaforum/alpha-lerp.zip
grilled ^^ , sinon, sur MarcaDS, j'utilise les 2 écrans de la DS en mode 0 avec sprites.
Si tu veux le faire en software pour le mode 3, c'est assez simple (mais très lent): en gros tu balayes une zone (le rectangle où se placera l'image redimensionnée), et pour chaque pixel tu retrouves par le calcul inverse à quel pixel il correspond dans l'image source. Par exemple si j'ai un zoom de 2x, je divise par deux, et je vois par exemple que le pixel 32 sur l'écran correspond en fait au pixel 16 de l'image source, donc chaque pixel de l'image source est dessiné deux fois sur l'écran (0 et 1 => 0 ; 2 et 3 => 1 ; 4 et 5 => 2, etc.), c'est donc bien un zoom 2x.
Voici un exemple (je l'ai pas testé et c'est pas super optimisé, mais ça te donne une idée ^^):
#define VIRGULE 16
void Rescale(unsigned short *spr, unsigned short *vptr, int x0, int y0, int lb, int hb, int l, int h) {
int x, y;
unsigned short *bits=vptr, *ptr, *spr2, *sprite;
int y_min, x_min, y_max, x_max;
long scaleX, scaleY, dstX, dstY;
int x1=x0+l, y1=y0+h;
//Clipping
if (x0>=0) x_min=x0;
else x_min=0;
if (y0>=0) y_min=y0;
else y_min=0;
if (x1<LARG) x_max=x1;
else x_max=LARG;
if (y1<HAUT) y_max=y1;
else y_max=HAUT;
//Calculs
scaleX=(lb<<VIRGULE)/l;
scaleY=(hb<<VIRGULE)/h;
dstY=scaleY*(y_min-y0);
for (y=y_min;y<y_max;y++) {
ptr=bits+LARG_BUF*y+x_min;
spr2=spr+lb*(dstY>>VIRGULE);
dstX=scaleX*(x_min-x0);
dstY+=scaleY;
for (x=x_min;x<x_max;x++) {
sprite=spr2+(dstX>>VIRGULE);
dstX+=scaleX;
if (*sprite==COLOR_TRANSPARENT) {
sprite++;
ptr++;
continue;
}
*ptr++=*sprite++;
}
}
}
Exemple d'appel:
#define LARG 240
#define HAUT 160
#define LARG_BUF 240
Rescale(mysprite, myvideobuffer, 0, 0, 16, 16, 32, 32);
Après si tu veux un filtrage bilinéaire pour agrandir c'est assez simple (tu calcules en virgule fixe plutôt qu'entier, et si tu es par exemple sur le pixel 1.4 de l'image source, tu prends 40% du pixel 1 + 60% du pixel 2), mais pour rapetisser un peu moins (et surtout beaucoup plus lent)...
Dr.Vince
18/01/2006, 14h59
Merci Brunni, mais en fait moi je voudrais faire l'inverse, c'est à dire réduire l'image source à la taille de l'écran GBA.
Alekmaul
18/01/2006, 15h47
Le topic sur PoketHeaven est le suivant, dans ma dernière réponse, il n'était pas présenté, désolé :| http://www.pocketheaven.com/boards/viewtopic.php?t=2368&postdays=0&postorder=asc&start=0
Alekmaul> La méthode utilisée pour PocketNES est vraiment très rapide mais elle ne fonctionne malheureusement que pour réduire la résolution verticale.
Dr. Vince> La routine que j'ai postée est un redimensionnement "au plus proche" (integer scaling), et avec ça tu peux réduire et aggrandir ton image sans problème. C'est juste si tu veux le faire en bilinéaire ("flou") que le rapetissage est plus compliqué.
Dr.Vince
18/01/2006, 16h01
ok, merci à vous deux !!!
Dans le meme genre : comment la gba micro avec ses 100*70 pixels (au pif) fait elle pour afficher des jeux concus pour du 240*160 ? Elle a de la puissance en plus pour faire du scaling ?
Dans le meme genre : comment la gba micro avec ses 100*70 pixels (au pif) fait elle pour afficher des jeux concus pour du 240*160 ? Elle a de la puissance en plus pour faire du scaling ?
elle fait 240x160 aussi mais ses pixels sont plus petits.
je vois mal nintendo s'amuser a saboter les images de ses jeux en les redimensionant. (surtout qu'il faudrai presque un 2 eme cpu rien que pour ca XD)
Le_Zouave
18/01/2006, 17h55
elle a pas moins de pixels, les pixels sont plus fin.
Alekmaul
18/01/2006, 17h55
EUh ... je pense pas dire une connerie en affirmant que GBA = GBA micro d'après les specs Nintendo , non :blink: ?
Donc elle est en 240x160 et pas moins ...
http://www.nintendo.com/techspecgba
[EDIT] Grilled, /me trop lent aujourd'hui ...[/EDIT}
EUh ... je pense pas dire une connerie en affirmant que GBA = GBA micro d'après les specs Nintendo , non :blink: ?
Donc elle est en 240x160 et pas moins ...
http://www.nintendo.com/techspecgba
[EDIT] Grilled, /me trop lent aujourd'hui ...[/EDIT}
huhu tu as vu ce triplé :)
mais toi tu as mis un lien ca prend + de temp ;)
elle fait 240x160 aussi mais ses pixels sont plus petits.
je vois mal nintendo s'amuser a saboter les images de ses jeux en les redimensionant. (surtout qu'il faudrai presque un 2 eme cpu rien que pour ca XD)
Ah c'etait donc ca !!
Dans ma profonde ignorance j'etais persuadé qu'un pixel etait une unité de valeur absolue, comme le centimetre...:-'
Merci a nes et aux autres :)
vBulletin® v.3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org