ID3D11Texture2Dのバイナリ化

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: ID3D11Texture2Dのバイナリ化

Re: ID3D11Texture2Dのバイナリ化

#7

by pell » 8年前

cpu利用率6% => 5%

コード:

#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3dCompiler.lib")
#include <dxgi1_2.h>
#include <d3dx11.h>
#include <d3dCompiler.h>
#include <crtdbg.h>
//安全に解放する
#define SAFE_RELEASE(x) if(x){x->Release(); x=NULL;}
#define SAFE_DELETE(x) if(x){delete x; x=NULL;}
//定数定義
#include <DirectXMath.h>
using namespace DirectX;
//頂点の構造体
struct SimpleVertex
{
	XMFLOAT3 Pos;  //位置
	XMFLOAT2 Uv; //UV座標
};

struct ConstantBuffer
{
	XMMATRIX mWorld;
};
//グローバル変数
HWND hWnd = NULL;
ID3D11Device* Device = NULL;      //デバイス
ID3D11DeviceContext* DeviceContext = NULL;   //デバイスコンテキスト
IDXGISwapChain* SwapChain = NULL;     //スワップチェイン
ID3D11RenderTargetView* RenderTargetView = NULL; //レンダーターゲットビュー
ID3D11InputLayout* VertexLayout = NULL;
ID3D11Buffer* VertexBuffer[2];

ID3D11VertexShader* VertexShader = NULL;//頂点シェーダー
ID3D11PixelShader* PixelShader[2];//ピクセルシェーダー

ID3D11Buffer*           g_pConstantBuffer = NULL;
ID3D11SamplerState* samplerState;
XMMATRIX                g_World[2];

static int WINDOW_WIDTH = 0;
static int WINDOW_HEIGHT = 0;
class ScreenCapture
{
public:
	ScreenCapture() { Init(); }
	~ScreenCapture()
	{
		if (g_deskDupl)g_deskDupl->Release();
	}
	void OnRender()
	{
		if (g_deskDupl == nullptr) return;
		
		ID3D11Texture2D*        g_texture = nullptr;
		IDXGIResource* resource = nullptr;
		DXGI_OUTDUPL_FRAME_INFO frameInfo;

		g_deskDupl->AcquireNextFrame(500, &frameInfo, &resource);

		mouseX = frameInfo.PointerPosition.Position.x;
		mouseY = frameInfo.PointerPosition.Position.y;

		resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast< void**>(&g_texture));

		Output(Device, DeviceContext, g_texture);

		resource->Release();
		g_deskDupl->ReleaseFrame();
	}
	void Init()
	{
		IDXGIFactory1* factory;
		CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast< void**>(&factory));

		IDXGIAdapter1* adapter;
		for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
		{
			// メインモニタを探す
			IDXGIOutput* output;
			for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); j++)
			{
				DXGI_OUTPUT_DESC outputDesc;
				output->GetDesc(&outputDesc);

				MONITORINFOEX monitorInfo;
				monitorInfo.cbSize = sizeof(MONITORINFOEX);
				GetMonitorInfo(outputDesc.Monitor, &monitorInfo);

				if (monitorInfo.dwFlags == MONITORINFOF_PRIMARY)
				{
					IDXGIOutput1* output1;
					output1 = reinterpret_cast< IDXGIOutput1*>(output);
					output1->DuplicateOutput(Device, &g_deskDupl);

					output->Release();
					adapter->Release();
					factory->Release();

					// シェーダ用にサンプラを作成する
					D3D11_SAMPLER_DESC samDesc;
					ZeroMemory(&samDesc, sizeof(samDesc));
					samDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
					samDesc.AddressU = samDesc.AddressV = samDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
					samDesc.MaxAnisotropy = 1;
					samDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
					samDesc.MaxLOD = D3D11_FLOAT32_MAX;

					Device->CreateSamplerState(&samDesc, &samplerState);
					return;
				}
				output->Release();
			}
			adapter->Release();
		}
		factory->Release();
	}
