fixed
This commit is contained in:
@ -26,6 +26,77 @@
|
||||
#include "../graphics/renderers/GameRenderer.h"
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
|
||||
// Frosted tint helper: draw a safe, inexpensive frosted overlay for the panel area.
|
||||
// This avoids renderer readback / surface APIs which aren't portable across SDL3 builds.
|
||||
static void renderBackdropBlur(SDL_Renderer* renderer, const SDL_Rect& logicalVP, float logicalScale, float panelTop, float panelH, SDL_Texture* sceneTex, int sceneW, int sceneH) {
|
||||
if (!renderer) return;
|
||||
// If we don't have a captured scene texture, fall back to the frosted tint.
|
||||
if (!sceneTex || sceneW <= 0 || sceneH <= 0) {
|
||||
float viewportLogicalW = (float)logicalVP.w / logicalScale;
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 210, 220, 48);
|
||||
SDL_FRect base{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderFillRect(renderer, &base);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 24);
|
||||
SDL_FRect highlight{ 0.0f, panelTop, viewportLogicalW, std::max(2.0f, panelH * 0.06f) };
|
||||
SDL_RenderFillRect(renderer, &highlight);
|
||||
SDL_SetRenderDrawColor(renderer, 16, 24, 32, 12);
|
||||
SDL_FRect shadow{ 0.0f, panelTop + panelH - std::max(2.0f, panelH * 0.06f), viewportLogicalW, std::max(2.0f, panelH * 0.06f) };
|
||||
SDL_RenderFillRect(renderer, &shadow);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute source rect in scene texture pixels for the panel area
|
||||
int panelWinX = 0;
|
||||
int panelWinY = static_cast<int>(std::floor(panelTop * logicalScale + logicalVP.y));
|
||||
int panelWinW = sceneW; // full width of captured scene
|
||||
int panelWinH = static_cast<int>(std::ceil(panelH * logicalScale));
|
||||
if (panelWinW <= 0 || panelWinH <= 0) return;
|
||||
|
||||
// Downsample size (cheap Gaussian-ish blur via scale).
|
||||
int blurW = std::max(8, panelWinW / 6);
|
||||
int blurH = std::max(4, panelWinH / 6);
|
||||
|
||||
// Create a small render target to draw the downsampled region into
|
||||
SDL_Texture* small = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, blurW, blurH);
|
||||
if (!small) {
|
||||
// Fall back to tint if we can't allocate
|
||||
float viewportLogicalW = (float)logicalVP.w / logicalScale;
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 210, 220, 48);
|
||||
SDL_FRect base{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderFillRect(renderer, &base);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Source rectangle in the scene texture (pixel coords) as floats
|
||||
SDL_FRect srcRectF{ (float)panelWinX, (float)panelWinY, (float)panelWinW, (float)panelWinH };
|
||||
|
||||
// Render the sub-region of the scene into the small texture
|
||||
SDL_SetRenderTarget(renderer, small);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
SDL_FRect smallDst{ 0.0f, 0.0f, (float)blurW, (float)blurH };
|
||||
SDL_RenderTexture(renderer, sceneTex, &srcRectF, &smallDst);
|
||||
|
||||
// Reset target
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
|
||||
// Render the small texture scaled up to the panel area with linear filtering
|
||||
SDL_SetTextureBlendMode(small, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureScaleMode(small, SDL_SCALEMODE_LINEAR);
|
||||
|
||||
float viewportLogicalW = (float)logicalVP.w / logicalScale;
|
||||
SDL_FRect dst{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderTexture(renderer, small, nullptr, &dst);
|
||||
|
||||
// Cleanup
|
||||
SDL_DestroyTexture(small);
|
||||
}
|
||||
|
||||
MenuState::MenuState(StateContext& ctx) : State(ctx) {}
|
||||
|
||||
void MenuState::onEnter() {
|
||||
@ -72,6 +143,8 @@ void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale,
|
||||
|
||||
float spacing = isSmall ? btnW * 1.2f : btnW * 1.15f;
|
||||
|
||||
|
||||
|
||||
// Draw semi-transparent background panel behind the full button group (draw first so text sits on top)
|
||||
{
|
||||
float groupCenterX = btnX;
|
||||
@ -81,13 +154,13 @@ void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale,
|
||||
float panelTop = btnY - btnH * 0.5f - 12.0f;
|
||||
float panelH = btnH + 24.0f;
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
// Backdrop blur pass before tint (use captured scene texture if available)
|
||||
renderBackdropBlur(renderer, logicalVP, logicalScale, panelTop, panelH, ctx.sceneTex, ctx.sceneW, ctx.sceneH);
|
||||
// Brighter, less-opaque background to increase contrast
|
||||
SDL_SetRenderDrawColor(renderer, 28, 36, 46, 180);
|
||||
// Fill full-width background so edges are covered in fullscreen
|
||||
float viewportLogicalW = (float)logicalVP.w / logicalScale;
|
||||
float fullLeft = 0.0f;
|
||||
float fullW = viewportLogicalW;
|
||||
SDL_FRect fullPanel{ fullLeft, panelTop, fullW, panelH };
|
||||
SDL_FRect fullPanel{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderFillRect(renderer, &fullPanel);
|
||||
// Also draw the central strip to keep visual center emphasis
|
||||
SDL_FRect panelRect{ panelLeft, panelTop, panelRight - panelLeft, panelH };
|
||||
@ -95,9 +168,7 @@ void MenuState::renderMainButtonTop(SDL_Renderer* renderer, float logicalScale,
|
||||
// brighter full-width border
|
||||
SDL_SetRenderDrawColor(renderer, 120, 140, 160, 200);
|
||||
// Expand border to cover full window width (use actual viewport)
|
||||
float fullLeftTop = 0.0f;
|
||||
float fullWTop = viewportLogicalW;
|
||||
SDL_FRect borderFull{ fullLeftTop, panelTop, fullWTop, panelH };
|
||||
SDL_FRect borderFull{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderRect(renderer, &borderFull);
|
||||
}
|
||||
|
||||
@ -792,13 +863,13 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
float panelTop = btnY - btnH * 0.5f - 12.0f;
|
||||
float panelH = btnH + 24.0f;
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
// Backdrop blur pass before tint (use captured scene texture if available)
|
||||
renderBackdropBlur(renderer, logicalVP, logicalScale, panelTop, panelH, ctx.sceneTex, ctx.sceneW, ctx.sceneH);
|
||||
// Brighter, less-opaque background to increase contrast (match top path)
|
||||
SDL_SetRenderDrawColor(renderer, 28, 36, 46, 180);
|
||||
// Fill full-width background so edges are covered in fullscreen
|
||||
float viewportLogicalW = (float)logicalVP.w / logicalScale;
|
||||
float fullLeft = 0.0f;
|
||||
float fullW = viewportLogicalW;
|
||||
SDL_FRect fullPanel{ fullLeft, panelTop, fullW, panelH };
|
||||
SDL_FRect fullPanel{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderFillRect(renderer, &fullPanel);
|
||||
// Also draw the central strip to keep visual center emphasis
|
||||
SDL_FRect panelRect{ panelLeft, panelTop, panelRight - panelLeft, panelH };
|
||||
@ -806,9 +877,7 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
// subtle border across full logical width
|
||||
SDL_SetRenderDrawColor(renderer, 120, 140, 160, 200);
|
||||
// Expand border to cover full window width (use actual viewport)
|
||||
float fullLeftNormal = 0.0f;
|
||||
float fullWNormal = viewportLogicalW;
|
||||
SDL_FRect borderFull{ fullLeftNormal, panelTop, fullWNormal, panelH };
|
||||
SDL_FRect borderFull{ 0.0f, panelTop, viewportLogicalW, panelH };
|
||||
SDL_RenderRect(renderer, &borderFull);
|
||||
}
|
||||
// Button 0 - PLAY
|
||||
@ -1048,7 +1117,9 @@ void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logi
|
||||
SDL_FRect rc{ area.x + c * (cellW + gapX), area.y + r * (cellH + gapY), cellW, cellH };
|
||||
bool hovered = (levelSelected == i) || (levelHovered == i);
|
||||
bool selected = (ctx.startLevelSelection && *ctx.startLevelSelection == i);
|
||||
SDL_Color fill = selected ? SDL_Color{255,140,40,160} : (hovered ? SDL_Color{60,80,100,120} : SDL_Color{30,40,60,110});
|
||||
// Use the project's gold/yellow tone for selected level to match UI accents
|
||||
SDL_Color selectedFill = SDL_Color{255,204,0,160};
|
||||
SDL_Color fill = selected ? selectedFill : (hovered ? SDL_Color{60,80,100,120} : SDL_Color{30,40,60,110});
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, fill.r, fill.g, fill.b, fill.a);
|
||||
SDL_RenderFillRect(renderer, &rc);
|
||||
|
||||
Reference in New Issue
Block a user