IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

DirectX Discussion :

Coment faire du post-processing avec Dx9 ?


Sujet :

DirectX

  1. #1
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut Coment faire du post-processing avec Dx9 ?
    Le post-processing consiste à modifier l'image 2D qui vient d'être rendue par notre moteur d'affichage. Je me demande comment faire sous DirectX 9. Car il paraît que capturer le backbuffer de la carte 3D est extrèmement lent (les données sont faites pour passer par le port AGP dans un seul sens, on est pas censé rapporter des textures de la carte, cette opération n'est donc pas très bien optimisée). Je cherche donc une solution rapide. svp, ne me renvoyez pas sur les forums de flipcode ou gamedev, j'en viens, sans succès (j'ai fait des recherches, j'ai rien trouvé). J'ai l'impression que les fonctionnalités de rendu multiple de DirectX 9 pourraient m'aider, mais je n'arrive pas à les mettre en oeuvre.

    Attention: pas de shaders ;-)

    Merci d'avance...

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Eh ben tu pourrais simplement rendre ta scène sur une texture, appliquer ton post-processing, puis afficher le résultat à l'aide d'un quad qui couvre tout l'écran.
    Pour ce qui est du rendu multiple je peux pas te dire, j'ai jamais essayé.

  3. #3
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par Loulou24
    Eh ben tu pourrais simplement rendre ta scène sur une texture, appliquer ton post-processing, puis afficher le résultat à l'aide d'un quad qui couvre tout l'écran.
    Justement... comment je fais çà ? Après deux heures devant la doc de DX9 g tjrs rien trouvé...

  4. #4
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Si tu n'utilises pas de shaders tu vas serieusement etre limité sur ce que tu peux faire.

    A la rigueur un bloom filter en utilisant les capacités d'auto mip filtering des cartes.
    Un effet de motion blur en rendant plusieurs fois ta scene par frame et en additionnant le resultat.

    La question est surtout qu'est-ce que tu veux faire ?

    LeGreg

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Justement... comment je fais çà ? Après deux heures devant la doc de DX9 g tjrs rien trouvé...
    1- Tu crées une texture de rendu (utilise le flag D3DUSAGE_RENDERTARGET lors de Device->CreateTexture())
    2- Tu la mets en tant que backbuffer avec Device->SetRenderTarget()
    3- Tu effectues ton rendu
    4- Tu remets le backbuffer d'origine (que tu auras sauvegardé avec Device->GetRenderTarget())
    5- Tu n'as plus qu'à afficher un quad qui couvre tout l'écran avec ta texture de rendu.

    Mais effectivement il y a peut-être une méthode + adaptée suivant ce que tu veux faire.

  6. #6
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Formidable, merci Loulou, je vais essayer çà cet après-midi (oui moi il me faut du temps ;-)).
    J'affirme que les shadres ne sont pas pour moi pour l'instant, c'est pour un prog 2D dans lequel j'aimerais faire quelques effets très simples comme la pluie ou le tremblement (des classiques ;-) faut bien commencer par quelquechose). Mais pour cela je fais du billboarding sous DirectX9 (j'utilise pas blit() mais present(), en somme) - ct juste pour info -.
    Merci bien.

  7. #7
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Non, juste une dernière chose... Ca marchera même avec ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    ?

  8. #8
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Citation Envoyé par rolkA
    Non, juste une dernière chose... Ca marchera même avec ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    ?
    Aucun rapport.

    LeGreg

  9. #9
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    J'ai bouffoné. Je parlais plutôt de ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferCount = 1;
    Désolé, je faisais plusieurs choses en même temps...

  10. #10
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Est-ce que ta question a un rapport avec le topic ?

    LeGreg

  11. #11
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Bon, non, rien, laisse-tomber, si tu vois pas le rapport c'est qu'il n'y en a pas, je te fais confiance, donc je te remercie, je vais essayer çà et comme l'a fait remarqué un certain acteur musclé: Je reviendrai.
    A+ ;-)
    PS: j'aimerais supprimer mes messages intermédiaires, c'est pas possible ?

  12. #12
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Salut j'ai un problème:
    CreateTexture attend une texture, un IDirect3DTexture9. Ceci me paraît normal.
    Là où je ne comprend plus, c'est quand SetRenderTarget et GetRenderTarget ma demandent eux une surface, un IDirect3DSurface9.
    Donc:
    1) comment je fais ?
    2) quel est la différence entre une surface et une texture ?
    Edit: ya un topic sur la différence texture/surface, je vais le lire... la première question tient toujours...
    Edit 2: bon finalement j'ai pas trop compris la différence. C'est quoi le backbuffer alors ? une texture ou une surface ?

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Le backbuffer est une surface.
    Pour envoyer une texture à SetRenderTarget il faut récupérer sa surface de niveau 0 (une texture est en fait une suite de plusieurs surfaces, chacune représentant un niveau de mipmap).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LPDIRECT3DSURFACE9 Surface;
    Texture->GetSurfaceLevel(0, &Surface);

  14. #14
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    C cool, je te remercie je vais essayer çà.

    Certains points cependant m'échappent (indépendamment de mon prob'):
    1) en modifiant la surface de niveau 0, les autres surfaces de la texture (correspondant aux autres niveaux) sont-elles automatiquement mises à jour ?
    2) la surface de niveau 0 a-t-elle la même dimension que la texture ?
    3) pour moi il y a donc 2 types de surfaces: les surfaces qu'on crée à partir de vertices (les triangles, quoi), et sur lequelles on applique des textures; et les surfaces qui composent chaque texture. C'est bien çà ?

    Merci de m'avoir accordé un peu de ton temps et @+

  15. #15
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Tu vas me dire que je suis lourd mais çà ne fonctionne toujours pas.
    Voilà ce que j'ai fait:
    Déclaration de ce que je vais utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    LPDIRECT3D9 lpD3D;
    LPDIRECT3DDEVICE9 lpD3DDevice;
    LPDIRECT3DTEXTURE9 lpTextureDeRendu;
    LPDIRECT3DSURFACE9 lpSurfaceDeRendu;
    LPDIRECT3DSURFACE9 lpBackBuffer;
    Au chargement du programme, je fais ceci (après l'initialisation de directX):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    D3DXCreateTexture(g_lpD3DDevice, 1024, 768, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &lpTextureDeRendu);
    lpTextureDeRendu->GetSurfaceLevel(0, &lpSurfaceDeRendu);
    g_lpD3DDevice->GetRenderTarget(0, &lpBackBuffer);
    Enfin, voici le rendu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
            g_lpD3DDevice->SetRenderTarget(0, lpSurfaceDeRendu);
     
        /* DEBUT */
            g_lpD3DDevice->BeginScene();
     
        /* RENDU */
            // ......
     
        /* FIN */
            g_lpD3DDevice->EndScene();
     
        // ici je modifie ma surface... (pour l'instant je ne fais rien).
        // puis:
            g_lpD3DDevice->UpdateSurface(lpSurfaceDeRendu, NULL, lpBackBuffer, NULL);
            g_lpD3DDevice->SetRenderTarget(0, lpBackBuffer);
    Au début, je n'avais pas fais UpdateSurface. J'ai fouillé dans la doc du SDK pour trouvé comment copier une surface sur l'autre et j'ai trouvé UpdateSurface (car il faut bien que mon backbuffer reçoive la surface que je viens de préparer...).

    J'ai épuré le code au max pour être plus simple à résoudre. Je vois pas trop où est le pb ?

  16. #16
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Citation Envoyé par rolkA
    1) en modifiant la surface de niveau 0, les autres surfaces de la texture (correspondant aux autres niveaux) sont-elles automatiquement mises à jour ?
    Cela depend si la carte a la capacité d'autogénerer
    les mipmaps. Il faut donc verifier les caps de ta carte graphique au lancement. De plus les cartes graphiques proposent rarement mieux qu'un square filter et ce n'est pas garanti que cela soit rapide non plus. (le driver peut l'emuler par n'importe quel moyen).

    Citation Envoyé par rolkA
    2) la surface de niveau 0 a-t-elle la même dimension que la texture ?
    Oui mais tu n'as pas le droit d'inferer le nombre de bytes entre deux lignes à partir des dimensions pour y lire ou y écrire, il faut que tu utilises le pitch (en bytes) retourné lorsque tu fais un lock de ta surface.

    Citation Envoyé par rolkA
    3) pour moi il y a donc 2 types de surfaces: les surfaces qu'on crée à partir de vertices (les triangles, quoi), et sur lequelles on applique des textures; et les surfaces qui composent chaque texture. C'est bien çà ?
    Surface pour D3D ca veut simplement dire un tableau de bytes bidimensionel. Il est le plus souvent associé avec une texture ou un buffer (color, depth).

    LeGreg

  17. #17
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour ce qui est des niveaux de mipmapping, n'en crée pas pour ta texture, ça sert à rien pour une texture de rendu, à moins que t'en aies vraiment l'utilité pour un truc en particulier.

    Sinon pour ton problème, déjà essaye de créer un texture qui ait comme dimension des puissances de 2, ta carte ne supporte peut-être pas tes dimensions (1024x768).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_lpD3DDevice->UpdateSurface(lpSurfaceDeRendu, NULL, lpBackBuffer, NULL);
    Je pense pas que ce soit la bonne méthode... Essaye plutot de rendre un quad qui couvre tout l'écran pour afficher ta texture.

  18. #18
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Je voudrais pas etre lourd mais est-ce que tu as regardé le sample :"Cube Map" dans le SDK
    Il fait exactement ce que tu veux (rendre dans une render target séparée utilisé plus tard dans le rendu comme une texture)..

    Si tu pars de ce sample pour faire ce que tu veux faire ça devrait etre plus simple..

    LeGreg

  19. #19
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Merci je vais regarder ce sample.
    Pour ce qui est des niveaux de mipmapping, n'en crée pas pour ta texture
    Ne t'inquiète pas, je n'en crée pas (enfin, un seul quoi).
    Je pense pas que ce soit la bonne méthode... Essaye plutot de rendre un quad qui couvre tout l'écran pour afficher ta texture.
    Rendre un quad ? rendre un quad.... hum.... çàd ?
    Merci à vous deux.

  20. #20
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Rendre un quad ? rendre un quad.... hum.... çàd ?
    2 triangles

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. faire un POST HTTP avec authentification.
    Par Jean-Pascal dans le forum VB.NET
    Réponses: 2
    Dernier message: 05/04/2011, 09h06
  2. [INDY] comment faire un 'POST' avec idHTTP??
    Par gamez dans le forum Composants VCL
    Réponses: 5
    Dernier message: 17/05/2004, 19h02
  3. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  4. Réponses: 1
    Dernier message: 19/05/2003, 15h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo