Jump to content

  • Log In with Google      Sign In   
  • Create Account

DirectX 11 maping ID3D11Texture2D


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
17 replies to this topic

#1 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 16 July 2013 - 09:09 AM

I'd like to change ID3D11Texture2D to data. This is my funtion: 

void getByte(ID3D11Texture2D* texture)
{
	ID3D11Texture2D* textureBuf;
	
	D3D11_TEXTURE2D_DESC textureDesc;

	ZeroMemory(&textureDesc, sizeof(textureDesc));
	textureDesc.Width = Width;
	textureDesc.Height = Height;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.SampleDesc.Quality = 0;
	textureDesc.Usage = D3D11_USAGE_STAGING ;
	textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
	textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	textureDesc.MiscFlags = 0;
	
	d3d11Device->CreateTexture2D(&textureDesc, NULL, &textureBuf);
	d3d11DevCon->CopyResource(textureBuf,texture);
	D3D11_MAPPED_SUBRESOURCE  mapResource;
	d3d11DevCon->Map(texture,0,D3D11_MAP_READ,NULL,&mapResource);
}

How can I now get pixel data ?



Sponsor:

#2 Zaoshi Kaba   Crossbones+   -  Reputation: 4356

Like
0Likes
Like

Posted 16 July 2013 - 09:53 AM

Your pixel data is in mapResource.pData. Typecast it into this structure (I hope I wrote correct order):
 

struct Color {
    float r, g, b, a;
};

Then access it like 1 dimensional array..

 



#3 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 16 July 2013 - 12:07 PM

I do what you say but my bufor is empty (when I try save sample data to file visual throws null ptr).

	struct Color {
    float r, g, b, a;
		};
	Color* obj;
	obj=(Color *)mapResource.pData;
	std::fstream file( "color.txt", std::ios::out );
	std::string str;
	std::stringstream ss (std::stringstream::in | std::stringstream::out);
	ss << obj[0].r;
	str=ss.str();
	file.write( & str[ 0 ], str.length() );


#4 Martins Mozeiko   Crossbones+   -  Reputation: 1422

Like
2Likes
Like

Posted 16 July 2013 - 12:29 PM

Verify that calls to CreateTexture2D and Map functions are not giving you error. Basically assign them to HRESULT hr variable. and check that SUCCEEDED(hr) is true.

Or enable debug runtime - either pass D3D11_CREATE_DEVICE_DEBUG flag for D3D11CreateDevice function, or go to DirectX Control Panel. That will show you errors in debugger output.



#5 unbird   Crossbones+   -  Reputation: 4981

Like
0Likes
Like

Posted 16 July 2013 - 12:42 PM