private:
		void Output(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC, ID3D11Texture2D* pBackBuffer)
		{
		D3D11_TEXTURE2D_DESC descBackBuffer;
		pBackBuffer->GetDesc(&descBackBuffer);

		descBackBuffer.ArraySize = 1;
		descBackBuffer.BindFlags = 0;
		descBackBuffer.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		descBackBuffer.MipLevels = 1;
		descBackBuffer.MiscFlags = 0;
		descBackBuffer.SampleDesc.Count = 1;
		descBackBuffer.SampleDesc.Quality = 0;
		descBackBuffer.Usage = D3D11_USAGE_STAGING;

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc0;
		srvDesc0.Format = descBackBuffer.Format;
		srvDesc0.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc0.Texture2D.MostDetailedMip = 0;
		srvDesc0.Texture2D.MipLevels = descBackBuffer.MipLevels;

		ID3D11Texture2D *hCaptureTexture;
		pd3dDevice->CreateTexture2D(&descBackBuffer, 0, &hCaptureTexture);

		ID3D11ShaderResourceView* resourceView;
		HRESULT hr = Device->CreateShaderResourceView(pBackBuffer, &srvDesc0, &resourceView);

		ID3D11Resource *hResource;
		resourceView->GetResource(&hResource);
		pd3dDC->CopyResource(hCaptureTexture, hResource);
		hResource->Release();

		D3D11_MAPPED_SUBRESOURCE mappedResource;
		pd3dDC->Map(hCaptureTexture, 0, D3D11_MAP_READ, 0, &mappedResource);

		UINT width = descBackBuffer.Width;
		UINT height = descBackBuffer.Height;

		UINT src_stride = mappedResource.RowPitch;
		size_t buffer_size = src_stride * height;
		LPBYTE bmp_buffer = static_cast<LPBYTE>(HeapAlloc(GetProcessHeap(), 0, buffer_size));

		memcpy(bmp_buffer, mappedResource.pData, buffer_size);

		pd3dDC->Unmap(hCaptureTexture, 0);

		pBackBuffer->Release();
		hCaptureTexture->Release();

		D3D11_SUBRESOURCE_DATA initData;
		initData.pSysMem = bmp_buffer;
		initData.SysMemPitch = src_stride;
		initData.SysMemSlicePitch = buffer_size;

		Input(pd3dDevice, pd3dDC, initData,
			width, height);

		HeapFree(GetProcessHeap(), 0, bmp_buffer);
	}
	void Input(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC,
		D3D11_SUBRESOURCE_DATA initData, UINT width, UINT height)
	{
		D3D11_TEXTURE2D_DESC desc;
		memset(&desc, 0, sizeof(desc));
		desc.Width = width;
		desc.Height = height;
		desc.MipLevels = 1;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DEFAULT;
		desc.BindFlags = 40;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

		ID3D11Texture2D* tex2D;
		pd3dDevice->CreateTexture2D(&desc, &initData, &tex2D);

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		srvDesc.Format = desc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc.MipLevels;
		ID3D11ShaderResourceView* resourceView;
		pd3dDevice->CreateShaderResourceView(tex2D, &srvDesc, &resourceView);

		Draw(tex2D, resourceView);
		resourceView->Release();

		tex2D->Release();
	}
	
	void Draw(ID3D11Texture2D* screen, ID3D11ShaderResourceView* resourceView)
	{
		D3D11_TEXTURE2D_DESC desc;
		screen->GetDesc(&desc);
		// ShaderResourceViewの情報を作成する
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc.MipLevels;

		float X = (mouseX / static_cast<float>(WINDOW_WIDTH)) - 0.99f;
		float Y = -(mouseY / static_cast<float>(WINDOW_HEIGHT)) + 0.98f;

		g_World[0] = XMMatrixIdentity();
		g_World[1] = XMMatrixTranslation(X,Y,0.0f);
		// ILのセット
		DeviceContext->IASetInputLayout(VertexLayout);
		// プリミティブタイプのセット
		DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

		ConstantBuffer cb;
		for (int i = 0; i < 2; i++) {
				cb.mWorld = XMMatrixTranspose(g_World[i]);
				DeviceContext->UpdateSubresource(g_pConstantBuffer, 0, NULL, &cb, 0, 0);

				//バーテックスバッファーをセット
				UINT stride = sizeof(SimpleVertex);
				UINT offset = 0;
				DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer[i], &stride, &offset);

			    DeviceContext->VSSetShader(VertexShader, NULL, 0);
				DeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
				DeviceContext->PSSetShader(PixelShader[i], NULL, 0);

				//テクスチャーをシェーダーに渡す
				DeviceContext->PSSetShaderResources(0, 1, &resourceView);
				DeviceContext->PSSetSamplers(0, 1, &samplerState);

				//プリミティブをレンダリング
				DeviceContext->Draw(4, 0);
		}
	}
	IDXGIOutputDuplication* g_deskDupl = nullptr;

	int mouseX = 0;
	int mouseY = 0;
}*screen;

//Direct3Dの初期化関数
HRESULT InitD3D(HWND hWnd)
{
	// デバイスとスワップチェーンの作成
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;         //バックバッファの数
	sd.BufferDesc.Width = WINDOW_WIDTH;     //バッファの幅
	sd.BufferDesc.Height = WINDOW_HEIGHT;    //バッファの高さ
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //バッファのフォーマット
	sd.BufferDesc.RefreshRate.Numerator =1;   //リフレッシュレート
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	D3D_FEATURE_LEVEL  FeatureLevel = D3D_FEATURE_LEVEL_11_0;


	if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
		&FeatureLevel, 1, D3D11_SDK_VERSION, &sd, &SwapChain, &Device, NULL, &DeviceContext)))
	{
		return FALSE;
	}
	//レンダーターゲットビューの作成
	ID3D11Texture2D *BackBuffer;
	SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&BackBuffer);
	Device->CreateRenderTargetView(BackBuffer, NULL, &RenderTargetView);
	BackBuffer->Release();
	DeviceContext->OMSetRenderTargets(1, &RenderTargetView, NULL);

	//ビューポートの設定
	D3D11_VIEWPORT vp;
	vp.Width = WINDOW_WIDTH;
	vp.Height = WINDOW_HEIGHT;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	DeviceContext->RSSetViewports(1, &vp);

	ID3DBlob *pCompiledShader = NULL;
	ID3DBlob *pErrors = NULL;
	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "VS", "vs_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"頂点シェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);

	if (FAILED(Device->CreateVertexShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &VertexShader)))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"頂点シェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}

	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = sizeof(layout) / sizeof(layout[0]);

	if (FAILED(Device->CreateInputLayout(layout, numElements, pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), &VertexLayout)))
		return FALSE;

	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "PS", "ps_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"ピクセルシェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);
	if (FAILED(Device->CreatePixelShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &PixelShader[0])))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"ピクセルシェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}

	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "PSc", "ps_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"ピクセルシェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);
	if (FAILED(Device->CreatePixelShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &PixelShader[1])))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"ピクセルシェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pCompiledShader);

	SimpleVertex vertices[] =
	{
		XMFLOAT3(-1.0f,-1.0f,0.5f),XMFLOAT2(0,1),
		XMFLOAT3(-1.0f,1.0f,0.5f),XMFLOAT2(0,0),
		XMFLOAT3(1.0f,-1.0f,0.5f),XMFLOAT2(1,1),
		XMFLOAT3(1.0f,1.0f,0.5f),XMFLOAT2(1,0),
	};
	D3D11_BUFFER_DESC bd;
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(SimpleVertex) * 4;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = vertices;
	if (FAILED(Device->CreateBuffer(&bd, &InitData, &VertexBuffer[0])))
		return FALSE;

	SimpleVertex vertices2[] =
	{
		XMFLOAT3(-0.01f,-0.01f,0.0f),XMFLOAT2(0,0),
		XMFLOAT3(-0.01f,0.01f,0.0f),XMFLOAT2(0,1),
		XMFLOAT3(0.01f,-0.01f,0.0f),XMFLOAT2(1,0),
		XMFLOAT3(0.01f,0.01f,0.0f),XMFLOAT2(1,1),
	};
	D3D11_BUFFER_DESC bd2;
	bd2.Usage = D3D11_USAGE_DEFAULT;
	bd2.ByteWidth = sizeof(SimpleVertex) * 4;
	bd2.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd2.CPUAccessFlags = 0;
	bd2.MiscFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData2;
	InitData2.pSysMem = vertices2;
	if (FAILED(Device->CreateBuffer(&bd2, &InitData2, &VertexBuffer[1])))
		return FALSE;

	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0;
	if (FAILED(Device->CreateBuffer(&bd, NULL, &g_pConstantBuffer)))
		return FALSE;

	screen = new ScreenCapture();
	return S_OK;
}

