mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-05-09 09:25:42 -04:00
221 lines
7.5 KiB
HLSL
221 lines
7.5 KiB
HLSL
#ifndef _CONTENT_BOX_H
|
|
#define _CONTENT_BOX_H
|
|
|
|
///////////////////////////////// MIT LICENSE ////////////////////////////////
|
|
|
|
// Copyright (C) 2020 Alex Gunter
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
|
|
|
|
#include "shared-objects.fxh"
|
|
|
|
|
|
void contentCropVS(
|
|
in uint id : SV_VertexID,
|
|
|
|
out float4 position : SV_Position,
|
|
out float2 texcoord : TEXCOORD0
|
|
) {
|
|
#if _DX9_ACTIVE
|
|
texcoord.x = (id == 1 || id == 3) ? content_right : content_left;
|
|
texcoord.y = (id > 1) ? content_lower : content_upper;
|
|
|
|
position.x = (id == 1 || id == 3) ? 1 : -1;
|
|
position.y = (id > 1) ? -1 : 1;
|
|
position.zw = 1;
|
|
#else
|
|
texcoord.x = (id & 1) ? content_right : content_left;
|
|
texcoord.y = (id & 2) ? content_lower : content_upper;
|
|
|
|
position.x = (id & 1) ? 1 : -1;
|
|
position.y = (id & 2) ? -1 : 1;
|
|
position.zw = 1;
|
|
#endif
|
|
}
|
|
|
|
#if USE_VERTEX_UNCROPPING
|
|
/*
|
|
* Using the vertex shader for uncropping can save about 0.1ms in some apps.
|
|
* However, some apps like SNES9X w/ DX9 don't trigger a refresh of the entire screen,
|
|
* which in turn causes the ReShade UI to "stick around" after it's closed.
|
|
*
|
|
* The slower algorithm forces the entire screen to refresh, which forces the
|
|
* area outside the content box to be black. I assume most users will prefer
|
|
* the results of the slower algorithm and won't notice the 0.1ms. Users who
|
|
* need that 0.1ms can use a preprocessor def to recover that time.
|
|
*/
|
|
void contentUncropVS(
|
|
in uint id : SV_VertexID,
|
|
|
|
out float4 position : SV_Position,
|
|
out float2 texcoord : TEXCOORD0
|
|
) {
|
|
#if _DX9_ACTIVE
|
|
texcoord.x = id == 1 || id == 3;
|
|
texcoord.y = id < 2;
|
|
|
|
position.x = (id == 1 || id == 3) ? content_scale.x : -content_scale.x;
|
|
position.y = (id > 1) ? content_scale.y : -content_scale.y;
|
|
position.zw = 1;
|
|
#else
|
|
texcoord.x = id & 1;
|
|
texcoord.y = !(id & 2);
|
|
|
|
position.x = (id & 1) ? content_scale.x : -content_scale.x;
|
|
position.y = (id & 2) ? content_scale.y : -content_scale.y;
|
|
position.zw = 1;
|
|
#endif
|
|
}
|
|
|
|
void uncropContentPixelShader(
|
|
in float4 pos : SV_Position,
|
|
in float2 texcoord : TEXCOORD0,
|
|
|
|
out float4 color : SV_Target
|
|
) {
|
|
color = tex2D(samplerGeometry, texcoord);
|
|
}
|
|
#else
|
|
void contentUncropVS(
|
|
in uint id : SV_VertexID,
|
|
|
|
out float4 position : SV_Position,
|
|
out float2 texcoord : TEXCOORD0
|
|
) {
|
|
// TODO: There's probably a better way to code this.
|
|
// I'll figure it out later.
|
|
#if _DX9_ACTIVE
|
|
texcoord.x = id == 1 || id == 3;
|
|
texcoord.y = id < 2;
|
|
|
|
position.x = (id == 1 || id == 3) ? 1 : -1;
|
|
position.y = (id > 1) ? 1 : -1;
|
|
position.zw = 1;
|
|
#else
|
|
texcoord.x = id & 1;
|
|
texcoord.y = !(id & 2);
|
|
|
|
position.x = (id & 1) ? 1 : -1;
|
|
position.y = (id & 2) ? 1 : -1;
|
|
position.zw = 1;
|
|
#endif
|
|
}
|
|
|
|
void uncropContentPixelShader(
|
|
in float4 pos : SV_Position,
|
|
in float2 texcoord : TEXCOORD0,
|
|
|
|
out float4 color : SV_Target
|
|
) {
|
|
const bool is_in_boundary = float(
|
|
texcoord.x >= content_left && texcoord.x <= content_right &&
|
|
texcoord.y >= content_upper && texcoord.y <= content_lower
|
|
);
|
|
const float2 texcoord_uncropped = ((texcoord - content_offset) * buffer_size + 0) / content_size;
|
|
|
|
const float4 raw_color = tex2D(samplerGeometry, texcoord_uncropped);
|
|
color = float4(is_in_boundary * raw_color.rgb, raw_color.a);
|
|
}
|
|
#endif
|
|
|
|
|
|
#if CONTENT_BOX_VISIBLE
|
|
#ifndef CONTENT_BOX_INSCRIBED
|
|
#define CONTENT_BOX_INSCRIBED 1
|
|
#endif
|
|
|
|
#ifndef CONTENT_BOX_THICKNESS
|
|
#define CONTENT_BOX_THICKNESS 5
|
|
#endif
|
|
|
|
#ifndef CONTENT_BOX_COLOR_R
|
|
#define CONTENT_BOX_COLOR_R 1.0
|
|
#endif
|
|
|
|
#ifndef CONTENT_BOX_COLOR_G
|
|
#define CONTENT_BOX_COLOR_G 0.0
|
|
#endif
|
|
|
|
#ifndef CONTENT_BOX_COLOR_B
|
|
#define CONTENT_BOX_COLOR_B 0.0
|
|
#endif
|
|
|
|
static const float vert_line_thickness = float(CONTENT_BOX_THICKNESS) / BUFFER_WIDTH;
|
|
static const float horiz_line_thickness = float(CONTENT_BOX_THICKNESS) / BUFFER_HEIGHT;
|
|
|
|
#if CONTENT_BOX_INSCRIBED
|
|
// Set the outer borders to the edge of the content
|
|
static const float left_line_1 = content_left;
|
|
static const float left_line_2 = left_line_1 + vert_line_thickness;
|
|
static const float right_line_2 = content_right;
|
|
static const float right_line_1 = right_line_2 - vert_line_thickness;
|
|
|
|
static const float upper_line_1 = content_upper;
|
|
static const float upper_line_2 = upper_line_1 + horiz_line_thickness;
|
|
static const float lower_line_2 = content_lower;
|
|
static const float lower_line_1 = lower_line_2 - horiz_line_thickness;
|
|
#else
|
|
// Set the inner borders to the edge of the content
|
|
static const float left_line_2 = content_left;
|
|
static const float left_line_1 = left_line_2 - vert_line_thickness;
|
|
static const float right_line_1 = content_right;
|
|
static const float right_line_2 = right_line_1 + vert_line_thickness;
|
|
|
|
static const float upper_line_2 = content_upper;
|
|
static const float upper_line_1 = upper_line_2 - horiz_line_thickness;
|
|
static const float lower_line_1 = content_lower;
|
|
static const float lower_line_2 = lower_line_1 + horiz_line_thickness;
|
|
#endif
|
|
|
|
|
|
static const float4 box_color = float4(
|
|
CONTENT_BOX_COLOR_R,
|
|
CONTENT_BOX_COLOR_G,
|
|
CONTENT_BOX_COLOR_B,
|
|
1.0
|
|
);
|
|
|
|
void contentBoxPixelShader(
|
|
in float4 pos : SV_Position,
|
|
in float2 texcoord : TEXCOORD0,
|
|
|
|
out float4 color : SV_Target
|
|
) {
|
|
|
|
const bool is_inside_outerbound = (
|
|
texcoord.x >= left_line_1 && texcoord.x <= right_line_2 &&
|
|
texcoord.y >= upper_line_1 && texcoord.y <= lower_line_2
|
|
);
|
|
const bool is_outside_innerbound = (
|
|
texcoord.x <= left_line_2 || texcoord.x >= right_line_1 ||
|
|
texcoord.y <= upper_line_2 || texcoord.y >= lower_line_1
|
|
);
|
|
|
|
if (is_inside_outerbound && is_outside_innerbound) {
|
|
color = box_color;
|
|
}
|
|
else {
|
|
color = tex2D(ReShade::BackBuffer, texcoord);
|
|
}
|
|
}
|
|
|
|
|
|
#endif // CONTENT_BOX_VISIBLE
|
|
#endif // _CONTENT_BOX_H |