使用Direct3D进行多个IDirect3DDevice9 进行资源共享:
1)创建Direct3D
2)源设备初始化
3)源设备进行处理
4)目标设备进行初始化
5)目标设备进行处理
1 ) 创建Direct3D
Direct3DCreate9Ex()
2)源设备初始化
CreateDevice():创建设备,所有的操作都需要基于设备完成。
CreateTexture():最后一个参数HANDLE hSharedHandle初始值为NULL,调用CreateTexture后会生成一个句柄hSharedHandle。
3)源设备进行处理
Clear():
清除一个或多个表面,如渲染目标、多个渲染目标、一个模板缓冲区和一个深度缓冲。
Present():将缓存区的数据刷到屏幕上。
GetBackBuffer():获取当前帧的后备缓存区。
GetSurfaceLevel():获取纹理后台缓存区的第N层表面,0则表示最上层。
StretchRect():将一个缓存区的数据拷贝到另一个缓存区。
4)目标设备进行初始化
CreateDevice()
CreateTexture() : 目标设备调用CreateTexture时,传入的hSharedHandle参数与源设备进行绑定。绑定时源设备和目标设备改函数的设置必须一致(包括大小、纹理数量、纹理格式、纹理类型等)否则无法共享。
5)目标设备进行处理
D3DXSaveTextureToFile():将表面矩形区保存到文件中。
源码:
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
|
bool
MyD3D::CreateEx()
{
HRESULT
hr = Direct3DCreate9Ex(D3D_SDK_VERSION,&d3dex);
//创建D3D此次不能用Direct3DCreate否则设置Texture的ShareHandle参数会失败。
if
(hr != D3D_OK)
{
return
false
;
}
return
true
;
}
HANDLE
MyD3D::GetSharedHandle()
{
return
m_hSharedSurfaceHandle;
}
bool
MyD3D::InitDev(
HWND
window,
HANDLE
hSharedHandle)
{
srand
(
time
(NULL));
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,
sizeof
(d3dpp));
d3dpp.Windowed =
true
;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = TEXTUREW;
d3dpp.BackBufferHeight = TEXTUREH;
d3dpp.hDeviceWindow = window;
HRESULT
hr = d3dex->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pD3ddev);
//D3DCREATE_HARDWARE_VERTEXPROCESSING 和D3DCREATE_SOFTWARE_VERTEXPROCESSING 后者会更多的占用内存。
if
(hr != D3D_OK)
return
false
;
if
(hSharedHandle == NULL)
{
//源创建纹理
HRESULT
result = m_pD3ddev->CreateTexture(TEXTUREW, TEXTUREH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_pTexture, &m_hSharedSurfaceHandle);
if
(result != D3D_OK)
return
false
;
}
else
{
//目标创建纹理,格式大小必须与源相同才能共享。
HRESULT
result = m_pD3ddev->CreateTexture(TEXTUREW, TEXTUREH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_pTexture, &hSharedHandle);
if
(result != D3D_OK)
return
false
;
}
return
true
;
}
void
MyD3D::D3dSource(
HWND
hwnd)
{
if
(!m_pD3ddev)
return
;
int
r =
rand
() % 255;
int
g =
rand
() % 255;
int
b =
rand
() % 255;
m_pD3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(r, g, b), 1.0f, 0);
//给表面缓冲区刷上颜色
m_pD3ddev->Present(NULL, NULL, NULL, NULL);
//将缓冲区刷到屏幕上
IDirect3DSurface9* pBackBuffer;
HRESULT
hr = m_pD3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
//取得第一个表面缓冲区
if
(FAILED(hr))
return
;
IDirect3DSurface9* pSharedSurface = NULL;
m_pTexture->GetSurfaceLevel(0, &pSharedSurface);
//取得纹理的最上层缓冲区(创建纹理时只建了一个缓冲区)
hr = m_pD3ddev->StretchRect(pBackBuffer, NULL, pSharedSurface, NULL, D3DTEXF_NONE);
//表面缓冲区拷贝到纹理缓冲区
if
(FAILED(hr))
return
;
//free resource
pBackBuffer->Release();
pSharedSurface->Release();
pBackBuffer = NULL;
pSharedSurface = NULL;
}
void
MyD3D::D3dOutcome(
wchar_t
* filename)
{
WCHAR
out_file[1024] = { 0 };
CreateDirectory(filename, NULL);
swprintf(out_file, 100, L
".//%s//Out_%d.bmp"
, filename, cont);
D3DXSaveTextureToFile(out_file, D3DXIFF_BMP, m_pTexture, NULL);
//将纹理存到文件
cont++;
}
|