VOID Render()
{
	float ClearColor[4] = { 0,0,0,0 };
	DeviceContext->ClearRenderTargetView(RenderTargetView, ClearColor);
	screen->OnRender();
	SwapChain->Present(1, 0);
}

VOID Cleanup()
{
	SAFE_DELETE(screen);
	SAFE_RELEASE(VertexShader);
	SAFE_RELEASE(PixelShader[0]);
	SAFE_RELEASE(PixelShader[1]);

	SAFE_RELEASE(VertexBuffer[0]);
	SAFE_RELEASE(VertexBuffer[1]);

	SAFE_RELEASE(g_pConstantBuffer);
	SAFE_RELEASE(VertexLayout);
	SAFE_RELEASE(SwapChain);
	SAFE_RELEASE(RenderTargetView);
	SAFE_RELEASE(DeviceContext);
	SAFE_RELEASE(Device);
}

LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szStr, INT iCmdShow)
{
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		L"Window1", NULL };
	RegisterClassEx(&wc);

	HWND hWnd = GetDesktopWindow();
	HDC hdc = GetDC(hWnd);
	WINDOW_WIDTH = GetDeviceCaps(hdc, HORZRES) / 2;
	WINDOW_HEIGHT = GetDeviceCaps(hdc, VERTRES) / 2;
	int res = ReleaseDC(hWnd, hdc);
	RECT rect;
	SetRect(&rect, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
	AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
	rect.right = rect.right - rect.left;
	rect.bottom = rect.bottom - rect.top;
	rect.top = 0;
	rect.left = 0;
	hWnd = CreateWindow(L"Window1", L"デスクトップキャプチャ",
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,
		NULL, NULL, wc.hInstance, NULL);

	MSG msg;
	ZeroMemory(&msg, sizeof(msg));
	if (SUCCEEDED(InitD3D(hWnd)))
	{
		ShowWindow(hWnd, SW_SHOW);
		UpdateWindow(hWnd);
		while (msg.message != WM_QUIT)
		{
			if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
			{
				Render();
			}
		}
	}
	return static_cast<int>(msg.wParam);
}
[code = fx]
//グローバル
Texture2D g_texDecal: register(t0);//テクスチャー
SamplerState g_samLinear : register(s0);//サンプラー

cbuffer ConstantBuffer : register(b0)
{
matrix World;
}
//構造体
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};

//頂点シェーダー
VS_OUTPUT VS(float4 Pos : POSITION, float2 Tex : TEXCOORD)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul(Pos, World);
output.Tex = Tex;

return output;
}

//ピクセルシェーダー
float4 PS(VS_OUTPUT input) : SV_Target
{
return g_texDecal.Sample(g_samLinear, input.Tex);
}
//ピクセルシェーダー
float4 PSc(float4 Pos : SV_POSITION) : SV_Target
{
return float4(1.0f, 0.0f, 0.0f, 1.0f); // Yellow, with Alpha = 1
}

[/code]

Re: ID3D11Texture2Dのバイナリ化

#6

by pell » 8年前

成功しました。現状この無駄なキャプチャプログラムはこのコードに変更すると自分のPCのcpu利用率が約6%。
でも通信をする以上減らせる負担は極限まで減らしたいので改善点があれば回答お願いします。
この回答から1週間後に解決とさせていただきます。

コード:

