bon j´ai un problème je suis en train d´essayer de faire une console, et j´aimerait bien faire un truc transparent donc j´ai essayé 2 ou 3 trucs mais ca donne une transparence trop moche, ou trop transparente, ou pas assez, ou alors l´image devient toute noire et j´ai eu toute les merdes possible.
si qqun s´en est déjà servi j´amerai savoir comment il faut régler ces paramètres:
g_pD3DDevice->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
g_pD3DDevice->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pour le moment je les ait mis comme ca mais mon image en toute blanche et c moche.
j´aimerais aussi savoir a quoi ca correspond DESTBLEND et SRCBLEND.
Direct3D uses the following formula to determine the final color for each pixel in the primitive´s image.
FinalColor = TexelColor × SourceBlendFactor + PixelColor × DestBlendFactor
et merde! c koi cette addition la !
ya pas moyen d´utiliser une autre methode parce ke moi ce ke je veu c´est une multiplication l´addition c pas du tout la bonne technique !
moi j´amerais ca:
FinalColor = Factor * PixelColor
pour faire du blending, tu peux faire (a priori, si je ne me trompe pas, j´ai pas essayé de mon côté, je me base que sur
le SDK). A priori pour ta console, il te faut du blending additif, dont la formule est :
AlphaColor = SrcColor * (1.0 - AlphaCoeff) + DestColor * AlphaCoeff (avec 1.0f > AlphaCoeff > 0.0f)
Le seul paramètres de Direct3d qui semble correspondre est :
D3DBLEND_BOTHINVSRCALPHA
Source blend factor is (1–As, 1–As, 1–As, 1–As), and destination blend factor is (As, As, As, As); the destination blend
selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state.
Donc tu fais g_pD3DDevice->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_BOTHINVSRCALPHA); (et seulement cette ligne, elle change les paramètres pour la source et la destination : "the destination blend selection is overridden")
Bien sur, t´oublie aps non plus la ligne g_pD3DDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, TRUE);
En conclusion :
g_pD3DDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_BOTHINVSRCALPHA);
(en croisant les doigts pour que ça marche, mais je pense que c´est ça)
--------------------------
Pour info, les paramètres D3DRS_SRCBLEND et D3DRS_DSTBLEND définissent les coefficients de la formule de blend. J´ai pas trop le temps de développer, mais si ça t´intéresse vraiment, dis le moi et je ferais un post plus détaillé.
j´ai déja essayé cette technique mais en développant:
g_pD3DDevice->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
ce qui revient au meme et d´ailleur la SDK dit que c´est une technique obsolete d´utiliser BOTH.
je ne sais pas pkoi (car tout le monde utilise ca!) et bien ca ne fonctionne pas je n´y vois absolument rien quand je regle comme ca (pas de console elle est 100\% transparente)
"mais si ça t´intéresse vraiment, dis le moi et >je ferais un post plus détaillé."
oui ca m´interesse
)
Oui tout le monde fait comme ça, c´est nomal le blend additif est le plus répandu (en fait il consiste en une moyenne pondérée de deux valeurs, tout bêtement).
Donc une couleur 32 bits est composé de 4 composantes A R G B (R G B A, ça dépend mais c´est pareil). Pour le blend additif, il est facile donc de retrouver les formules :
Blended_A = Src_A * As + Dst_A * (1.0f - As)
Blended_R = Src_R * As + Dst_R * (1.0f - As)
Blended_G = Src_G * As + Dst_G * (1.0f - As)
Blended_B = Src_B * As + Dst_B * (1.0f - As)
(Avec Src_X, Dst_X et As des float compris entre 0.0f et 1.0f)
Ici, par analogie au SDK qui dit "FinalColor = TexelColor × SourceBlendFactor + PixelColor × DestBlendFactor", on a SourceBlendFactor = (1.0f - As) et DestBlendFactor = As
Src pour toi, c´est ta console, et Dst c´est ton frame buffer.
Si As == 1.0f, alors ton objet est entièrement opaque et s´il est égal à 0, il est transparent. Je pense que ton problème vient de là, car je ne vois nul prt que tu définis ce coeeficient As (qui dans to ncas sera égal à 0.5f, ta colsole sera alors à moitié transparente). Je ne sais pas comment ça marche dans Direct3D, mais à mon avis il te faut préciser cette valeur dans la texture dans ta console. Donc avant de passer ton bitmap pour que Direct3D créé ta texture, pense à bien mettre toutes tes composantes As à la bonne valeur (je pense que ta texture est en fait un tableau de unsigned char (ou BYTE, c´est pareil, ou UCHAR), donc la valeur à mettre est 255 * As.
Pour être plus clair, si ton bitmap est par exemple BYTE* Texture; (dans l´ordre ARGB)
for(int Color=0; Color<Texture_Width*Texture_Height*4; Color+=4)
{
Texture[Color] = 128; // Si As == 0.5f en float, ça donne bien sur 128 en BYTE
}
Ou dans l´ordre RGBA :
for(int Color=3; Color<Texture_Width*Texture_Height*4; Color+=4)
{
Texture[Color] = 128; // Si As == 0.5f en float, ça donne bien sur 128 en BYTE
}
Mais tout cela est bien longuet, et puis comment faire si on bosse avec des textures 24 bits RGB ? (ce qui, entre nous, n´est pas très malin, car même si la composante A ne va pas nous servir, elle permait à une couleur d´être traité en une fois 32 bits, et non pas en 3 * 8 bits, magie des proc 32 bits)
J´ai pas regardé en profondeur, mais je suis sur qu´il y a moyen d´imposer la valeur As à Direct3D, qui ignorera alors tout simplement la composante A dans ta texture. En fait, on ne se sert jamais de la composante A pour un simple belnding comme le tien, mais par contre, c´est pratique pour faire un mask blit, ou si toi apr exemple tu veux que ta console soit plus transparente à certains endroits.
En tout cas, regarde du côté de SetTextureStage, je suis sur que c´est quelque part là dedans.
-----------------------------------------------------
D3DRS_SRCBLEND et D3DRS_DSTBLEND servent en fait juste à définir comment vont être blendé les deux couleurs.
Par ex :
g_pD3DDevice->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_INVSRCCOLOR);
ça va correspondre à :
Blended_A = Src_A * As + Dst_A * (1.0f - Src_A)
Blended_R = Src_R * As + Dst_R * (1.0f - Src_R)
Blended_G = Src_G * As + Dst_G * (1.0f - Src_G)
Blended_B = Src_B * As + Dst_B * (1.0f - Src_B)
car D3DBLEND_SRCALPHA --> Blend factor is (As, As, As, As).
et D3DBLEND_INVDESTCOLOR --> Blend factor is (1–Rd, 1–Gd, 1–Bd, 1–Ad).
etc etc... Toutes les combinaisons sont possibles, mais certaines doivent rendre bien bizarre : )
En tout cas il faut retenir qu´on se sert très très souvent de l´additif, aussi car il est commutatif. Imagine que tu doives renderisé un objet transparent. Le fait que le blend soit commutatif te permet renderiser les faces de l´objet dans le desordre (bien sur, l´objet transparent doit être renderisé APRES les objets non transparents, et en désactivant le ZBuffer).
Par contre, pour un blend non commutatif, il faut trier les faces de l´arrière vers l´avant, obligatoirement sinon ça ne rend pas pareil.
Voila voila, en esperant t´avoir éclairer un petit (bien que certains passages soit confus, o nse perd dans les A,R,G,B,As,Dest...).
non c´est bon g tout compris.
par contre pour les textures je ne peux pas faire de boucles comme ca parce ke mes textures sont gérées par les interfaces de DX et j´ai pas facilement accès bas niveau comme ca, d´ailleur ma texture est en 8 bits palétisés.
pour régler l´alpha en théorie je dois m´occuper seulement de la couleur de vertices (en réalité il s´agit un Vertex shader rélgé en Flat qui serait largement suffisant si ca fonctionnait, un mode gouraud me permettrait de faire plus transparent dans les angles mais c un peu ridicule)
de toute manire ca ne fonctionne pas et comme tu le dis mon As doit etre 0 parce ke le SRCALPHA c focrément le Channel alpha de la texture en elle meme (et en effet dans ce cas on peu faire des Mask mais moi une valeur uniforme pour tout le rectangle m´irait tres bien ! )
je n´ai pas de problemes de rendu la désactivation du Zbuffer je m´en était occupé.
j´ai créé un type de vertex Transofmed and Litted expres pour pouvoir afficher a plat (ne pas passer par les transformations de DirectX et donc imposser mes coordonnées physiques a l´ecran en l´occurence c´est la technique que l´on utilise pour faire de la 2D (D3DVECTOR4 x,y,z,w ou reciprocal of homogeneous w)
c´est tres pratique si on veu faire des couches d´objets 2D il suffit de se servir du w.
donc en réalité il faudrait ke je charge ma texture de manière a lui inculquer un channel alpha (meme si a chaque pixel je SET la meme valeur) et de cette maniere le BOTHINVSRCALPHA fonctionnerait surement !
si j´y arrive pas j´ai une autre methode, je vais utiliser le Texture blending:
je capture le frame buffer derriere la zone de la console, je créer une texture que je met dans le Stage 1, et ensuite je Blend avec le stage 0 en utilisant l´Op Modulate ce qui donnera exactement l´effet ke j´attend!
par contre la technique est tres mauvaise du fait des copies de buffer qui vont ramer de manière exponentielle avec la résolution et personne n´a envie de jouer en 320*240 donc l´alpha blending c ma seule solution.
J´y pense, dans ta structure de vertex Transformed & Litted, tu peux pas mettre l´alpha dans la valeur Diffuse ? (en fait je suis sur que si : p)
Donc voila, le pb serait réglé, tu définirais une valeur alpha pour chaque vertex, et basta (c´est comme que je faisais avec OpenGL en tout cas). Et donc je pense que l´alpha de ta texture (qui est à priori à 0 par défaut) serait ignoré.
En tout cas j´ai deja vu des progs OpenGL qui utilisait une console, et qui faisait comme ça.
mais oui justement c´est ce ke je fait précisement, dans le diffuse j´utilise la fonction D3DCOLOR_ARGB (g tout essayé RGBA, XRG) et ben ca donne rien du tout. g meme forcé une valeur alpha dans ma texture g choisi un format 8 bits plus 8 bits pour alpha et ben c tjs pareil c tres bizare.
HEY, méga up sur ce post !
vous voulez voir ce que ca donne les pros du jeu vidéo en action ?
lol ben voila 2 exemples !
en tout cas, je vous rassurce j´ai réglé mon probleme, et mon alpha blending est magnifique maintenant !
J´aime les gens modestes.
Quand t´auras le quart de mes connaissances je t´autoriserais à m´addresser la parole.
bon alors c t koi la solution ?
car il est vrai que le blending c toujours un peu la merde a controler....
t´a pas le courage de tout relire ? ^^
la solution c´etait d´utiliser ca:
SetRenderState ( D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB(trans, r, v, b));
SetTextureStageState ( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
SetTextureStageState ( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
SetTextureStageState ( 0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
et ne pas oublier des vertices rhw.