mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added DisplayFilter setting
This commit is contained in:
parent
ffc8e04a35
commit
00a78097d2
@ -4,6 +4,7 @@ namespace Config
|
||||
{
|
||||
Settings::CpuAffinity cpuAffinity;
|
||||
Settings::DesktopColorDepth desktopColorDepth;
|
||||
Settings::DisplayFilter displayFilter;
|
||||
Settings::DisplayResolution displayResolution;
|
||||
Settings::SupportedResolutions supportedResolutions;
|
||||
Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
#include <Config/Settings/DesktopColorDepth.h>
|
||||
#include <Config/Settings/DisplayFilter.h>
|
||||
#include <Config/Settings/DisplayResolution.h>
|
||||
#include <Config/Settings/SupportedResolutions.h>
|
||||
#include <Config/Settings/ThreadPriorityBoost.h>
|
||||
@ -14,6 +15,7 @@ namespace Config
|
||||
|
||||
extern Settings::CpuAffinity cpuAffinity;
|
||||
extern Settings::DesktopColorDepth desktopColorDepth;
|
||||
extern Settings::DisplayFilter displayFilter;
|
||||
extern Settings::DisplayResolution displayResolution;
|
||||
extern Settings::SupportedResolutions supportedResolutions;
|
||||
extern Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
|
@ -21,26 +21,68 @@ namespace Config
|
||||
{
|
||||
}
|
||||
|
||||
std::string getValueStr() const override
|
||||
virtual std::string getParamStr() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual std::string getValueStr() const override
|
||||
{
|
||||
for (const auto& pair : m_valueMapping)
|
||||
{
|
||||
if (pair.second == m_value)
|
||||
{
|
||||
return pair.first;
|
||||
std::string param(getParamStr());
|
||||
if (!param.empty())
|
||||
{
|
||||
param = '(' + param + ')';
|
||||
}
|
||||
return pair.first + param;
|
||||
}
|
||||
}
|
||||
throw ParsingError("MappedSetting::getValueStr(): value not found in mapping");
|
||||
}
|
||||
|
||||
void setValue(const std::string& value) override
|
||||
virtual void setDefaultParam(const Value& /*value*/)
|
||||
{
|
||||
auto it = m_valueMapping.find(value);
|
||||
}
|
||||
|
||||
virtual void setValue(const std::string& value) override
|
||||
{
|
||||
std::string val(value);
|
||||
std::string param;
|
||||
auto parenPos = value.find('(');
|
||||
if (std::string::npos != parenPos)
|
||||
{
|
||||
val = value.substr(0, parenPos);
|
||||
param = value.substr(parenPos + 1);
|
||||
if (param.length() < 2 || param.back() != ')')
|
||||
{
|
||||
throw ParsingError("invalid value: '" + value + "'");
|
||||
}
|
||||
param = param.substr(0, param.length() - 1);
|
||||
}
|
||||
|
||||
auto it = m_valueMapping.find(val);
|
||||
if (it == m_valueMapping.end())
|
||||
{
|
||||
throw ParsingError("invalid value: '" + value + "'");
|
||||
}
|
||||
m_value = it->second;
|
||||
|
||||
if (param.empty())
|
||||
{
|
||||
m_value = it->second;
|
||||
setDefaultParam(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(it->second, param);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setValue(const Value& /*value*/, const std::string& param)
|
||||
{
|
||||
throw ParsingError("invalid parameter: '" + param + "'");
|
||||
}
|
||||
|
||||
Value m_value;
|
||||
|
38
DDrawCompat/Config/Settings/DisplayFilter.cpp
Normal file
38
DDrawCompat/Config/Settings/DisplayFilter.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <Config/Settings/DisplayFilter.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
DisplayFilter::DisplayFilter()
|
||||
: MappedSetting("DisplayFilter", "bilinear(0)", { {"point", POINT}, {"bilinear", BILINEAR} })
|
||||
, m_param(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string DisplayFilter::getParamStr() const
|
||||
{
|
||||
return BILINEAR == m_value ? std::to_string(m_param) : std::string();
|
||||
}
|
||||
|
||||
void DisplayFilter::setDefaultParam(const UINT& value)
|
||||
{
|
||||
m_param = BILINEAR == value ? 100 : 0;
|
||||
}
|
||||
|
||||
void DisplayFilter::setValue(const UINT& value, const std::string& param)
|
||||
{
|
||||
if (BILINEAR == value)
|
||||
{
|
||||
const UINT p = Config::Parser::parseUnsigned(param);
|
||||
if (p <= 100)
|
||||
{
|
||||
m_value = BILINEAR;
|
||||
m_param = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw ParsingError("invalid parameter: '" + param + "'");
|
||||
}
|
||||
}
|
||||
}
|
27
DDrawCompat/Config/Settings/DisplayFilter.h
Normal file
27
DDrawCompat/Config/Settings/DisplayFilter.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/MappedSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class DisplayFilter : public MappedSetting<UINT>
|
||||
{
|
||||
public:
|
||||
static const UINT POINT = 0;
|
||||
static const UINT BILINEAR = 1;
|
||||
|
||||
DisplayFilter();
|
||||
|
||||
UINT getParam() const { return m_param; }
|
||||
|
||||
protected:
|
||||
virtual std::string getParamStr() const override;
|
||||
virtual void setDefaultParam(const UINT& value) override;
|
||||
virtual void setValue(const UINT& value, const std::string& param) override;
|
||||
|
||||
UINT m_param;
|
||||
};
|
||||
}
|
||||
}
|
@ -91,6 +91,7 @@ namespace D3dDdi
|
||||
m_renderState[D3DDDIRS_PATCHSEGMENTS] = 0x3F800000;
|
||||
m_renderState[D3DDDIRS_COLORWRITEENABLE] = 0xF;
|
||||
m_renderState[D3DDDIRS_BLENDOP] = D3DBLENDOP_ADD;
|
||||
m_renderState[D3DDDIRS_SRGBWRITEENABLE] = FALSE;
|
||||
|
||||
for (UINT i = 0; i < m_renderState.size(); i++)
|
||||
{
|
||||
@ -122,6 +123,7 @@ namespace D3dDdi
|
||||
m_textureStageState[i][D3DDDITSS_MAXMIPLEVEL] = 0;
|
||||
m_textureStageState[i][D3DDDITSS_MAXANISOTROPY] = 1;
|
||||
m_textureStageState[i][D3DDDITSS_TEXTURETRANSFORMFLAGS] = D3DTTFF_DISABLE;
|
||||
m_textureStageState[i][D3DDDITSS_SRGBTEXTURE] = FALSE;
|
||||
m_textureStageState[i][D3DDDITSS_ADDRESSW] = D3DTADDRESS_WRAP;
|
||||
m_textureStageState[i][D3DDDITSS_DISABLETEXTURECOLORKEY] = TRUE;
|
||||
|
||||
|
@ -15,6 +15,9 @@ namespace D3dDdi
|
||||
class DeviceState
|
||||
{
|
||||
public:
|
||||
typedef std::array<FLOAT, 4> ShaderConstF;
|
||||
typedef std::array<INT, 4> ShaderConstI;
|
||||
|
||||
DeviceState(Device& device);
|
||||
|
||||
HRESULT pfnCreateVertexShaderDecl(D3DDDIARG_CREATEVERTEXSHADERDECL* data, const D3DDDIVERTEXELEMENT* vertexElements);
|
||||
@ -44,9 +47,6 @@ namespace D3dDdi
|
||||
void onDestroyResource(HANDLE resource);
|
||||
|
||||
private:
|
||||
typedef std::tuple<FLOAT, FLOAT, FLOAT, FLOAT> ShaderConstF;
|
||||
typedef std::tuple<INT, INT, INT, INT> ShaderConstI;
|
||||
|
||||
HRESULT deleteShader(HANDLE shader, HANDLE& currentShader,
|
||||
HRESULT(APIENTRY* origDeleteShaderFunc)(HANDLE, HANDLE));
|
||||
HRESULT setShader(HANDLE shader, HANDLE& currentShader,
|
||||
@ -148,6 +148,38 @@ namespace D3dDdi
|
||||
using ScopedHandle::ScopedHandle;
|
||||
};
|
||||
|
||||
class ScopedPixelShaderConst
|
||||
{
|
||||
public:
|
||||
ScopedPixelShaderConst(
|
||||
DeviceState& deviceState, const D3DDDIARG_SETPIXELSHADERCONST& data, const ShaderConstF* registers)
|
||||
: m_deviceState(deviceState)
|
||||
, m_register(data.Register)
|
||||
{
|
||||
if (data.Register + data.Count > m_deviceState.m_pixelShaderConst.size())
|
||||
{
|
||||
m_deviceState.m_pixelShaderConst.resize(data.Register + data.Count);
|
||||
}
|
||||
|
||||
auto it = deviceState.m_pixelShaderConst.begin() + data.Register;
|
||||
m_prevRegisters.assign(it, it + data.Count);
|
||||
m_deviceState.pfnSetPixelShaderConst(&data, reinterpret_cast<const FLOAT*>(registers));
|
||||
}
|
||||
|
||||
~ScopedPixelShaderConst()
|
||||
{
|
||||
D3DDDIARG_SETPIXELSHADERCONST data = {};
|
||||
data.Register = m_register;
|
||||
data.Count = m_prevRegisters.size();
|
||||
m_deviceState.pfnSetPixelShaderConst(&data, reinterpret_cast<const FLOAT*>(m_prevRegisters.data()));
|
||||
}
|
||||
|
||||
private:
|
||||
DeviceState& m_deviceState;
|
||||
UINT m_register;
|
||||
std::vector<ShaderConstF> m_prevRegisters;
|
||||
};
|
||||
|
||||
class ScopedRenderState
|
||||
{
|
||||
public:
|
||||
@ -244,6 +276,7 @@ namespace D3dDdi
|
||||
, m_scopedMagFilter(deviceState, { stage, D3DDDITSS_MAGFILTER, filter })
|
||||
, m_scopedMinFilter(deviceState, { stage, D3DDDITSS_MINFILTER, filter })
|
||||
, m_scopedMipFilter(deviceState, { stage, D3DDDITSS_MIPFILTER, D3DTEXF_NONE })
|
||||
, m_scopedSrgbTexture(deviceState, { stage, D3DDDITSS_SRGBTEXTURE, D3DTEXF_LINEAR == filter })
|
||||
, m_scopedWrap(deviceState, { static_cast<D3DDDIRENDERSTATETYPE>(D3DDDIRS_WRAP0 + stage), 0 })
|
||||
, m_prevTextureColorKeyVal(deviceState.m_textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL])
|
||||
, m_prevDisableTextureColorKey(deviceState.m_textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY])
|
||||
@ -285,6 +318,7 @@ namespace D3dDdi
|
||||
ScopedTextureStageState m_scopedMagFilter;
|
||||
ScopedTextureStageState m_scopedMinFilter;
|
||||
ScopedTextureStageState m_scopedMipFilter;
|
||||
ScopedTextureStageState m_scopedSrgbTexture;
|
||||
ScopedRenderState m_scopedWrap;
|
||||
UINT m_prevTextureColorKeyVal;
|
||||
UINT m_prevDisableTextureColorKey;
|
||||
|
@ -24,6 +24,8 @@ namespace
|
||||
|
||||
const UINT g_resourceTypeFlags = getResourceTypeFlags().Value;
|
||||
RECT g_presentationRect = {};
|
||||
UINT g_presentationFilter = Config::Settings::DisplayFilter::POINT;
|
||||
UINT g_presentationFilterParam = 0;
|
||||
|
||||
RECT calculatePresentationRect()
|
||||
{
|
||||
@ -124,6 +126,25 @@ namespace D3dDdi
|
||||
Gdi::Cursor::setEmulated(true);
|
||||
}
|
||||
Gdi::VirtualScreen::setFullscreenMode(true);
|
||||
|
||||
if (g_presentationRect.right - g_presentationRect.left != rect.right ||
|
||||
g_presentationRect.bottom - g_presentationRect.top != rect.bottom)
|
||||
{
|
||||
g_presentationFilter = Config::displayFilter.get();
|
||||
g_presentationFilterParam = Config::displayFilter.getParam();
|
||||
|
||||
if (Config::Settings::DisplayFilter::BILINEAR == g_presentationFilter &&
|
||||
0 == g_presentationFilterParam &&
|
||||
0 == (g_presentationRect.right - g_presentationRect.left) % rect.right &&
|
||||
0 == (g_presentationRect.bottom - g_presentationRect.top) % rect.bottom)
|
||||
{
|
||||
g_presentationFilter = Config::Settings::DisplayFilter::POINT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_presentationFilter = Config::Settings::DisplayFilter::POINT;
|
||||
}
|
||||
}
|
||||
|
||||
fixResourceData();
|
||||
@ -548,7 +569,8 @@ namespace D3dDdi
|
||||
const RECT monitorRect = DDraw::PrimarySurface::getMonitorRect();
|
||||
const bool isLayeredPresentNeeded = Gdi::Window::presentLayered(nullptr, monitorRect);
|
||||
|
||||
if (isPalettized || isCursorEmulated || isLayeredPresentNeeded)
|
||||
if (isPalettized || isCursorEmulated || isLayeredPresentNeeded ||
|
||||
Config::Settings::DisplayFilter::POINT != g_presentationFilter)
|
||||
{
|
||||
const auto& si = srcResource->m_fixedData.pSurfList[0];
|
||||
const auto& dst(SurfaceRepository::get(m_device.getAdapter()).getRenderTarget(si.Width, si.Height));
|
||||
@ -580,9 +602,6 @@ namespace D3dDdi
|
||||
m_device.getOrigVtable().pfnBlt(m_device, &blt);
|
||||
}
|
||||
|
||||
srcResource = dst.resource;
|
||||
data.hSrcResource = *dst.resource;
|
||||
|
||||
if (isLayeredPresentNeeded)
|
||||
{
|
||||
Gdi::Window::presentLayered(dst.surface, monitorRect);
|
||||
@ -591,13 +610,22 @@ namespace D3dDdi
|
||||
if (isCursorEmulated)
|
||||
{
|
||||
POINT pos = { cursorInfo.ptScreenPos.x - monitorRect.left, cursorInfo.ptScreenPos.y - monitorRect.top };
|
||||
m_device.getShaderBlitter().cursorBlt(*srcResource, 0, cursorInfo.hCursor, pos);
|
||||
m_device.getShaderBlitter().cursorBlt(*dst.resource, 0, cursorInfo.hCursor, pos);
|
||||
}
|
||||
|
||||
if (Config::Settings::DisplayFilter::BILINEAR == g_presentationFilter)
|
||||
{
|
||||
m_device.getShaderBlitter().genBilinearBlt(*this, data.DstSubResourceIndex, g_presentationRect,
|
||||
*dst.resource, data.SrcRect, g_presentationFilterParam);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
data.hSrcResource = *dst.resource;
|
||||
}
|
||||
|
||||
data.DstRect = g_presentationRect;
|
||||
data.Flags.Linear = 1;
|
||||
data.Flags.Point = 0;
|
||||
data.Flags.Linear = 0;
|
||||
data.Flags.Point = 1;
|
||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,9 @@
|
||||
#include <D3dDdi/ShaderBlitter.h>
|
||||
#include <D3dDdi/SurfaceRepository.h>
|
||||
#include <Shaders/DrawCursor.h>
|
||||
#include <Shaders/GenBilinear.h>
|
||||
#include <Shaders/PaletteLookup.h>
|
||||
#include <Shaders/TextureSampler.h>
|
||||
|
||||
#define CONCAT_(a, b) a##b
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
@ -16,7 +18,9 @@ namespace D3dDdi
|
||||
ShaderBlitter::ShaderBlitter(Device& device)
|
||||
: m_device(device)
|
||||
, m_psDrawCursor(createPixelShader(g_psDrawCursor))
|
||||
, m_psGenBilinear(createPixelShader(g_psGenBilinear))
|
||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup))
|
||||
, m_psTextureSampler(createPixelShader(g_psTextureSampler))
|
||||
, m_vertexShaderDecl(createVertexShaderDecl())
|
||||
{
|
||||
}
|
||||
@ -55,6 +59,7 @@ namespace D3dDdi
|
||||
SCOPED_STATE(RenderState, { D3DDDIRS_CLIPPLANEENABLE, 0 });
|
||||
SCOPED_STATE(RenderState, { D3DDDIRS_MULTISAMPLEANTIALIAS, FALSE });
|
||||
SCOPED_STATE(RenderState, { D3DDDIRS_COLORWRITEENABLE, 0xF });
|
||||
SCOPED_STATE(RenderState, { D3DDDIRS_SRGBWRITEENABLE, D3DTEXF_LINEAR == filter });
|
||||
|
||||
SCOPED_STATE(Texture, 0, srcResource, filter);
|
||||
|
||||
@ -164,6 +169,33 @@ namespace D3dDdi
|
||||
blt(dstResource, dstSubResourceIndex, clippedDstRect, *cur.tempTexture, clippedSrcRect, m_psDrawCursor, D3DTEXF_POINT);
|
||||
}
|
||||
|
||||
void ShaderBlitter::genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, UINT blurPercent)
|
||||
{
|
||||
if (100 == blurPercent)
|
||||
{
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psTextureSampler, D3DTEXF_LINEAR);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& srcDesc = srcResource.getFixedDesc().pSurfList[0];
|
||||
float scaleX = static_cast<float>(dstRect.right - dstRect.left) / (srcRect.right - srcRect.left);
|
||||
float scaleY = static_cast<float>(dstRect.bottom - dstRect.top) / (srcRect.bottom - srcRect.top);
|
||||
|
||||
const float blur = blurPercent / 100.0f;
|
||||
scaleX = 1 / ((1 - blur) / scaleX + blur);
|
||||
scaleY = 1 / ((1 - blur) / scaleY + blur);
|
||||
|
||||
const DeviceState::ShaderConstF registers[] = {
|
||||
{ static_cast<float>(srcDesc.Width), static_cast<float>(srcDesc.Height), 0.0f, 0.0f },
|
||||
{ scaleX, scaleY, 0.0f, 0.0f }
|
||||
};
|
||||
|
||||
SCOPED_STATE(PixelShaderConst, { 0, sizeof(registers) / sizeof(registers[0]) }, registers);
|
||||
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psGenBilinear, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
||||
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256])
|
||||
{
|
||||
|
@ -17,6 +17,8 @@ namespace D3dDdi
|
||||
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
||||
|
||||
void cursorBlt(const Resource& dstResource, UINT dstSubResourceIndex, HCURSOR cursor, POINT pt);
|
||||
void genBilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
const Resource& srcResource, const RECT& srcRect, UINT blurPercent);
|
||||
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256]);
|
||||
|
||||
@ -35,7 +37,9 @@ namespace D3dDdi
|
||||
|
||||
Device& m_device;
|
||||
HANDLE m_psDrawCursor;
|
||||
HANDLE m_psGenBilinear;
|
||||
HANDLE m_psPaletteLookup;
|
||||
HANDLE m_psTextureSampler;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
};
|
||||
}
|
||||
|
@ -215,6 +215,7 @@
|
||||
<ClInclude Include="Config\Setting.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayFilter.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayResolution.h" />
|
||||
<ClInclude Include="Config\Settings\SupportedResolutions.h" />
|
||||
<ClInclude Include="Config\Settings\ThreadPriorityBoost.h" />
|
||||
@ -320,6 +321,7 @@
|
||||
<ClCompile Include="Config\Parser.cpp" />
|
||||
<ClCompile Include="Config\Setting.cpp" />
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayResolution.cpp" />
|
||||
<ClCompile Include="Config\Settings\SupportedResolutions.cpp" />
|
||||
<ClCompile Include="D3dDdi\Adapter.cpp" />
|
||||
@ -403,7 +405,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="Shaders\DrawCursor.hlsl" />
|
||||
<FxCompile Include="Shaders\GenBilinear.hlsl" />
|
||||
<FxCompile Include="Shaders\PaletteLookup.hlsl" />
|
||||
<FxCompile Include="Shaders\TextureSampler.hlsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -444,6 +444,9 @@
|
||||
<ClInclude Include="Config\Settings\SupportedResolutions.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\DisplayFilter.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -698,6 +701,9 @@
|
||||
<ClCompile Include="Config\Settings\SupportedResolutions.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\DisplayFilter.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
@ -716,5 +722,11 @@
|
||||
<FxCompile Include="Shaders\DrawCursor.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="Shaders\GenBilinear.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="Shaders\TextureSampler.hlsl">
|
||||
<Filter>Shaders</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
12
DDrawCompat/Shaders/GenBilinear.hlsl
Normal file
12
DDrawCompat/Shaders/GenBilinear.hlsl
Normal file
@ -0,0 +1,12 @@
|
||||
sampler2D s_texture : register(s0);
|
||||
float2 g_textureRes : register(c0);
|
||||
float2 g_scaleFactor : register(c1);
|
||||
|
||||
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float2 coord = texCoord * g_textureRes - 0.5f;
|
||||
float2 fracPart = frac(coord);
|
||||
float2 intPart = coord - fracPart;
|
||||
coord = (intPart + saturate(g_scaleFactor * (fracPart - 0.5f) + 0.5f) + 0.5f) / g_textureRes;
|
||||
return tex2D(s_texture, coord);
|
||||
}
|
6
DDrawCompat/Shaders/TextureSampler.hlsl
Normal file
6
DDrawCompat/Shaders/TextureSampler.hlsl
Normal file
@ -0,0 +1,6 @@
|
||||
sampler2D s_texture : register(s0);
|
||||
|
||||
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||
{
|
||||
return tex2D(s_texture, texCoord);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user