void Output(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC, ID3D11Texture2D* pBackBuffer)
		{
		D3D11_TEXTURE2D_DESC descBackBuffer;
		pBackBuffer->GetDesc(&descBackBuffer);

		D3D11_TEXTURE2D_DESC Texture2DDesc;
		Texture2DDesc.ArraySize = 1;
		Texture2DDesc.BindFlags = 0;
		Texture2DDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		Texture2DDesc.Format = descBackBuffer.Format;
		Texture2DDesc.Height = descBackBuffer.Height;
		Texture2DDesc.Width = descBackBuffer.Width;
		Texture2DDesc.MipLevels = 1;
		Texture2DDesc.MiscFlags = 0;
		Texture2DDesc.SampleDesc.Count = 1;
		Texture2DDesc.SampleDesc.Quality = 0;
		Texture2DDesc.Usage = D3D11_USAGE_STAGING;

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc0;
		D3D11_TEXTURE2D_DESC desc0;
		pBackBuffer->GetDesc(&desc0);
		ZeroMemory(&srvDesc0, sizeof(srvDesc0));
		srvDesc0.Format = desc0.Format;
		srvDesc0.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc0.Texture2D.MostDetailedMip = 0;
		srvDesc0.Texture2D.MipLevels = desc0.MipLevels;
		ID3D11ShaderResourceView* resourceView;
		HRESULT hr = Device->CreateShaderResourceView(pBackBuffer, &srvDesc0, &resourceView);

		ID3D11Texture2D *hCaptureTexture;
		pd3dDevice->CreateTexture2D(&Texture2DDesc, 0, &hCaptureTexture);

		ID3D11Resource *hResource;
		resourceView->GetResource(&hResource);
		pd3dDC->CopyResource(hCaptureTexture, hResource);
		hResource->Release();

		D3D11_MAPPED_SUBRESOURCE mappedResource;
		pd3dDC->Map(hCaptureTexture, 0, D3D11_MAP_READ, 0, &mappedResource);

		UINT width = Texture2DDesc.Width;
		UINT height = Texture2DDesc.Height;
		UINT src_stride = mappedResource.RowPitch;
		size_t buffer_size = src_stride * height;
		BYTE *bmp_buffer = new BYTE[buffer_size];
		CopyMemory(bmp_buffer, mappedResource.pData, buffer_size);
		pd3dDC->Unmap(hCaptureTexture, 0);

		pBackBuffer->Release();
		hCaptureTexture->Release();

		D3D11_SUBRESOURCE_DATA initData;
		initData.pSysMem = bmp_buffer;
		initData.SysMemPitch = src_stride;
		initData.SysMemSlicePitch = buffer_size;

//initDataを通信でとばして受け取ったとする
		Input(pd3dDevice, pd3dDC, initData,width, height);

		delete[] bmp_buffer;
	}
	void Input(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC,
		D3D11_SUBRESOURCE_DATA initData, UINT width, UINT height)
	{
		D3D11_TEXTURE2D_DESC desc;
		memset(&desc, 0, sizeof(desc));
		desc.Width = width;
		desc.Height = height;
		desc.MipLevels = 1;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DEFAULT;
		desc.BindFlags = 40;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;


		ID3D11Texture2D* tex2D;
		HRESULT hr = pd3dDevice->CreateTexture2D(&desc, &initData, &tex2D);

		
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		D3D11_TEXTURE2D_DESC desc_;
		tex2D->GetDesc(&desc_);
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc_.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc_.MipLevels;
		ID3D11ShaderResourceView* resourceView2;
		hr = Device->CreateShaderResourceView(tex2D, &srvDesc, &resourceView2);

		Draw(tex2D, resourceView2, !(premouseX == mouseX || premouseY == mouseY));
		resourceView2->Release();

		tex2D->Release();
	}

Re: ID3D11Texture2Dのバイナリ化

#5

by pell » 8年前

説明が抜けていました。
上のコードは現状のバグを再現したものです。
デスクトップキャプチャーがしたいわけではありません。画像の問題です。
あくまでパッと作った再現ですのでコードは普通に見ると気持ち悪いです。
見て欲しい部分はinput関数だけです。

Re: ID3D11Texture2Dのバイナリ化

#4

by pell » 8年前

コード:

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dx11.lib")
#pragma comment(lib,"d3dCompiler.lib")
#include < dxgi1_2.h>
#include < d3dx11.h>
#include < d3dCompiler.h>
#include <crtdbg.h>
//安全に解放する
#define SAFE_RELEASE(x) if(x){x->Release(); x=NULL;}
#define SAFE_DELETE(x) if(x){delete x; x=NULL;}
//定数定義
#include <DirectXMath.h>
using namespace DirectX;
//頂点の構造体
struct SimpleVertex
{
	XMFLOAT3 Pos;  //位置
	XMFLOAT2 Uv; //UV座標
};

struct ConstantBuffer
{
	XMMATRIX mWorld;
};
//グローバル変数
HWND hWnd = NULL;
ID3D11Device* Device = NULL;      //デバイス
ID3D11DeviceContext* DeviceContext = NULL;   //デバイスコンテキスト
IDXGISwapChain* SwapChain = NULL;     //スワップチェイン
ID3D11RenderTargetView* RenderTargetView = NULL; //レンダーターゲットビュー
ID3D11InputLayout* VertexLayout = NULL;
ID3D11Buffer* VertexBuffer[2];

ID3D11VertexShader* VertexShader = NULL;//頂点シェーダー
ID3D11PixelShader* PixelShader[2];//ピクセルシェーダー

ID3D11Buffer*           g_pConstantBuffer = NULL;
ID3D11SamplerState* samplerState;
XMMATRIX                g_World[2];

static int WINDOW_WIDTH = 0;
static int WINDOW_HEIGHT = 0;
class ScreenCapture
{
public:
	ScreenCapture() :g_width(-1), g_height(-1) { Init(); }
	~ScreenCapture()
	{
		if (g_deskDupl)g_deskDupl->Release();
	}
	void GetDestopMousePos(int * mouseXp,int *mouseYp)
	{
		*mouseXp = mouseX;
		*mouseYp = mouseY;
	}
	int premouseX;
	int premouseY;
	void OnRender()
	{
		if (g_deskDupl == nullptr) return;
		
		ID3D11Texture2D*        g_texture = nullptr;
		IDXGIResource* resource = nullptr;
		DXGI_OUTDUPL_FRAME_INFO frameInfo;

		g_deskDupl->AcquireNextFrame(500, &frameInfo, &resource);
		
		premouseX = mouseX;
		premouseY = mouseY;

		mouseX = frameInfo.PointerPosition.Position.x;
		mouseY = frameInfo.PointerPosition.Position.y;

		resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast< void**>(&g_texture));
			//Drawscreen(g_texture, !(premouseX == mouseX || premouseY == mouseY));
			//CreateTexture(g_texture, DeviceContext, WINDOW_WIDTH, WINDOW_HEIGHT);

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		D3D11_TEXTURE2D_DESC desc;
		g_texture->GetDesc(&desc);
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc.MipLevels;
		ID3D11ShaderResourceView* resourceView; ///<シェーダとリソースを繋ぐインターフェイス
												// ShaderResourceViewを作成する
		 Device->CreateShaderResourceView(g_texture, &srvDesc, &resourceView);
		 Output(Device, DeviceContext, g_texture);

