Added screen
This commit is contained in:
112
src/display/screen.c
Normal file
112
src/display/screen.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "screen.h"
|
||||
#include "assert/assert.h"
|
||||
#include "display/spritebatch/spritebatch.h"
|
||||
|
||||
screen_t SCREEN;
|
||||
|
||||
void screenInit(void) {
|
||||
// Virtual backbuffer for dynamic resolution scaling
|
||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||
frameBufferInit(&SCREEN.frameBuffer, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||
cameraInit(&SCREEN.frameBufferCamera);
|
||||
SCREEN.frameBufferCamera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC;
|
||||
SCREEN.frameBufferCamera.viewType = CAMERA_VIEW_TYPE_MATRIX;
|
||||
glm_lookat(
|
||||
(vec3){0.0f, 0.0f, 1.0f},
|
||||
(vec3){0.0f, 0.0f, 0.0f},
|
||||
(vec3){0.0f, 1.0f, 0.0f},
|
||||
SCREEN.frameBufferCamera.view
|
||||
);
|
||||
SCREEN.frameBufferCamera.nearClip = -1.0f;
|
||||
SCREEN.frameBufferCamera.farClip = 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void screenBind(void) {
|
||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||
frameBufferBind(&SCREEN.frameBuffer);
|
||||
#else
|
||||
frameBufferBind(NULL);
|
||||
#endif
|
||||
|
||||
frameBufferClear(
|
||||
FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH,
|
||||
COLOR_CORNFLOWER_BLUE
|
||||
);
|
||||
}
|
||||
|
||||
void screenUnbindAndRender(void) {
|
||||
assertTrue(SPRITEBATCH.spriteCount == 0, "Sprite batch not flushed");
|
||||
|
||||
// Render to real backbuffer
|
||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||
frameBufferBind(NULL);
|
||||
frameBufferClear(
|
||||
FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH,
|
||||
COLOR_BLACK
|
||||
);
|
||||
|
||||
|
||||
SCREEN.frameBufferCamera.orthographic.left = 0;
|
||||
SCREEN.frameBufferCamera.orthographic.right = frameBufferGetWidth(
|
||||
FRAMEBUFFER_BOUND
|
||||
);
|
||||
SCREEN.frameBufferCamera.orthographic.bottom = frameBufferGetHeight(
|
||||
FRAMEBUFFER_BOUND
|
||||
);
|
||||
SCREEN.frameBufferCamera.orthographic.top = 0;
|
||||
cameraPushMatrix(&SCREEN.frameBufferCamera);
|
||||
|
||||
vec2 backbuffer = {
|
||||
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND),
|
||||
(float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND)
|
||||
};
|
||||
vec2 virtual = {
|
||||
(float_t)frameBufferGetWidth(&SCREEN.frameBuffer),
|
||||
(float_t)frameBufferGetHeight(&SCREEN.frameBuffer)
|
||||
};
|
||||
|
||||
// Compare aspect ratios.
|
||||
vec4 viewport;
|
||||
float_t backbufferAspect = backbuffer[0] / backbuffer[1];
|
||||
float_t virtualAspect = virtual[0] / virtual[1];
|
||||
if (backbufferAspect > virtualAspect) {
|
||||
// Backbuffer is wider: pillarbox
|
||||
float_t scale = backbuffer[1] / virtual[1];
|
||||
float_t width = virtual[0] * scale;
|
||||
viewport[0] = (backbuffer[0] - width) * 0.5f;
|
||||
viewport[1] = 0;
|
||||
viewport[2] = width;
|
||||
viewport[3] = backbuffer[1];
|
||||
} else {
|
||||
// Backbuffer is taller: letterbox
|
||||
float_t scale = backbuffer[0] / virtual[0];
|
||||
float_t height = virtual[1] * scale;
|
||||
viewport[0] = 0;
|
||||
viewport[1] = (backbuffer[1] - height) * 0.5f;
|
||||
viewport[2] = backbuffer[0];
|
||||
viewport[3] = height;
|
||||
}
|
||||
|
||||
spriteBatchPush(
|
||||
&SCREEN.frameBuffer.texture,
|
||||
viewport[0], viewport[1],
|
||||
viewport[0] + viewport[2], viewport[1] + viewport[3],
|
||||
COLOR_WHITE,
|
||||
0.0f, 1.0f, 1.0f, 0.0f
|
||||
);
|
||||
spriteBatchFlush();
|
||||
cameraPopMatrix();
|
||||
#endif
|
||||
}
|
||||
|
||||
void screenDispose(void) {
|
||||
frameBufferDispose(&SCREEN.frameBuffer);
|
||||
}
|
Reference in New Issue
Block a user