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 :

D3DXCreateSphere et modification FVF, et accés Vertex buffer


Sujet :

DirectX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Par défaut D3DXCreateSphere et modification FVF, et accés Vertex buffer
    bonjour
    je créé une sphère avec D3DXCreateSphere,
    qui possède donc comme FVF : D3DFVF_XYZ | D3DFVF_NORMAL

    je clone ce mesh avec un nouveau FVF:

    déclaration du nouveau FVF :
    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
     
    #define D3DFVF_SPHEREMESHVERTEX  (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX0 ) // 
    struct SPHEREMESHVERTEX
    {
        D3DXVECTOR3 Position;
    	D3DXVECTOR3 Normale;
    	D3DXVECTOR3 Couleur;
     	D3DXVECTOR2 UVTex0;
     
    	const static D3DVERTEXELEMENT9 Decl[5];
    };
     
    const D3DVERTEXELEMENT9 SPHEREMESHVERTEX::Decl[] =
    {
        { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
    	{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
    	{ 0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,	   0 },
      	{ 0, 36, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
     
       D3DDECL_END()
    };
    clonage du mesh :
    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
     
    	hr = D3DXCreateSphere(	pd3dDevice,
    								50.0f,		// Radius,
    								64,		// UINT Slices,
    								64,		// UINT Stacks,
    								&pSphereMesh,
                                                                    NULL
    							);
    	if ( hr == S_OK ) OutputDebugString( L"D3DXCreateSphere ok \n" );
    	else  OutputDebugString( L"D3DXCreateSphere échoué \n" );
     
     
    	// clonage spheremesh
    	hr = pSphereMesh->CloneMeshFVF(	pSphereMesh->GetOptions()|D3DXMESH_MANAGED,
    										    D3DFVF_SPHEREMESHVERTEX, // FVF demandé
    	pd3dDevice,	// device
    										&g_pCloneSphereMesh				// pointeur vers mesh cloné
    										);
    	if ( hr != S_OK ) OutputDebugString(TEXT("erreur clone sphere mesh\n") );
    	else OutputDebugString(TEXT("clonage sphere mesh ok\n") );
     
    	if ( pSphereMesh ) SAFE_RELEASE( pSphereMesh );	// libération mesh original
    jusque là tout va bien:

    puis je veux verrouiller le vb pour y accéder et remplir la couleur et les coordonnées de texture

    pour vérifier mes valeurs, je fais :
    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
     
    	LPDIRECT3DVERTEXBUFFER9 pVB = NULL;
    	VerifHR( g_pCloneSphereMesh->GetVertexBuffer( &pVB));	// acquiert pointeur buffer mesh cloné
     
    	int nb_vertices = (int)(g_pCloneSphereMesh->GetNumVertices());			// nb de vertices du mesh
    	DWORD vFVF=g_pCloneSphereMesh->GetFVF();										// acquiert FVF
    	DWORD stride = D3DXGetFVFVertexSize (vFVF);								// taille d'un vertice
     
    	// vérification
    	UINT spherevertex_size =  D3DXGetFVFVertexSize(D3DFVF_SPHEREMESHVERTEX); // taille vertice demandée
    	DWORD vertex_size = g_pCloneSphereMesh->GetNumBytesPerVertex();	// taille vertice buffer mesh cloné
     
    	D3DVERTEXBUFFER_DESC desc;
    	VerifHR( pVB->GetDesc( &desc));
    	UINT buffer_size =  desc.Size;									// longueur buffer mesh cloné
    j'obtiens :
    nb_vertices = 4034
    stride = 28

    spherevertex_size = 28
    vertex_size =28

    buffer_size = 112952

    soit nb_vertices * spherevertex_size

    le VB a donc l'air ok

    je veux maintenant verrouiller le VB et accéder aux valeurs pour les modifier
    avec ce 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
     
    	SPHEREMESHVERTEX* pVertex;	// pour copier le vb du mesh
    	VOID* pVertices;			// zone mémoire à copier
     
    	// verouillage du VB
    	hr = pVB->Lock(	0,	// offset ( décalage ) dans le vb
    				0,	// taille à verrouiller 0 = tout
    				(void **)&pVertices,
    				0  // pas de drapeau spécifique de verouillage  
    				);
    	if ( hr != D3D_OK ) OutputDebugString( L"  pVB->Lock échoué\n" );
    	else  OutputDebugString( L"pVB->Lock ok\n" );
     
    	// copy en mémoire du VB du mesh
    	memcpy( &pVertex, pVertices, sizeof(pVertices));
     
    	// debug valeur vertex
    	wchar_t sz[256];
    	for ( int i = 0; i<nb_vertices; i++)
    	{
    		StringCchPrintfW(	sz,
    							256,
    							L"i: %d  pos: %0.2f %0.2f %0.2f color: %0.2f \n",
    							i,
    							&pVertex->Position.x,
    							&pVertex->Position.y,
    							&pVertex->Position.z,
    							&pVertex->Couleur.x							
     
    						);
     
    		OutputDebugString( sz );
     
    		pVertex++;	// vertice suivant
    	}
     
    	// déverrouillage VB
    	hr = pVB->Unlock();
    	if ( hr != D3D_OK ) OutputDebugString( L"  pVB->Unlock échoué\n" );
    	else  OutputDebugString( L"pVB->Unlock ok\n" );
    	if ( pVB ) pVB->Release();
    et la, j'obtiens des valeurs à 0, et si je veux modifier une valeur dans le buffer,
    j'ai une violation d'écriture

    j'ai essayé d'accéder au valeurs des vertex via :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pVertex[i].Position.x
    avec un erreur de violation mémoire pour résultat

    donc je m'y prends mal:

    durant le verrouillage du buffer,
    durant le memcpy() ou l'accès aux vertex, ou les trois ??

    dans les exemples on ne trouve que des créations de VB suivi de modifications, mais pas d'exemple de clonage de mesh avec modification de FVF et des valeurs du VB.

    je crois que je mélange des trucs
    un peu d'aide serait bienvenue

    merci d'avance

  2. #2
    Membre extrêmement actif

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 408
    Par défaut
    alors moi je vois ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SPHEREMESHVERTEX* pVertex;	// pour copier le vb du mesh
    as tu réservé la place en mémoire pour le stockage des informations?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // copy en mémoire du VB du mesh
    memcpy( &pVertex, pVertices, sizeof(pVertices));
    pVertex et pas &pVertex, et sizeof(pVertices) ne doit pas être bon, à cette place tu dois mettre la taille en octet des données à copier, soit dans ton cas un multiple de sizeof(SPHEREMESHVERTEX).

  3. #3
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 13
    Par défaut
    Bonjour,

    Sans être expert dans ce domaine (donc vérifiez ce que je dit), je pense que tu commets une erreur lors de la copie du Vertex Buffer vers la mémoire. En effet,
    sizeof(pVertices) n'est pas défini (sizeof sur les pointeurs attention). Tu peux le tester en incluant un affichage de Debug sur sizeof(pVertices), je pense que ca va t'afficher n'importe quoi.

    A mon sens, pour connaitre la taille du Vertex Buffer, tu est obligé d'appeler la méthode IDirect3DVertexBuffer9::GetDesc() qui va te retourner une structure
    D3DVERTEXBUFFER_DESC dans lequel le membre UINT Size correspond à la taille du VertexBuffer.

    Je n'ai survoler ton problème que rapidement, donc si d'autre soucis ...

  4. #4
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 13
    Par défaut
    OOps je viens de découvrir la réponse de stardeath, collision de réponse. Ca comfirme ce que je pense et effectivement pVertex c'est mieux que &pVertex.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Par défaut
    comment fait-on pour réserver la mémoire pour pVertex ?

    parce qu'effectivement si j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy( pVertex, pVertices, sizeof(buffer_size));
    j'obtiens un avertissement
    warning C4700: uninitialized local variable 'pVertex' used

    puis un plantage à l'éxecution


    seconde question :

    faut il copier le vertex buffer d'origine du mesh soit: pVertices dans une autre zone mémoire pour modifier des valeurs
    ou est ce qu'on peut modifier les valeurs originales durant le lock buffer

  6. #6
    Membre extrêmement actif

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 408
    Par défaut
    alors pour la première question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SPHEREMESHVERTEX* pVertex = new SPHEREMESHVERTEX[nombre de sommet que tu as récupéré avant]
    ensuite tu n'es pas obligé de recopier les sommets ailleurs, quand tu lock, dans pVertices tu récupères une adresse où sont stockés tes sommets, en fait tu devrais déclarer pVertices en tant que SPHEREMESHVERTEX* (et donc le cast dans le lock devient utile).

    selon les drapeaux que tu mets dans le lock (read only, read write, etc...) tu pourras lire/écrire directement en faisant pVertices[i] avec i l'indice de ton sommet, comme un bête tableau et sans se préoccuper d'allocation éventuelle.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Par défaut
    merci stardeath avec ce code l'allocation est bonne pour pVertex

    et le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //	memcpy( pVertex, pVertices, buffer_size);
    ne fait pas d'erreur

    en oubliant la copie vers pVertex pour l'instant, et en bouclant sur pVertices
    ce code fonctionne partiellement mais plante avant que i n'atteigne nb_vertices

    je déborde visiblement du tableau

    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
     
     
    	LPDIRECT3DVERTEXBUFFER9 pVB = NULL;
    	VerifHR( g_pCloneSphereMesh->GetVertexBuffer(&pVB) );	// acquiert pointeur buffer mesh cloné
    	if ( hr !=S_OK ) OutputDebugString( L"  GetVertexBuffer échoué\n" );
    	else  OutputDebugString( L"GetVertexBuffer ok\n" );
     
    	DWORD vFVF=g_pCloneSphereMesh->GetFVF();						// acquiert FVF
    	DWORD stride = D3DXGetFVFVertexSize(vFVF);						// taille d'un vertice
    /*
    	// vérification
    	UINT spherevertex_size =  D3DXGetFVFVertexSize(D3DFVF_SPHEREMESHVERTEX2); // taille vertice demandée
    	DWORD vertex_size = g_pCloneSphereMesh->GetNumBytesPerVertex();	// taille vertice buffer mesh cloné
    */	
     
    	D3DVERTEXBUFFER_DESC desc;
    	VerifHR( pVB->GetDesc( &desc));
    	UINT buffer_size =  desc.Size;									// longueur buffer mesh cloné
    	int nb_vertices = (int)(g_pCloneSphereMesh->GetNumVertices());	// nb de vertices du mesh
     
    	SPHEREMESHVERTEX2* pVertices;									// zone mémoire à copier
    	SPHEREMESHVERTEX2* pVertex=new SPHEREMESHVERTEX2[nb_vertices];	// pour copier le vb du mesh
     
    	// verrouillage du VB
    	hr = pVB->Lock(	0,							// offset ( décalage ) dans le vb
    					0,							// taille à verrouiller 0 = tout
    					(void**)&pVertices,			// cast pour le lock
    					D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY	// 
    					);
    	if ( hr != S_OK ) OutputDebugString( L"  pVB->Lock échoué\n" );
    	else  OutputDebugString( L"pVB->Lock ok\n" );
     
    // copy en mémoire du VB du mesh
    //	memcpy( pVertex, pVertices, nb_vertices*sizeof(SPHEREMESHVERTEX2));
    //	memcpy( pVertex, pVertices, buffer_size);
     
    	// debug valeur vertex
    	wchar_t sz[256];
    	for ( int i = 0; i < nb_vertices; i++)
    	{
    		StringCchPrintfW(	sz,
    							256,
    							L"i: %d  pos: %0.2f %0.2f %0.2f \n",
    							i,
    							pVertices[i].Position.x,
    							pVertices[i].Position.y,
    							pVertices[i].Position.z
    							);
    		OutputDebugString( sz );
     
    		pVertices++;	// vertice suivant
    	}
    	// déverrouillage VB
    	hr = pVB->Unlock();
    	if ( hr != S_OK ) OutputDebugString( L"  pVB->Unlock échoué\n" );
    	else  OutputDebugString( L"pVB->Unlock ok\n" );
     
    	if ( pVB ) pVB->Release();
    ouput:
    D3DXCreateSphere ok
    clonage sphere mesh ok
    GetVertexBuffer ok
    pVB->Lock ok
    i: 0 pos: 0.00 0.00 50.00
    i: 1 pos: 2.41 49.94 0.01
    i: 2 pos: 49.94 0.02 0.04
    ..........
    i: 1282 pos: 2.27 -49.94 -0.02
    i: 1283 pos: -49.94 -0.00 0.05
    i: 1284 pos: -0.00 0.00 0.00
    i: 1285 pos: 0.00 0.00 0.00
    i: 1286 pos: -0.00 0.00 0.00
    i: 1287 pos: 0.00 -0.00 -0.00
    i: 1288 pos: 6260903337279335100000000.00 0.00 0.00
    i: 1289 pos: -0.00 0.00 0.00
    i: 1290 pos: 0.00 0.00 -0.00
    i: 1291 pos: 0.00 0.00 -0.00
    i: 1292 pos: 0.00 0.00 0.00
    i: 1293 pos: 0.00 0.00 0.00
    i: 1294 pos: 0.00 0.00 0.00
    i: 1295 pos: 2005594867528336600000000.00 0.00 0.00
    i: 1296 pos: -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00
    i: 1297 pos: -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00
    i: 1298 pos: -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00

    .....
    i: 1326 pos: -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00 -158839966806181750000000000000000000000.00
    i: 1327 pos: 0.00 0.00 0.00
    First-chance exception at 0x0126b4df in DOOM2009.exe: 0xC0000005: Access violation reading location 0x096fe048.
    Unhandled exception at 0x0126b4df in DOOM2009.exe: 0xC0000005: Access violation reading location 0x096fe048.
    The program '[2216] DOOM2009.exe: Native' has exited with code -1073741819 (0xc0000005).

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

Discussions similaires

  1. [d3d] modification (non voulue) d'un vertex buffer
    Par d'Oursse dans le forum DirectX
    Réponses: 5
    Dernier message: 04/01/2008, 11h00
  2. [Debutant] Affichage du contenu d'un vertex buffer
    Par Edouard Kaiser dans le forum DirectX
    Réponses: 12
    Dernier message: 20/12/2005, 10h26
  3. Vertex buffer et géométrie complexe
    Par Omeyocan dans le forum DirectX
    Réponses: 13
    Dernier message: 14/12/2005, 11h28
  4. Probleme avec le vertex buffer
    Par nicoo dans le forum DirectX
    Réponses: 12
    Dernier message: 19/10/2004, 21h45
  5. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38

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