		resource->Release();
		g_deskDupl->ReleaseFrame();
	}
	void Init()
	{
		IDXGIFactory1* factory;
		CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast< void**>(&factory));

		IDXGIAdapter1* adapter;
		for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
		{
			// メインモニタを探す
			IDXGIOutput* output;
			for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); j++)
			{
				DXGI_OUTPUT_DESC outputDesc;
				output->GetDesc(&outputDesc);

				MONITORINFOEX monitorInfo;
				monitorInfo.cbSize = sizeof(MONITORINFOEX);
				GetMonitorInfo(outputDesc.Monitor, &monitorInfo);

				if (monitorInfo.dwFlags == MONITORINFOF_PRIMARY)
				{
					g_width = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
					g_height = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;

					IDXGIOutput1* output1;
					output1 = reinterpret_cast< IDXGIOutput1*>(output);
					output1->DuplicateOutput(Device, &g_deskDupl);

					output->Release();
					adapter->Release();
					factory->Release();

					// シェーダ用にサンプラを作成する
					D3D11_SAMPLER_DESC samDesc;
					ZeroMemory(&samDesc, sizeof(samDesc));
					samDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
					samDesc.AddressU = samDesc.AddressV = samDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
					samDesc.MaxAnisotropy = 1;
					samDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
					samDesc.MaxLOD = D3D11_FLOAT32_MAX;

					Device->CreateSamplerState(&samDesc, &samplerState);
					return;
				}
				output->Release();
			}
			adapter->Release();
		}
		factory->Release();
	}
private:
	BOOL WriteBitmap(LPTSTR lpszFileName, int nWidth, int nHeight, LPVOID lpBits)
	{
		HANDLE           hFile;
		DWORD            dwResult;
		DWORD            dwSizeImage;
		BITMAPFILEHEADER bmfHeader;
		BITMAPINFOHEADER bmiHeader;

		hFile = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (hFile == INVALID_HANDLE_VALUE)
			return FALSE;

		dwSizeImage = nHeight * ((3 * nWidth + 3) / 4) * 4;

		ZeroMemory(&bmfHeader, sizeof(BITMAPFILEHEADER));
		bmfHeader.bfType = *(LPWORD)"BM";
		bmfHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwSizeImage;
		bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

		WriteFile(hFile, &bmfHeader, sizeof(BITMAPFILEHEADER), &dwResult, NULL);

		ZeroMemory(&bmiHeader, sizeof(BITMAPINFOHEADER));
		bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmiHeader.biWidth = nWidth;
		bmiHeader.biHeight = nHeight;
		bmiHeader.biPlanes = 1;
		bmiHeader.biBitCount = 24;
		bmiHeader.biCompression = BI_RGB;
		bmiHeader.biSizeImage = 0;
		bmiHeader.biXPelsPerMeter = 0;
		bmiHeader.biYPelsPerMeter = 0;
		bmiHeader.biClrUsed = 0;
		bmiHeader.biClrImportant = 0;

		WriteFile(hFile, &bmiHeader, sizeof(BITMAPINFOHEADER), &dwResult, NULL);

		WriteFile(hFile, lpBits, dwSizeImage, &dwResult, NULL);

		CloseHandle(hFile);

		return TRUE;
	}
		//GLで描画した内容をビットマップ画像として保存//
		void Output(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC, ID3D11Texture2D* pBackBuffer)
		{
		D3D11_TEXTURE2D_DESC descBackBuffer;
		pBackBuffer->GetDesc(&descBackBuffer);

		D3D11_TEXTURE2D_DESC Texture2DDesc;
		Texture2DDesc.ArraySize = 1;
		Texture2DDesc.BindFlags = 0;
		Texture2DDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		Texture2DDesc.Format = descBackBuffer.Format;
		Texture2DDesc.Height = descBackBuffer.Height;
		Texture2DDesc.Width = descBackBuffer.Width;
		Texture2DDesc.MipLevels = 1;
		Texture2DDesc.MiscFlags = 0;
		Texture2DDesc.SampleDesc.Count = 1;
		Texture2DDesc.SampleDesc.Quality = 0;
		Texture2DDesc.Usage = D3D11_USAGE_STAGING;

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc0;
		D3D11_TEXTURE2D_DESC desc0;
		pBackBuffer->GetDesc(&desc0);
		ZeroMemory(&srvDesc0, sizeof(srvDesc0));
		srvDesc0.Format = desc0.Format;
		srvDesc0.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc0.Texture2D.MostDetailedMip = 0;
		srvDesc0.Texture2D.MipLevels = desc0.MipLevels;
		ID3D11ShaderResourceView* resourceView;
		HRESULT hr = Device->CreateShaderResourceView(pBackBuffer, &srvDesc0, &resourceView);

		ID3D11Texture2D *hCaptureTexture;
		pd3dDevice->CreateTexture2D(&Texture2DDesc, 0, &hCaptureTexture);

		ID3D11Resource *hResource;
		resourceView->GetResource(&hResource);
		pd3dDC->CopyResource(hCaptureTexture, hResource);
		hResource->Release();

		D3D11_MAPPED_SUBRESOURCE mappedResource;
		pd3dDC->Map(hCaptureTexture, 0, D3D11_MAP_READ, 0, &mappedResource);

		UINT width = Texture2DDesc.Width;
		UINT height = Texture2DDesc.Height;
		UINT src_stride = mappedResource.RowPitch;
		size_t buffer_size = src_stride * height;
		BYTE *bmp_buffer = new BYTE[buffer_size];
		CopyMemory(bmp_buffer, mappedResource.pData, buffer_size);
		pd3dDC->Unmap(hCaptureTexture, 0);

		pBackBuffer->Release();
		hCaptureTexture->Release();

		Input(pd3dDevice, pd3dDC, bmp_buffer, buffer_size,
			width, height);

		delete[] bmp_buffer;
	}
	void Input(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC,
		BYTE *bmp_buffer, size_t buffer_size, UINT width, UINT height)
	{
		D3D11_TEXTURE2D_DESC desc;
		memset(&desc, 0, sizeof(desc));
		desc.Width = width;
		desc.Height = height;
		desc.MipLevels = 1;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DYNAMIC;
		desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

		ID3D11Texture2D* tex2D;
		HRESULT hr = pd3dDevice->CreateTexture2D(&desc, 0, &tex2D);

		D3D11_MAPPED_SUBRESOURCE hMappedResource;
		hr = pd3dDC->Map(
			tex2D,
			0,
			D3D11_MAP_WRITE_DISCARD,
			0,
			&hMappedResource);

		DWORD Color;
		//α
		Color &= 0x00ffffff;
		Color |= (0 & 0x000000ff) << 24;
		//B
		Color &= 0xffffff00;
		Color |= 0xFF & 0x000000ff;
		//G
		Color &= 0xffff00ff;
		Color |= (0xFF & 0x000000ff) << 8;
		//R
		Color &= 0xff00ffff;
		Color |= (0xFF & 0x000000ff) << 16;

		BYTE* pBits = reinterpret_cast<BYTE*>(hMappedResource.pData);
		memset(pBits, 0, buffer_size);
		BYTE* copy = NULL;

		const UINT iOfs_x = 0;
		const UINT iOfs_y = 0;
		const UINT iBmp_w = iOfs_x + width;
		const UINT iBmp_h = iOfs_y + height;
		const UINT Level = 6;

		for (int count = 0, y = iOfs_y; y < iBmp_h; y++)
		{
			for (int x = iOfs_x; x < iBmp_w; x++)
			{
				const DWORD Alpha = (bmp_buffer[count] * 255) >> Level;
				const DWORD Color_ = Color | (Alpha << 24);//α
				copy = pBits + hMappedResource.RowPitch * y + 4 * x;
				memcpy(copy, &Color_, sizeof(DWORD));
				count++;
			}
		}
		pd3dDC->Unmap(tex2D, 0);
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		D3D11_TEXTURE2D_DESC desc_;
		tex2D->GetDesc(&desc_);
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc_.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc_.MipLevels;
		ID3D11ShaderResourceView* resourceView2;
		hr = Device->CreateShaderResourceView(tex2D, &srvDesc, &resourceView2);

		Draw(tex2D, resourceView2, !(premouseX == mouseX || premouseY == mouseY));
		resourceView2->Release();

		tex2D->Release();
	}
	
	void Draw(ID3D11Texture2D* screen, ID3D11ShaderResourceView* resourceView,bool cur)
	{
		D3D11_TEXTURE2D_DESC desc;
		screen->GetDesc(&desc);
		// ShaderResourceViewの情報を作成する
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc.MipLevels;

		float X = (mouseX / static_cast<float>(WINDOW_WIDTH)) - 0.99f;
		float Y = -(mouseY / static_cast<float>(WINDOW_HEIGHT)) + 0.98f;

		g_World[0] = XMMatrixIdentity();
		g_World[1] = XMMatrixTranslation(X,Y,0.0f);
		// ILのセット
		DeviceContext->IASetInputLayout(VertexLayout);
		// プリミティブタイプのセット
		DeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

		ConstantBuffer cb;
		for (int i = 0; i < 2; i++) {
			if (cur || i == 0) {
				
				cb.mWorld = XMMatrixTranspose(g_World[i]);
				DeviceContext->UpdateSubresource(g_pConstantBuffer, 0, NULL, &cb, 0, 0);

				//バーテックスバッファーをセット
				UINT stride = sizeof(SimpleVertex);
				UINT offset = 0;
				DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer[i], &stride, &offset);

			    DeviceContext->VSSetShader(VertexShader, NULL, 0);
				DeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
				DeviceContext->PSSetShader(PixelShader[i], NULL, 0);

				//テクスチャーをシェーダーに渡す
					DeviceContext->PSSetShaderResources(0, 1, &resourceView);
					DeviceContext->PSSetSamplers(0, 1, &samplerState);

				//プリミティブをレンダリング
				DeviceContext->Draw(4, 0);
			}
		}
	}
	IDXGIOutputDuplication* g_deskDupl = nullptr;

	ID3D11ShaderResourceView* shaderres;
	int mouseX = 0;
	int mouseY = 0;
	int                     g_width = -1;
	int                     g_height = -1;
}*screen;

