gfx: add an option to render using framebuffers (#974)

Resolves #114.
This commit is contained in:
Marcin Kurczewski 2023-09-10 17:26:09 +02:00 committed by GitHub
parent a4d1baae9d
commit 60323acf05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 587 additions and 149 deletions

View file

@ -1,4 +1,5 @@
## [Unreleased](https://github.com/rr-/Tomb1Main/compare/stable...develop) - ××××-××-×× ## [Unreleased](https://github.com/rr-/Tomb1Main/compare/stable...develop) - ××××-××-××
- added a new rendering mode called "framebuffer" that lets the game to run at lower resolutions (#114)
- added the current music track and timestamp to the savegame so they now persist on load (#419) - added the current music track and timestamp to the savegame so they now persist on load (#419)
- added the triggered music tracks to the savegame so one shot tracks don't replay on load (#371) - added the triggered music tracks to the savegame so one shot tracks don't replay on load (#371)
- added forward/backward input detection in line with TR2+ for jump-twists (#931) - added forward/backward input detection in line with TR2+ for jump-twists (#931)

View file

@ -637,7 +637,11 @@
"DETAIL_BRIGHTNESS": "Brightness", "DETAIL_BRIGHTNESS": "Brightness",
"DETAIL_UI_TEXT_SCALE": "UI text scale", "DETAIL_UI_TEXT_SCALE": "UI text scale",
"DETAIL_UI_BAR_SCALE": "UI bar scale", "DETAIL_UI_BAR_SCALE": "UI bar scale",
"DETAIL_RENDER_MODE": "Render mode",
"DETAIL_RENDER_MODE_LEGACY": "Window size",
"DETAIL_RENDER_MODE_FBO": "Framebuffer",
"DETAIL_RESOLUTION": "Resolution", "DETAIL_RESOLUTION": "Resolution",
"DETAIL_STRING_FMT": "%s",
"DETAIL_FLOAT_FMT": "%.1f", "DETAIL_FLOAT_FMT": "%.1f",
"DETAIL_RESOLUTION_FMT": "%dx%d", "DETAIL_RESOLUTION_FMT": "%dx%d",
"SOUND_SET_VOLUMES": "Set Volumes", "SOUND_SET_VOLUMES": "Set Volumes",

View file

@ -175,7 +175,11 @@
"DETAIL_BRIGHTNESS": "Brightness", "DETAIL_BRIGHTNESS": "Brightness",
"DETAIL_UI_TEXT_SCALE": "UI text scale", "DETAIL_UI_TEXT_SCALE": "UI text scale",
"DETAIL_UI_BAR_SCALE": "UI bar scale", "DETAIL_UI_BAR_SCALE": "UI bar scale",
"DETAIL_RENDER_MODE": "Render mode",
"DETAIL_RENDER_MODE_LEGACY": "Window size",
"DETAIL_RENDER_MODE_FBO": "Framebuffer",
"DETAIL_RESOLUTION": "Resolution", "DETAIL_RESOLUTION": "Resolution",
"DETAIL_STRING_FMT": "%s",
"DETAIL_FLOAT_FMT": "%.1f", "DETAIL_FLOAT_FMT": "%.1f",
"DETAIL_RESOLUTION_FMT": "%dx%d", "DETAIL_RESOLUTION_FMT": "%dx%d",
"SOUND_SET_VOLUMES": "Set Volumes", "SOUND_SET_VOLUMES": "Set Volumes",

9
bin/shaders/fbo.fsh Normal file
View file

@ -0,0 +1,9 @@
#version 120
varying vec2 vertTexCoords;
uniform sampler2D tex0;
void main(void) {
gl_FragColor = texture2D(tex0, vertTexCoords);
}

11
bin/shaders/fbo.vsh Normal file
View file

@ -0,0 +1,11 @@
#version 120
#extension GL_ARB_explicit_attrib_location: enable
layout(location = 0) in vec2 inPosition;
varying vec2 vertTexCoords;
void main(void) {
vertTexCoords = inPosition;
gl_Position = vec4(vertTexCoords * vec2(2.0, 2.0) + vec2(-1.0, -1.0), 0.0, 1.0);
}

View file

@ -223,6 +223,7 @@ sources = [
'src/game/stats.c', 'src/game/stats.c',
'src/game/text.c', 'src/game/text.c',
'src/game/viewport.c', 'src/game/viewport.c',
'src/gfx/fbo/fbo_renderer.c',
'src/gfx/2d/2d_renderer.c', 'src/gfx/2d/2d_renderer.c',
'src/gfx/2d/2d_surface.c', 'src/gfx/2d/2d_surface.c',
'src/gfx/3d/3d_renderer.c', 'src/gfx/3d/3d_renderer.c',

View file

@ -4,7 +4,6 @@
#include "game/input.h" #include "game/input.h"
#include "game/music.h" #include "game/music.h"
#include "game/sound.h" #include "game/sound.h"
#include "gfx/context.h"
#include "global/const.h" #include "global/const.h"
#include "global/types.h" #include "global/types.h"
#include "json/json_base.h" #include "json/json_base.h"
@ -243,6 +242,7 @@ bool Config_ReadFromJSON(const char *cfg_data)
CLAMP(g_Config.camera_speed, 1, 10); CLAMP(g_Config.camera_speed, 1, 10);
// User settings // User settings
READ_INTEGER(rendering.render_mode, GFX_RM_LEGACY);
READ_BOOL(rendering.enable_bilinear_filter, true); READ_BOOL(rendering.enable_bilinear_filter, true);
READ_BOOL(rendering.enable_perspective_filter, true); READ_BOOL(rendering.enable_perspective_filter, true);
READ_BOOL(rendering.enable_vsync, true); READ_BOOL(rendering.enable_vsync, true);
@ -431,6 +431,7 @@ bool Config_Write(void)
WRITE_BOOL(enable_save_crystals); WRITE_BOOL(enable_save_crystals);
// User settings // User settings
WRITE_INTEGER(rendering.render_mode);
WRITE_BOOL(rendering.enable_bilinear_filter); WRITE_BOOL(rendering.enable_bilinear_filter);
WRITE_BOOL(rendering.enable_perspective_filter); WRITE_BOOL(rendering.enable_perspective_filter);
WRITE_BOOL(rendering.enable_vsync); WRITE_BOOL(rendering.enable_vsync);

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "gfx/context.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -124,6 +126,7 @@ typedef struct {
} input; } input;
struct { struct {
GFX_RENDER_MODE render_mode;
bool enable_perspective_filter; bool enable_perspective_filter;
bool enable_bilinear_filter; bool enable_bilinear_filter;
bool enable_vsync; bool enable_vsync;

View file

@ -78,7 +78,11 @@ static GAME_STRING_ID GameFlow_StringToGameStringID(const char *str)
{ "DETAIL_BRIGHTNESS", GS_DETAIL_BRIGHTNESS }, { "DETAIL_BRIGHTNESS", GS_DETAIL_BRIGHTNESS },
{ "DETAIL_UI_TEXT_SCALE", GS_DETAIL_UI_TEXT_SCALE }, { "DETAIL_UI_TEXT_SCALE", GS_DETAIL_UI_TEXT_SCALE },
{ "DETAIL_UI_BAR_SCALE", GS_DETAIL_UI_BAR_SCALE }, { "DETAIL_UI_BAR_SCALE", GS_DETAIL_UI_BAR_SCALE },
{ "DETAIL_RENDER_MODE", GS_DETAIL_RENDER_MODE },
{ "DETAIL_RENDER_MODE_LEGACY", GS_DETAIL_RENDER_MODE_LEGACY },
{ "DETAIL_RENDER_MODE_FBO", GS_DETAIL_RENDER_MODE_FBO },
{ "DETAIL_RESOLUTION", GS_DETAIL_RESOLUTION }, { "DETAIL_RESOLUTION", GS_DETAIL_RESOLUTION },
{ "DETAIL_STRING_FMT", GS_DETAIL_STRING_FMT },
{ "DETAIL_FLOAT_FMT", GS_DETAIL_FLOAT_FMT }, { "DETAIL_FLOAT_FMT", GS_DETAIL_FLOAT_FMT },
{ "DETAIL_RESOLUTION_FMT", GS_DETAIL_RESOLUTION_FMT }, { "DETAIL_RESOLUTION_FMT", GS_DETAIL_RESOLUTION_FMT },
{ "SOUND_SET_VOLUMES", GS_SOUND_SET_VOLUMES }, { "SOUND_SET_VOLUMES", GS_SOUND_SET_VOLUMES },

View file

@ -783,7 +783,7 @@ bool Level_Initialise(int32_t level_num)
level_num == g_GameFlow.title_level_num level_num == g_GameFlow.title_level_num
? g_GameFlow.main_menu_background_path ? g_GameFlow.main_menu_background_path
: NULL); : NULL);
Output_ApplyResolution(); Output_ApplyRenderSettings();
if (!Level_Load(g_CurrentLevel)) { if (!Level_Load(g_CurrentLevel)) {
return false; return false;

View file

@ -3,6 +3,7 @@
#include "config.h" #include "config.h"
#include "game/gameflow.h" #include "game/gameflow.h"
#include "game/input.h" #include "game/input.h"
#include "game/output.h"
#include "game/screen.h" #include "game/screen.h"
#include "game/text.h" #include "game/text.h"
#include "gfx/context.h" #include "gfx/context.h"
@ -23,26 +24,28 @@
#define RIGHT_ARROW_OFFSET 35 #define RIGHT_ARROW_OFFSET 35
typedef enum GRAPHICS_TEXT { typedef enum GRAPHICS_TEXT {
TEXT_PERSPECTIVE = 0, TEXT_PERSPECTIVE,
TEXT_BILINEAR = 1, TEXT_BILINEAR,
TEXT_VSYNC = 2, TEXT_VSYNC,
TEXT_BRIGHTNESS = 3, TEXT_BRIGHTNESS,
TEXT_UI_TEXT_SCALE = 4, TEXT_UI_TEXT_SCALE,
TEXT_UI_BAR_SCALE = 5, TEXT_UI_BAR_SCALE,
TEXT_RESOLUTION = 6, TEXT_RENDER_MODE,
TEXT_TITLE = 7, TEXT_RESOLUTION,
TEXT_TITLE_BORDER = 8, TEXT_TITLE,
TEXT_PERSPECTIVE_TOGGLE = 9, TEXT_TITLE_BORDER,
TEXT_BILINEAR_TOGGLE = 10, TEXT_PERSPECTIVE_TOGGLE,
TEXT_VSYNC_TOGGLE = 11, TEXT_BILINEAR_TOGGLE,
TEXT_BRIGHTNESS_TOGGLE = 12, TEXT_VSYNC_TOGGLE,
TEXT_UI_TEXT_SCALE_TOGGLE = 13, TEXT_BRIGHTNESS_TOGGLE,
TEXT_UI_BAR_SCALE_TOGGLE = 14, TEXT_UI_TEXT_SCALE_TOGGLE,
TEXT_RESOLUTION_TOGGLE = 15, TEXT_UI_BAR_SCALE_TOGGLE,
TEXT_LEFT_ARROW = 16, TEXT_RENDER_MODE_VALUE,
TEXT_RIGHT_ARROW = 17, TEXT_RESOLUTION_TOGGLE,
TEXT_ROW_SELECT = 18, TEXT_LEFT_ARROW,
TEXT_NUMBER_OF = 19, TEXT_RIGHT_ARROW,
TEXT_ROW_SELECT,
TEXT_NUMBER_OF,
TEXT_EMPTY_ENTRY = -1, TEXT_EMPTY_ENTRY = -1,
TEXT_OPTION_MIN = TEXT_PERSPECTIVE, TEXT_OPTION_MIN = TEXT_PERSPECTIVE,
TEXT_OPTION_MAX = TEXT_RESOLUTION, TEXT_OPTION_MAX = TEXT_RESOLUTION,
@ -62,6 +65,7 @@ static const TEXT_COLUMN_PLACEMENT m_GfxTextPlacement[] = {
{ TEXT_BRIGHTNESS, 0, GS_DETAIL_BRIGHTNESS }, { TEXT_BRIGHTNESS, 0, GS_DETAIL_BRIGHTNESS },
{ TEXT_UI_TEXT_SCALE, 0, GS_DETAIL_UI_TEXT_SCALE }, { TEXT_UI_TEXT_SCALE, 0, GS_DETAIL_UI_TEXT_SCALE },
{ TEXT_UI_BAR_SCALE, 0, GS_DETAIL_UI_BAR_SCALE }, { TEXT_UI_BAR_SCALE, 0, GS_DETAIL_UI_BAR_SCALE },
{ TEXT_RENDER_MODE, 0, GS_DETAIL_RENDER_MODE },
{ TEXT_RESOLUTION, 0, GS_DETAIL_RESOLUTION }, { TEXT_RESOLUTION, 0, GS_DETAIL_RESOLUTION },
// right column // right column
{ TEXT_PERSPECTIVE_TOGGLE, 1, GS_MISC_ON }, { TEXT_PERSPECTIVE_TOGGLE, 1, GS_MISC_ON },
@ -70,6 +74,7 @@ static const TEXT_COLUMN_PLACEMENT m_GfxTextPlacement[] = {
{ TEXT_BRIGHTNESS_TOGGLE, 1, GS_DETAIL_FLOAT_FMT }, { TEXT_BRIGHTNESS_TOGGLE, 1, GS_DETAIL_FLOAT_FMT },
{ TEXT_UI_TEXT_SCALE_TOGGLE, 1, GS_DETAIL_FLOAT_FMT }, { TEXT_UI_TEXT_SCALE_TOGGLE, 1, GS_DETAIL_FLOAT_FMT },
{ TEXT_UI_BAR_SCALE_TOGGLE, 1, GS_DETAIL_FLOAT_FMT }, { TEXT_UI_BAR_SCALE_TOGGLE, 1, GS_DETAIL_FLOAT_FMT },
{ TEXT_RENDER_MODE_VALUE, 1, GS_DETAIL_STRING_FMT },
{ TEXT_RESOLUTION_TOGGLE, 1, GS_DETAIL_RESOLUTION_FMT }, { TEXT_RESOLUTION_TOGGLE, 1, GS_DETAIL_RESOLUTION_FMT },
// end // end
{ TEXT_EMPTY_ENTRY, -1, -1 }, { TEXT_EMPTY_ENTRY, -1, -1 },
@ -144,6 +149,7 @@ static void Option_GraphicsInitText(void)
Option_GraphicsChangeTextOption(TEXT_BRIGHTNESS); Option_GraphicsChangeTextOption(TEXT_BRIGHTNESS);
Option_GraphicsChangeTextOption(TEXT_UI_TEXT_SCALE); Option_GraphicsChangeTextOption(TEXT_UI_TEXT_SCALE);
Option_GraphicsChangeTextOption(TEXT_UI_BAR_SCALE); Option_GraphicsChangeTextOption(TEXT_UI_BAR_SCALE);
Option_GraphicsChangeTextOption(TEXT_RENDER_MODE);
Option_GraphicsChangeTextOption(TEXT_RESOLUTION); Option_GraphicsChangeTextOption(TEXT_RESOLUTION);
} }
@ -157,7 +163,7 @@ static void Option_GraphicsShutdownText(void)
static void Option_GraphicsUpdateArrows(void) static void Option_GraphicsUpdateArrows(void)
{ {
int16_t resolution_offset = 0; int16_t local_right_arrow_offset = 0;
switch (g_OptionSelected) { switch (g_OptionSelected) {
case TEXT_PERSPECTIVE: case TEXT_PERSPECTIVE:
@ -184,8 +190,13 @@ static void Option_GraphicsUpdateArrows(void)
m_HideArrowLeft = g_Config.ui.bar_scale <= MIN_BAR_SCALE; m_HideArrowLeft = g_Config.ui.bar_scale <= MIN_BAR_SCALE;
m_HideArrowRight = g_Config.ui.bar_scale >= MAX_BAR_SCALE; m_HideArrowRight = g_Config.ui.bar_scale >= MAX_BAR_SCALE;
break; break;
case TEXT_RENDER_MODE:
local_right_arrow_offset = 95;
m_HideArrowLeft = false;
m_HideArrowRight = false;
break;
case TEXT_RESOLUTION: case TEXT_RESOLUTION:
resolution_offset = 70; local_right_arrow_offset = 95;
m_HideArrowLeft = !Screen_CanSetPrevRes(); m_HideArrowLeft = !Screen_CanSetPrevRes();
m_HideArrowRight = !Screen_CanSetNextRes(); m_HideArrowRight = !Screen_CanSetNextRes();
break; break;
@ -199,7 +210,7 @@ static void Option_GraphicsUpdateArrows(void)
Text_SetPos( Text_SetPos(
m_Text[TEXT_RIGHT_ARROW], m_Text[TEXT_RIGHT_ARROW],
m_Text[g_OptionSelected + TEXT_PERSPECTIVE_TOGGLE]->pos.x m_Text[g_OptionSelected + TEXT_PERSPECTIVE_TOGGLE]->pos.x
+ RIGHT_ARROW_OFFSET + resolution_offset, + RIGHT_ARROW_OFFSET + local_right_arrow_offset,
m_Text[g_OptionSelected + TEXT_PERSPECTIVE_TOGGLE]->pos.y); m_Text[g_OptionSelected + TEXT_PERSPECTIVE_TOGGLE]->pos.y);
Text_Hide(m_Text[TEXT_LEFT_ARROW], m_HideArrowLeft); Text_Hide(m_Text[TEXT_LEFT_ARROW], m_HideArrowLeft);
@ -211,7 +222,7 @@ static int16_t Option_GraphicsPlaceColumns(bool create)
const int16_t centre = Screen_GetResWidthDownscaled(RSR_TEXT) / 2; const int16_t centre = Screen_GetResWidthDownscaled(RSR_TEXT) / 2;
int16_t max_y = 0; int16_t max_y = 0;
int16_t xs[2] = { centre - 142, centre + 30 }; int16_t xs[2] = { centre - 142, centre };
int16_t ys[2] = { TOP_Y + ROW_HEIGHT + BORDER * 2, int16_t ys[2] = { TOP_Y + ROW_HEIGHT + BORDER * 2,
TOP_Y + ROW_HEIGHT + BORDER * 2 }; TOP_Y + ROW_HEIGHT + BORDER * 2 };
@ -289,6 +300,15 @@ static void Option_GraphicsChangeTextOption(int32_t option_num)
Text_ChangeText(m_Text[TEXT_UI_BAR_SCALE_TOGGLE], buf); Text_ChangeText(m_Text[TEXT_UI_BAR_SCALE_TOGGLE], buf);
break; break;
case TEXT_RENDER_MODE:
sprintf(
buf, g_GameFlow.strings[GS_DETAIL_STRING_FMT],
(g_Config.rendering.render_mode == GFX_RM_FRAMEBUFFER
? g_GameFlow.strings[GS_DETAIL_RENDER_MODE_FBO]
: g_GameFlow.strings[GS_DETAIL_RENDER_MODE_LEGACY]));
Text_ChangeText(m_Text[TEXT_RENDER_MODE_VALUE], buf);
break;
case TEXT_RESOLUTION: case TEXT_RESOLUTION:
sprintf( sprintf(
buf, g_GameFlow.strings[GS_DETAIL_RESOLUTION_FMT], buf, g_GameFlow.strings[GS_DETAIL_RESOLUTION_FMT],
@ -362,6 +382,16 @@ void Option_Graphics(INVENTORY_ITEM *inv_item)
reset = TEXT_UI_BAR_SCALE; reset = TEXT_UI_BAR_SCALE;
break; break;
case TEXT_RENDER_MODE:
if (g_Config.rendering.render_mode == GFX_RM_LEGACY) {
g_Config.rendering.render_mode = GFX_RM_FRAMEBUFFER;
} else {
g_Config.rendering.render_mode = GFX_RM_LEGACY;
}
Output_ApplyRenderSettings();
reset = TEXT_RENDER_MODE;
break;
case TEXT_RESOLUTION: case TEXT_RESOLUTION:
if (Screen_SetNextRes()) { if (Screen_SetNextRes()) {
reset = TEXT_NUMBER_OF; reset = TEXT_NUMBER_OF;
@ -414,6 +444,16 @@ void Option_Graphics(INVENTORY_ITEM *inv_item)
reset = TEXT_UI_BAR_SCALE; reset = TEXT_UI_BAR_SCALE;
break; break;
case TEXT_RENDER_MODE:
if (g_Config.rendering.render_mode == GFX_RM_LEGACY) {
g_Config.rendering.render_mode = GFX_RM_FRAMEBUFFER;
} else {
g_Config.rendering.render_mode = GFX_RM_LEGACY;
}
Output_ApplyRenderSettings();
reset = TEXT_RENDER_MODE;
break;
case TEXT_RESOLUTION: case TEXT_RESOLUTION:
if (Screen_SetPrevRes()) { if (Screen_SetPrevRes()) {
reset = TEXT_NUMBER_OF; reset = TEXT_NUMBER_OF;

View file

@ -384,9 +384,9 @@ void Output_Shutdown(void)
Memory_FreePointer(&m_BackdropImagePath); Memory_FreePointer(&m_BackdropImagePath);
} }
void Output_SetViewport(int width, int height) void Output_SetWindowSize(int width, int height)
{ {
S_Output_SetViewport(width, height); S_Output_SetWindowSize(width, height);
} }
void Output_SetFullscreen(bool fullscreen) void Output_SetFullscreen(bool fullscreen)
@ -394,9 +394,9 @@ void Output_SetFullscreen(bool fullscreen)
S_Output_SetFullscreen(fullscreen); S_Output_SetFullscreen(fullscreen);
} }
void Output_ApplyResolution(void) void Output_ApplyRenderSettings(void)
{ {
S_Output_ApplyResolution(); S_Output_ApplyRenderSettings();
if (m_BackdropImagePath) { if (m_BackdropImagePath) {
Output_LoadBackdropImage(m_BackdropImagePath); Output_LoadBackdropImage(m_BackdropImagePath);
} }
@ -600,9 +600,9 @@ void Output_DrawShadow(int16_t size, int16_t *bptr, ITEM_INFO *item)
PHD_VBUF *vn2 = &m_VBuf[g_Config.enable_round_shadow ? 4 : 1]; PHD_VBUF *vn2 = &m_VBuf[g_Config.enable_round_shadow ? 4 : 1];
PHD_VBUF *vn3 = &m_VBuf[g_Config.enable_round_shadow ? 8 : 2]; PHD_VBUF *vn3 = &m_VBuf[g_Config.enable_round_shadow ? 8 : 2];
bool visible = int32_t c1 = (vn3->xs - vn2->xs) * (vn1->ys - vn2->ys);
((int32_t)(((vn3->xs - vn2->xs) * (vn1->ys - vn2->ys)) - ((vn1->xs - vn2->xs) * (vn3->ys - vn2->ys))) int32_t c2 = (vn1->xs - vn2->xs) * (vn3->ys - vn2->ys);
>= 0); bool visible = (int32_t)(c1 - c2) >= 0;
if (!clip_and && clip_positive && visible) { if (!clip_and && clip_positive && visible) {
S_Output_DrawShadow( S_Output_DrawShadow(

View file

@ -8,9 +8,9 @@
bool Output_Init(void); bool Output_Init(void);
void Output_Shutdown(void); void Output_Shutdown(void);
void Output_SetViewport(int width, int height); void Output_SetWindowSize(int width, int height);
void Output_SetFullscreen(bool fullscreen); void Output_SetFullscreen(bool fullscreen);
void Output_ApplyResolution(void); void Output_ApplyRenderSettings(void);
void Output_DownloadTextures(int page_count); void Output_DownloadTextures(int page_count);
RGBA8888 Output_RGB2RGBA(const RGB888 color); RGBA8888 Output_RGB2RGBA(const RGB888 color);

View file

@ -39,7 +39,7 @@ static void Screen_ApplyResolution(void)
int32_t height = Screen_GetResHeight(); int32_t height = Screen_GetResHeight();
Viewport_Init(width, height); Viewport_Init(width, height);
Output_ApplyResolution(); Output_ApplyRenderSettings();
Matrix_ResetStack(); Matrix_ResetStack();
Viewport_AlterFOV(g_Config.fov_value * PHD_DEGREE); Viewport_AlterFOV(g_Config.fov_value * PHD_DEGREE);

View file

@ -4,15 +4,14 @@
#include "game/random.h" #include "game/random.h"
#include "game/room.h" #include "game/room.h"
#include "game/shell.h" #include "game/shell.h"
#include "global/const.h"
#include "global/vars.h" #include "global/vars.h"
#include "log.h"
#include "math/math.h" #include "math/math.h"
#include "specific/s_audio.h" #include "specific/s_audio.h"
#include "util.h" #include "util.h"
#include <math.h> #include <math.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h>
#define MAX_PLAYING_FX AUDIO_MAX_ACTIVE_SAMPLES #define MAX_PLAYING_FX AUDIO_MAX_ACTIVE_SAMPLES
#define MAX_AMBIENT_FX 8 #define MAX_AMBIENT_FX 8

View file

@ -2,9 +2,15 @@
#include "gfx/gl/gl_core_3_3.h" #include "gfx/gl/gl_core_3_3.h"
#include "gfx/gl/utils.h" #include "gfx/gl/utils.h"
#include "log.h"
#include <assert.h>
void GFX_2D_Renderer_Init(GFX_2D_Renderer *renderer) void GFX_2D_Renderer_Init(GFX_2D_Renderer *renderer)
{ {
LOG_INFO("");
assert(renderer);
GFX_GL_Buffer_Init(&renderer->surface_buffer, GL_ARRAY_BUFFER); GFX_GL_Buffer_Init(&renderer->surface_buffer, GL_ARRAY_BUFFER);
GFX_GL_Buffer_Bind(&renderer->surface_buffer); GFX_GL_Buffer_Bind(&renderer->surface_buffer);
GLfloat verts[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, GLfloat verts[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
@ -43,6 +49,9 @@ void GFX_2D_Renderer_Init(GFX_2D_Renderer *renderer)
void GFX_2D_Renderer_Close(GFX_2D_Renderer *renderer) void GFX_2D_Renderer_Close(GFX_2D_Renderer *renderer)
{ {
LOG_INFO("");
assert(renderer);
GFX_GL_VertexArray_Close(&renderer->surface_format); GFX_GL_VertexArray_Close(&renderer->surface_format);
GFX_GL_Buffer_Close(&renderer->surface_buffer); GFX_GL_Buffer_Close(&renderer->surface_buffer);
GFX_GL_Texture_Close(&renderer->surface_texture); GFX_GL_Texture_Close(&renderer->surface_texture);
@ -69,10 +78,12 @@ void GFX_2D_Renderer_Upload(
glTexImage2D( glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, renderer->width, renderer->height, 0, GL_TEXTURE_2D, 0, GL_RGBA, renderer->width, renderer->height, 0,
tex_format, tex_type, data); tex_format, tex_type, data);
GFX_GL_CheckError();
} else { } else {
glTexSubImage2D( glTexSubImage2D(
GL_TEXTURE_2D, 0, 0, 0, renderer->width, renderer->height, GL_TEXTURE_2D, 0, 0, 0, renderer->width, renderer->height,
tex_format, tex_type, data); tex_format, tex_type, data);
GFX_GL_CheckError();
} }
} }
@ -95,6 +106,7 @@ void GFX_2D_Renderer_Render(GFX_2D_Renderer *renderer)
} }
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
GFX_GL_CheckError();
if (blend) { if (blend) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
@ -103,6 +115,4 @@ void GFX_2D_Renderer_Render(GFX_2D_Renderer *renderer)
if (depth_test) { if (depth_test) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
GFX_GL_CheckError();
} }

View file

@ -163,9 +163,6 @@ bool GFX_2D_Surface_Flip(GFX_2D_Surface *surface)
GFX_Context_SwapBuffers(); GFX_Context_SwapBuffers();
} }
// update viewport in case the window size has changed
GFX_Context_SetupViewport();
// render surface // render surface
GFX_2D_Renderer_Render(surface->renderer); GFX_2D_Renderer_Render(surface->renderer);

View file

@ -29,7 +29,9 @@ static void GFX_3D_Renderer_SelectTextureImpl(
void GFX_3D_Renderer_Init(GFX_3D_Renderer *renderer) void GFX_3D_Renderer_Init(GFX_3D_Renderer *renderer)
{ {
LOG_INFO("");
assert(renderer); assert(renderer);
// TODO: make me configurable // TODO: make me configurable
renderer->wireframe = false; renderer->wireframe = false;
renderer->selected_texture_num = GFX_NO_TEXTURE; renderer->selected_texture_num = GFX_NO_TEXTURE;
@ -82,7 +84,9 @@ void GFX_3D_Renderer_Init(GFX_3D_Renderer *renderer)
void GFX_3D_Renderer_Close(GFX_3D_Renderer *renderer) void GFX_3D_Renderer_Close(GFX_3D_Renderer *renderer)
{ {
LOG_INFO("");
assert(renderer); assert(renderer);
GFX_3D_VertexStream_Close(&renderer->vertex_stream); GFX_3D_VertexStream_Close(&renderer->vertex_stream);
GFX_GL_Program_Close(&renderer->program); GFX_GL_Program_Close(&renderer->program);
GFX_GL_Sampler_Close(&renderer->sampler); GFX_GL_Sampler_Close(&renderer->sampler);
@ -96,6 +100,7 @@ void GFX_3D_Renderer_RenderBegin(GFX_3D_Renderer *renderer)
if (renderer->wireframe) { if (renderer->wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
} }
GFX_GL_CheckError();
GFX_GL_Program_Bind(&renderer->program); GFX_GL_Program_Bind(&renderer->program);
GFX_3D_VertexStream_Bind(&renderer->vertex_stream); GFX_3D_VertexStream_Bind(&renderer->vertex_stream);
@ -124,7 +129,6 @@ void GFX_3D_Renderer_RenderBegin(GFX_3D_Renderer *renderer)
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
GFX_GL_CheckError(); GFX_GL_CheckError();
} }
@ -143,6 +147,7 @@ void GFX_3D_Renderer_RenderEnd(GFX_3D_Renderer *renderer)
void GFX_3D_Renderer_ClearDepth(GFX_3D_Renderer *renderer) void GFX_3D_Renderer_ClearDepth(GFX_3D_Renderer *renderer)
{ {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
GFX_GL_CheckError();
} }
int GFX_3D_Renderer_TextureReg( int GFX_3D_Renderer_TextureReg(
@ -151,8 +156,7 @@ int GFX_3D_Renderer_TextureReg(
assert(renderer); assert(renderer);
assert(data); assert(data);
GFX_GL_Texture *texture = GFX_GL_Texture_Create(GL_TEXTURE_2D); GFX_GL_Texture *texture = GFX_GL_Texture_Create(GL_TEXTURE_2D);
GFX_GL_Texture_Bind(texture); GFX_GL_Texture_Load(texture, data, width, height, GL_RGBA, GL_BGRA);
GFX_GL_Texture_Load(texture, data, width, height);
int texture_num = GFX_NO_TEXTURE; int texture_num = GFX_NO_TEXTURE;
for (int i = 0; i < GFX_MAX_TEXTURES; i++) { for (int i = 0; i < GFX_MAX_TEXTURES; i++) {

View file

@ -154,7 +154,6 @@ void GFX_3D_VertexStream_RenderPending(GFX_3D_VertexStream *vertex_stream)
glDrawArrays( glDrawArrays(
GL_PRIM_MODES[vertex_stream->prim_type], 0, GL_PRIM_MODES[vertex_stream->prim_type], 0,
vertex_stream->pending_vertices.count); vertex_stream->pending_vertices.count);
GFX_GL_CheckError(); GFX_GL_CheckError();
vertex_stream->pending_vertices.count = 0; vertex_stream->pending_vertices.count = 0;

View file

@ -1,6 +1,5 @@
#include "gfx/context.h" #include "gfx/context.h"
#include "config.h"
#include "game/shell.h" #include "game/shell.h"
#include "gfx/gl/gl_core_3_3.h" #include "gfx/gl/gl_core_3_3.h"
#include "gfx/gl/utils.h" #include "gfx/gl/utils.h"
@ -8,39 +7,46 @@
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include <SDL2/SDL.h> #include <SDL2/SDL_video.h>
#include <string.h> #include <string.h>
typedef struct GFX_Context { typedef struct GFX_CONTEXT {
SDL_GLContext context; SDL_GLContext context;
SDL_Window *window_handle; SDL_Window *window_handle;
bool is_fullscreen; // fullscreen flag GFX_RENDER_MODE render_mode;
bool is_rendered; // rendering flag
int32_t display_width; int32_t display_width;
int32_t display_height; int32_t display_height;
int32_t screen_width;
int32_t screen_height;
int32_t window_width; int32_t window_width;
int32_t window_height; int32_t window_height;
bool is_fullscreen; // fullscreen flag
bool is_rendered; // rendering flag
char *scheduled_screenshot_path; char *scheduled_screenshot_path;
GFX_FBO_Renderer renderer_fbo;
GFX_2D_Renderer renderer_2d; GFX_2D_Renderer renderer_2d;
GFX_3D_Renderer renderer_3d; GFX_3D_Renderer renderer_3d;
} GFX_Context; } GFX_CONTEXT;
static GFX_Context m_Context = { 0 }; static GFX_CONTEXT m_Context = { 0 };
static bool GFX_Context_IsExtensionSupported(const char *name); static bool GFX_Context_IsExtensionSupported(const char *name);
static void GFX_Context_CheckExtensionSupport(const char *name); static void GFX_Context_CheckExtensionSupport(const char *name);
static void GFX_Context_SwitchToWindowViewport(void);
static void GFX_Context_SwitchToWindowViewportAR(void);
static void GFX_Context_SwitchToDisplayViewport(void);
static bool GFX_Context_IsExtensionSupported(const char *name) static bool GFX_Context_IsExtensionSupported(const char *name)
{ {
int number_of_extensions; int number_of_extensions;
glGetIntegerv(GL_NUM_EXTENSIONS, &number_of_extensions); glGetIntegerv(GL_NUM_EXTENSIONS, &number_of_extensions);
GFX_GL_CheckError();
for (int i = 0; i < number_of_extensions; i++) { for (int i = 0; i < number_of_extensions; i++) {
const char *gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i); const char *gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
GFX_GL_CheckError();
if (gl_ext && !strcmp(gl_ext, name)) { if (gl_ext && !strcmp(gl_ext, name)) {
return true; return true;
} }
@ -55,6 +61,47 @@ static void GFX_Context_CheckExtensionSupport(const char *name)
GFX_Context_IsExtensionSupported(name) ? "yes" : "no"); GFX_Context_IsExtensionSupported(name) ? "yes" : "no");
} }
static void GFX_Context_SwitchToWindowViewport(void)
{
glViewport(0, 0, m_Context.window_width, m_Context.window_height);
GFX_GL_CheckError();
}
static void GFX_Context_SwitchToWindowViewportAR(void)
{
// switch to window viewport at the aspect ratio of the display viewport
int vp_width = m_Context.window_width;
int vp_height = m_Context.window_height;
// default to bottom left corner of the window
int vp_x = 0;
int vp_y = 0;
int hw = m_Context.display_height * vp_width;
int wh = m_Context.display_width * vp_height;
// create viewport offset if the window has a different
// aspect ratio than the current display mode
if (hw > wh) {
int max_w = wh / m_Context.display_height;
vp_x = (vp_width - max_w) / 2;
vp_width = max_w;
} else if (hw < wh) {
int max_h = hw / m_Context.display_width;
vp_y = (vp_height - max_h) / 2;
vp_height = max_h;
}
glViewport(vp_x, vp_y, vp_width, vp_height);
GFX_GL_CheckError();
}
static void GFX_Context_SwitchToDisplayViewport(void)
{
glViewport(0, 0, m_Context.display_width, m_Context.display_height);
GFX_GL_CheckError();
}
void GFX_Context_Attach(void *window_handle) void GFX_Context_Attach(void *window_handle)
{ {
const char *shading_ver; const char *shading_ver;
@ -65,6 +112,12 @@ void GFX_Context_Attach(void *window_handle)
LOG_INFO("Attaching to window %p", window_handle); LOG_INFO("Attaching to window %p", window_handle);
m_Context.render_mode = -1;
m_Context.window_width = 800;
m_Context.window_height = 600;
m_Context.display_width = 800;
m_Context.display_height = 600;
m_Context.window_handle = window_handle; m_Context.window_handle = window_handle;
m_Context.context = SDL_GL_CreateContext(m_Context.window_handle); m_Context.context = SDL_GL_CreateContext(m_Context.window_handle);
@ -90,16 +143,9 @@ void GFX_Context_Attach(void *window_handle)
GFX_Context_CheckExtensionSupport("GL_ARB_explicit_attrib_location"); GFX_Context_CheckExtensionSupport("GL_ARB_explicit_attrib_location");
GFX_Context_CheckExtensionSupport("GL_EXT_gpu_shader4"); GFX_Context_CheckExtensionSupport("GL_EXT_gpu_shader4");
// get screen dimensions
SDL_DisplayMode DM;
SDL_GetDesktopDisplayMode(0, &DM);
m_Context.screen_width = DM.w;
m_Context.screen_height = DM.h;
LOG_INFO("GetDesktopDisplayMode=%dx%d", DM.w, DM.h);
glClearColor(0, 0, 0, 0); glClearColor(0, 0, 0, 0);
glClearDepth(1); glClearDepth(1);
GFX_GL_CheckError();
// VSync defaults to on unless user disabled it in runtime json // VSync defaults to on unless user disabled it in runtime json
SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);
@ -114,6 +160,9 @@ void GFX_Context_Detach(void)
return; return;
} }
if (m_Context.render_mode == GFX_RM_FRAMEBUFFER) {
GFX_FBO_Renderer_Close(&m_Context.renderer_fbo);
}
GFX_2D_Renderer_Close(&m_Context.renderer_2d); GFX_2D_Renderer_Close(&m_Context.renderer_2d);
GFX_3D_Renderer_Close(&m_Context.renderer_3d); GFX_3D_Renderer_Close(&m_Context.renderer_3d);
@ -150,9 +199,39 @@ void GFX_Context_SetWindowSize(int32_t width, int32_t height)
void GFX_Context_SetDisplaySize(int32_t width, int32_t height) void GFX_Context_SetDisplaySize(int32_t width, int32_t height)
{ {
if (width == m_Context.display_width
&& height == m_Context.display_height) {
return;
}
LOG_INFO("Display size: %dx%d", width, height); LOG_INFO("Display size: %dx%d", width, height);
if (width <= 0 || height <= 0) {
LOG_INFO("invalid size, ignoring");
return;
}
m_Context.display_width = width; m_Context.display_width = width;
m_Context.display_height = height; m_Context.display_height = height;
if (m_Context.render_mode == GFX_RM_FRAMEBUFFER) {
GFX_FBO_Renderer_Close(&m_Context.renderer_fbo);
GFX_FBO_Renderer_Init(&m_Context.renderer_fbo);
}
}
void GFX_Context_SetRenderingMode(GFX_RENDER_MODE target_mode)
{
GFX_RENDER_MODE current_mode = m_Context.render_mode;
if (current_mode == target_mode) {
return;
}
LOG_INFO("Render mode: %d", target_mode);
if (current_mode == GFX_RM_FRAMEBUFFER) {
GFX_FBO_Renderer_Close(&m_Context.renderer_fbo);
} else if (target_mode == GFX_RM_FRAMEBUFFER) {
GFX_FBO_Renderer_Init(&m_Context.renderer_fbo);
}
m_Context.render_mode = target_mode;
} }
int32_t GFX_Context_GetDisplayWidth(void) int32_t GFX_Context_GetDisplayWidth(void)
@ -165,69 +244,47 @@ int32_t GFX_Context_GetDisplayHeight(void)
return m_Context.display_height; return m_Context.display_height;
} }
int32_t GFX_Context_GetWindowWidth(void)
{
return m_Context.window_width ? m_Context.window_width
: m_Context.display_width;
}
int32_t GFX_Context_GetWindowHeight(void)
{
return m_Context.window_height ? m_Context.window_height
: m_Context.display_height;
}
int32_t GFX_Context_GetScreenWidth(void)
{
return m_Context.screen_width;
}
int32_t GFX_Context_GetScreenHeight(void)
{
return m_Context.screen_height;
}
void GFX_Context_SetupViewport(void)
{
int vp_width = m_Context.window_width;
int vp_height = m_Context.window_height;
// default to bottom left corner of the window
int vp_x = 0;
int vp_y = 0;
int hw = m_Context.display_height * vp_width;
int wh = m_Context.display_width * vp_height;
// create viewport offset if the window has a different
// aspect ratio than the current display mode
if (hw > wh) {
int max_w = wh / m_Context.display_height;
vp_x = (vp_width - max_w) / 2;
vp_width = max_w;
} else if (hw < wh) {
int max_h = hw / m_Context.display_width;
vp_y = (vp_height - max_h) / 2;
vp_height = max_h;
}
glViewport(vp_x, vp_y, vp_width, vp_height);
}
void GFX_Context_SwapBuffers(void) void GFX_Context_SwapBuffers(void)
{ {
glFinish(); glFinish();
GFX_GL_CheckError();
if (m_Context.scheduled_screenshot_path) { switch (m_Context.render_mode) {
GFX_Screenshot_CaptureToFile(m_Context.scheduled_screenshot_path); case GFX_RM_FRAMEBUFFER:
Memory_FreePointer(&m_Context.scheduled_screenshot_path); if (m_Context.scheduled_screenshot_path) {
GFX_Screenshot_CaptureToFile(m_Context.scheduled_screenshot_path);
Memory_FreePointer(&m_Context.scheduled_screenshot_path);
}
GFX_Context_SwitchToWindowViewportAR();
GFX_FBO_Renderer_Render(&m_Context.renderer_fbo);
SDL_GL_SwapWindow(m_Context.window_handle);
GFX_Context_SwitchToWindowViewport();
GFX_FBO_Renderer_Unbind(&m_Context.renderer_fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GFX_GL_CheckError();
GFX_FBO_Renderer_Bind(&m_Context.renderer_fbo);
GFX_Context_SwitchToDisplayViewport();
break;
case GFX_RM_LEGACY:
GFX_Context_SwitchToWindowViewportAR();
if (m_Context.scheduled_screenshot_path) {
GFX_Screenshot_CaptureToFile(m_Context.scheduled_screenshot_path);
Memory_FreePointer(&m_Context.scheduled_screenshot_path);
}
SDL_GL_SwapWindow(m_Context.window_handle);
glDrawBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GFX_GL_CheckError();
break;
} }
SDL_GL_SwapWindow(m_Context.window_handle);
glDrawBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_Context.is_rendered = false; m_Context.is_rendered = false;
} }
@ -243,6 +300,7 @@ bool GFX_Context_IsRendered(void)
void GFX_Context_ScheduleScreenshot(const char *path) void GFX_Context_ScheduleScreenshot(const char *path)
{ {
Memory_FreePointer(&m_Context.scheduled_screenshot_path);
m_Context.scheduled_screenshot_path = Memory_DupStr(path); m_Context.scheduled_screenshot_path = Memory_DupStr(path);
} }
@ -255,3 +313,8 @@ GFX_3D_Renderer *GFX_Context_GetRenderer3D(void)
{ {
return &m_Context.renderer_3d; return &m_Context.renderer_3d;
} }
GFX_FBO_Renderer *GFX_Context_GetRendererFBO(void)
{
return &m_Context.renderer_fbo;
}

View file

@ -2,11 +2,17 @@
#include "gfx/2d/2d_renderer.h" #include "gfx/2d/2d_renderer.h"
#include "gfx/3d/3d_renderer.h" #include "gfx/3d/3d_renderer.h"
#include "gfx/fbo/fbo_renderer.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
typedef struct GFX_Context GFX_Context; typedef struct GFX_CONTEXT GFX_CONTEXT;
typedef enum GFX_RENDER_MODE {
GFX_RM_LEGACY,
GFX_RM_FRAMEBUFFER,
} GFX_RENDER_MODE;
void GFX_Context_Attach(void *window_handle); void GFX_Context_Attach(void *window_handle);
void GFX_Context_Detach(void); void GFX_Context_Detach(void);
@ -15,16 +21,13 @@ bool GFX_Context_IsFullscreen(void);
void GFX_Context_SetFullscreen(bool fullscreen); void GFX_Context_SetFullscreen(bool fullscreen);
void GFX_Context_SetWindowSize(int32_t width, int32_t height); void GFX_Context_SetWindowSize(int32_t width, int32_t height);
void GFX_Context_SetDisplaySize(int32_t width, int32_t height); void GFX_Context_SetDisplaySize(int32_t width, int32_t height);
void GFX_Context_SetRenderingMode(GFX_RENDER_MODE target_mode);
int32_t GFX_Context_GetDisplayWidth(void); int32_t GFX_Context_GetDisplayWidth(void);
int32_t GFX_Context_GetDisplayHeight(void); int32_t GFX_Context_GetDisplayHeight(void);
int32_t GFX_Context_GetWindowWidth(void);
int32_t GFX_Context_GetWindowHeight(void);
int32_t GFX_Context_GetScreenWidth(void);
int32_t GFX_Context_GetScreenHeight(void);
void GFX_Context_SetupViewport(void);
void GFX_Context_SwapBuffers(void); void GFX_Context_SwapBuffers(void);
void GFX_Context_SetRendered(void); void GFX_Context_SetRendered(void);
bool GFX_Context_IsRendered(void); bool GFX_Context_IsRendered(void);
void GFX_Context_ScheduleScreenshot(const char *path); void GFX_Context_ScheduleScreenshot(const char *path);
GFX_2D_Renderer *GFX_Context_GetRenderer2D(void); GFX_2D_Renderer *GFX_Context_GetRenderer2D(void);
GFX_3D_Renderer *GFX_Context_GetRenderer3D(void); GFX_3D_Renderer *GFX_Context_GetRenderer3D(void);
GFX_FBO_Renderer *GFX_Context_GetRendererFBO(void);

165
src/gfx/fbo/fbo_renderer.c Normal file
View file

@ -0,0 +1,165 @@
#include "gfx/fbo/fbo_renderer.h"
#include "gfx/context.h"
#include "gfx/gl/utils.h"
#include "log.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
void GFX_FBO_Renderer_Init(GFX_FBO_Renderer *renderer)
{
LOG_INFO("");
assert(renderer);
int32_t fbo_width = GFX_Context_GetDisplayWidth();
int32_t fbo_height = GFX_Context_GetDisplayHeight();
GFX_GL_Buffer_Init(&renderer->buffer, GL_ARRAY_BUFFER);
GFX_GL_Buffer_Bind(&renderer->buffer);
GLfloat verts[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 1.0, 0.0, 1.0, 1.0 };
GFX_GL_Buffer_Data(&renderer->buffer, sizeof(verts), verts, GL_STATIC_DRAW);
GFX_GL_VertexArray_Init(&renderer->vertex_array);
GFX_GL_VertexArray_Bind(&renderer->vertex_array);
GFX_GL_VertexArray_Attribute(
&renderer->vertex_array, 0, 2, GL_FLOAT, GL_FALSE, 0, 0);
GFX_GL_Texture_Init(&renderer->texture, GL_TEXTURE_2D);
GFX_GL_Sampler_Init(&renderer->sampler);
GFX_GL_Sampler_Bind(&renderer->sampler, 0);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
GFX_GL_Program_Init(&renderer->program);
GFX_GL_Program_AttachShader(
&renderer->program, GL_VERTEX_SHADER, "shaders/fbo.vsh");
GFX_GL_Program_AttachShader(
&renderer->program, GL_FRAGMENT_SHADER, "shaders/fbo.fsh");
GFX_GL_Program_Link(&renderer->program);
GFX_GL_Program_FragmentData(&renderer->program, "fragColor");
glGenFramebuffers(1, &renderer->fbo);
GFX_GL_CheckError();
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo);
GFX_GL_CheckError();
GFX_GL_Texture_Load(
&renderer->texture, NULL, fbo_width, fbo_height, GL_RGB, GL_RGB);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
renderer->texture.id, 0);
GFX_GL_CheckError();
glGenRenderbuffers(1, &renderer->rbo);
GFX_GL_CheckError();
glBindRenderbuffer(GL_RENDERBUFFER, renderer->rbo);
GFX_GL_CheckError();
glRenderbufferStorage(
GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fbo_width, fbo_height);
GFX_GL_CheckError();
glBindRenderbuffer(GL_RENDERBUFFER, 0);
GFX_GL_CheckError();
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
renderer->rbo);
GFX_GL_CheckError();
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG_ERROR("framebuffer is not complete!");
}
}
void GFX_FBO_Renderer_Close(GFX_FBO_Renderer *renderer)
{
LOG_INFO("");
assert(renderer);
if (!renderer->fbo) {
return;
}
glDeleteFramebuffers(1, &renderer->fbo);
renderer->fbo = 0;
GFX_GL_VertexArray_Close(&renderer->vertex_array);
GFX_GL_Buffer_Close(&renderer->buffer);
GFX_GL_Texture_Close(&renderer->texture);
GFX_GL_Sampler_Close(&renderer->sampler);
GFX_GL_Program_Close(&renderer->program);
}
void GFX_FBO_Renderer_Render(GFX_FBO_Renderer *renderer)
{
assert(renderer);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GFX_GL_CheckError();
GFX_GL_Program_Bind(&renderer->program);
GFX_GL_Buffer_Bind(&renderer->buffer);
GFX_GL_VertexArray_Bind(&renderer->vertex_array);
GFX_GL_Texture_Bind(&renderer->texture);
GFX_GL_Sampler_Bind(&renderer->sampler, 0);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_MAG_FILTER,
renderer->is_smoothing_enabled ? GL_LINEAR : GL_NEAREST);
GFX_GL_Sampler_Parameteri(
&renderer->sampler, GL_TEXTURE_MIN_FILTER,
renderer->is_smoothing_enabled ? GL_LINEAR : GL_NEAREST);
GLboolean blend = glIsEnabled(GL_BLEND);
if (blend) {
glDisable(GL_BLEND);
}
GLboolean depth_test = glIsEnabled(GL_DEPTH_TEST);
if (depth_test) {
glDisable(GL_DEPTH_TEST);
}
glDrawArrays(GL_TRIANGLES, 0, 6);
GFX_GL_CheckError();
if (blend) {
glEnable(GL_BLEND);
}
if (depth_test) {
glEnable(GL_DEPTH_TEST);
}
GFX_GL_CheckError();
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo);
GFX_GL_CheckError();
}
void GFX_FBO_Renderer_SetSmoothingEnabled(
GFX_FBO_Renderer *renderer, bool is_enabled)
{
assert(renderer);
renderer->is_smoothing_enabled = is_enabled;
}
void GFX_FBO_Renderer_Bind(const GFX_FBO_Renderer *renderer)
{
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo);
}
void GFX_FBO_Renderer_Unbind(const GFX_FBO_Renderer *renderer)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "gfx/gl/buffer.h"
#include "gfx/gl/gl_core_3_3.h"
#include "gfx/gl/program.h"
#include "gfx/gl/sampler.h"
#include "gfx/gl/texture.h"
#include "gfx/gl/vertex_array.h"
#include <stdbool.h>
#include <stdint.h>
typedef struct GFX_FBO_Renderer {
GLuint fbo;
GLuint rbo;
bool is_smoothing_enabled;
GFX_GL_VertexArray vertex_array;
GFX_GL_Buffer buffer;
GFX_GL_Texture texture;
GFX_GL_Sampler sampler;
GFX_GL_Program program;
} GFX_FBO_Renderer;
void GFX_FBO_Renderer_Init(GFX_FBO_Renderer *renderer);
void GFX_FBO_Renderer_Close(GFX_FBO_Renderer *renderer);
void GFX_FBO_Renderer_Render(GFX_FBO_Renderer *renderer);
void GFX_FBO_Renderer_SetSmoothingEnabled(
GFX_FBO_Renderer *renderer, bool is_enabled);
void GFX_FBO_Renderer_Bind(const GFX_FBO_Renderer *renderer);
void GFX_FBO_Renderer_Unbind(const GFX_FBO_Renderer *renderer);

View file

@ -1,5 +1,7 @@
#include "gfx/gl/buffer.h" #include "gfx/gl/buffer.h"
#include "gfx/gl/utils.h"
#include <assert.h> #include <assert.h>
void GFX_GL_Buffer_Init(GFX_GL_Buffer *buf, GLenum target) void GFX_GL_Buffer_Init(GFX_GL_Buffer *buf, GLenum target)
@ -7,18 +9,21 @@ void GFX_GL_Buffer_Init(GFX_GL_Buffer *buf, GLenum target)
assert(buf); assert(buf);
buf->target = target; buf->target = target;
glGenBuffers(1, &buf->id); glGenBuffers(1, &buf->id);
GFX_GL_CheckError();
} }
void GFX_GL_Buffer_Close(GFX_GL_Buffer *buf) void GFX_GL_Buffer_Close(GFX_GL_Buffer *buf)
{ {
assert(buf); assert(buf);
glDeleteBuffers(1, &buf->id); glDeleteBuffers(1, &buf->id);
GFX_GL_CheckError();
} }
void GFX_GL_Buffer_Bind(GFX_GL_Buffer *buf) void GFX_GL_Buffer_Bind(GFX_GL_Buffer *buf)
{ {
assert(buf); assert(buf);
glBindBuffer(buf->target, buf->id); glBindBuffer(buf->target, buf->id);
GFX_GL_CheckError();
} }
void GFX_GL_Buffer_Data( void GFX_GL_Buffer_Data(
@ -26,6 +31,7 @@ void GFX_GL_Buffer_Data(
{ {
assert(buf); assert(buf);
glBufferData(buf->target, size, data, usage); glBufferData(buf->target, size, data, usage);
GFX_GL_CheckError();
} }
void GFX_GL_Buffer_SubData( void GFX_GL_Buffer_SubData(
@ -33,18 +39,22 @@ void GFX_GL_Buffer_SubData(
{ {
assert(buf); assert(buf);
glBufferSubData(buf->target, offset, size, data); glBufferSubData(buf->target, offset, size, data);
GFX_GL_CheckError();
} }
void *GFX_GL_Buffer_Map(GFX_GL_Buffer *buf, GLenum access) void *GFX_GL_Buffer_Map(GFX_GL_Buffer *buf, GLenum access)
{ {
assert(buf); assert(buf);
return glMapBuffer(buf->target, access); void *ret = glMapBuffer(buf->target, access);
GFX_GL_CheckError();
return ret;
} }
void GFX_GL_Buffer_Unmap(GFX_GL_Buffer *buf) void GFX_GL_Buffer_Unmap(GFX_GL_Buffer *buf)
{ {
assert(buf); assert(buf);
glUnmapBuffer(buf->target); glUnmapBuffer(buf->target);
GFX_GL_CheckError();
} }
GLint GFX_GL_Buffer_Parameter(GFX_GL_Buffer *buf, GLenum pname) GLint GFX_GL_Buffer_Parameter(GFX_GL_Buffer *buf, GLenum pname)
@ -52,5 +62,6 @@ GLint GFX_GL_Buffer_Parameter(GFX_GL_Buffer *buf, GLenum pname)
assert(buf); assert(buf);
GLint params = 0; GLint params = 0;
glGetBufferParameteriv(buf->target, pname, &params); glGetBufferParameteriv(buf->target, pname, &params);
GFX_GL_CheckError();
return params; return params;
} }

View file

@ -2,6 +2,7 @@
#include "filesystem.h" #include "filesystem.h"
#include "game/shell.h" #include "game/shell.h"
#include "gfx/gl/utils.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
@ -12,6 +13,7 @@ bool GFX_GL_Program_Init(GFX_GL_Program *program)
{ {
assert(program); assert(program);
program->id = glCreateProgram(); program->id = glCreateProgram();
GFX_GL_CheckError();
if (!program->id) { if (!program->id) {
LOG_ERROR("Can't create shader program"); LOG_ERROR("Can't create shader program");
return false; return false;
@ -23,6 +25,7 @@ void GFX_GL_Program_Close(GFX_GL_Program *program)
{ {
if (program->id) { if (program->id) {
glDeleteProgram(program->id); glDeleteProgram(program->id);
GFX_GL_CheckError();
program->id = 0; program->id = 0;
} }
} }
@ -30,12 +33,14 @@ void GFX_GL_Program_Close(GFX_GL_Program *program)
void GFX_GL_Program_Bind(GFX_GL_Program *program) void GFX_GL_Program_Bind(GFX_GL_Program *program)
{ {
glUseProgram(program->id); glUseProgram(program->id);
GFX_GL_CheckError();
} }
void GFX_GL_Program_AttachShader( void GFX_GL_Program_AttachShader(
GFX_GL_Program *program, GLenum type, const char *path) GFX_GL_Program *program, GLenum type, const char *path)
{ {
GLuint shader_id = glCreateShader(type); GLuint shader_id = glCreateShader(type);
GFX_GL_CheckError();
if (!shader_id) { if (!shader_id) {
Shell_ExitSystem("Failed to create shader"); Shell_ExitSystem("Failed to create shader");
} }
@ -46,14 +51,21 @@ void GFX_GL_Program_AttachShader(
} }
glShaderSource(shader_id, 1, (const char **)&content, NULL); glShaderSource(shader_id, 1, (const char **)&content, NULL);
GFX_GL_CheckError();
glCompileShader(shader_id); glCompileShader(shader_id);
GFX_GL_CheckError();
int compile_status; int compile_status;
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &compile_status); glGetShaderiv(shader_id, GL_COMPILE_STATUS, &compile_status);
GFX_GL_CheckError();
if (compile_status != GL_TRUE) { if (compile_status != GL_TRUE) {
GLsizei info_log_size = 4096; GLsizei info_log_size = 4096;
char info_log[info_log_size]; char info_log[info_log_size];
glGetShaderInfoLog(shader_id, info_log_size, &info_log_size, info_log); glGetShaderInfoLog(shader_id, info_log_size, &info_log_size, info_log);
GFX_GL_CheckError();
if (info_log[0]) { if (info_log[0]) {
Shell_ExitSystemFmt("Shader compilation failed:\n%s", info_log); Shell_ExitSystemFmt("Shader compilation failed:\n%s", info_log);
} else { } else {
@ -62,21 +74,29 @@ void GFX_GL_Program_AttachShader(
} }
Memory_FreePointer(&content); Memory_FreePointer(&content);
glAttachShader(program->id, shader_id); glAttachShader(program->id, shader_id);
GFX_GL_CheckError();
glDeleteShader(shader_id); glDeleteShader(shader_id);
GFX_GL_CheckError();
} }
void GFX_GL_Program_Link(GFX_GL_Program *program) void GFX_GL_Program_Link(GFX_GL_Program *program)
{ {
glLinkProgram(program->id); glLinkProgram(program->id);
GFX_GL_CheckError();
GLint linkStatus; GLint linkStatus;
glGetProgramiv(program->id, GL_LINK_STATUS, &linkStatus); glGetProgramiv(program->id, GL_LINK_STATUS, &linkStatus);
GFX_GL_CheckError();
if (!linkStatus) { if (!linkStatus) {
GLsizei info_log_size = 4096; GLsizei info_log_size = 4096;
char info_log[info_log_size]; char info_log[info_log_size];
glGetProgramInfoLog( glGetProgramInfoLog(
program->id, info_log_size, &info_log_size, info_log); program->id, info_log_size, &info_log_size, info_log);
GFX_GL_CheckError();
if (info_log[0]) { if (info_log[0]) {
Shell_ExitSystemFmt("Shader linking failed:\n%s", info_log); Shell_ExitSystemFmt("Shader linking failed:\n%s", info_log);
} else { } else {
@ -88,11 +108,13 @@ void GFX_GL_Program_Link(GFX_GL_Program *program)
void GFX_GL_Program_FragmentData(GFX_GL_Program *program, const char *name) void GFX_GL_Program_FragmentData(GFX_GL_Program *program, const char *name)
{ {
glBindFragDataLocation(program->id, 0, name); glBindFragDataLocation(program->id, 0, name);
GFX_GL_CheckError();
} }
GLint GFX_GL_Program_UniformLocation(GFX_GL_Program *program, const char *name) GLint GFX_GL_Program_UniformLocation(GFX_GL_Program *program, const char *name)
{ {
GLint location = glGetUniformLocation(program->id, name); GLint location = glGetUniformLocation(program->id, name);
GFX_GL_CheckError();
if (location == -1) { if (location == -1) {
LOG_INFO("Shader uniform not found: %s", name); LOG_INFO("Shader uniform not found: %s", name);
} }
@ -103,6 +125,7 @@ void GFX_GL_Program_Uniform3f(
GFX_GL_Program *program, GLint loc, GLfloat v0, GLfloat v1, GLfloat v2) GFX_GL_Program *program, GLint loc, GLfloat v0, GLfloat v1, GLfloat v2)
{ {
glUniform3f(loc, v0, v1, v2); glUniform3f(loc, v0, v1, v2);
GFX_GL_CheckError();
} }
void GFX_GL_Program_Uniform4f( void GFX_GL_Program_Uniform4f(
@ -110,11 +133,13 @@ void GFX_GL_Program_Uniform4f(
GLfloat v3) GLfloat v3)
{ {
glUniform4f(loc, v0, v1, v2, v3); glUniform4f(loc, v0, v1, v2, v3);
GFX_GL_CheckError();
} }
void GFX_GL_Program_Uniform1i(GFX_GL_Program *program, GLint loc, GLint v0) void GFX_GL_Program_Uniform1i(GFX_GL_Program *program, GLint loc, GLint v0)
{ {
glUniform1i(loc, v0); glUniform1i(loc, v0);
GFX_GL_CheckError();
} }
void GFX_GL_Program_UniformMatrix4fv( void GFX_GL_Program_UniformMatrix4fv(
@ -122,4 +147,5 @@ void GFX_GL_Program_UniformMatrix4fv(
const GLfloat *value) const GLfloat *value)
{ {
glUniformMatrix4fv(loc, count, transpose, value); glUniformMatrix4fv(loc, count, transpose, value);
GFX_GL_CheckError();
} }

View file

@ -1,28 +1,35 @@
#include "gfx/gl/sampler.h" #include "gfx/gl/sampler.h"
#include "gfx/gl/utils.h"
void GFX_GL_Sampler_Init(GFX_GL_Sampler *sampler) void GFX_GL_Sampler_Init(GFX_GL_Sampler *sampler)
{ {
glGenSamplers(1, &sampler->id); glGenSamplers(1, &sampler->id);
GFX_GL_CheckError();
} }
void GFX_GL_Sampler_Close(GFX_GL_Sampler *sampler) void GFX_GL_Sampler_Close(GFX_GL_Sampler *sampler)
{ {
glDeleteSamplers(1, &sampler->id); glDeleteSamplers(1, &sampler->id);
GFX_GL_CheckError();
} }
void GFX_GL_Sampler_Bind(GFX_GL_Sampler *sampler, GLuint unit) void GFX_GL_Sampler_Bind(GFX_GL_Sampler *sampler, GLuint unit)
{ {
glBindSampler(unit, sampler->id); glBindSampler(unit, sampler->id);
GFX_GL_CheckError();
} }
void GFX_GL_Sampler_Parameteri( void GFX_GL_Sampler_Parameteri(
GFX_GL_Sampler *sampler, GLenum pname, GLint param) GFX_GL_Sampler *sampler, GLenum pname, GLint param)
{ {
glSamplerParameteri(sampler->id, pname, param); glSamplerParameteri(sampler->id, pname, param);
GFX_GL_CheckError();
} }
void GFX_GL_Sampler_Parameterf( void GFX_GL_Sampler_Parameterf(
GFX_GL_Sampler *sampler, GLenum pname, GLfloat param) GFX_GL_Sampler *sampler, GLenum pname, GLfloat param)
{ {
glSamplerParameterf(sampler->id, pname, param); glSamplerParameterf(sampler->id, pname, param);
GFX_GL_CheckError();
} }

View file

@ -25,32 +25,36 @@ void GFX_GL_Texture_Init(GFX_GL_Texture *texture, GLenum target)
assert(texture); assert(texture);
texture->target = target; texture->target = target;
glGenTextures(1, &texture->id); glGenTextures(1, &texture->id);
GFX_GL_CheckError();
} }
void GFX_GL_Texture_Close(GFX_GL_Texture *texture) void GFX_GL_Texture_Close(GFX_GL_Texture *texture)
{ {
assert(texture); assert(texture);
glDeleteTextures(1, &texture->id); glDeleteTextures(1, &texture->id);
GFX_GL_CheckError();
} }
void GFX_GL_Texture_Bind(GFX_GL_Texture *texture) void GFX_GL_Texture_Bind(GFX_GL_Texture *texture)
{ {
assert(texture); assert(texture);
glBindTexture(texture->target, texture->id); glBindTexture(texture->target, texture->id);
GFX_GL_CheckError();
} }
void GFX_GL_Texture_Load( void GFX_GL_Texture_Load(
GFX_GL_Texture *texture, const void *data, int width, int height) GFX_GL_Texture *texture, const void *data, int width, int height,
GLint internal_format, GLint format)
{ {
assert(texture); assert(texture);
assert(data);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
data);
GFX_GL_Texture_Bind(texture); GFX_GL_Texture_Bind(texture);
glGenerateMipmap(GL_TEXTURE_2D);
glTexImage2D(
GL_TEXTURE_2D, 0, internal_format, width, height, 0, format,
GL_UNSIGNED_BYTE, data);
GFX_GL_CheckError();
glGenerateMipmap(GL_TEXTURE_2D);
GFX_GL_CheckError(); GFX_GL_CheckError();
} }

View file

@ -14,4 +14,5 @@ void GFX_GL_Texture_Init(GFX_GL_Texture *texture, GLenum target);
void GFX_GL_Texture_Close(GFX_GL_Texture *texture); void GFX_GL_Texture_Close(GFX_GL_Texture *texture);
void GFX_GL_Texture_Bind(GFX_GL_Texture *texture); void GFX_GL_Texture_Bind(GFX_GL_Texture *texture);
void GFX_GL_Texture_Load( void GFX_GL_Texture_Load(
GFX_GL_Texture *texture, const void *data, int width, int height); GFX_GL_Texture *texture, const void *data, int width, int height,
GLint internal_format, GLint format);

View file

@ -1,23 +1,28 @@
#include "gfx/gl/vertex_array.h" #include "gfx/gl/vertex_array.h"
#include "gfx/gl/utils.h"
#include <assert.h> #include <assert.h>
void GFX_GL_VertexArray_Init(GFX_GL_VertexArray *array) void GFX_GL_VertexArray_Init(GFX_GL_VertexArray *array)
{ {
assert(array); assert(array);
glGenVertexArrays(1, &array->id); glGenVertexArrays(1, &array->id);
GFX_GL_CheckError();
} }
void GFX_GL_VertexArray_Close(GFX_GL_VertexArray *array) void GFX_GL_VertexArray_Close(GFX_GL_VertexArray *array)
{ {
assert(array); assert(array);
glDeleteVertexArrays(1, &array->id); glDeleteVertexArrays(1, &array->id);
GFX_GL_CheckError();
} }
void GFX_GL_VertexArray_Bind(GFX_GL_VertexArray *array) void GFX_GL_VertexArray_Bind(GFX_GL_VertexArray *array)
{ {
assert(array); assert(array);
glBindVertexArray(array->id); glBindVertexArray(array->id);
GFX_GL_CheckError();
} }
void GFX_GL_VertexArray_Attribute( void GFX_GL_VertexArray_Attribute(
@ -26,6 +31,9 @@ void GFX_GL_VertexArray_Attribute(
{ {
assert(array); assert(array);
glEnableVertexAttribArray(index); glEnableVertexAttribArray(index);
GFX_GL_CheckError();
glVertexAttribPointer( glVertexAttribPointer(
index, size, type, normalized, stride, (void *)offset); index, size, type, normalized, stride, (void *)offset);
GFX_GL_CheckError();
} }

View file

@ -1034,7 +1034,11 @@ typedef enum GAME_STRING_ID {
GS_DETAIL_BRIGHTNESS, GS_DETAIL_BRIGHTNESS,
GS_DETAIL_UI_TEXT_SCALE, GS_DETAIL_UI_TEXT_SCALE,
GS_DETAIL_UI_BAR_SCALE, GS_DETAIL_UI_BAR_SCALE,
GS_DETAIL_RENDER_MODE,
GS_DETAIL_RENDER_MODE_LEGACY,
GS_DETAIL_RENDER_MODE_FBO,
GS_DETAIL_RESOLUTION, GS_DETAIL_RESOLUTION,
GS_DETAIL_STRING_FMT,
GS_DETAIL_FLOAT_FMT, GS_DETAIL_FLOAT_FMT,
GS_DETAIL_RESOLUTION_FMT, GS_DETAIL_RESOLUTION_FMT,

View file

@ -8,6 +8,8 @@
#include <SDL2/SDL_audio.h> #include <SDL2/SDL_audio.h>
#include <errno.h> #include <errno.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavcodec/codec.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavformat/avio.h> #include <libavformat/avio.h>
#include <libavutil/avutil.h> #include <libavutil/avutil.h>

View file

@ -10,6 +10,8 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavcodec/codec.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavformat/avio.h> #include <libavformat/avio.h>
#include <libavutil/avutil.h> #include <libavutil/avutil.h>

View file

@ -7,6 +7,7 @@
#include <assert.h> #include <assert.h>
#include <dirent.h> #include <dirent.h>
#include <string.h> #include <string.h>
#include <strings.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <direct.h> #include <direct.h>

View file

@ -42,7 +42,6 @@
#include <SDL2/SDL_audio.h> #include <SDL2/SDL_audio.h>
#include <SDL2/SDL_error.h> #include <SDL2/SDL_error.h>
#include <SDL2/SDL_events.h> #include <SDL2/SDL_events.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_keycode.h> #include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_mutex.h> #include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_pixels.h> #include <SDL2/SDL_pixels.h>
@ -53,6 +52,10 @@
#include <SDL2/SDL_video.h> #include <SDL2/SDL_video.h>
#include <errno.h> #include <errno.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavcodec/codec.h>
#include <libavcodec/codec_id.h>
#include <libavcodec/codec_par.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavformat/avio.h> #include <libavformat/avio.h>
#include <libavutil/attributes.h> #include <libavutil/attributes.h>
@ -2241,7 +2244,7 @@ static void S_FMV_EventLoop(VideoState *is)
is->width = event.window.data1; is->width = event.window.data1;
is->height = event.window.data2; is->height = event.window.data2;
is->force_refresh = true; is->force_refresh = true;
Output_SetViewport(event.window.data1, event.window.data2); Output_SetWindowSize(event.window.data1, event.window.data2);
break; break;
case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_EXPOSED:
@ -2312,7 +2315,7 @@ cleanup:
S_Audio_Init(); S_Audio_Init();
S_Output_ApplyResolution(); S_Output_ApplyRenderSettings();
return ret; return ret;
} }

View file

@ -1,6 +1,5 @@
#include "specific/s_input.h" #include "specific/s_input.h"
#include "game/input.h"
#include "log.h" #include "log.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>

View file

@ -11,6 +11,7 @@
#include "gfx/3d/vertex_stream.h" #include "gfx/3d/vertex_stream.h"
#include "gfx/blitter.h" #include "gfx/blitter.h"
#include "gfx/context.h" #include "gfx/context.h"
#include "gfx/fbo/fbo_renderer.h"
#include "global/vars.h" #include "global/vars.h"
#include "log.h" #include "log.h"
#include "specific/s_shell.h" #include "specific/s_shell.h"
@ -30,6 +31,8 @@
static int m_TextureMap[GFX_MAX_TEXTURES] = { GFX_NO_TEXTURE }; static int m_TextureMap[GFX_MAX_TEXTURES] = { GFX_NO_TEXTURE };
static RGB888 m_ColorPalette[256]; static RGB888 m_ColorPalette[256];
static GFX_FBO_Renderer *m_RendererFBO = NULL;
static GFX_3D_Renderer *m_Renderer3D = NULL; static GFX_3D_Renderer *m_Renderer3D = NULL;
static bool m_IsPaletteActive = false; static bool m_IsPaletteActive = false;
static bool m_IsRendering = false; static bool m_IsRendering = false;
@ -78,6 +81,8 @@ static void S_Output_SetupRenderContextAndRender(void)
S_Output_RenderBegin(); S_Output_RenderBegin();
GFX_3D_Renderer_SetSmoothingEnabled( GFX_3D_Renderer_SetSmoothingEnabled(
m_Renderer3D, g_Config.rendering.enable_bilinear_filter); m_Renderer3D, g_Config.rendering.enable_bilinear_filter);
GFX_FBO_Renderer_SetSmoothingEnabled(
m_RendererFBO, g_Config.rendering.enable_bilinear_filter);
S_Output_RenderToggle(); S_Output_RenderToggle();
} }
@ -916,7 +921,7 @@ void S_Output_DrawShadow(PHD_VBUF *vbufs, int clip, int vertex_count)
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false); GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false);
} }
void S_Output_ApplyResolution(void) void S_Output_ApplyRenderSettings(void)
{ {
S_Output_ReleaseSurfaces(); S_Output_ReleaseSurfaces();
@ -928,6 +933,7 @@ void S_Output_ApplyResolution(void)
m_SurfaceMaxY = Screen_GetResHeight() - 1.0f; m_SurfaceMaxY = Screen_GetResHeight() - 1.0f;
GFX_Context_SetDisplaySize(m_SurfaceWidth, m_SurfaceHeight); GFX_Context_SetDisplaySize(m_SurfaceWidth, m_SurfaceHeight);
GFX_Context_SetRenderingMode(g_Config.rendering.render_mode);
{ {
GFX_2D_SurfaceDesc surface_desc = { GFX_2D_SurfaceDesc surface_desc = {
@ -955,7 +961,7 @@ void S_Output_ApplyResolution(void)
S_Output_SetupRenderContextAndRender(); S_Output_SetupRenderContextAndRender();
} }
void S_Output_SetViewport(int width, int height) void S_Output_SetWindowSize(int width, int height)
{ {
GFX_Context_SetWindowSize(width, height); GFX_Context_SetWindowSize(width, height);
} }
@ -974,8 +980,9 @@ bool S_Output_Init(void)
GFX_Context_Attach(S_Shell_GetWindowHandle()); GFX_Context_Attach(S_Shell_GetWindowHandle());
m_Renderer3D = GFX_Context_GetRenderer3D(); m_Renderer3D = GFX_Context_GetRenderer3D();
m_RendererFBO = GFX_Context_GetRendererFBO();
S_Output_ApplyResolution(); S_Output_ApplyRenderSettings();
GFX_3D_Renderer_SetPrimType(m_Renderer3D, GFX_3D_PRIM_TRI); GFX_3D_Renderer_SetPrimType(m_Renderer3D, GFX_3D_PRIM_TRI);
@ -988,6 +995,7 @@ void S_Output_Shutdown(void)
S_Output_ReleaseSurfaces(); S_Output_ReleaseSurfaces();
GFX_Context_Detach(); GFX_Context_Detach();
m_Renderer3D = NULL; m_Renderer3D = NULL;
m_RendererFBO = NULL;
} }
void S_Output_DrawFlatTriangle( void S_Output_DrawFlatTriangle(

View file

@ -21,9 +21,9 @@ void S_Output_DumpScreen(void);
void S_Output_ClearDepthBuffer(void); void S_Output_ClearDepthBuffer(void);
void S_Output_DrawEmpty(void); void S_Output_DrawEmpty(void);
void S_Output_SetViewport(int width, int height); void S_Output_SetWindowSize(int width, int height);
void S_Output_SetFullscreen(bool fullscreen); void S_Output_SetFullscreen(bool fullscreen);
void S_Output_ApplyResolution(void); void S_Output_ApplyRenderSettings(void);
void S_Output_SetPalette(RGB888 palette[256]); void S_Output_SetPalette(RGB888 palette[256]);
RGB888 S_Output_GetPaletteColor(uint8_t idx); RGB888 S_Output_GetPaletteColor(uint8_t idx);

View file

@ -8,6 +8,9 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavcodec/codec.h>
#include <libavcodec/codec_id.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavutil/avutil.h> #include <libavutil/avutil.h>
#include <libavutil/error.h> #include <libavutil/error.h>

View file

@ -10,14 +10,23 @@
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include <libavcodec/avcodec.h>
#define SDL_MAIN_HANDLED #define SDL_MAIN_HANDLED
#ifdef _WIN32 #ifdef _WIN32
#include <objbase.h>
#include <windows.h> #include <windows.h>
#endif #endif
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_error.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_messagebox.h>
#include <SDL2/SDL_mouse.h>
#include <SDL2/SDL_video.h>
#include <libavcodec/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h> #include <time.h>
static int m_ArgCount = 0; static int m_ArgCount = 0;
@ -40,7 +49,7 @@ static void S_Shell_PostWindowResize(void)
int width; int width;
int height; int height;
SDL_GetWindowSize(m_Window, &width, &height); SDL_GetWindowSize(m_Window, &width, &height);
Output_SetViewport(width, height); Output_SetWindowSize(width, height);
} }
void S_Shell_ShowFatalError(const char *message) void S_Shell_ShowFatalError(const char *message)
@ -107,7 +116,7 @@ void S_Shell_SpinMessageLoop(void)
break; break;
case SDL_WINDOWEVENT_RESIZED: { case SDL_WINDOWEVENT_RESIZED: {
Output_SetViewport(event.window.data1, event.window.data2); Output_SetWindowSize(event.window.data1, event.window.data2);
break; break;
} }
} }