Fiou, ça c'est de l'optimisation de longueur de topic.
Voici mon petit problème. Je crée un petit programme en c++ avec la librairie SDL. Sur le site du zero, mes recherches m'ont permis de trouver un moyen de manipuler les pixels de l'écran sans passer par la fonction SDL_BlitSurface(...).
Voici ma fonction COLORIER qui, pour les coordonnées de l'écran x et y spécifiées par l'utilisateur, colorie le pixel possédant ces coordonnées avec la couleur (r,g,b) et avec la transparence (a).
Pour les couleurs ça marche parfaitement ; en revanche je n'obtiens aucune nuance de transparence. Ainsi, que je mette a = 0 ou a = 255, mon pixel est entièrement opaque.
Voici le code de la fonction :
void COLORIER(int x, int y, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
{
if(x>0 && y>0 && x<=screen->w && y<=screen->h){
Uint32 pixel;
pixel=SDL_MapRGBA(screen->format, r, g, b, alpha);
int nbOctetsParPixel = screen->format->BytesPerPixel;
Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/
switch(nbOctetsParPixel)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
/*Suivant l'architecture de la machine*/
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
}
Voilà, merci beaucoup ! ![]()
tiens, je connais ce code-là.
j'en avais aussi un peu bavé pour savoir à quoi correspondait tel ou tel octet... essaye dans l'ordre de ARGB, plutôt?
et si c'est la surface qui est affichée sur la fenêtre que tu dont tu cherches à faire varier l'alpha, abandonne, c'est carrément hors de propos. ![]()
Oula le CAPS LOCK pour le nom des fonctions c'est bien moche.
Avant toute chose, c'est quoi ton "protocole de test" ?
Ah, tu veux dire que si ma fenetre c'est "screen" et que mon pixel est collé sur la surface screen, je peux pas changer l'alpha de ce pixel?
Sinon, si ça intéresse certain :
Pour coller 1 million de pixels avec la fonction colorier, mon ordi a pris 8 millièmes de seconde.
Pour coller 1 million de pixels avec SDL_FillRect + SDL_BlitSurface (en collant des surfaces de 1 pixel par 1 pixel), l'ordi a pris 610 millièmes de secondes.
Par contre, si je crée une fonction RECTANGLE qui permet de dessiner des rectangles via une boucle for sur la fonction COLORIER, j'obtiens un résultat marrant.
Quand la surface contient moins de 42 pixels, la fonction RECTANGLE est plus rapide que SDL_Blitsurface, mais au-delà de 42 pixels, c'est SDL_blitsurface qui gagne. Bon à savoir.
tbop2 : je suis pas programmeur donc je suis pas sûr de ce que tu appelles protocole de test^^ Mais pour en arriver à la conclusion que mon alpha est pas/mal interprété, j'ai simplement créé une fenêtre SDL nommé screen. Ensuite j'ai créé une fonction qui dessine des rectangle avec une boucle for sur la fonction COLORIER. J'ai créé une seconde fonction qui elle dessine des rectangle avec SDL_FillRect et SDL_BlitSurface et qui prend aussi la valeur alpha.
J'ai mis les deux rectangles cote à cote sur un fond noir, les deux blittés sur la surface screen.
Le rectangle provenant de COLORIER était d'un vert vif, tandis que celui provenant de BlitSurface était un peu estompé (valeur alpha à 100)
C'est bien ta methode semble judicieuse au moins.
As tu regarde un peu ce qu'ils font dans le cas simple du RGB sur le site officiel ? http://www.libsdl.org/intro.en/usingvideo.html
J'ai regarde sur google mais rien trouve de concluant mais je suis sur qu'il y a un moyen pas tres complique d'y arriver.
Lu en diagonal en fin de pause mais ca doit sans doute repondre en grande partie a tes interrogations : http://www.gamedev.net/topic/528674-sdl_getrgbasdl_maprgba/
Oui j'ai déjà regardé dans la doc officielle.
Je vais voir ton second lien, merci pour tes réponses !
"Par contre, si je crée une fonction RECTANGLE qui permet de dessiner des rectangles via une boucle for sur la fonction COLORIER, j'obtiens un résultat marrant. "
need voir la tronche du code de la fonction RECTANGLE.
ben, absolument, les fenêtres ne sont généralement pas semi-transparentes sur une interface graphique. ![]()
une question pour op,
Si tu as un pixel noir sur ta surface screen et que tu utilise ta fonction colorier en passant en parametre un pixel blanc avec un alpha de .5, qu'est ce que tu attend sur ton ecran?
-------------caelacanthe :
tiens tu vas pas sur le 18-25 des fois?
La fonction RECTANGLE, en gros (je l'écris de mémoire):
void RECTANGLE(longueur,hauteur,x0,y0,R,G,B,A)
{
for(i=x0;i<=x0+longueur;i++)
{
for(j=y0;j<=y0+hauteur;j++){COLORIER(i,j,R,G,B,A);
}
}
}
"ben, absolument, les fenêtres ne sont généralement pas semi-transparentes sur une interface graphique."
==> Non mais je cherche pas à changer l'alpha de screen, je cherche à changer l'alpha des surfaces que je colle sur screen.
-------------godrik :
Euh, je suis pas certain, c'est le genre de truc trompeur^^ (ce qui est certain c'est que j'ai testé de mille manières et que mes surfaces provenant de COLORIER sont effectivement absolument opaques)
Mais je dirais que le pixel est, en RGB, (0,0,0) + 0.5*(255,255,255) = (122,122,122), ce qui devrait nous donner une espèce de gris, non?
(Je viens de penser qu'en fait, je pourrais récolter la valeur de tous les pixels de l'écran dans un tableau ecran[taille_ecran_x][taille_ecran_y][3] (3 pour RGB) et faire une fonction qui, selon une valeur alpha, colle une image sur l'écran en reproduisant cet effet de transparance)
Ah oui et pour ma fonction RECTANGLE, avant la double boucle j'ajoute juste deux lignes qui font que si le rectangle deborde de la surface sur laquelle il est collé, il est rogné proprement (c'est-à-dire que je réduis sa taille de manière qu'il rentre dans la surface, je ne "force" pas la surface à l'accueillir).
Pour répondre à Godrik http://en.wikipedia.org/wiki/Alpha_compositing
oui, ça m'arrive d'aller sur le 18-25, pour troller.
tu fais un appel de fonction à chaque fois? non mais okay quoi, mets-la en inline pour voir? ![]()
il s'agit de mettre le keyword inline, voir si c'est plus rapide, et l'enlever au cas où il ne conviendrait pas, c'est un test très basique pour un projet non-professionnel. ![]()
oh, et si les surfaces SDL se voyaient attribuer un flag, au chargement de l'image?
un petit flag genre contient des pixels semi-transparents, passe par la fonction lourde de calcul d'alpha à chaque pixel.
naturellement, la modification directe d'un pixel de l'image ne changerait pas la valeur du flag. ![]()
Tbop2,
Non, ca c'est ce que conchoide essaye de faire.
Si j'ai bien compris ce que la fonction colorier fait, elle remplace un pixel par un autre de couleurs donnees en parametre. Aucun compositing n'est effectue. Si tu ecris 0,0,0,0 sur la surface ecran, tu obtiens un pixel noir, si tu ecrit 1,1,1,1 alors tu obtiens un pixel blanc. Le canal alpha n'a pas de sens sur la surface ecran.
Regarde ce que fait la fonction colorier. I'll est evident qu'elle remplace sans composer. C'est pour cela qu'elle est plus rapide que blit.
J'ai vu que colorier remplacait sans composait mais c'est bien ce que Conchoide devrait faire n'est-ce pas ?
Excuse j'ai cru que tu posais une question innocente sur la composition en fait ![]()
EDIT: Ce que Conchoide devrait faire est bien de l'alpha compositing et non pas son code actuel.