Skip to content

Commit

Permalink
0.7
Browse files Browse the repository at this point in the history
  • Loading branch information
mausimus committed Dec 19, 2021
1 parent 9b025c0 commit da5d1e2
Show file tree
Hide file tree
Showing 15 changed files with 493 additions and 228 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ BasedOnStyle: WebKit
TabWidth: 4
IndentWidth: 4
UseTab: Never
ColumnLimit: 140
ColumnLimit: 180

# Other languages JavaScript, Proto

Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ Overlay for running GPU shaders on top of Windows desktop.

### Download

Latest release (v0.6, 31st Oct 2021):
* adds ability to fine-tune Parameters for each shader
* refresh of RetroArch shader library (200+ new shader profiles)
Latest release (v0.7, 19 Dec 2021):
* load .png/.jpg image file as input
* lock capture area to clone a portion of the screen
* free resizing & scaling support in Windowed Clone mode
* option to account for display DPI scaling in pixel size adjustment
* fixes to shaders

https://github.com/mausimus/ShaderGlass/releases/download/v0.6/ShaderGlass-0.6-win-x64.zip
https://github.com/mausimus/ShaderGlass/releases/download/v0.7/ShaderGlass-0.7-win-x64.zip

<br/>

Expand Down Expand Up @@ -105,14 +108,21 @@ Currently supported options are:

* _Input -> Desktop_ - captures the whole desktop or an individual monitor, defaults to Glass mode

* _Lock Current Area_ - always capture current area even if ShaderGlass window is moved

* _Input -> Window_ - captures the selected window, defaults to Clone mode

* _Input -> File..._ - load a .png or .jpg file as input

* _Input -> Capture Cursor_ - whether to include mouse cursor in capture

* _Input -> Remove Yellow Border_ - disables yellow frame around captured area (forced security feature); currently only supported on Windows 11

* _Input -> Pixel Size_ - indicates the size of input pixels (pre-scaling), i.e. if you run a game in x3 scaling mode set this to x3 as well so that ShaderGlass can tell the original resolution

* _Adjust for DPI Scale_ - if your source always applies Windows DPI Scaling when displaying images
(for example browsers) enable this option to take it into account; most emulators don't do this however

* _Output -> Mode_ - overrides default mode for the input type:

* _Glass_ (default for Desktop) - ShaderGlass window appears transparent, you have to position it over the window or area you'd like to capture
Expand All @@ -127,13 +137,17 @@ Currently supported options are:

* _Output -> Scale_ - apply additional scaling to the output if you'd like it to be larger; using no pre-scaling and only output scaling should result in best performance

* _Free_ - allow manual resizing of ShaderGlass window (Window Clone and File modes only)

* _Output -> Aspect Ratio Correction_ - presets for common aspect ratio correction factors (DOS, etc.), applied horizontally to preserve scanline count

* If you select _Custom_ you can enter your own correction ratio expressed as pixel height (1.0 being square pixel). For example,
in MS-DOS era a picture of 320x200 resolution (16:10) was displayed on a 4:3 screen meaning each pixel was 1.2x tall on screen, 1.2 = (16/10) / (4/3)

* _Output -> Frame Skip_ - in order to improve performance divide frame rate by n (capture is done at VSync rate)

* _Output -> Take Snapshot_ - export current picture in .png format

* _Output -> Fullscreen_ (Ctrl+Shift+G) - turn ShaderGlass into a topmost fullscreen borderless window, in Glass mode you will still see yellow outline around the screen but if you can use
Window Glass (surrounding black bars) or Window Clone (top-left aligned) with your source then you can avoid yellow edges; press Ctrl+Shift+G to revert

Expand Down
10 changes: 5 additions & 5 deletions ShaderGen/ShaderGen.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,32 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{0ac8c8e0-010b-4829-9282-060eab89d5d0}</ProjectGuid>
<RootNamespace>ShaderGen</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
Expand Down
77 changes: 70 additions & 7 deletions ShaderGlass/CaptureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@

#include <wincodec.h>
#include "WIC\ScreenGrab11.h"
#include "WIC\WICTextureLoader11.h"

using namespace std;
using namespace util;
using namespace util::uwp;

CaptureManager::CaptureManager() : m_options() { }
class CaptureManager* CaptureManager::s_this {nullptr};

CaptureManager::CaptureManager() : m_options(), m_timer(0) { }

bool CaptureManager::Initialize()
{
Expand Down Expand Up @@ -54,23 +57,52 @@ void CaptureManager::StartSession()

auto dxgiDevice = m_d3dDevice.as<IDXGIDevice>();
auto device = CreateDirect3DDevice(dxgiDevice.get());
auto captureItem =
m_options.captureWindow ? CreateCaptureItemForWindow(m_options.captureWindow) : CreateCaptureItemForMonitor(m_options.monitor);

#ifdef _DEBUG
m_d3dDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(m_debug.put()));
#endif

m_shaderGlass = make_unique<ShaderGlass>();
m_shaderGlass->Initialize(m_options.outputWindow, m_options.captureWindow, m_options.monitor, m_options.clone, m_d3dDevice, m_context);
m_shaderGlass->Initialize(m_options.outputWindow, m_options.captureWindow, m_options.monitor, m_options.clone, !m_options.imageFile.empty(), m_d3dDevice, m_context);
UpdatePixelSize();
UpdateOutputSize();
UpdateOutputFlip();
UpdateShaderPreset();
UpdateFrameSkip();
UpdateLockedArea();

