Enhance video texture handling and add release build configurations
This commit is contained in:
125
src/effect.cpp
125
src/effect.cpp
@@ -13,6 +13,106 @@
|
||||
|
||||
GLuint Effect::g_dummyVAO = 0;
|
||||
|
||||
static std::string shaderHeader = R"(#version 460 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 vUV;
|
||||
in vec2 vPosition;
|
||||
|
||||
uniform float uTime;
|
||||
uniform vec4 uMouse;
|
||||
uniform vec2 uDesktopSize;
|
||||
uniform vec4 uDisplay[16]; // support up to 16 displays, more can be added if needed
|
||||
uniform vec4 uDisplayNorm[16]; // pre-normalized display rects for convenience
|
||||
uniform int uNumDisplays;
|
||||
|
||||
#define MAX_DISPLAYS 16
|
||||
|
||||
// Background modes
|
||||
#define BG_FIT_WIDTH 0
|
||||
#define BG_FIT_HEIGHT 1
|
||||
#define BG_COVER 2
|
||||
#define BG_STRETCH 3
|
||||
#define BG_CONTAIN 4
|
||||
#define BG_TILE 5
|
||||
|
||||
vec2 GetDisplayUV(sampler2D tex, int displayIndex, int mode) {
|
||||
vec2 inUV = vec2(0.0);
|
||||
|
||||
if (displayIndex < 0 || displayIndex >= uNumDisplays) {
|
||||
// Entire desktop as fallback
|
||||
inUV = vUV;
|
||||
} else {
|
||||
// Map global UV to display-local [0,1]
|
||||
inUV = (vUV - uDisplayNorm[displayIndex].xy) / uDisplayNorm[displayIndex].zw;
|
||||
}
|
||||
|
||||
vec2 uv = inUV;
|
||||
|
||||
if (mode == BG_STRETCH) {
|
||||
// No adjustment needed
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec4 display = uDisplay[displayIndex];
|
||||
float displayRatio = display.z / display.w;
|
||||
|
||||
vec2 texSize = vec2(textureSize(tex, 0));
|
||||
float textureRatio = texSize.x / texSize.y;
|
||||
|
||||
if (mode == BG_COVER) {
|
||||
if (displayRatio > textureRatio) {
|
||||
// Display wider: crop top/bottom
|
||||
float scale = textureRatio / displayRatio;
|
||||
uv.y = uv.y * scale + (1.0 - scale) * 0.5;
|
||||
} else {
|
||||
// Display taller: crop left/right
|
||||
float scale = displayRatio / textureRatio;
|
||||
uv.x = uv.x * scale + (1.0 - scale) * 0.5;
|
||||
}
|
||||
} else if (mode == BG_CONTAIN) {
|
||||
if (displayRatio > textureRatio) {
|
||||
// Display wider: pillarbox left/right
|
||||
float scale = displayRatio / textureRatio;
|
||||
uv.x = uv.x * scale + (1.0 - scale) * 0.5;
|
||||
} else {
|
||||
// Display taller: letterbox top/bottom
|
||||
float scale = textureRatio / displayRatio;
|
||||
uv.y = uv.y * scale + (1.0 - scale) * 0.5;
|
||||
}
|
||||
} else if (mode == BG_FIT_WIDTH) {
|
||||
// Scale to match display width, adjust Y
|
||||
float scale = textureRatio / displayRatio;
|
||||
uv.y = uv.y * scale + (1.0 - scale) * 0.5;
|
||||
} else if (mode == BG_FIT_HEIGHT) {
|
||||
// Scale to match display height, adjust X
|
||||
float scale = displayRatio / textureRatio;
|
||||
uv.x = uv.x * scale + (1.0 - scale) * 0.5;
|
||||
} else if (mode == BG_TILE) {
|
||||
// Tile at native texture resolution
|
||||
uv = uv * display.zw / texSize;
|
||||
}
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
// Default mode = BG_COVER
|
||||
vec2 GetDisplayUV(sampler2D tex, int displayIndex) {
|
||||
return GetDisplayUV(tex, displayIndex, BG_COVER);
|
||||
}
|
||||
|
||||
vec2 GetFullUV(sampler2D tex) {
|
||||
return GetDisplayUV(tex, -1, BG_COVER);
|
||||
}
|
||||
|
||||
vec2 GetFullUV(sampler2D tex, int mode) {
|
||||
return GetDisplayUV(tex, -1, mode);
|
||||
}
|
||||
|
||||
#line 1
|
||||
)";
|
||||
|
||||
static std::vector<std::string> SplitLines(const std::string& str) {
|
||||
std::vector<std::string> lines;
|
||||
size_t start = 0, end = 0;
|
||||
@@ -32,27 +132,13 @@ Effect::Effect(const std::string& fragmentShaderSource)
|
||||
#include "fx_vertex.glsl.h"
|
||||
;
|
||||
|
||||
std::string code =
|
||||
"#version 460 core\n\n"
|
||||
"out vec4 FragColor;\n\n"
|
||||
"uniform float uTime;\n"
|
||||
"uniform vec4 uMouse;\n"
|
||||
"uniform vec2 uDesktopSize;\n";
|
||||
|
||||
for (size_t i = 0; i < g_Displays.size(); i++) {
|
||||
code += "uniform vec4 uDisplay" + std::to_string(i) + ";\n";
|
||||
}
|
||||
|
||||
// reset line number
|
||||
code += "#line 1\n";
|
||||
|
||||
GLuint vertexShader = CreateShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
if (!vertexShader) {
|
||||
throw std::runtime_error("Failed to compile vertex shader");
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint fragmentShader = CreateShader(code + fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
GLuint fragmentShader = CreateShader(shaderHeader + fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
if (!fragmentShader) {
|
||||
glDeleteShader(vertexShader);
|
||||
throw std::runtime_error("Failed to compile fragment shader");
|
||||
@@ -122,6 +208,11 @@ void Effect::SetTexture(const std::string &name, const Texture& texture, size_t
|
||||
glUniform1i(GetUniformLocation(name), static_cast<GLint>(textureUnit));
|
||||
}
|
||||
|
||||
void Effect::SetInt(const std::string &name, int value)
|
||||
{
|
||||
glUniform1i(GetUniformLocation(name), value);
|
||||
}
|
||||
|
||||
void Effect::SetFloat(const std::string &name, float value)
|
||||
{
|
||||
glUniform1f(GetUniformLocation(name), value);
|
||||
@@ -156,8 +247,10 @@ void Effect::Render()
|
||||
SetVector4("uMouse", g_Mouse);
|
||||
SetVector2("uDesktopSize", g_DesktopSize);
|
||||
for (size_t i = 0; i < g_Displays.size(); i++) {
|
||||
SetVector4("uDisplay" + std::to_string(i), g_Displays[i]);
|
||||
SetVector4("uDisplay[" + std::to_string(i) + "]", g_Displays[i]);
|
||||
SetVector4("uDisplayNorm[" + std::to_string(i) + "]", g_Displays[i] / Vector4(g_DesktopSize, g_DesktopSize));
|
||||
}
|
||||
SetInt("uNumDisplays", static_cast<int>(g_Displays.size()));
|
||||
|
||||
glBindVertexArray(g_dummyVAO);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
Reference in New Issue
Block a user