//Direct3Dの初期化関数
HRESULT InitD3D(HWND hWnd)
{
	// デバイスとスワップチェーンの作成
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;         //バックバッファの数
	sd.BufferDesc.Width = WINDOW_WIDTH;     //バッファの幅
	sd.BufferDesc.Height = WINDOW_HEIGHT;    //バッファの高さ
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //バッファのフォーマット
	sd.BufferDesc.RefreshRate.Numerator =1;   //リフレッシュレート
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	D3D_FEATURE_LEVEL  FeatureLevel = D3D_FEATURE_LEVEL_11_0;


	if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
		&FeatureLevel, 1, D3D11_SDK_VERSION, &sd, &SwapChain, &Device, NULL, &DeviceContext)))
	{
		return FALSE;
	}
	//レンダーターゲットビューの作成
	ID3D11Texture2D *BackBuffer;
	SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&BackBuffer);
	Device->CreateRenderTargetView(BackBuffer, NULL, &RenderTargetView);
	BackBuffer->Release();
	DeviceContext->OMSetRenderTargets(1, &RenderTargetView, NULL);

	//ビューポートの設定
	D3D11_VIEWPORT vp;
	vp.Width = WINDOW_WIDTH;
	vp.Height = WINDOW_HEIGHT;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	DeviceContext->RSSetViewports(1, &vp);

	ID3DBlob *pCompiledShader = NULL;
	ID3DBlob *pErrors = NULL;
	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "VS", "vs_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"頂点シェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);

	if (FAILED(Device->CreateVertexShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &VertexShader)))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"頂点シェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}

	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = sizeof(layout) / sizeof(layout[0]);

	if (FAILED(Device->CreateInputLayout(layout, numElements, pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), &VertexLayout)))
		return FALSE;

	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "PS", "ps_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"ピクセルシェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);
	if (FAILED(Device->CreatePixelShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &PixelShader[0])))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"ピクセルシェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}

	if (FAILED(D3DX11CompileFromFile(L"shader.fx", NULL, NULL, "PSc", "ps_5_0", 0, 0, NULL, &pCompiledShader, &pErrors, NULL)))
	{
		MessageBox(0, L"ピクセルシェーダー読み込み失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pErrors);
	if (FAILED(Device->CreatePixelShader(pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(), NULL, &PixelShader[1])))
	{
		SAFE_RELEASE(pCompiledShader);
		MessageBox(0, L"ピクセルシェーダー作成失敗", NULL, MB_OK);
		return E_FAIL;
	}
	SAFE_RELEASE(pCompiledShader);

	SimpleVertex vertices[] =
	{
		XMFLOAT3(-1.0f,-1.0f,0.5f),XMFLOAT2(0,1),
		XMFLOAT3(-1.0f,1.0f,0.5f),XMFLOAT2(0,0),
		XMFLOAT3(1.0f,-1.0f,0.5f),XMFLOAT2(1,1),
		XMFLOAT3(1.0f,1.0f,0.5f),XMFLOAT2(1,0),
	};
	D3D11_BUFFER_DESC bd;
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(SimpleVertex) * 4;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = vertices;
	if (FAILED(Device->CreateBuffer(&bd, &InitData, &VertexBuffer[0])))
		return FALSE;

	SimpleVertex vertices2[] =
	{
		XMFLOAT3(-0.01f,-0.01f,0.0f),XMFLOAT2(0,0),
		XMFLOAT3(-0.01f,0.01f,0.0f),XMFLOAT2(0,1),
		XMFLOAT3(0.01f,-0.01f,0.0f),XMFLOAT2(1,0),
		XMFLOAT3(0.01f,0.01f,0.0f),XMFLOAT2(1,1),
	};
	D3D11_BUFFER_DESC bd2;
	bd2.Usage = D3D11_USAGE_DEFAULT;
	bd2.ByteWidth = sizeof(SimpleVertex) * 4;
	bd2.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd2.CPUAccessFlags = 0;
	bd2.MiscFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData2;
	InitData2.pSysMem = vertices2;
	if (FAILED(Device->CreateBuffer(&bd2, &InitData2, &VertexBuffer[1])))
		return FALSE;

	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0;
	if (FAILED(Device->CreateBuffer(&bd, NULL, &g_pConstantBuffer)))
		return FALSE;

	screen = new ScreenCapture();
	return S_OK;
}

VOID Render()
{
	float ClearColor[4] = { 0,0,0,0 };
	DeviceContext->ClearRenderTargetView(RenderTargetView, ClearColor);
	screen->OnRender();
	SwapChain->Present(1, 0);
}

VOID Cleanup()
{
	SAFE_DELETE(screen);
	SAFE_RELEASE(VertexShader);
	SAFE_RELEASE(PixelShader[0]);
	SAFE_RELEASE(PixelShader[1]);

	SAFE_RELEASE(VertexBuffer[0]);
	SAFE_RELEASE(VertexBuffer[1]);

	SAFE_RELEASE(g_pConstantBuffer);
	SAFE_RELEASE(VertexLayout);
	SAFE_RELEASE(SwapChain);
	SAFE_RELEASE(RenderTargetView);
	SAFE_RELEASE(DeviceContext);
	SAFE_RELEASE(Device);
}

LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szStr, INT iCmdShow)
{
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		L"Window1", NULL };
	RegisterClassEx(&wc);

	HWND hWnd = GetDesktopWindow();
	HDC hdc = GetDC(hWnd);
	WINDOW_WIDTH = GetDeviceCaps(hdc, HORZRES) / 2;
	WINDOW_HEIGHT = GetDeviceCaps(hdc, VERTRES) / 2;
	int res = ReleaseDC(hWnd, hdc);
	RECT rect;
	SetRect(&rect, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
	AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
	rect.right = rect.right - rect.left;
	rect.bottom = rect.bottom - rect.top;
	rect.top = 0;
	rect.left = 0;
	hWnd = CreateWindow(L"Window1", L"デスクトップキャプチャ",
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,
		NULL, NULL, wc.hInstance, NULL);

	MSG msg;
	ZeroMemory(&msg, sizeof(msg));
	if (SUCCEEDED(InitD3D(hWnd)))
	{
		ShowWindow(hWnd, SW_SHOW);
		UpdateWindow(hWnd);
		while (msg.message != WM_QUIT)
		{
			if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
			{
				Render();
			}
		}
	}
	return static_cast<int>(msg.wParam);
}

コード:

//グローバル
Texture2D g_texDecal: register(t0);//テクスチャー
SamplerState g_samLinear : register(s0);//サンプラー

cbuffer ConstantBuffer : register(b0)
{
	matrix World;
}
										//構造体
struct VS_OUTPUT
{
	float4 Pos : SV_POSITION;
	float2 Tex : TEXCOORD;
};

//頂点シェーダー
VS_OUTPUT VS(float4 Pos : POSITION, float2 Tex : TEXCOORD)
{
	VS_OUTPUT output = (VS_OUTPUT)0;
	output.Pos = mul(Pos, World);
	output.Tex = Tex;

	return output;
}

//ピクセルシェーダー
float4 PS(VS_OUTPUT input) : SV_Target
{
	return g_texDecal.Sample(g_samLinear, input.Tex);
}
//ピクセルシェーダー
float4 PSc(float4 Pos : SV_POSITION) : SV_Target
{
	return float4(1.0f, 0.0f, 0.0f, 1.0f);    // Yellow, with Alpha = 1
}

Re: ID3D11Texture2Dのバイナリ化

#3

by pell » 8年前

受信側現状報告

コード:

void Input(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC,
		BYTE *bmp_buffer, size_t buffer_size, UINT width, UINT height)
	{
		D3D11_TEXTURE2D_DESC desc;
		memset(&desc, 0, sizeof(desc));
		desc.Width = width;
		desc.Height = height;
		desc.MipLevels = 1;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DYNAMIC;
		desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

		ID3D11Texture2D* tex2D;
		HRESULT hr = pd3dDevice->CreateTexture2D(&desc, 0, &tex2D);

		D3D11_MAPPED_SUBRESOURCE hMappedResource;
		hr = pd3dDC->Map(
			tex2D,
			0,
			D3D11_MAP_WRITE_DISCARD,
			0,
			&hMappedResource);

		DWORD Color;
		//α
		Color &= 0x00ffffff;
		Color |= (0 & 0x000000ff) << 24;
		//B
		Color &= 0xffffff00;
		Color |= 0xFF & 0x000000ff;
		//G
		Color &= 0xffff00ff;
		Color |= (0xFF & 0x000000ff) << 8;
		//R
		Color &= 0xff00ffff;
		Color |= (0xFF & 0x000000ff) << 16;

		BYTE* pBits = reinterpret_cast<BYTE*>(hMappedResource.pData);
		memset(pBits, 0, buffer_size);
		BYTE* copy = NULL;

		const UINT iOfs_x = 0;
		const UINT iOfs_y = 0;
		const UINT iBmp_w = iOfs_x + width;
		const UINT iBmp_h = iOfs_y + height;
		const UINT Level = 6;

		for (int count = 0, y = iOfs_y; y < iBmp_h; y++)
		{
			for (int x = iOfs_x; x < iBmp_w; x++)
			{
				const DWORD Alpha = (bmp_buffer[count] * 255) >> Level;
				const DWORD Color_ = Color | (Alpha << 24);//α
				copy = pBits + hMappedResource.RowPitch * y + 4 * x;
				memcpy(copy, &Color_, sizeof(DWORD));
				count++;
			}
		}
		pd3dDC->Unmap(tex2D, 0);
		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		D3D11_TEXTURE2D_DESC desc_;
		tex2D->GetDesc(&desc_);
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc_.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc_.MipLevels;
		ID3D11ShaderResourceView* resourceView2;
		hr = Device->CreateShaderResourceView(tex2D, &srvDesc, &resourceView2);

		Draw(tex2D, resourceView2);
		resourceView2->Release();

		tex2D->Release();
	}