Good idea, because those flags look incompatible (a staging resource can't be a render target or shader resource view).

 

Furthermore: The mapped memory you receive is not necessarily contiguous. You have to take the D3D11_MAPPED_SUBRESOURCE.RowPitch into account - which gives you the memory offset in byte from one row to the next.

 



#6 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 16 July 2013 - 01:57 PM

Now I change desc but still i have problem. Maping is not succeeded.

        textureDesc.Width = Width;
	textureDesc.Height = Height;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.SampleDesc.Quality = 0;
	textureDesc.Usage = D3D11_USAGE_STAGING;
	textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	textureDesc.MiscFlags = 0;
	
	d3d11Device->CreateTexture2D(&textureDesc, NULL, &textureBuf);
	d3d11DevCon->CopyResource(textureBuf,texture);
	D3D11_MAPPED_SUBRESOURCE  mapResource;
	hr=d3d11DevCon->Map(texture,0,D3D11_MAP_READ,NULL,&mapResource);

Edited by kolarz3, 16 July 2013 - 01:59 PM.


#7 Zaoshi Kaba   Crossbones+   -  Reputation: 4356

Like
0Likes
Like

Posted 16 July 2013 - 02:17 PM

  1. I don't think you can use D3D11_BIND_SHADER_RESOURCE flag either.
  2. You seem to be using DXGI_FORMAT_R32G32B32A32_FLOAT format, are you sure your source texture is same format?
  3. It seems you try to Map() wrong texture.


#8 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 16 July 2013 - 03:23 PM

Now work(with copying with "obj=(Color *)mapResource.pData;"), but I don't known why I cant copy with memcpy. How can I copy this data with memcpy?

memcpy ( obj,mapResource.pData, sizeof(Color) );


#9 Martins Mozeiko   Crossbones+   -  Reputation: 1422

Like
0Likes
Like

Posted 16 July 2013 - 04:46 PM

sizeof(Color) is 16. You are copying only 16 bytes. You need to copy Height * RowPitch bytes.



#10 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 17 July 2013 - 12:39 AM

I cant copy anything because debuger stop on memcpy, if I continue debuging visual jump into memcpy.asm file :

rep     movsd           ;N - move all of our dwords
memcpy(obj,mapResource.pData,mapResource.RowPitch);

Edit: I forget to allocate memory/



#11 Naruto-kun   Members   -  Reputation: 336

Like
0Likes
Like

Posted 17 July 2013 - 07:45 AM

I suspect he is failing on the 2D Texture creation. Try setting the BindFlags to 0. I have just spent several hours trying to create a 2D Texture instance that the CPU can read from with no success until i set the BindFlags to 0.



#12 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 17 July 2013 - 08:17 AM

I dont known why i cant move pointer of my structer. Any solution ?

	struct Color {
    float r, g, b, a;
		};
	Color* obj;
	obj=new Color[mapResource.RowPitch*Height];
	BYTE* mappedData = reinterpret_cast<BYTE*>(mapResource.pData);
	for(UINT i = 0; i < Height; ++i)
	{
	memcpy(obj, mappedData, mapResource.RowPitch);
	mappedData += mapResource.RowPitch;
	obj += mapResource.RowPitch;//without this line program work
	}


#13 unbird   Crossbones+   -  Reputation: 4981

Like
0Likes
Like

Posted 17 July 2013 - 10:59 AM

Pointer arithmetic. obj does not not increase by RowPitch but by RowPitch*sizeof(Color). Use a BYTE pointer for the loop.

 

Edit: Similarly, your allocated array is 16 times too big.

 

But since you're copying everything anyway you could as well use only one memcpy.


Edited by unbird, 17 July 2013 - 02:25 PM.


#14 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 18 July 2013 - 10:12 AM

Now everything work.I found also thet all rows of pixel have extra 4 pixel data(I dont known what they mean) . If anybody later searching for solution I put code .

void Pick(ID3D11Texture2D* texture)
{
	ID3D11Texture2D* textureBuf;
	D3D11_TEXTURE2D_DESC textureDesc;
	ZeroMemory(&textureDesc, sizeof(textureDesc));
	textureDesc.Width = Width;
	textureDesc.Height = Height;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.SampleDesc.Quality = 0;
	textureDesc.Usage = D3D11_USAGE_STAGING;
	textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	textureDesc.MiscFlags = 0;
	d3d11Device->CreateTexture2D(&textureDesc, NULL, &textureBuf);

	d3d11DevCon->CopyResource(textureBuf,texture);
	D3D11_MAPPED_SUBRESOURCE  mapResource;
	hr=d3d11DevCon->Map(textureBuf,0,D3D11_MAP_READ,NULL,&mapResource);
	
	struct Color {float r, g, b, a;};
	Color* obj;
	obj=new Color[(mapResource.RowPitch/sizeof(Color))*Height];
	memcpy(obj, mapResource.pData,mapResource.RowPitch*Height);

	if(mousePos.x>0&&mousePos.x<Width&&mousePos.y>0&&mousePos.y<Height)
	if(obj[(mousePos.y*Width)+(4*mousePos.y)+mousePos.x].r==1.0/*If object that we was pick mouse have 1.0 on red bit we draw little cloud*/)model.rysujOtoczkę(model.dolny,model.gorny);
	
	d3d11DevCon->Unmap(textureBuf,0);
	textureBuf->Release();
	delete [] obj;
}

Edited by kolarz3, 18 July 2013 - 10:20 AM.


#15 Martins Mozeiko   Crossbones+   -  Reputation: 1422

Like
0Likes
Like

Posted 18 July 2013 - 01:16 PM

You don't need to copy all memory just to access one element of mapped memory.

hr=d3d11DevCon->Map(textureBuf,0,D3D11_MAP_READ,NULL,&mapResource);
if (FAILED(hr)) abort();
    
struct Color {float r, g, b, a;};
Color* obj = (Color*)mapResource.pData;
 
if(mousePos.x>0&&mousePos.x<Width&&mousePos.y>0&&mousePos.y<Height)
  if(obj[(mousePos.y*(mapResource.RowPitch)/sizeof(Color))+(4*mousePos.y)+mousePos.x].r==1.0/*If object that we was pick mouse have 1.0 on red bit we draw little cloud*/)
    model.rysujOtoczkę(model.dolny,model.gorny);
    
d3d11DevCon->Unmap(textureBuf,0);
textureBuf->Release();

Edited by Martins Mozeiko, 18 July 2013 - 01:16 PM.


#16 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 18 July 2013 - 04:22 PM

But in this case we must to cast data from D3D11_MAPPED_SUBRESOURCE to BYTE.


Edited by kolarz3, 18 July 2013 - 04:25 PM.


#17 Martins Mozeiko   Crossbones+   -  Reputation: 1422

Like
0Likes
Like

Posted 18 July 2013 - 06:23 PM

What?

Only thing you need to cast is pData member of D3D11_MAPPED_SUBRESOURCE. It has void* type, but you need Color*



#18 kolarz3   Members   -  Reputation: 164

Like
0Likes
Like

Posted 19 July 2013 - 01:14 AM

Anyway "Color* obj = (Color*)mapResource.pData;" do the same that "memcpy(obj, mapResource.pData,mapResource.RowPitch*Height);"






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS