Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
450a276f
Commit
450a276f
authored
May 12, 2015
by
Vladimir Dudnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
directx opencl interop samples (with copy from opencl image2d to buffer)
parent
4af2eb22
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1714 additions
and
0 deletions
+1714
-0
d3d10_opencl.cpp
samples/directx/d3d10_opencl.cpp
+397
-0
d3d11_opencl.cpp
samples/directx/d3d11_opencl.cpp
+403
-0
d3d9_opencl.cpp
samples/directx/d3d9_opencl.cpp
+396
-0
d3d9ex_opencl.cpp
samples/directx/d3d9ex_opencl.cpp
+396
-0
winapp.hpp
samples/directx/winapp.hpp
+122
-0
No files found.
samples/directx/d3d10_opencl.cpp
0 → 100644
View file @
450a276f
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d10.h>
#include <string>
#include <iostream>
#include <queue>
#include "opencv2/core.hpp"
#include "opencv2/core/directx.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "winapp.hpp"
#pragma comment (lib, "d3d10.lib")
class
D3D10WinApp
:
public
WinApp
{
public
:
D3D10WinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
,
cv
::
VideoCapture
&
cap
)
:
WinApp
(
width
,
height
,
window_name
)
{
m_shutdown
=
false
;
m_mode
=
0
;
m_modeStr
[
0
]
=
cv
::
String
(
"No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Processing on GPU"
);
m_disableProcessing
=
false
;
m_cap
=
cap
;
}
~
D3D10WinApp
()
{}
int
onClose
(
void
)
{
m_shutdown
=
true
;
cleanup
();
::
DestroyWindow
(
m_hWnd
);
return
0
;
}
virtual
LRESULT
CALLBACK
WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
message
)
{
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
{
m_mode
=
(
char
)
wParam
-
'0'
;
return
0
;
}
else
if
(
wParam
==
VK_SPACE
)
{
m_disableProcessing
=
!
m_disableProcessing
;
return
0
;
}
else
if
(
wParam
==
VK_ESCAPE
)
{
return
onClose
();
}
break
;
case
WM_CLOSE
:
return
onClose
();
case
WM_DESTROY
:
::
PostQuitMessage
(
0
);
return
0
;
}
return
::
DefWindowProc
(
hWnd
,
message
,
wParam
,
lParam
);
}
static
float
getFps
()
{
static
std
::
queue
<
int64
>
time_queue
;
int64
now
=
cv
::
getTickCount
();
int64
then
=
0
;
time_queue
.
push
(
now
);
if
(
time_queue
.
size
()
>=
2
)
then
=
time_queue
.
front
();
if
(
time_queue
.
size
()
>=
25
)
time_queue
.
pop
();
return
time_queue
.
size
()
*
(
float
)
cv
::
getTickFrequency
()
/
(
now
-
then
);
}
int
init
(
void
)
{
HRESULT
r
;
DXGI_SWAP_CHAIN_DESC
scd
;
ZeroMemory
(
&
scd
,
sizeof
(
DXGI_SWAP_CHAIN_DESC
));
scd
.
BufferCount
=
1
;
// one back buffer
scd
.
BufferDesc
.
Format
=
DXGI_FORMAT_R8G8B8A8_UNORM
;
// use 32-bit color
scd
.
BufferDesc
.
Width
=
m_width
;
// set the back buffer width
scd
.
BufferDesc
.
Height
=
m_height
;
// set the back buffer height
scd
.
BufferUsage
=
DXGI_USAGE_RENDER_TARGET_OUTPUT
;
// how swap chain is to be used
scd
.
OutputWindow
=
m_hWnd
;
// the window to be used
scd
.
SampleDesc
.
Count
=
1
;
// how many multisamples
scd
.
Windowed
=
TRUE
;
// windowed/full-screen mode
scd
.
SwapEffect
=
DXGI_SWAP_EFFECT_DISCARD
;
scd
.
Flags
=
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
// allow full-screen switching
r
=
::
D3D10CreateDeviceAndSwapChain
(
NULL
,
D3D10_DRIVER_TYPE_HARDWARE
,
NULL
,
0
,
D3D10_SDK_VERSION
,
&
scd
,
&
m_pD3D10SwapChain
,
&
m_pD3D10Dev
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D10SwapChain
->
GetBuffer
(
0
,
__uuidof
(
ID3D10Texture2D
),
(
LPVOID
*
)
&
m_pBackBuffer
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D10Dev
->
CreateRenderTargetView
(
m_pBackBuffer
,
NULL
,
&
m_pRenderTarget
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
m_pD3D10Dev
->
OMSetRenderTargets
(
1
,
&
m_pRenderTarget
,
NULL
);
D3D10_VIEWPORT
viewport
;
ZeroMemory
(
&
viewport
,
sizeof
(
D3D10_VIEWPORT
));
viewport
.
Width
=
m_width
;
viewport
.
Height
=
m_height
;
viewport
.
MinDepth
=
0.0
f
;
viewport
.
MaxDepth
=
0.0
f
;
m_pD3D10Dev
->
RSSetViewports
(
1
,
&
viewport
);
D3D10_TEXTURE2D_DESC
desc
=
{
0
};
desc
.
Width
=
m_width
;
desc
.
Height
=
m_height
;
desc
.
MipLevels
=
1
;
desc
.
ArraySize
=
1
;
desc
.
Format
=
DXGI_FORMAT_R8G8B8A8_UNORM
;
desc
.
SampleDesc
.
Count
=
1
;
desc
.
BindFlags
=
D3D10_BIND_SHADER_RESOURCE
;
desc
.
Usage
=
D3D10_USAGE_DYNAMIC
;
desc
.
CPUAccessFlags
=
D3D10_CPU_ACCESS_WRITE
;
r
=
m_pD3D10Dev
->
CreateTexture2D
(
&
desc
,
NULL
,
&
m_pSurface
);
if
(
FAILED
(
r
))
{
std
::
cerr
<<
"Can't create texture with input image"
<<
std
::
endl
;
return
-
1
;
}
if
(
cv
::
ocl
::
haveOpenCL
())
{
m_oclCtx
=
cv
::
directx
::
ocl
::
initializeContextFromD3D10Device
(
m_pD3D10Dev
);
}
m_oclDevName
=
cv
::
ocl
::
useOpenCL
()
?
cv
::
ocl
::
Context
::
getDefault
().
device
(
0
).
name
()
:
"No OpenCL device"
;
return
0
;
}
// init()
int
get_surface
(
ID3D10Texture2D
**
ppSurface
)
{
HRESULT
r
;
if
(
!
m_cap
.
read
(
m_frame_bgr
))
return
-
1
;
cv
::
cvtColor
(
m_frame_bgr
,
m_frame_rgba
,
CV_RGB2BGRA
);
UINT
subResource
=
::
D3D10CalcSubresource
(
0
,
0
,
1
);
D3D10_MAPPED_TEXTURE2D
mappedTex
;
r
=
m_pSurface
->
Map
(
subResource
,
D3D10_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
// copy video frame data to surface
m_frame_rgba
.
copyTo
(
m
);
m_pSurface
->
Unmap
(
subResource
);
*
ppSurface
=
m_pSurface
;
return
0
;
}
void
print_info
(
ID3D10Texture2D
*
pSurface
,
int
mode
,
float
fps
,
cv
::
String
oclDevName
)
{
HRESULT
r
;
UINT
subResource
=
::
D3D10CalcSubresource
(
0
,
0
,
1
);
D3D10_MAPPED_TEXTURE2D
mappedTex
;
r
=
pSurface
->
Map
(
subResource
,
D3D10_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
cv
::
String
strMode
=
cv
::
format
(
"%s"
,
m_modeStr
[
mode
].
c_str
());
cv
::
String
strFPS
=
cv
::
format
(
"%2.1f"
,
fps
);
cv
::
String
strDevName
=
cv
::
format
(
"%s"
,
oclDevName
.
c_str
());
cv
::
putText
(
m
,
strMode
,
cv
::
Point
(
0
,
16
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
cv
::
putText
(
m
,
strFPS
,
cv
::
Point
(
0
,
32
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
cv
::
putText
(
m
,
strDevName
,
cv
::
Point
(
0
,
48
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
m_pSurface
->
Unmap
(
subResource
);
return
;
}
int
render
()
{
try
{
if
(
m_shutdown
)
return
0
;
HRESULT
r
;
ID3D10Texture2D
*
pSurface
;
r
=
get_surface
(
&
pSurface
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
switch
(
m_mode
)
{
case
0
:
// no processing
break
;
case
1
:
{
// process video frame on CPU
UINT
subResource
=
::
D3D10CalcSubresource
(
0
,
0
,
1
);
D3D10_MAPPED_TEXTURE2D
mappedTex
;
r
=
m_pSurface
->
Map
(
subResource
,
D3D10_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
if
(
!
m_disableProcessing
)
{
// blur D3D10 surface with OpenCV on CPU
cv
::
blur
(
m
,
m
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
m_pSurface
->
Unmap
(
subResource
);
break
;
}
case
2
:
{
// process video frame on GPU
cv
::
UMat
u
;
cv
::
directx
::
convertFromD3D10Texture2D
(
pSurface
,
u
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on GPU with OpenCL
cv
::
blur
(
u
,
u
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
cv
::
directx
::
convertToD3D10Texture2D
(
u
,
pSurface
);
break
;
}
}
// switch
print_info
(
pSurface
,
m_mode
,
getFps
(),
m_oclDevName
);
// traditional DX render pipeline:
// BitBlt surface to backBuffer and flip backBuffer to frontBuffer
m_pD3D10Dev
->
CopyResource
(
m_pBackBuffer
,
pSurface
);
// present the back buffer contents to the display
// switch the back buffer and the front buffer
r
=
m_pD3D10SwapChain
->
Present
(
0
,
0
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
return
0
;
}
int
cleanup
(
void
)
{
SAFE_RELEASE
(
m_pSurface
);
SAFE_RELEASE
(
m_pBackBuffer
);
SAFE_RELEASE
(
m_pD3D10SwapChain
);
SAFE_RELEASE
(
m_pRenderTarget
);
SAFE_RELEASE
(
m_pD3D10Dev
);
return
0
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
];
int
m_disableProcessing
;
ID3D10Device
*
m_pD3D10Dev
;
IDXGISwapChain
*
m_pD3D10SwapChain
;
ID3D10Texture2D
*
m_pBackBuffer
;
ID3D10Texture2D
*
m_pSurface
;
ID3D10RenderTargetView
*
m_pRenderTarget
;
cv
::
VideoCapture
m_cap
;
cv
::
Mat
m_frame_bgr
;
cv
::
Mat
m_frame_rgba
;
cv
::
ocl
::
Context
m_oclCtx
;
cv
::
String
m_oclPlatformName
;
cv
::
String
m_oclDevName
;
};
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
VideoCapture
cap
;
if
(
argc
>
1
)
{
cap
.
open
(
argv
[
1
]);
}
else
cap
.
open
(
0
);
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
int
height
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
);
std
::
string
wndname
=
"D3D10 Window"
;
D3D10WinApp
app
(
width
,
height
,
wndname
,
cap
);
try
{
app
.
Create
();
return
app
.
run
();
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
catch
(...)
{
std
::
cerr
<<
"FATAL ERROR: Unknown exception"
<<
std
::
endl
;
return
11
;
}
}
samples/directx/d3d11_opencl.cpp
0 → 100644
View file @
450a276f
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d11.h>
#include <string>
#include <iostream>
#include <queue>
#include "opencv2/core.hpp"
#include "opencv2/core/directx.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "winapp.hpp"
#pragma comment (lib, "d3d11.lib")
class
D3D11WinApp
:
public
WinApp
{
public
:
D3D11WinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
,
cv
::
VideoCapture
&
cap
)
:
WinApp
(
width
,
height
,
window_name
)
{
m_shutdown
=
false
;
m_mode
=
0
;
m_modeStr
[
0
]
=
cv
::
String
(
"No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Processing on GPU"
);
m_disableProcessing
=
false
;
m_cap
=
cap
;
}
~
D3D11WinApp
()
{}
int
onClose
(
void
)
{
m_shutdown
=
true
;
cleanup
();
::
DestroyWindow
(
m_hWnd
);
return
0
;
}
virtual
LRESULT
CALLBACK
WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
message
)
{
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
{
m_mode
=
(
char
)
wParam
-
'0'
;
return
0
;
}
else
if
(
wParam
==
VK_SPACE
)
{
m_disableProcessing
=
!
m_disableProcessing
;
return
0
;
}
else
if
(
wParam
==
VK_ESCAPE
)
{
return
onClose
();
}
break
;
case
WM_CLOSE
:
return
onClose
();
case
WM_DESTROY
:
::
PostQuitMessage
(
0
);
return
0
;
}
return
::
DefWindowProc
(
hWnd
,
message
,
wParam
,
lParam
);
}
static
float
getFps
()
{
static
std
::
queue
<
int64
>
time_queue
;
int64
now
=
cv
::
getTickCount
();
int64
then
=
0
;
time_queue
.
push
(
now
);
if
(
time_queue
.
size
()
>=
2
)
then
=
time_queue
.
front
();
if
(
time_queue
.
size
()
>=
25
)
time_queue
.
pop
();
return
time_queue
.
size
()
*
(
float
)
cv
::
getTickFrequency
()
/
(
now
-
then
);
}
int
init
(
void
)
{
HRESULT
r
;
DXGI_SWAP_CHAIN_DESC
scd
;
ZeroMemory
(
&
scd
,
sizeof
(
DXGI_SWAP_CHAIN_DESC
));
scd
.
BufferCount
=
1
;
// one back buffer
scd
.
BufferDesc
.
Format
=
DXGI_FORMAT_R8G8B8A8_UNORM
;
// use 32-bit color
scd
.
BufferDesc
.
Width
=
m_width
;
// set the back buffer width
scd
.
BufferDesc
.
Height
=
m_height
;
// set the back buffer height
scd
.
BufferUsage
=
DXGI_USAGE_RENDER_TARGET_OUTPUT
;
// how swap chain is to be used
scd
.
OutputWindow
=
m_hWnd
;
// the window to be used
scd
.
SampleDesc
.
Count
=
1
;
// how many multisamples
scd
.
Windowed
=
TRUE
;
// windowed/full-screen mode
scd
.
SwapEffect
=
DXGI_SWAP_EFFECT_DISCARD
;
scd
.
Flags
=
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
;
// allow full-screen switching
r
=
::
D3D11CreateDeviceAndSwapChain
(
NULL
,
D3D_DRIVER_TYPE_HARDWARE
,
NULL
,
0
,
NULL
,
0
,
D3D11_SDK_VERSION
,
&
scd
,
&
m_pD3D11SwapChain
,
&
m_pD3D11Dev
,
NULL
,
&
m_pD3D11Ctx
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D11SwapChain
->
GetBuffer
(
0
,
__uuidof
(
ID3D11Texture2D
),
(
LPVOID
*
)
&
m_pBackBuffer
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D11Dev
->
CreateRenderTargetView
(
m_pBackBuffer
,
NULL
,
&
m_pRenderTarget
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
m_pD3D11Ctx
->
OMSetRenderTargets
(
1
,
&
m_pRenderTarget
,
NULL
);
D3D11_VIEWPORT
viewport
;
ZeroMemory
(
&
viewport
,
sizeof
(
D3D11_VIEWPORT
));
viewport
.
Width
=
(
float
)
m_width
;
viewport
.
Height
=
(
float
)
m_height
;
viewport
.
MinDepth
=
0.0
f
;
viewport
.
MaxDepth
=
0.0
f
;
m_pD3D11Ctx
->
RSSetViewports
(
1
,
&
viewport
);
D3D11_TEXTURE2D_DESC
desc
=
{
0
};
desc
.
Width
=
m_width
;
desc
.
Height
=
m_height
;
desc
.
MipLevels
=
1
;
desc
.
ArraySize
=
1
;
desc
.
Format
=
DXGI_FORMAT_R8G8B8A8_UNORM
;
desc
.
SampleDesc
.
Count
=
1
;
desc
.
BindFlags
=
D3D11_BIND_SHADER_RESOURCE
;
desc
.
Usage
=
D3D11_USAGE_DYNAMIC
;
desc
.
CPUAccessFlags
=
D3D11_CPU_ACCESS_WRITE
;
r
=
m_pD3D11Dev
->
CreateTexture2D
(
&
desc
,
NULL
,
&
m_pSurface
);
if
(
FAILED
(
r
))
{
std
::
cerr
<<
"Can't create texture with input image"
<<
std
::
endl
;
return
-
1
;
}
if
(
cv
::
ocl
::
haveOpenCL
())
{
m_oclCtx
=
cv
::
directx
::
ocl
::
initializeContextFromD3D11Device
(
m_pD3D11Dev
);
}
m_oclDevName
=
cv
::
ocl
::
useOpenCL
()
?
cv
::
ocl
::
Context
::
getDefault
().
device
(
0
).
name
()
:
"No OpenCL device"
;
return
0
;
}
// init()
int
get_surface
(
ID3D11Texture2D
**
ppSurface
)
{
HRESULT
r
;
if
(
!
m_cap
.
read
(
m_frame_bgr
))
return
-
1
;
cv
::
cvtColor
(
m_frame_bgr
,
m_frame_rgba
,
CV_RGB2BGRA
);
UINT
subResource
=
::
D3D11CalcSubresource
(
0
,
0
,
1
);
D3D11_MAPPED_SUBRESOURCE
mappedTex
;
r
=
m_pD3D11Ctx
->
Map
(
m_pSurface
,
subResource
,
D3D11_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
// copy video frame data to surface
m_frame_rgba
.
copyTo
(
m
);
m_pD3D11Ctx
->
Unmap
(
m_pSurface
,
subResource
);
*
ppSurface
=
m_pSurface
;
return
0
;
}
void
print_info
(
ID3D11Texture2D
*
pSurface
,
int
mode
,
float
fps
,
cv
::
String
oclDevName
)
{
HRESULT
r
;
UINT
subResource
=
::
D3D11CalcSubresource
(
0
,
0
,
1
);
D3D11_MAPPED_SUBRESOURCE
mappedTex
;
r
=
m_pD3D11Ctx
->
Map
(
pSurface
,
subResource
,
D3D11_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
cv
::
String
strMode
=
cv
::
format
(
"%s"
,
m_modeStr
[
mode
].
c_str
());
cv
::
String
strFPS
=
cv
::
format
(
"%2.1f"
,
fps
);
cv
::
String
strDevName
=
cv
::
format
(
"%s"
,
oclDevName
.
c_str
());
cv
::
putText
(
m
,
strMode
,
cv
::
Point
(
0
,
16
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
cv
::
putText
(
m
,
strFPS
,
cv
::
Point
(
0
,
32
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
cv
::
putText
(
m
,
strDevName
,
cv
::
Point
(
0
,
48
),
1
,
0.8
,
cv
::
Scalar
(
0
,
0
,
0
));
m_pD3D11Ctx
->
Unmap
(
pSurface
,
subResource
);
return
;
}
int
render
()
{
try
{
if
(
m_shutdown
)
return
0
;
HRESULT
r
;
ID3D11Texture2D
*
pSurface
;
r
=
get_surface
(
&
pSurface
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
switch
(
m_mode
)
{
case
0
:
// no processing
break
;
case
1
:
{
// process video frame on CPU
UINT
subResource
=
::
D3D11CalcSubresource
(
0
,
0
,
1
);
D3D11_MAPPED_SUBRESOURCE
mappedTex
;
r
=
m_pD3D11Ctx
->
Map
(
m_pSurface
,
subResource
,
D3D11_MAP_WRITE_DISCARD
,
0
,
&
mappedTex
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
mappedTex
.
pData
,
(
int
)
mappedTex
.
RowPitch
);
if
(
!
m_disableProcessing
)
{
// blur D3D10 surface with OpenCV on CPU
cv
::
blur
(
m
,
m
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
m_pD3D11Ctx
->
Unmap
(
m_pSurface
,
subResource
);
break
;
}
case
2
:
{
// process video frame on GPU
cv
::
UMat
u
;
cv
::
directx
::
convertFromD3D11Texture2D
(
pSurface
,
u
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on GPU with OpenCL
cv
::
blur
(
u
,
u
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
cv
::
directx
::
convertToD3D11Texture2D
(
u
,
pSurface
);
break
;
}
}
// switch
print_info
(
pSurface
,
m_mode
,
getFps
(),
m_oclDevName
);
// traditional DX render pipeline:
// BitBlt surface to backBuffer and flip backBuffer to frontBuffer
m_pD3D11Ctx
->
CopyResource
(
m_pBackBuffer
,
pSurface
);
// present the back buffer contents to the display
// switch the back buffer and the front buffer
r
=
m_pD3D11SwapChain
->
Present
(
0
,
0
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
return
0
;
}
int
cleanup
(
void
)
{
SAFE_RELEASE
(
m_pSurface
);
SAFE_RELEASE
(
m_pBackBuffer
);
SAFE_RELEASE
(
m_pD3D11SwapChain
);
SAFE_RELEASE
(
m_pRenderTarget
);
SAFE_RELEASE
(
m_pD3D11Dev
);
SAFE_RELEASE
(
m_pD3D11Ctx
);
return
0
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
];
int
m_disableProcessing
;
ID3D11Device
*
m_pD3D11Dev
;
IDXGISwapChain
*
m_pD3D11SwapChain
;
ID3D11DeviceContext
*
m_pD3D11Ctx
;
ID3D11Texture2D
*
m_pBackBuffer
;
ID3D11Texture2D
*
m_pSurface
;
ID3D11RenderTargetView
*
m_pRenderTarget
;
cv
::
VideoCapture
m_cap
;
cv
::
Mat
m_frame_bgr
;
cv
::
Mat
m_frame_rgba
;
cv
::
ocl
::
Context
m_oclCtx
;
cv
::
String
m_oclPlatformName
;
cv
::
String
m_oclDevName
;
};
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
VideoCapture
cap
;
if
(
argc
>
1
)
{
cap
.
open
(
argv
[
1
]);
}
else
cap
.
open
(
0
);
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
int
height
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
);
std
::
string
wndname
=
"D3D11 Window"
;
D3D11WinApp
app
(
width
,
height
,
wndname
,
cap
);
try
{
app
.
Create
();
return
app
.
run
();
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
catch
(...)
{
std
::
cerr
<<
"FATAL ERROR: Unknown exception"
<<
std
::
endl
;
return
11
;
}
}
samples/directx/d3d9_opencl.cpp
0 → 100644
View file @
450a276f
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#include <string>
#include <iostream>
#include <queue>
#include "opencv2/core.hpp"
#include "opencv2/core/directx.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "winapp.hpp"
#pragma comment (lib, "d3d9.lib")
class
D3D9WinApp
:
public
WinApp
{
public
:
D3D9WinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
,
cv
::
VideoCapture
&
cap
)
:
WinApp
(
width
,
height
,
window_name
)
{
m_shutdown
=
false
;
m_mode
=
0
;
m_modeStr
[
0
]
=
cv
::
String
(
"No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Processing on GPU"
);
m_disableProcessing
=
false
;
m_cap
=
cap
;
}
~
D3D9WinApp
()
{}
int
onClose
(
void
)
{
m_shutdown
=
true
;
cleanup
();
::
DestroyWindow
(
m_hWnd
);
return
0
;
}
virtual
LRESULT
CALLBACK
WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
message
)
{
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
{
m_mode
=
(
char
)
wParam
-
'0'
;
return
0
;
}
else
if
(
wParam
==
VK_SPACE
)
{
m_disableProcessing
=
!
m_disableProcessing
;
return
0
;
}
else
if
(
wParam
==
VK_ESCAPE
)
{
return
onClose
();
}
break
;
case
WM_CLOSE
:
return
onClose
();
case
WM_DESTROY
:
::
PostQuitMessage
(
0
);
return
0
;
}
return
::
DefWindowProc
(
hWnd
,
message
,
wParam
,
lParam
);
}
static
float
getFps
()
{
static
std
::
queue
<
int64
>
time_queue
;
int64
now
=
cv
::
getTickCount
();
int64
then
=
0
;
time_queue
.
push
(
now
);
if
(
time_queue
.
size
()
>=
2
)
then
=
time_queue
.
front
();
if
(
time_queue
.
size
()
>=
25
)
time_queue
.
pop
();
return
time_queue
.
size
()
*
(
float
)
cv
::
getTickFrequency
()
/
(
now
-
then
);
}
int
init
(
void
)
{
HRESULT
r
;
m_pD3D9
=
::
Direct3DCreate9
(
D3D_SDK_VERSION
);
if
(
NULL
==
m_pD3D9
)
{
return
-
1
;
}
DWORD
flags
=
D3DCREATE_HARDWARE_VERTEXPROCESSING
|
D3DCREATE_PUREDEVICE
|
D3DCREATE_NOWINDOWCHANGES
|
D3DCREATE_MULTITHREADED
|
D3DCREATE_FPU_PRESERVE
;
D3DPRESENT_PARAMETERS
d3dpp
;
::
ZeroMemory
(
&
d3dpp
,
sizeof
(
D3DPRESENT_PARAMETERS
));
d3dpp
.
Windowed
=
true
;
d3dpp
.
Flags
=
0
;
d3dpp
.
BackBufferCount
=
0
;
d3dpp
.
BackBufferFormat
=
D3DFMT_A8R8G8B8
;
d3dpp
.
BackBufferHeight
=
m_height
;
d3dpp
.
BackBufferWidth
=
m_width
;
d3dpp
.
MultiSampleType
=
D3DMULTISAMPLE_NONE
;
d3dpp
.
SwapEffect
=
D3DSWAPEFFECT_DISCARD
;
d3dpp
.
hDeviceWindow
=
m_hWnd
;
d3dpp
.
PresentationInterval
=
D3DPRESENT_INTERVAL_IMMEDIATE
;
d3dpp
.
FullScreen_RefreshRateInHz
=
D3DPRESENT_RATE_DEFAULT
;
r
=
m_pD3D9
->
CreateDevice
(
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
m_hWnd
,
flags
,
&
d3dpp
,
&
m_pD3D9Dev
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D9Dev
->
GetBackBuffer
(
0
,
0
,
D3DBACKBUFFER_TYPE_MONO
,
&
m_pBackBuffer
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D9Dev
->
CreateOffscreenPlainSurface
(
m_width
,
m_height
,
D3DFMT_A8R8G8B8
,
D3DPOOL_DEFAULT
,
&
m_pSurface
,
NULL
);
if
(
FAILED
(
r
))
{
std
::
cerr
<<
"Can't create surface for result"
<<
std
::
endl
;
return
-
1
;
}
if
(
cv
::
ocl
::
haveOpenCL
())
{
m_oclCtx
=
cv
::
directx
::
ocl
::
initializeContextFromDirect3DDevice9
(
m_pD3D9Dev
);
}
m_oclDevName
=
cv
::
ocl
::
useOpenCL
()
?
cv
::
ocl
::
Context
::
getDefault
().
device
(
0
).
name
()
:
"No OpenCL device"
;
return
0
;
}
// init()
int
get_surface
(
LPDIRECT3DSURFACE9
*
ppSurface
)
{
HRESULT
r
;
if
(
!
m_cap
.
read
(
m_frame_bgr
))
return
-
1
;
cv
::
cvtColor
(
m_frame_bgr
,
m_frame_rgba
,
CV_RGB2RGBA
);
D3DLOCKED_RECT
memDesc
=
{
0
,
NULL
};
RECT
rc
=
{
0
,
0
,
m_width
,
m_height
};
r
=
m_pSurface
->
LockRect
(
&
memDesc
,
&
rc
,
0
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
memDesc
.
pBits
,
memDesc
.
Pitch
);
// copy video frame data to surface
m_frame_rgba
.
copyTo
(
m
);
r
=
m_pSurface
->
UnlockRect
();
if
(
FAILED
(
r
))
{
return
r
;
}
*
ppSurface
=
m_pSurface
;
return
0
;
}
void
print_info
(
LPDIRECT3DSURFACE9
pSurface
,
int
mode
,
float
fps
,
cv
::
String
oclDevName
)
{
HDC
hDC
;
HRESULT
r
=
pSurface
->
GetDC
(
&
hDC
);
if
(
FAILED
(
r
))
{
return
;
}
HFONT
hFont
=
(
HFONT
)
::
GetStockObject
(
SYSTEM_FONT
);
HFONT
hOldFont
=
(
HFONT
)
::
SelectObject
(
hDC
,
hFont
);
if
(
hOldFont
)
{
TEXTMETRIC
tm
;
::
GetTextMetrics
(
hDC
,
&
tm
);
char
buf
[
256
];
int
y
=
0
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"Mode: %s"
,
m_modeStr
[
mode
].
c_str
());
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"FPS: %2.1f"
,
fps
);
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"OpenCL device: %s"
,
oclDevName
.
c_str
());
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
::
SelectObject
(
hDC
,
hOldFont
);
}
r
=
pSurface
->
ReleaseDC
(
hDC
);
return
;
}
int
render
()
{
try
{
if
(
m_shutdown
)
return
0
;
HRESULT
r
;
LPDIRECT3DSURFACE9
pSurface
;
r
=
get_surface
(
&
pSurface
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
switch
(
m_mode
)
{
case
0
:
// no processing
break
;
case
1
:
{
// process video frame on CPU
D3DLOCKED_RECT
memDesc
=
{
0
,
NULL
};
RECT
rc
=
{
0
,
0
,
m_width
,
m_height
};
r
=
pSurface
->
LockRect
(
&
memDesc
,
&
rc
,
0
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
memDesc
.
pBits
,
memDesc
.
Pitch
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on CPU
cv
::
blur
(
m
,
m
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
r
=
pSurface
->
UnlockRect
();
if
(
FAILED
(
r
))
{
return
-
1
;
}
break
;
}
case
2
:
{
// process video frame on GPU
cv
::
UMat
u
;
cv
::
directx
::
convertFromDirect3DSurface9
(
pSurface
,
u
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on GPU with OpenCL
cv
::
blur
(
u
,
u
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
cv
::
directx
::
convertToDirect3DSurface9
(
u
,
pSurface
);
break
;
}
}
// switch
print_info
(
pSurface
,
m_mode
,
getFps
(),
m_oclDevName
);
// traditional DX render pipeline:
// BitBlt surface to backBuffer and flip backBuffer to frontBuffer
r
=
m_pD3D9Dev
->
StretchRect
(
pSurface
,
NULL
,
m_pBackBuffer
,
NULL
,
D3DTEXF_NONE
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
// present the back buffer contents to the display
r
=
m_pD3D9Dev
->
Present
(
NULL
,
NULL
,
NULL
,
NULL
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
return
0
;
}
int
cleanup
(
void
)
{
SAFE_RELEASE
(
m_pSurface
);
SAFE_RELEASE
(
m_pBackBuffer
);
SAFE_RELEASE
(
m_pD3D9Dev
);
SAFE_RELEASE
(
m_pD3D9
);
return
0
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
];
int
m_disableProcessing
;
LPDIRECT3D9
m_pD3D9
;
LPDIRECT3DDEVICE9
m_pD3D9Dev
;
LPDIRECT3DSURFACE9
m_pBackBuffer
;
LPDIRECT3DSURFACE9
m_pSurface
;
cv
::
VideoCapture
m_cap
;
cv
::
Mat
m_frame_bgr
;
cv
::
Mat
m_frame_rgba
;
cv
::
ocl
::
Context
m_oclCtx
;
cv
::
String
m_oclPlatformName
;
cv
::
String
m_oclDevName
;
};
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
VideoCapture
cap
;
if
(
argc
>
1
)
{
cap
.
open
(
argv
[
1
]);
}
else
cap
.
open
(
0
);
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
int
height
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
);
std
::
string
wndname
=
"D3D9 Window"
;
D3D9WinApp
app
(
width
,
height
,
wndname
,
cap
);
try
{
app
.
Create
();
return
app
.
run
();
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
catch
(...)
{
std
::
cerr
<<
"FATAL ERROR: Unknown exception"
<<
std
::
endl
;
return
11
;
}
}
samples/directx/d3d9ex_opencl.cpp
0 → 100644
View file @
450a276f
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#include <string>
#include <iostream>
#include <queue>
#include "opencv2/core.hpp"
#include "opencv2/core/directx.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "winapp.hpp"
#pragma comment (lib, "d3d9.lib")
class
D3D9ExWinApp
:
public
WinApp
{
public
:
D3D9ExWinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
,
cv
::
VideoCapture
&
cap
)
:
WinApp
(
width
,
height
,
window_name
)
{
m_shutdown
=
false
;
m_mode
=
0
;
m_modeStr
[
0
]
=
cv
::
String
(
"No processing"
);
m_modeStr
[
1
]
=
cv
::
String
(
"Processing on CPU"
);
m_modeStr
[
2
]
=
cv
::
String
(
"Processing on GPU"
);
m_disableProcessing
=
false
;
m_cap
=
cap
;
}
~
D3D9ExWinApp
()
{}
int
onClose
(
void
)
{
m_shutdown
=
true
;
cleanup
();
::
DestroyWindow
(
m_hWnd
);
return
0
;
}
virtual
LRESULT
CALLBACK
WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
message
)
{
case
WM_CHAR
:
if
(
wParam
>=
'0'
&&
wParam
<=
'2'
)
{
m_mode
=
(
char
)
wParam
-
'0'
;
return
0
;
}
else
if
(
wParam
==
VK_SPACE
)
{
m_disableProcessing
=
!
m_disableProcessing
;
return
0
;
}
else
if
(
wParam
==
VK_ESCAPE
)
{
return
onClose
();
}
break
;
case
WM_CLOSE
:
return
onClose
();
case
WM_DESTROY
:
::
PostQuitMessage
(
0
);
return
0
;
}
return
::
DefWindowProc
(
hWnd
,
message
,
wParam
,
lParam
);
}
static
float
getFps
()
{
static
std
::
queue
<
int64
>
time_queue
;
int64
now
=
cv
::
getTickCount
();
int64
then
=
0
;
time_queue
.
push
(
now
);
if
(
time_queue
.
size
()
>=
2
)
then
=
time_queue
.
front
();
if
(
time_queue
.
size
()
>=
25
)
time_queue
.
pop
();
return
time_queue
.
size
()
*
(
float
)
cv
::
getTickFrequency
()
/
(
now
-
then
);
}
int
init
(
void
)
{
HRESULT
r
;
r
=
::
Direct3DCreate9Ex
(
D3D_SDK_VERSION
,
&
m_pD3D9Ex
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
DWORD
flags
=
D3DCREATE_HARDWARE_VERTEXPROCESSING
|
D3DCREATE_PUREDEVICE
|
D3DCREATE_NOWINDOWCHANGES
|
D3DCREATE_MULTITHREADED
|
D3DCREATE_FPU_PRESERVE
;
D3DPRESENT_PARAMETERS
d3dpp
;
::
ZeroMemory
(
&
d3dpp
,
sizeof
(
D3DPRESENT_PARAMETERS
));
d3dpp
.
Windowed
=
true
;
d3dpp
.
Flags
=
0
;
d3dpp
.
BackBufferCount
=
0
;
d3dpp
.
BackBufferFormat
=
D3DFMT_A8R8G8B8
;
d3dpp
.
BackBufferHeight
=
m_height
;
d3dpp
.
BackBufferWidth
=
m_width
;
d3dpp
.
MultiSampleType
=
D3DMULTISAMPLE_NONE
;
d3dpp
.
SwapEffect
=
D3DSWAPEFFECT_DISCARD
;
d3dpp
.
hDeviceWindow
=
m_hWnd
;
d3dpp
.
PresentationInterval
=
D3DPRESENT_INTERVAL_IMMEDIATE
;
d3dpp
.
FullScreen_RefreshRateInHz
=
D3DPRESENT_RATE_DEFAULT
;
r
=
m_pD3D9Ex
->
CreateDeviceEx
(
D3DADAPTER_DEFAULT
,
D3DDEVTYPE_HAL
,
m_hWnd
,
flags
,
&
d3dpp
,
NULL
,
&
m_pD3D9DevEx
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D9DevEx
->
GetBackBuffer
(
0
,
0
,
D3DBACKBUFFER_TYPE_MONO
,
&
m_pBackBuffer
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
r
=
m_pD3D9DevEx
->
CreateOffscreenPlainSurface
(
m_width
,
m_height
,
D3DFMT_A8R8G8B8
,
D3DPOOL_DEFAULT
,
&
m_pSurface
,
NULL
);
if
(
FAILED
(
r
))
{
std
::
cerr
<<
"Can't create surface for result"
<<
std
::
endl
;
return
-
1
;
}
if
(
cv
::
ocl
::
haveOpenCL
())
{
m_oclCtx
=
cv
::
directx
::
ocl
::
initializeContextFromDirect3DDevice9
(
m_pD3D9DevEx
);
}
m_oclDevName
=
cv
::
ocl
::
useOpenCL
()
?
cv
::
ocl
::
Context
::
getDefault
().
device
(
0
).
name
()
:
"No OpenCL device"
;
return
0
;
}
// init()
int
get_surface
(
LPDIRECT3DSURFACE9
*
ppSurface
)
{
HRESULT
r
;
if
(
!
m_cap
.
read
(
m_frame_bgr
))
return
-
1
;
cv
::
cvtColor
(
m_frame_bgr
,
m_frame_rgba
,
CV_RGB2RGBA
);
D3DLOCKED_RECT
memDesc
=
{
0
,
NULL
};
RECT
rc
=
{
0
,
0
,
m_width
,
m_height
};
r
=
m_pSurface
->
LockRect
(
&
memDesc
,
&
rc
,
0
);
if
(
FAILED
(
r
))
{
return
r
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
memDesc
.
pBits
,
memDesc
.
Pitch
);
// copy video frame data to surface
m_frame_rgba
.
copyTo
(
m
);
r
=
m_pSurface
->
UnlockRect
();
if
(
FAILED
(
r
))
{
return
r
;
}
*
ppSurface
=
m_pSurface
;
return
0
;
}
void
print_info
(
LPDIRECT3DSURFACE9
pSurface
,
int
mode
,
float
fps
,
cv
::
String
oclDevName
)
{
HDC
hDC
;
HRESULT
r
=
pSurface
->
GetDC
(
&
hDC
);
if
(
FAILED
(
r
))
{
return
;
}
HFONT
hFont
=
(
HFONT
)
::
GetStockObject
(
SYSTEM_FONT
);
HFONT
hOldFont
=
(
HFONT
)
::
SelectObject
(
hDC
,
hFont
);
if
(
hOldFont
)
{
TEXTMETRIC
tm
;
::
GetTextMetrics
(
hDC
,
&
tm
);
char
buf
[
256
];
int
y
=
0
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"Mode: %s"
,
m_modeStr
[
mode
].
c_str
());
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"FPS: %2.1f"
,
fps
);
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
y
+=
tm
.
tmHeight
;
buf
[
0
]
=
0
;
sprintf
(
buf
,
"OpenCL device: %s"
,
oclDevName
.
c_str
());
::
TextOut
(
hDC
,
0
,
y
,
buf
,
(
int
)
strlen
(
buf
));
::
SelectObject
(
hDC
,
hOldFont
);
}
r
=
pSurface
->
ReleaseDC
(
hDC
);
return
;
}
int
render
()
{
try
{
if
(
m_shutdown
)
return
0
;
HRESULT
r
;
LPDIRECT3DSURFACE9
pSurface
;
r
=
get_surface
(
&
pSurface
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
switch
(
m_mode
)
{
case
0
:
// no processing
break
;
case
1
:
{
// process video frame on CPU
D3DLOCKED_RECT
memDesc
=
{
0
,
NULL
};
RECT
rc
=
{
0
,
0
,
m_width
,
m_height
};
r
=
pSurface
->
LockRect
(
&
memDesc
,
&
rc
,
0
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
cv
::
Mat
m
(
m_height
,
m_width
,
CV_8UC4
,
memDesc
.
pBits
,
memDesc
.
Pitch
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on CPU
cv
::
blur
(
m
,
m
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
r
=
pSurface
->
UnlockRect
();
if
(
FAILED
(
r
))
{
return
-
1
;
}
break
;
}
case
2
:
{
// process video frame on GPU
cv
::
UMat
u
;
cv
::
directx
::
convertFromDirect3DSurface9
(
pSurface
,
u
);
if
(
!
m_disableProcessing
)
{
// blur D3D9 surface with OpenCV on GPU with OpenCL
cv
::
blur
(
u
,
u
,
cv
::
Size
(
15
,
15
),
cv
::
Point
(
-
7
,
-
7
));
}
cv
::
directx
::
convertToDirect3DSurface9
(
u
,
pSurface
);
break
;
}
}
// switch
print_info
(
pSurface
,
m_mode
,
getFps
(),
m_oclDevName
);
// traditional DX render pipeline:
// BitBlt surface to backBuffer and flip backBuffer to frontBuffer
r
=
m_pD3D9DevEx
->
StretchRect
(
pSurface
,
NULL
,
m_pBackBuffer
,
NULL
,
D3DTEXF_NONE
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
// present the back buffer contents to the display
r
=
m_pD3D9DevEx
->
Present
(
NULL
,
NULL
,
NULL
,
NULL
);
if
(
FAILED
(
r
))
{
return
-
1
;
}
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
return
0
;
}
int
cleanup
(
void
)
{
SAFE_RELEASE
(
m_pSurface
);
SAFE_RELEASE
(
m_pBackBuffer
);
SAFE_RELEASE
(
m_pD3D9DevEx
);
SAFE_RELEASE
(
m_pD3D9Ex
);
return
0
;
}
private
:
bool
m_shutdown
;
int
m_mode
;
cv
::
String
m_modeStr
[
3
];
int
m_disableProcessing
;
LPDIRECT3D9EX
m_pD3D9Ex
;
LPDIRECT3DDEVICE9EX
m_pD3D9DevEx
;
LPDIRECT3DSURFACE9
m_pBackBuffer
;
LPDIRECT3DSURFACE9
m_pSurface
;
cv
::
VideoCapture
m_cap
;
cv
::
Mat
m_frame_bgr
;
cv
::
Mat
m_frame_rgba
;
cv
::
ocl
::
Context
m_oclCtx
;
cv
::
String
m_oclPlatformName
;
cv
::
String
m_oclDevName
;
};
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
)
{
cv
::
VideoCapture
cap
;
if
(
argc
>
1
)
{
cap
.
open
(
argv
[
1
]);
}
else
cap
.
open
(
0
);
int
width
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
);
int
height
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
);
std
::
string
wndname
=
"D3D9Ex Window"
;
D3D9ExWinApp
app
(
width
,
height
,
wndname
,
cap
);
try
{
app
.
Create
();
return
app
.
run
();
}
catch
(
cv
::
Exception
&
e
)
{
std
::
cerr
<<
"Exception: "
<<
e
.
what
()
<<
std
::
endl
;
return
10
;
}
catch
(...)
{
std
::
cerr
<<
"FATAL ERROR: Unknown exception"
<<
std
::
endl
;
return
11
;
}
}
samples/directx/winapp.hpp
0 → 100644
View file @
450a276f
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#define WINCLASS "WinAppWnd"
#define SAFE_RELEASE(p) if (p) { p->Release(); p = NULL; }
class
WinApp
{
public
:
WinApp
(
int
width
,
int
height
,
std
::
string
&
window_name
)
{
m_width
=
width
;
m_height
=
height
;
m_window_name
=
window_name
;
m_hInstance
=
::
GetModuleHandle
(
NULL
);
}
virtual
~
WinApp
()
{
::
UnregisterClass
(
WINCLASS
,
m_hInstance
);
}
int
Create
()
{
WNDCLASSEX
wcex
;
wcex
.
cbSize
=
sizeof
(
WNDCLASSEX
);
wcex
.
style
=
CS_HREDRAW
|
CS_VREDRAW
;
wcex
.
lpfnWndProc
=
&
WinApp
::
StaticWndProc
;
wcex
.
cbClsExtra
=
0
;
wcex
.
cbWndExtra
=
0
;
wcex
.
hInstance
=
m_hInstance
;
wcex
.
hIcon
=
LoadIcon
(
0
,
IDI_APPLICATION
);
wcex
.
hCursor
=
LoadCursor
(
0
,
IDC_ARROW
);
wcex
.
hbrBackground
=
0
;
wcex
.
lpszMenuName
=
0L
;
wcex
.
lpszClassName
=
WINCLASS
;
wcex
.
hIconSm
=
0
;
ATOM
wc
=
::
RegisterClassEx
(
&
wcex
);
RECT
rc
=
{
0
,
0
,
m_width
,
m_height
};
::
AdjustWindowRect
(
&
rc
,
WS_OVERLAPPEDWINDOW
,
false
);
m_hWnd
=
::
CreateWindow
(
(
LPCTSTR
)
wc
,
m_window_name
.
c_str
(),
WS_OVERLAPPEDWINDOW
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
rc
.
right
-
rc
.
left
,
rc
.
bottom
-
rc
.
top
,
NULL
,
NULL
,
m_hInstance
,
(
void
*
)
this
);
if
(
!
m_hWnd
)
return
-
1
;
::
ShowWindow
(
m_hWnd
,
SW_SHOW
);
::
UpdateWindow
(
m_hWnd
);
::
SetFocus
(
m_hWnd
);
return
init
();
}
virtual
LRESULT
CALLBACK
WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
=
0
;
int
run
()
{
MSG
msg
;
::
ZeroMemory
(
&
msg
,
sizeof
(
msg
));
while
(
msg
.
message
!=
WM_QUIT
)
{
if
(
::
PeekMessage
(
&
msg
,
NULL
,
0U
,
0U
,
PM_REMOVE
))
{
::
TranslateMessage
(
&
msg
);
::
DispatchMessage
(
&
msg
);
}
else
{
render
();
}
}
return
static_cast
<
int
>
(
msg
.
wParam
);
}
protected
:
static
LRESULT
CALLBACK
StaticWndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
WinApp
*
pWnd
;
if
(
message
==
WM_NCCREATE
)
{
LPCREATESTRUCT
pCreateStruct
=
((
LPCREATESTRUCT
)
lParam
);
pWnd
=
(
WinApp
*
)(
pCreateStruct
->
lpCreateParams
);
::
SetWindowLongPtr
(
hWnd
,
GWLP_USERDATA
,
(
LONG_PTR
)
pWnd
);
}
pWnd
=
GetObjectFromWindow
(
hWnd
);
if
(
pWnd
)
return
pWnd
->
WndProc
(
hWnd
,
message
,
wParam
,
lParam
);
else
return
::
DefWindowProc
(
hWnd
,
message
,
wParam
,
lParam
);
}
inline
static
WinApp
*
GetObjectFromWindow
(
HWND
hWnd
)
{
return
(
WinApp
*
)
::
GetWindowLongPtr
(
hWnd
,
GWLP_USERDATA
);
}
virtual
int
init
()
=
0
;
virtual
int
render
()
=
0
;
HINSTANCE
m_hInstance
;
HWND
m_hWnd
;
int
m_width
;
int
m_height
;
std
::
string
m_window_name
;
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment