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 :

prise rapide de screenshot


Sujet :

DirectX

  1. #1
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut prise rapide de screenshot
    de la meme maniere que mon post rpecedant, j'ai fait une fonction qui prend un screenshot à chaque frame, seulemt je tombe à 5fps avec cette methode, ce qui prend le + de tps est de locker et delocker la surface poru recuperer les infos, quelqu'un a une idée pour aller + vite ?
    je colle ma fonction si vous voulez.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 71
    Points : 78
    Points
    78
    Par défaut
    peut etre faire tourner ton programme en software rendering, ce qui permettrai de faire des locks très rapides bien que diminuerait les perfs...

  3. #3
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut
    ouais mais je voudrai conserver la qualitée du rendu ...

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 71
    Points : 78
    Points
    78
    Par défaut
    la qualité en serait la même c'est les perforances qui risqueraient de diminuer. Maintenant si ce que tu veux afficher est relativement simple, tu peux largement prendre le risque...
    Et encore un truc : où sont stockés tes screenshots ? Si c'est en mémoire pas de problème mais si c'est sur le dur c'est peut etre l'enregistrement et/ou conversion de format qui pose problème...

  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
    Voilà la mienne, si ça peut t'aider :

    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
    void CD3DManager::TakeScreenShot(string pFilename)
    {
    	// Surface de destination
    	LPDIRECT3DSURFACE9 Surface = NULL;
     
    	// Si on est en mode fenêtré alors on récupère le backbuffer, sinon on prend le frontbuffer (qui permet d'avoir l'anti-aliasing)
    	if (m_bWindowed)
    	{
    		// Récupération du backbuffer
    		m_D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &Surface);
     
    		// Sauvegarde de la surface dans le fichier
    		D3DXSaveSurfaceToFile(pFilename, D3DXIFF_BMP, Surface, NULL, NULL);
    	}
    	else
    	{
    		// Création de la surface de destination
    		m_D3DDevice->CreateOffscreenPlainSurface(m_CurDispMode.Width, m_CurDispMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &Surface, NULL);
     
    		// Récupération du front buffer
    		m_D3DDevice->GetFrontBufferData(NULL, Surface);
     
    		// Sauvegarde - le seul format supporté est BMP (et DDS, mais inexploitable)
    		D3DXSaveSurfaceToFile(pFilename, D3DXIFF_BMP, Surface, NULL, NULL);
    	}
     
    	// Destruction de la surface
    	RELEASE(Surface);
    }
    Mais si tu veux le faire toutes les frames, tu ne pourras pas avoir beaucoup mieux que 5 FPS, quelle que soit la méthode
    A noter que pour récuperer le front buffer, le format de surface doit toujours être D3DFMT_A8R8G8B8 (il me semble, cf. doc du SDK).

  6. #6
    Membre régulier
    Inscrit en
    Mai 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 99
    Points : 115
    Points
    115
    Par défaut
    hmmm, deux fois release ? C'est un safe release, j'espere...

    En general, on fait un screen par frame pour faire un petit film du jeu en action. C'est le but ? Si c'est le cas, c'est presque impossible a faire en temps reel.

    Il faut enregister les entrees ( touches, souris ) en temps reel et faire ensuite un mode playback ou le temps du jeu est artificiellement ralenti. On a alors tout le temps qu'il faut dans ce mode pour prendre des screenshot a intervalles reguliers, ce qui est important pour que le film soit visualisable sans a-coups.

  7. #7
    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
    hmmm, deux fois release ? C'est un safe release, j'espere...
    Héhé ouaip, d'ailleurs j'ai vu ça en postant mon code. Hop corrigé
    RELEASE() est bien un safe release, jamais je ne libère de pointeur sans le tester puis le mettre à NULL
    Tiens et je me demandais aussi si c'était bien nécessaire de créer la surface à chaque fois pour le cas où je choppe le front buffer... Enfin bref !

  8. #8
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut
    ok thx loulou42 pour ta fonction sceenshot, je v tester mais je pense que ca sera pas bcp + rapide.

    Le but Laurent-USA c'est de faire un film avec le jeu oui. Je n'ai pas trouvé de methode pour ralentir le jeu.
    On utilise ca pour un trajet de camera predefini pour les interaction clavier / souris sont pas prises en compte.
    sinon, j'ecris mon image a chaque fois sur le disque dur, en .jpg, mais meme sans l'ecrire ca rame, donc c plus la conversion qui prend du temps à mon avis!
    Donc pour le moment ca marche mais il faut faire aller la camera moin vite sur le trajet, histoire de prendre plus de frames, et d'avoir une video plus fluide à la sortie.

  9. #9
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut
    donc j'ai tester et en effet ca va pas + vite
    mais ta fonction est bcp plus simple que la mienne, et marche aussi bien, sauf que moi je sors en .jpg, voici ma fonction si tuveux voir :
    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
     
    void d3d_MakeScreenShotBMP(const char *pFilename, uint32 nWidth, uint32 nHeight)
    {
    	ilInit(); // pour initialiser IL
    	int len = strlen(pFilename) + 1;
     
    	LPDIRECT3DSURFACE8 pBackBuffer = NULL;
    	D3DSURFACE_DESC SurfDesc;
    	if (FAILED(PD3DDEVICE->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer)))	
    	{ 
    		return; 
    	}
    	pBackBuffer->GetDesc(&SurfDesc);
     
    	uint32 imageSize = nWidth * nHeight;
     
    	// Lock the back buffer.
    	D3DLOCKED_RECT LockRect;
    	HRESULT hResult;
    	if (FAILED(hResult = pBackBuffer->LockRect(&LockRect, NULL, NULL))) 
    	{
    		dsi_ConsolePrint("MakeScreenShotBMP: g_pOffscreen->Lock returned %d.", hResult); 
    		return; 
    	}
     
     
    	if (FAILED(pBackBuffer->UnlockRect())) 
    	{ 
    //		dsi_ConsolePrint("MakeScreenShotBMP: FormatMgr::ConvertPixels returned %d.", dResult); 
    		return; 
    	}
     
     
    	unsigned int id;
    	ilGenImages(1, &id);
    	ilBindImage(id); // LockRect.pBits
     
    	uint8 *data;
    	data = new uint8[imageSize*4];
    	uint8 *m_pSrc;
    	m_pSrc  = (uint8*)LockRect.pBits; // car pBits est un void *
    	for (uint32 y=0; y < nHeight; ++y) // parcours des lignes, ok ! 640
    	{
    	 uint8 *pOutBuf = &m_pSrc[(nHeight-y-1) * nWidth*4]; // pour recuperer la ligne
         uint8 *pImageLine = &data[y*nWidth*4];
    	 memcpy(pImageLine, pOutBuf, nWidth*4);
    	}
     
     ilTexImage(nWidth, nHeight, 1, 4, IL_BGRA, IL_BYTE, data);
     
     ilSave(IL_JPG, pFilename);
     ilDeleteImages(1, &id);
    }
    Par contre j'arrive que avec le flag D3DXIFF_BMP avec ta methode, en jpg ou tga ca marche pas... peut etre parce que j'ai pas fait de release vu que ton RELEASE est surement une macro ...

  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 : 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
    Par contre j'arrive que avec le flag D3DXIFF_BMP avec ta methode, en jpg ou tga ca marche pas...
    Réponse dans le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Sauvegarde - le seul format supporté est BMP (et DDS, mais inexploitable) 
          D3DXSaveSurfaceToFile(pFilename, D3DXIFF_BMP, Surface, NULL, NULL);
    Je crois que c'est assez explicite

    Sinon mon RELEASE c'est le SAFE_RELEASE des samples Dx, je l'ai juste renomée.

  11. #11
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut
    oui merci je l'ai vu qu'apres, vu que j'ai utilise la methode en mode fenetre, j'ai pas tout lu le reste, pour le release, ok thx

  12. #12
    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
    Récuperer les données de rendu se font
    par getFrontBufferData sous Dx9
    toute autre méthode est invalide
    (tu n'as pas le résultat finale tant que tu n'as pas fait l'appel à present()
    notamment pour ce qui est des différentes méthodes d'antialiasing)
    Surtout locker le front ou le back buffer c'est une horreur qu'il faut éviter à tout prix.

    Je confirme ce que dit Laurent :

    pour arriver à capturer un film fluide, il faut avoir tout d'abord une méthode de replay capable de tourner à n'importe quel vitesse et surtout avoir découplé le rythme d'update du moteur du temps qui s'ecoule réellement.

    Quand je dis "replay", il peut s'agir d'une cinématique peu importe, l'important c'est que tu ne sois pas dépendant d'une action du joueur au moment de la capture du film. Lors de la capture, tu viseras le 30 images video par secondes mais le jeu tournera a 5 images par secondes, ce qui fait que la personne qui dirigera le personnage devra le controler à sa vitesse effective divisée par six. Bref c'est suffisant pour devenir fou.

    Capturer les inputs du joueur a vitesse normale (ca ne coute rien). Puis rejouer la partie a vitesse réduite pour pouvoir avoir les 30 images video par seconde de jeu c'est une bonne solution.

    L'autre solution (pas forcément plus couteuse si tu n'as pas de replay) c'est d'avoir un mécanisme de capture de vidéo externe.

    LeGreg

  13. #13
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 79
    Points : 37
    Points
    37
    Par défaut
    meci pour ta réponse, en fait je suis sous directX 8.1 et j'ai juste cette fonction IDirect3DDevice8::GetFrontBuffer, c la meme que GetFrontBufferData tu crois ?

    Sinon il existe dans le moteur un moyen de faire parcourir la camera sur un trajet prédéfini, donc il n'y a pas besoin de trop s'embeter, et je n'ai pas trouvé le moyen de ralentir le rythme d'update dans le moteur, donc ce qu'on a fait c qu'o na ralenti la vistesse de deplacement de la cam sur le trajet predefini et ensuite adobe premiere a sorti le film.

    entre temps, on a trouvé une autre solution pas mal, le programme Fraps http://www.fraps.com/ enregistre totu ce qu'i lse passe a l'ecran y compris dans uen fenetre direct x, et il enregistre à 40 fps direct en .avi donc c du tout bon. Je sais pas comment il fonctionne, il fait des imprim ecran vs croyez ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 27/04/2014, 18h33
  2. Prise de ScreenShot : probleme
    Par spyk dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 05/09/2005, 18h42

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