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 :

Modifier la surface primaire (avec un filtre)


Sujet :

DirectX

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut Modifier la surface primaire (avec un filtre)
    salut,
    J'aimerai modifier la surface qui sera affichée à l'écran avec un filtre.
    Pour cela je dois récuprer la surface et ensuite appliquer mon filtre, à l'aide de DeViL.
    Je vois dans quelle fonction je dois implementer ca mais ca ne foncionne pas, je vous copie colle mon code :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    void d3d_SwapBuffers(uint flags)
    {
    	CSAccess cLoadRenderCSLock(&g_Device.GetLoadRenderCS());
     
    	if (!PD3DDEVICE)
    		return;
     
    	//see if we need to perform the trick to prevent cards from buffering up frames
    	if(g_CV_VSyncOnFlip.m_Val)
    	{
    		d3d_PreventFrameBuffering();
    	}
     
    	if ((flags & FLIPSCREEN_DIRTY) != 0) 
    	{
    		DirtyRectSwap(); 
    	}
    	else 
    	{
    	LPDIRECT3DSURFACE8 pBackBuffer = NULL;
    	D3DSURFACE_DESC SurfDesc;
    		PD3DDEVICE->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer);
    		//Buffer->LockRect;
    		pBackBuffer->GetDesc(&SurfDesc);
    		D3DLOCKED_RECT LockRect;
    		pBackBuffer->LockRect(&LockRect, NULL, NULL);	
     
    		ilInit(); // pour initialiser IL
    			iluInit(); // pour initialiser ILU
    		unsigned int id;
    		ilGenImages(1, &id);
    		ilBindImage(id); // LockRect.pBits
    		ilTexImage(640, 180, 1, 4, IL_BGRA, IL_BYTE, LockRect.pBits);
    		iluAlienify();
    		ilDeleteImages(1, &id);
    		pBackBuffer->UnlockRect();
     
    		pBackBuffer->UnlockRect();
    		HRESULT hResult = PD3DDEVICE->Present(NULL,NULL,NULL,NULL); 
    	}
     
    	ClearDirtyRects();
     
    }

    Si quelqu'un a deja fait ca ou a une idée ... merci de m'aider

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    Bon ca marche, j'arrive à appliquer un filtre, (par ex un négatif) mais le pb c'est qu'il passe par tous les pixels pour modifier la couleur, or c'est tres long, et c'est pour intégrer dans un moteur 3D tps réel.
    Donc j'amerai faire le traitement bcp + vite, quelqu'un a deja appliqué un filtre en tps réel ?
    Merci de m'aider, car la je vois pas du tout comment faire...

  3. #3
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    En gros, récupérer le backbuffer est une mauvaise idée. Je sais pas trop si ce serait plus adapté (jamais essayé ), mais à ta place j'essayerai de rendre la scène sur une texture dynamique, d'appliquer tes modifications sur celle-ci, puis de la rendre, avec un quad couvrant l'écran par exemple.

    Sinon tu peux envisager les pixel shaders aussi.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 22
    Par défaut
    Effectivement, il ne faut jamais locker le buffer d'affichage sous peine de tomber à 3 fps...

    Tu rends ta scène dans une texture qui a était créee exprès pour ça. (avec le flag D3DUSAGE_RENDERTARGET)
    Ensuite soit tu suis la voie du riche propiètaire de carte avec Pixel Shaders, et tu appliques ta texture directement sur un quad. (c'est le PS qui fera ton filtre)
    Soit tu suis l'autre voie (plus lente), tu locks ta texture et tu la modifie comme une image normale. Enfin tu l'affiches sur un quad.
    Attention car ça peut-être très long, soit conscient que ton filtre ne dois pas prendre plus d' 10ms (et encore c'est énorme) pour avoir du temps réel.

    Bonne chance.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    ok merci pour vos réponse, donc apparemment pour avoir une rapiditée suffisante, il est obligé de passer par des pixels shaders?

    Sinon un quad c'est quoi ?
    et si je dois passer par des pixels shaders, est ce que ca vous semble compliqué de faire un filtre image avec ca ?
    sachant que le code sur lequel je travail est basé sur direct x 8.1 ...
    Merci

  6. #6
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Obligé de passer par des pixel shaders non, je pense que tu peux avoir des performances correctes sans. C'est mieux évidemment, mais si tu veux que ton application soit compatible avec les cartes 3D pas récentes (en dessous de la GF3) c'est à éviter.

    Un quad c'est un carré (2 triangles).

    Pour la complexité du shader, tout dépend de l'effet souhaité. A priori tant que tu ne fais pas des choses tarabiscotées ce sera assez "simple". Ca dépend aussi de la version de pixel shader supportée par ta carte.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    ok, je vais le faire sans je pense alors, il s'agirai jsute d'appliquer un filtre à l'ecran en tps réel, ca peux etre un filtre négatif, un filtre de flou etc. ..

    est ce que tu pourrai m'expliquer plus en detail la méthode sans pixel shaders ? Si t'as un exemple de code meme ... car j'ai pas trouvé grand chose sur les filtre sur le net.

    Sinon je suis a environ 100 fps et je tombe a 3fps avec ma méthode qui fait un lock, avec ta méthode sans pixel shaders je serai au dessus de 30 fps au moin ? car le moteur affiche de grosses scenes 3D en fait, c pr des simulations de batiments.
    voilà c tout, merci.

  8. #8
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    est ce que tu pourrai m'expliquer plus en detail la méthode sans pixel shaders ?
    Création de la texture de rendu ? Rendu sur la texture ? Accès aux pixels de la texture ? Précise un peu ce qui pose problème.
    avec ta méthode sans pixel shaders je serai au dessus de 30 fps au moin ?
    Impossible à dire, ça dépend de tellement de choses... Tu verras bien.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    En fait je voudria une explication de toute la démarche, comment creer la surface (quadro ?) qui va stocker l'image, puis comment appliquer mon filtre à l'image, la méthode est la meme ?

    Pour modifier un buffer je connais que la méthode du lock donc si tu peux m'aider avec ta méthode sans le lock en m'epliquant tout depuis le début ca serai cool, je n'ai en effet aucune idée de comment faire autrement.
    Merci.

  10. #10
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Pour modifier un buffer je connais que la méthode du lock donc si tu peux m'aider avec ta méthode sans le lock en m'epliquant tout depuis le début ca serai cool
    Ben... Sans le lock c'est avec pixel shader ! Là tu devras procéder de la même manière, sauf qu'au lieu de verrouiller ton backbuffer tu verrouilleras ta texture de rendu.

    Pour la méthode, voilà en gros comment faire, ensuite la documentation du SDK est là pour les détails :
    1- Crée une texture de rendu dynamique de la taille de ton écran (enfin ta résolution courante, quoi).
    2- Met là comme surface de rendu (SetRenderTarget())
    3- Rend ta scène
    4- Remet ta surface de rendu d'origine
    5- Applique ton filtre a ta texture (Lock etc...)
    6- Affiche un carré recouvrant l'écran avec cette texture
    7- Voilà c'est gagné

    A noter que ça requiert tout de même une bonne carte graphique (et des drivers à jour), notamment pour la création d'une texture de rendu dynamique dont les dimensions ne sont pas des puissances de 2.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 22
    Par défaut
    J'ajouterais que si tu veux (est obligé) d'utiliser des textures en puissance de 2, il te suffit de regler ton viewport avant de rendre dans ta texture. Quand tu affiches le quad il faut que tes coordonnées de textures correspondent au ration de la résolution de ton écran par rapport à celle de la texture.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    pour le moment je fais le rendu dans mon backbuffer je pense...
    ca change quoi finalement de le faire dans une texture dynamique ?
    je me sert de ca aussi D3DUSAGE_RENDERTARGET ?

    Car me scene est rendue un peu partout, il y a au moin 20 fichiers avec des fonctions de rendu dedans ... moi je pensais intervenir que au moment du swap pour modifier ma surface qui sera affichée.

    Dans ta méthode il y a un lock aussi, c'est parce qu'il est + court que c + rapide ?
    Sinon est ce que tu pourrai m'aider à partir de mon code qui est + haut ?
    le modifier en appelant les bonens fonctions par ex ... car je sais pas comment creer une texture de rendu dynamique etc ...
    Merci loulou et les autres

    autre chose, il y a bien un moment ou uen fonction écris dans ma surface primaire (ou dans l'autre je c pas), donc je pourrai pas écrire mon code de filtre au meme moment ?
    ps : j'ai testé c bien le lock / unlock qui fait ramer et pas les 1 200 000 opérations.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 22
    Par défaut
    il y a au moin 20 fichiers avec des fonctions de rendu dedans
    Pas bien...

    Effectivement c'est le lock qui est couteux, tout simplement car non seulement tu te tapes le transfert de la ram vidéo vers la ram system pour que le CPU puisse y accèder, mais en plus tu bloques complètement le pipeline de la carte 3D qui attend que le buffer lui soit rendu. Si tu rends dans une texture, tu ne bloques pas complètement le pipeline de la carte et donc c'est plus rapide (enfin... c'est potentiellement plus rapide).

    L'avantage de rendre dans une texture, c'est que tu vas pouvoir faire des opérations hardware dessus. Exemple, si tu veux un flou, tu rends dans une texture deux fois plus petite et le filtrage ferra le reste. Tu peux aussi appliquer des déformations en modifiant non pas ta texture, mais les vertex sur lesquels elle est projetée.

    autre chose, il y a bien un moment ou uen fonction écris dans ma surface primaire (ou dans l'autre je c pas), donc je pourrai pas écrire mon code de filtre au meme moment ?
    Non car cette "fonction" est directement intégrée en silicium dans ta carte 3D... ce qui s'en rapproche le plus c'est les PS.

    Sinon est ce que tu pourrai m'aider à partir de mon code qui est + haut ?
    Loulou24, on a besoin de toi
    J'essairai de trouver le temps...

    Bonne chance.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    je regarde pour faire comme vous avez dis, mais pour D3DUSAGE_RENDERTARGET je trouve ca,

    #define D3DUSAGE_RENDERTARGET (0x00000001L)

    Je suppose que ca veut dire que ca utilise une surface pour le rendu.

    Non car cette "fonction" est directement intégrée en silicium dans ta carte 3D... ce qui s'en rapproche le plus c'est les PS.
    donc le code permet d'écrire dans le backbuffer alors, puis c flippé avec la surface primaire dans la fonction g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); et les PS c quoi ?

    Soit tu suis l'autre voie (plus lente), tu locks ta texture et tu la modifie comme une image normale. Enfin tu l'affiches sur un quad.
    comment je crée une texture dynamique ?
    comment je met mon image dans une texture ?
    et comment je l'affiche sur un quad ?

    Je me demandais puisque le code écris a un moment l'image qu'il calculée dans le backbuffer, et que c'est rapide puisque je suis à 150 fps, je pourrai appliquer à cet endroit mon filtre, c possible vs croyez ?

    merci

  15. #15
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je suppose que ca veut dire que ca utilise une surface pour le rendu
    Ce flag indique que la texture/surface sera utilisée comme surface de rendu, càd que tu la mettras à un moment donnée à la place de ton backbuffer. Une texture de rendu ne peut être placée qu'en pool D3DPOOL_DEFAULT (au cas où t'aurais eu l'idée de la mettre ailleurs ).

    et les PS c quoi ?
    Les Pixel Shaders pardi !

    comment je crée une texture dynamique ?
    Là en fait c'est plus compliqué, j'ai été un peu vite. Une texture de rendu lockable perso j'ai jamais réussi a le faire, j'ai du pâsser par une surface. Il faudra donc une manip supplémentaire pour mettre a jour une texture avec cette surface pour le rendu. Pour la surface :
    Device->CreateRenderTarget(Width, Height, Format, D3DMULTISAMPLE_NONE, 0, true, &Surface, NULL)

    comment je met mon image dans une texture ?
    Tu ne mets pas ton image dans une texture, tu effectues le rendu de ta scène dessus. Tu fais ceci avant de rendre :

    OldRenderTarget->Release();
    Device->GetRenderTarget(0, &OldRenderTarget); // sauvegarde de l'ancienne
    Device->SetRenderTarget(0, Surface); // Surface de rendu

    Et ça après :
    Device->SetRenderTarget(0, OldRenderTarget);

    et comment je l'affiche sur un quad ?
    Bon là si t'avais eu une texture t'aurais juste fait un SetTexture(), mais comme t'as une surface, il faut d'abord mettre a jour une texture avec cette surface, puis utiliser cette texture au moment de rendre le quad. Je ne l'ai jamais faitmais ça doit tres bien etre expliqué dans la doc du SDK, cherche du coté de UpdateTexture() par exemple.

    Je me demandais puisque le code écris a un moment l'image qu'il calculée dans le backbuffer, et que c'est rapide puisque je suis à 150 fps, je pourrai appliquer à cet endroit mon filtre, c possible vs croyez ?
    Oui, et c'est aussi en pixel shader que ça se fait, mais :
    - Tu ne dois pas avoir d'alphablending
    - Ton filtre ne doit agir que sur un pixel a la fois
    - ... Bon de toute façon ne le fais pas, par ce qu'en gros tu modifieras une image dont le rendu ne sera pas fini, si t'appliques ton filtre a chaque fois que tu rends un triangle.

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    merci loulou24 pr les expli, je me mélange les pinceaux entre surface et texture.
    quel est l'interet de la surface par rapport à la texture ?

    afficher la texture sur un quad recouvant l'ecran, ca veux bien dire que je place ma texture sur une surface et qu'ensuite j'applique ma surface à l'écran...

    sinon j'ai pas bien compris comment creer une texture,
    Device->CreateRenderTarget(Width, Height, Format, D3DMULTISAMPLE_NONE, 0, true, &Surface, NULL)
    Format c quoi ?
    surface je met l'ancienne surface qui est affichée à l'ecran dans mon code pour le moment?

    aussi comment je dois modifier le flag pour prendre la bonne texture, je lui donne quoi comme valeur ...
    merci encore

  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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    quel est l'interet de la surface par rapport à la texture ?
    C'est pas la même chose, une texture étant une collection de surfaces (les niveaux de mipmapping). Tu ne pourras pas utiliser une surface avec SetTexture(). Là il aurait fallu utiliser une texture, mais comme je te l'ai dit, une texture de rendu lockable moi perso j'ai pas réussi a faire, donc obligé de passer par une surface. Ceci-dit c'est peut-être possible, après tout je ne suis pas un pro

    afficher la texture sur un quad recouvant l'ecran, ca veux bien dire que je place ma texture sur une surface et qu'ensuite j'applique ma surface à l'écran...
    Qu'est-ce que t'appelles "surface" là ?
    Il faut simplement que tu affiches 2 triangles texturés, ça tu sais faire non ?

    Format c quoi ?
    Un D3DFMT_***** (cf la doc du SDK). Pour une surface de rendu il y a des restrictions au niveau du format. Un conseil : prend le même format que ton backbuffer, en remplaçant les X par des A (ex : D3DFMT_X8R8G8B8 -> D3DFMT_A8R8G8B8).

    surface je met l'ancienne surface qui est affichée à l'ecran dans mon code pour le moment?
    C'est quoi la surface qui est affichée à l'écran ? De toute façon là tu mets une nouvelle surface, le but de cette fonction étant de la créer

    aussi comment je dois modifier le flag pour prendre la bonne texture, je lui donne quoi comme valeur ...
    Quel flag ?

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 22
    Par défaut
    Voila comment tu peux faire.
    Pour des raisons de lisibilité, j'ai supprimé (presque) tous les tests de retour des fonctions, mais il faut le faire!
    Attention c'est long...

    voila pour la partie a ne faire qu'une fois à l'initialisation
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    IDirect3DDevice8 *pDevice = rayDisplay.GetDevice ();	// On recupère un device valide
    IDirect3DTexture8 *pTexture;	// Pointeur sur la texture qui va nous servir pour faire le rendu
    IDirect3DSurface8 *pLevel0Surface;	// Pointeur vers la première surface de la texture
    IDirect3DSurface8 *pSurface;	// Pointeur vers la surface de rendu
    IDirect3DSurface8 *pZSurface;	// Pointeur vers le Z-buffer de rendu
    IDirect3DSurface8 *pRenderSurface;	// Pointeur sur la surface de rendu
     
    // On crée la texture dans laquelle on va copier notre surface de rendu
    pDevice->CreateTexture (256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture);
    // On récupère la surface principale, c'est elle qui va nous servir pour le rendu
    pTexture->GetSurfaceLevel (0, &pLevel0Surface);
    // On crée une surface dans laquelle on va rendre notre scene
    pDevice->CreateRenderTarget(256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, TRUE, &pSurface);
    // On récupère le Z-Buffer qui a était passé lors de la création du device
    pDevice->GetDepthStencilSurface(&pZSurface);
    // On récupère le buffer d'affichage qui a était passé lors de la création du device
    pDevice->GetRenderTarget (&pRenderSurface);
     
     
    // On crée le quad qui va nous servir pour l'affichage du rendu de la scène
    rfloat pVertexBuffer [6*6], *v;	// 6 vertex de 6 floattant (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
    v = pVertexBuffer;
     
    // Pour pas m'embetter avec la conversion dword -> float pour la couleur des vertex
    memset (v, 0xFFFFFFFF, sizeof(rfloat)*36);
     
    // Première face de notre quad
    *v++ =-1.f;		*v++ = 1.f;		*v++ = 0.f;	v++; *v++ = 0.f;	*v++ = 0.f;
    *v++ = 1.f;		*v++ =-1.f;		*v++ = 0.f;	v++; *v++ = 1.f;	*v++ = 1.f;
    *v++ =-1.f;		*v++ =-1.f;		*v++ = 0.f;	v++; *v++ = 0.f;	*v++ = 1.f;
     
    // Deuxième face du quad
    *v++ = 1.f;		*v++ =-1.f;		*v++ = 0.f;	v++; *v++ = 1.f;	*v++ = 1.f;
    *v++ =-1.f;		*v++ = 1.f;		*v++ = 0.f;	v++; *v++ = 0.f;	*v++ = 0.f;
    *v++ = 1.f;		*v++ = 1.f;		*v++ = 0.f;	v++; *v++ = 1.f;	*v++ = 0.f;
    Puis la partie pour 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    // On passe la notre surface de rendu et on garde le Z-Buffer déja existant
    pDevice->SetRenderTarget (pSurface, pZSurface);
     
    // On efface le buffer d'affichage mais PAS le Z-Buffer (me demande pas pourquoi, sinon ça ne marche pas)
    pDevice->Clear (0, NULL, D3DCLEAR_TARGET, 0xFF404040, 1.0f, 0);
     
    // ------- Ici tu fais le rendu de ta scène 3D -------
     
    // On rend maintenant notre quad
    // On remet notre surface la surface d'affichage qui a était crée lors de la création du device
    pDevice->SetRenderTarget (pRenderSurface, pZSurface);
     
    // On va s'occuper de ton filtre ici, avant de préciser la texture à Direct3D en tout cas
    D3DLOCKED_RECT lockRect;
     
    // On lock notre surface de rendu
    errorCode = pSurface->LockRect (&lockRect, NULL, 0);
    if (!errorCode)
    {
    	rdword pixel;
    	rdword color;
    	rdword *pPixel = (rdword*) lockRect.pBits;
    	// Normalement il faut prendre en compte lockRect.Pitch mais pas pour le format passé
    	// lockRect.Pitch représente le nombre d'octet par ligne de texture
    	for (pixel = 0; pixel < 256*256; pixel++)
    		*pPixel++ = (0xFF000000 & *pPixel) | (0x00FFFFFF & ~*pPixel);	// Un bête filtre inverse qui conserve l'alpha
     
    	// On delock la surface
    	pSurface->UnlockRect ();
    }
     
    // On copie notre surface de rendu dans la surface du premier niveau de la texture
    pDevice->CopyRects (pSurface, NULL, 0, pLevel0Surface, NULL);
     
    // On efface le buffer d'affichage et le Z-Buffer
    pDevice->Clear (0, NULL, D3DCLEAR_ZBUFFER, 0xFF808080, 1.0f, 0);
     
    // On sauvegarde les matrices car on va tout mettre à l'identité pour pas s'embetter avec les transformations
    CRMatrix pSavedMatrix[3];
    pDevice->GetTransform (D3DTS_WORLD, (D3DMATRIX *) pSavedMatrix);
    pDevice->GetTransform (D3DTS_VIEW, (D3DMATRIX *) pSavedMatrix+1);
    pDevice->GetTransform (D3DTS_PROJECTION, (D3DMATRIX *) pSavedMatrix+2);
     
    // On met toute les matrices à l'identité
    CRMatrix id;
    pDevice->SetTransform (D3DTS_WORLD, (D3DMATRIX *) &id);
    pDevice->SetTransform (D3DTS_VIEW, (D3DMATRIX *) &id);
    pDevice->SetTransform (D3DTS_PROJECTION, (D3DMATRIX *) &id);
     
    // J'ai fait mon quad en CCW
    pDevice->SetRenderState (D3DRS_CULLMODE, D3DCULL_CCW);
     
    // C'est parti, on commence le rendu de notre quad
    pDevice->BeginScene ();
     
    // On précise notre le format de vertex pour l'affichage de notre quad
    pDevice->SetVertexShader (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
     
    // Je vais utiliser un DrawPrimitiveUP, donc je ne passe pas de vertexBuffer et je demande de déssiner 2 triangles
    pDevice->SetStreamSource (0, NULL, 2);
     
    // Ah! Enfin je précise que j'utilise la texture ou j'ai rendu ma scène
    pDevice->SetTexture (0, pTexture);
     
    // On affiche notre quad, j'utilise DrawPrimitiveUP car j'étais trop fénéant pour crée un vertexBuffer
    // Bien sûr pour avoir de bonne performance, il faudrait passer par un vertexBuffer et utiliser un strip
    pDevice->DrawPrimitiveUP (D3DPT_TRIANGLELIST, 2, pVertexBuffer, 24);
     
    // On a fini l'affichage du quad
    pDevice->EndScene ();
     
    // On restaure nos matrices, au cas ou on voudrait faire autre chose...
    pDevice->SetTransform (D3DTS_WORLD, (D3DMATRIX *) pSavedMatrix);
    pDevice->SetTransform (D3DTS_VIEW, (D3DMATRIX *) pSavedMatrix+1);
    pDevice->SetTransform (D3DTS_PROJECTION, (D3DMATRIX *) pSavedMatrix+2);
     
    // On revient en mode CW
    pDevice->SetRenderState (D3DRS_CULLMODE, D3DCULL_CW);
     
    // On flip histoire d'avoir notre affichage à l'écran
    pDevice->Present (NULL, NULL, NULL, NULL);
    Pour information, je passe de 300 fps à 200fps en rendant dans une texture (avec une texture de 256x256) et je passe à 9 fps avec le lock et l'application du filtre.

    Je te conseil de faire, tant que possible, une modification au niveau des vertex ou alors des render states pour afficher ta texture différement plutôt que de la locker.

    Voila,
    Bonne chance.

  19. #19
    Membre éprouvé
    Inscrit en
    Mai 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 99
    Par défaut
    Ouf...
    Tout ca pour arriver a 9fps... sur quelle config ? carte ?

    Le lock, ca tue. Le pixel shader, va falloir s'y mettre...

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Par défaut
    merci loulou et virquel,
    j'ai quelques precisions de demander à loulou, virquel thx pr le code je regarde apres.

    C'est pas la même chose, une texture étant une collection de surfaces
    t sur que c pas une surface qui contien une colelction de texture ?
    car d'aprers ce que j'a icompris la surface represente l'image qui sera affichée à l'ecran, et qui est composée de multiples texture...

    [de moi avant]
    afficher la texture sur un quad recouvant l'ecran, ca veux bien dire que je place ma texture sur une surface et qu'ensuite j'applique ma surface à l'écran...
    Qu'est-ce que t'appelles "surface" là ?
    Il faut simplement que tu affiches 2 triangles texturés, ça tu sais faire non ?
    je parle de la surface qui contient l'image finale et qui sera affichée à l'ecran.
    sinon afficher 2 triangles texturés je sais pas faire ... j'ai jamais fait de directX, je me base sur un code deja fait et j'ai quasiment rien codé dessus qui a a voir avec du directx

    [de moi avant]
    aussi comment je dois modifier le flag pour prendre la bonne texture, je lui donne quoi comme valeur ...

    Quel flag ?
    le flag D3DUSAGE_RENDERTARGET

    sinon j'au trouvé une solution dans un bouquin , mais ca utilise des DDSURFACEDESC2 alors que moi c des D3DSURFACE_DESC

    voici le code qui est proposé dans le livre (game programming gurus) et qui est cencé etre "10 times faster"
    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
     
    inline void Plot_pixel8Fast16(int x, int y, int red, int greeen, int blue, USHOR *videobuffer, int lpitch)
    {
    // this fonction  polots a ipxel in 16 - bit color mode
    // assuming that the caller already locked the surface
    // and is sending a pointer and byte pitch to it
     
    DDSURFACEDESC2 ddsd;
    USHORT pixel = __RGB16BIT464(red, green, blue);
    USHORT *videobuffer = ddsd.lpsurface;
    // write the data 
    video_buffer[x + y*(lpitch >> 1] = pixel;
    }
    //ca place un pixel de couleur n'imprte ou dans l'ecran.
    //lPitch is memory width in bytes.
    dans mon D3DSURFACE_DESC j'ai ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct _D3DSURFACE_DESC
    {
        D3DFORMAT           Format;
        D3DRESOURCETYPE     Type;
        DWORD               Usage;
        D3DPOOL             Pool;
        UINT                Size;
     
        D3DMULTISAMPLE_TYPE MultiSampleType;
        UINT                Width;
        UINT                Height;
    } D3DSURFACE_DESC;
    la je comprend pas pkoi j'ai pas les infos data... c a dire tous les pixels de l'image .

    voila c'est tout, merci bien pr votre aide.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 28/06/2014, 18h49
  2. Modifier un cle primaire avec JSF
    Par dalidali86 dans le forum JSF
    Réponses: 4
    Dernier message: 12/09/2009, 15h44
  3. insertion d'une clé primaire avec un "d" apostroph
    Par imer5 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 18/05/2005, 14h51
  4. Comment modifier les .pas fournis avec Delphi ?
    Par prgasp77 dans le forum Langage
    Réponses: 2
    Dernier message: 09/02/2005, 15h12
  5. Modifier une partion ntfs avec Disk druid
    Par Sébastien dans le forum Administration système
    Réponses: 5
    Dernier message: 24/09/2003, 14h58

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