Bonjour,

Je viens vous demander de l’aide car je me sens coincé dans une situation des plus paradoxales.
Dans le cadre de la création de distance maps, je dois lire les données d’une texture 2D et calculer ensuite les distances que je stock dans une texture 3D.

Je passerais sur les difficultés que j’ai eut à lire les données d’une texture puis à en créer une. Le système de texture de directX10 est des plus étranges.

La situation est donc la suivante : Je dois passer ma ID3D10Texture3D au shader. Il me faut donc la convertir en ID3D10ShaderResourceView. Cette conversion n’est pas des plus complexes, s’il n’y avait ce paradoxe :
Pour pouvoir utiliser la fonction CreateShaderResourceView, il me faut avoir créé la texture avec le BindFlag D3D10_BIND_SHADER_RESOURCE. Or cette texture a été créé sans aucun BindFlag, sinon, je n’aurais pu agir dessus avec le CPU.
Je me retrouve donc dans cette situation pour le moins étrange où je ne peux passer au shader une texture que j’ai créé à moins de l’avoir créé de telle sorte que je ne puisse la modifier.

Voici le 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
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
83
84
85
 
D3DX10_IMAGE_LOAD_INFO loadInfo;
loadInfo.Width = D3DX10_DEFAULT;
loadInfo.Height = D3DX10_DEFAULT;
loadInfo.Depth = D3DX10_DEFAULT;
loadInfo.FirstMipLevel = D3DX10_DEFAULT;
loadInfo.MipLevels = D3DX10_DEFAULT;
loadInfo.BindFlags = 0;
loadInfo.MiscFlags = D3DX10_DEFAULT;
loadInfo.Filter = D3DX10_FILTER_NONE;
loadInfo.MipFilter = D3DX10_FILTER_NONE;
loadInfo.CpuAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE; //Ces deux flags sont nécessaires. On ne peut pas lire si on ne peut pas écrire.
loadInfo.pSrcInfo = NULL;
loadInfo.Usage = D3D10_USAGE_STAGING; //Donne les droits en lecture et écriture sur la resource
 
ID3D10Texture2D *pTexture2D = NULL;
ID3D10Resource *pTexture = NULL;
hr = D3DX10CreateTextureFromFile( g_pd3dDevice, fileName, &loadInfo, NULL, &pTexture, NULL );
if( FAILED( hr ) )
	return false;
 
pTexture->QueryInterface(__uuidof(ID3D10Texture2D),(LPVOID*)&pTexture2D); //conversion de la resource en texture2D
pTexture->Release();
 
D3D10_MAPPED_TEXTURE2D mappedTex;
D3D10_TEXTURE2D_DESC desc;
pTexture2D->GetDesc(&desc);
hr = pTexture2D->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ_WRITE, 0, &mappedTex );
 
if( FAILED( hr ) )
	return false;
//On se ménage un accès aux données de la texture
UCHAR* pTexels = (UCHAR*)mappedTex.pData;
 
//Puis on créé la texture 3D qui va bien.
int maxDepth = 15;
ID3D10Texture3D *distMap;
D3D10_TEXTURE3D_DESC createInfo; //Il faut attribuer à la texture 3D les meme caractéristiques qu'à la texture 2D
createInfo.Width = desc.Width;
createInfo.Height = desc.Height;
createInfo.Depth = maxDepth;
createInfo.MipLevels = desc.MipLevels;
createInfo.Format = desc.Format;
createInfo.Usage = desc.Usage;
createInfo.BindFlags = 0; //Je ne peux pas mettre le BindFlag au shader ici non plus.
createInfo.CPUAccessFlags = desc.CPUAccessFlags; //J'utilise ici les meme paramètres que pour la texture2D.
createInfo.MiscFlags = desc.MiscFlags;
hr = g_pd3dDevice->CreateTexture3D(&createInfo, NULL, &distMap); //On créé la texture3D
 
if( FAILED( hr ) )
	MessageBox(NULL, "Echec de la creation de la texture 3D", "Error", MB_OK);
 
D3D10_MAPPED_TEXTURE3D mappedDistMap;
hr = distMap->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ_WRITE, 0, &mappedDistMap);
 
if( FAILED( hr ) )
	MessageBox(NULL, "Echec du mappage de la texture 3D", "Error", MB_OK);
 
UCHAR* p3DTexels = (UCHAR*)mappedDistMap.pData;
 
for(unsigned int curZ=0; curZ < (unsigned int)maxDepth; curZ++)
{
	for(unsigned int curY=0; curY < desc.Height; curY++)
	{
		for(unsigned int curX=0; curX < desc.Width; curX++)
		{
			p3DTexels[curZ*desc.Height*desc.Width*4+curY*desc.Width*4+curX*4] = 255;  //Ici j'attribue des valeurs arbitraires pour pouvoir vérifier
			p3DTexels[curZ*desc.Height*desc.Width*4+curY*desc.Width*4+curX*4+1] = 255;//que ma texture peut etre remplie par mes soins et que
			p3DTexels[curZ*desc.Height*desc.Width*4+curY*desc.Width*4+curX*4+2] = 255;//le shader affiche les informations ensuite.
			p3DTexels[curZ*desc.Height*desc.Width*4+curY*desc.Width*4+curX*4+3] = 255;
		}
	}
}
 
D3D10_TEXTURE3D_DESC desc2; //paramètre nécessaire à l'utilisation de CreateShaderResourceView
distMap->GetDesc(&desc2);
D3D10_SHADER_RESOURCE_VIEW_DESC viewDesc;
ZeroMemory( &viewDesc, sizeof(viewDesc) );
viewDesc.Format = desc2.Format;
viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE3D;
viewDesc.Texture3D.MipLevels = desc2.MipLevels;
hr = g_pd3dDevice->CreateShaderResourceView( distMap, &viewDesc, &g_pTextureRV); //Et cette fonction ne donne pas de résultat
 
if( FAILED( hr ) )
	MessageBox(NULL, "Echec de l'allocation de la texture 3D au shader", "Error", MB_OK); //Ce message s'affiche systématiquement au lancement du programme

Quelqu’un aurait il une idée de ce que je pourrais faire pour obtenir une texture (ID3D10Texture3D) ou ressource (ID3D10Resource) à passer au shader ?

J’espère avoir été clair, d’avance merci.