if(m_options.imageFile.size())
{
winrt::com_ptr<ID3D11Texture2D> inputTexture;
winrt::com_ptr<ID3D11ShaderResourceView> inputTextureView;
auto hr = DirectX::CreateWICTextureFromFile(m_d3dDevice.get(), m_options.imageFile.c_str(), (ID3D11Resource**)(inputTexture.put()), inputTextureView.put());
assert(SUCCEEDED(hr));

// retrieve input image size
D3D11_TEXTURE2D_DESC desc = {};
inputTexture->GetDesc(&desc);
m_options.imageWidth = desc.Width;
m_options.imageHeight = desc.Height;

m_session = make_unique<CaptureSession>(device, inputTexture, *m_shaderGlass);

int frameInterval = 1000 / 60; // set to 60fps if we fail to retrieve refresh rate

DEVMODE devmode;
devmode.dmSize = sizeof(DEVMODE);
if(EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode) && devmode.dmDisplayFrequency != 0)
{
frameInterval = 1000 / devmode.dmDisplayFrequency;
}
s_this = this; // horrible hack
m_timer = SetTimer(NULL, 0, frameInterval, CaptureManager::TimerFuncProxy);
}
else
{
auto captureItem = m_options.captureWindow ? CreateCaptureItemForWindow(m_options.captureWindow) : CreateCaptureItemForMonitor(m_options.monitor);

m_session = make_unique<CaptureSession>(
device, captureItem, winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized, *m_shaderGlass);
m_session = make_unique<CaptureSession>(device, captureItem, winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized, *m_shaderGlass);
}
UpdateCursor();
}

Expand All @@ -96,6 +128,14 @@ bool CaptureManager::IsActive()
return m_session.get();
}

void CaptureManager::ForceProcess()
{
if(m_session.get())
{
m_session->ProcessInput();
}
}

void CaptureManager::StopSession()
{
if(m_session.get())
Expand All @@ -110,6 +150,12 @@ void CaptureManager::Exit()
{
if(m_session.get())
{
if(m_timer)
{
KillTimer(NULL, m_timer);
m_timer = 0;
}

m_session->Stop();
delete m_session.release();

Expand All @@ -128,7 +174,7 @@ void CaptureManager::UpdatePixelSize()
{
if(m_shaderGlass)
{
m_shaderGlass->SetInputScale(m_options.pixelWidth, m_options.pixelHeight);
m_shaderGlass->SetInputScale(m_options.pixelWidth * m_options.dpiScale, m_options.pixelHeight * m_options.dpiScale);
}
}

Expand All @@ -137,6 +183,7 @@ void CaptureManager::UpdateOutputSize()
if(m_shaderGlass)
{
m_shaderGlass->SetOutputScale(1.0f * m_options.aspectRatio / m_options.outputScale, 1.0f / m_options.outputScale);
m_shaderGlass->SetFreeScale(m_options.freeScale);
}
}

Expand Down Expand Up @@ -165,6 +212,14 @@ void CaptureManager::UpdateFrameSkip()
}
}

void CaptureManager::UpdateLockedArea()
{
if(m_shaderGlass)
{
m_shaderGlass->SetLockedArea(m_options.inputArea);
}
}

void CaptureManager::GrabOutput()
{
if(m_shaderGlass)
Expand Down Expand Up @@ -196,4 +251,12 @@ void CaptureManager::ResetParams()
{
m_shaderGlass->ResetParams();
}
}

void CaptureManager::TimerFuncProxy(_In_ HWND hwnd, _In_ UINT param2, _In_ UINT_PTR param3, _In_ DWORD param4)
{
if(s_this)
{
s_this->ForceProcess();
}
}
41 changes: 26 additions & 15 deletions ShaderGlass/CaptureManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@

struct CaptureOptions
{
HMONITOR monitor {0};
HWND captureWindow {0};
HWND outputWindow {0};
float pixelWidth {3.0f};
float pixelHeight {3.0f};
float aspectRatio {1.0f};
unsigned presetNo {0};
unsigned frameSkip {0};
float outputScale {1};
bool flipHorizontal {false};
bool flipVertical {false};
bool clone {false};
bool transparent {false};
bool paused {false};
bool captureCursor {false};
HMONITOR monitor {0};
HWND captureWindow {0};
HWND outputWindow {0};
float pixelWidth {3.0f};
float pixelHeight {3.0f};
float aspectRatio {1.0f};
unsigned presetNo {0};
unsigned frameSkip {0};
float outputScale {1};
bool flipHorizontal {false};
bool flipVertical {false};
bool clone {false};
bool transparent {false};
bool paused {false};
bool captureCursor {false};
std::wstring imageFile {};
int imageWidth {0};
int imageHeight {0};
RECT inputArea {0, 0, 0, 0};
float dpiScale {1.0f};
bool freeScale {false};
};

class CaptureManager
Expand All @@ -43,14 +49,19 @@ class CaptureManager
void UpdateFrameSkip();
void UpdateInput();
void UpdateCursor();
void UpdateLockedArea();
void GrabOutput();
void UpdateParams();
void ResetParams();
void SetParams(const std::vector<std::tuple<int, std::string, double>>& params);
void SaveOutput(LPWSTR fileName);
void ForceProcess();
void Exit();

private:
static class CaptureManager* s_this;
UINT_PTR m_timer {0};
static void CALLBACK TimerFuncProxy(_In_ HWND hwnd, _In_ UINT param2, _In_ UINT_PTR param3, _In_ DWORD param4);
winrt::com_ptr<ID3D11Device> m_d3dDevice {nullptr};
winrt::com_ptr<ID3D11DeviceContext> m_context {nullptr};
winrt::com_ptr<ID3D11Debug> m_debug {nullptr};
Expand Down
Loading

0 comments on commit da5d1e2

Please sign in to comment.