DirectX9 display change (#1191)

* Fix issue #1190

* Correct output image with size decimation used

* Correct image format (BGR -> RGB)

* Another approach
This commit is contained in:
Paulchen Panther 2021-02-23 20:37:59 +01:00 committed by GitHub
parent 6ed9553ca3
commit 45bd23ca5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 32 deletions

View File

@ -318,30 +318,6 @@ macro(DeployWindows TARGET)
)
endforeach()
if(ENABLE_DX)
# Download DirectX End-User Runtimes (June 2010)
set(url "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe")
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe")
file(DOWNLOAD "${url}" "${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe"
STATUS result
)
# Check if the download is successful
list(GET result 0 result_code)
if(NOT result_code EQUAL 0)
list(GET result 1 reason)
message(FATAL_ERROR "Could not download DirectX End-User Runtimes: ${reason}")
endif()
endif()
# Copy DirectX End-User Runtimes to 'hyperion'
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe
DESTINATION "bin"
COMPONENT "Hyperion"
)
endif (ENABLE_DX)
else()
# Run CMake after target was built
add_custom_command(

View File

@ -54,6 +54,11 @@ public:
///
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
///
/// @brief Apply display index
///
void setDisplayIndex(int index) override;
private:
///
/// @brief Setup a new capture display, will free the previous one
@ -68,6 +73,7 @@ private:
private:
int _pixelDecimation;
unsigned _display;
unsigned _displayWidth;
unsigned _displayHeight;
RECT* _srcRect;

View File

@ -1,12 +1,13 @@
#include <windows.h>
#include <grabber/DirectXGrabber.h>
#include <QImage>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
DirectXGrabber::DirectXGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display)
: Grabber("DXGRABBER", 0, 0, cropLeft, cropRight, cropTop, cropBottom)
, _pixelDecimation(pixelDecimation)
, _display(unsigned(display))
, _displayWidth(0)
, _displayHeight(0)
, _srcRect(0)
@ -43,6 +44,8 @@ bool DirectXGrabber::setupDisplay()
D3DDISPLAYMODE ddm;
D3DPRESENT_PARAMETERS d3dpp;
HMONITOR hMonitor = nullptr;
MONITORINFO monitorInfo = { 0 };
if ((_d3d9 = Direct3DCreate9(D3D_SDK_VERSION)) == nullptr)
{
@ -50,7 +53,17 @@ bool DirectXGrabber::setupDisplay()
return false;
}
if (FAILED(_d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ddm)))
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(MONITORINFO);
hMonitor = _d3d9->GetAdapterMonitor(_display);
if (hMonitor == nullptr || GetMonitorInfo(hMonitor, &monitorInfo) == FALSE)
{
Info(_log, "Specified display %d is not available. Primary display %d is used", _display, D3DADAPTER_DEFAULT);
_display = D3DADAPTER_DEFAULT;
}
if (FAILED(_d3d9->GetAdapterDisplayMode(_display, &ddm)))
{
Error(_log, "Failed to get current display mode");
return false;
@ -69,7 +82,7 @@ bool DirectXGrabber::setupDisplay()
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
if (FAILED(_d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, nullptr, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &_device)))
if (FAILED(_d3d9->CreateDevice(_display, D3DDEVTYPE_HAL, nullptr, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &_device)))
{
Error(_log, "CreateDevice failed");
return false;
@ -147,12 +160,11 @@ int DirectXGrabber::grabFrame(Image<ColorRgb> & image)
return 0;
}
memcpy(image.memptr(), lockedRect.pBits, _width * _height * 3);
for(int i=0 ; i < _height ; i++)
memcpy((unsigned char*)image.memptr() + i * _width * 3, (unsigned char*)lockedRect.pBits + i * lockedRect.Pitch, _width * 3);
for (int idx = 0; idx < _width * _height; idx++)
{
const ColorRgb & color = image.memptr()[idx];
image.memptr()[idx] = ColorRgb{color.blue, color.green, color.red};
}
image.memptr()[idx] = ColorRgb{image.memptr()[idx].blue, image.memptr()[idx].green, image.memptr()[idx].red};
if (FAILED(_surfaceDest->UnlockRect()))
{
@ -179,3 +191,12 @@ void DirectXGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned
Grabber::setCropping(cropLeft, cropRight, cropTop, cropBottom);
setupDisplay();
}
void DirectXGrabber::setDisplayIndex(int index)
{
if(_display != unsigned(index))
{
_display = unsigned(index);
setupDisplay();
}
}