Ben si j'ai bien compris ce que les linuxiens tout fiers m'ont raconté, Wine prend un exécutable Windows et exécute le code dans un environnement virtuel (j'imagine qu'il charge les DLL et que la résolution des noms se fait au début de l'application comme sous Windows, donc du coup pas d'overhead au milieu).
Ca ne change pas que si je fais selon la vieille API Windows:
void DessineRectangle(int32 x0, int32 y0, int32 x1, int32 y1, uint32 color)
{
uint32 colorBGR = (color & 0xff00ff00) | ((color >> 16) & 255) | (color & 255) << 16;
HBRUSH hbr = CreateSolidBrush(colorBGR);
RECT rt = {x0, y0, x1, y1};
FillRect(hdcWindow, &rt, hbr);
DeleteObject(hbr);
}
Maintenant que je fais pareil, disons avec OSLib (je ne connais pas linux, c'est pour prendre un exemple):
void DessineRectangle(int32 x0, int32 y0, int32 x1, int32 y1, uint32 color)
{
oslDrawFillRect(x0, y0, x1, y1, color);
}
En faisant de la même manière que Windows je devrais émuler le CreateSolidBrush qui me crée un objet qui servirait à rien ici vu qu'il contient juste une bête couleur. C'est forcément moins bon. Plus haut je parlais de la différence en hard, alors voilà le même exemple mais en hard (sceGu se mappe quasi 1:1 sur le hard, et dans cet exemple c'est le cas):
typedef struct {
unsigned long color;
short x, y, z;
} OSL_LINE_VERTEX;
OSL_LINE_VERTEX* vertices = sceGuGetMemory(2 * sizeof(OSL_LINE_VERTEX));
vertices[0].color = color;
vertices[0].x = x0;
vertices[0].y = y0;
vertices[0].z = 0;
vertices[1].color = color;
vertices[1].x = x1;
vertices[1].y = y1;
vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES, GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices);
Maintenant regardons la manière de faire en OpenGL:
glBegin(GL_QUADS);
glColor4ub(color & 255, (color >> 8) & 255, (color >> 16) & 255, (color >> 24) & 255);
glVertex2d(x0, y0);
glVertex2d(x1, y0);
glVertex2d(x1, y1);
glVertex2d(x0, y1);
glEnd();
Ca n'a purement rien à voir. Dans le cas d'openGL tu traces tes vertices à la volée, tu ne sais pas combien à l'avance il y en a (elles ont peut être une mémoire à eux comme sur DS, elles sont peut être dans une pile à la fin de la VRAM, ...). Sur PSP on les met dans le commandbuffer (display list), donc tu vas devoir détecter quand une liste de vertices commence à être tracée, sauvegarder la position du commandbuffer, puis ensuite revenir dès que tu as fini (comment détecter? => un check de plus dans toutes les fonctions qui accèdent à la command list) pour définir à cette endroit un saut (histoire que le GU n'exécute pas la liste de vertices). Note qu'on pourrait aussi stocker les vertices à la fin de la displaylist mais ça serait pas efficace si on veut la garder pour la réexécuter plus tard vu qu'elle prendrait forcément tout l'espace qui lui est alloué.
Sur PSP tu as la primitive SPRITES qui est bien adaptée, sur OpenGL tu te taperas toujours des quads, qui sont moins performants. Sur OpenGL les couleurs sont définies en 4 parties donc il y a décomposition puis recomposition (pas efficace). Bref je maintiens que dans tous les cas du moment que tu as une API différente de ce que ton système propose vraiment, même en 100% natif tu as de l'overhead car tu ne fais rien d'autre que simuler un environnement virtuel qui n'est pas celui d'origine