テクスチャは真っ白です。つまり何も書き込めてない状態ですね。

Re: ID3D11Texture2Dのバイナリ化

#2

by pell » 8年前

今の状態は

送信側

コード:

		void Output(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dDC, ID3D11Texture2D* pBackBuffer)
		{
		D3D11_TEXTURE2D_DESC descBackBuffer;
		pBackBuffer->GetDesc(&descBackBuffer);

		D3D11_TEXTURE2D_DESC Texture2DDesc;
		Texture2DDesc.ArraySize = 1;
		Texture2DDesc.BindFlags = 0;
		Texture2DDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		Texture2DDesc.Format = descBackBuffer.Format;
		Texture2DDesc.Height = descBackBuffer.Height;
		Texture2DDesc.Width = descBackBuffer.Width;
		Texture2DDesc.MipLevels = 1;
		Texture2DDesc.MiscFlags = 0;
		Texture2DDesc.SampleDesc.Count = 1;
		Texture2DDesc.SampleDesc.Quality = 0;
		Texture2DDesc.Usage = D3D11_USAGE_STAGING;

		D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
		D3D11_TEXTURE2D_DESC desc;
		pBackBuffer->GetDesc(&desc);
		ZeroMemory(&srvDesc, sizeof(srvDesc));
		srvDesc.Format = desc.Format;
		srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MostDetailedMip = 0;
		srvDesc.Texture2D.MipLevels = desc.MipLevels;
		ID3D11ShaderResourceView* resourceView;
		HRESULT hr = Device->CreateShaderResourceView(pBackBuffer, &srvDesc, &resourceView);

		ID3D11Texture2D *hCaptureTexture;
		pd3dDevice->CreateTexture2D(&Texture2DDesc, 0, &hCaptureTexture);

		ID3D11Resource *hResource;
		resourceView->GetResource(&hResource);
		pd3dDC->CopyResource(hCaptureTexture, hResource);
		hResource->Release();

		D3D11_MAPPED_SUBRESOURCE mappedResource;
		pd3dDC->Map(hCaptureTexture, 0, D3D11_MAP_READ, 0, &mappedResource);

		double width = descBackBuffer.Width;
		double height = descBackBuffer.Height;
		double src_stride = mappedResource.RowPitch;
		size_t buffer_size = src_stride * height;
		BYTE *bmp_buffer = new BYTE[buffer_size];
		CopyMemory(bmp_buffer, mappedResource.pData, buffer_size);
		pd3dDC->Unmap(hCaptureTexture, 0);

//ここで送信//

		pBackBuffer->Release();
		hCaptureTexture->Release();

		delete[] bmp_buffer;

	}
 
受信側

コード:

ID3D11Texture2D* Input(BYTE* b)
{
		D3D11_TEXTURE2D_DESC desc;
		memset(&desc, 0, sizeof(desc));
		desc.Width = 幅;
		desc.Height = 高さ;
		desc.MipLevels = 1;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DYNAMIC;
		desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;	

		ID3D11Texture2D* tex2D;					
		DXUTGetD3D11Device()->CreateTexture2D(&desc, 0, &tex2D);

		D3D11_MAPPED_SUBRESOURCE hMappedResource;
		hr = DXUTGetD3D11DeviceContext()->Map(
			tex2D,
			0,
			D3D11_MAP_WRITE_DISCARD,
			0,
			&hMappedResource);

		BYTE* pBits = reinterpret_cast<BYTE*>(hMappedResource.pData);
                memset(pBits, 0, hMappedResource.RowPitch * 高さ);
               
                 pBits = b;//この辺がよく分からないです
                return tex2D;
}
 

ID3D11Texture2Dのバイナリ化

#1

by pell » 8年前

ID3D11Texture2D*をchar*にキャストしたい訳では無く中のデータをバイナリ化して
ネットワーク通信でテクスチャのやり取りがしたいです。
ネットワーク通信の部分は完成しています。
他のライブラリとd3dxの使用は避けたいです。
最終的に両クライアント側でID3D11Texture2D*に戻せる形であれば大丈夫です。
これが不可能であれば可能な方法を教えてください。

ページトップ