mirror of https://github.com/sm64pc/sm64pc.git
Add menu for configuring raytracing options.
This commit is contained in:
parent
87b9c716d9
commit
a68bffc544
|
@ -127,10 +127,15 @@ typedef struct {
|
|||
float attenuationExponent;
|
||||
float flickerIntensity;
|
||||
unsigned int groupBits;
|
||||
unsigned int minSamples;
|
||||
unsigned int maxSamples;
|
||||
} RT64_LIGHT;
|
||||
|
||||
typedef struct {
|
||||
float resolutionScale;
|
||||
unsigned int softLightSamples;
|
||||
unsigned int giBounces;
|
||||
float ambGiMixWeight;
|
||||
bool denoiserEnabled;
|
||||
} RT64_VIEW_CONFIG;
|
||||
|
||||
// Forward declaration of types.
|
||||
typedef struct RT64_DEVICE RT64_DEVICE;
|
||||
|
@ -201,6 +206,7 @@ typedef void(*DrawDevicePtr)(RT64_DEVICE* device, int vsyncInterval);
|
|||
typedef void(*DestroyDevicePtr)(RT64_DEVICE* device);
|
||||
typedef RT64_VIEW* (*CreateViewPtr)(RT64_SCENE* scenePtr);
|
||||
typedef void(*SetViewPerspectivePtr)(RT64_VIEW *viewPtr, RT64_MATRIX4 viewMatrix, float fovRadians, float nearDist, float farDist);
|
||||
typedef void(*SetViewConfigurationPtr)(RT64_VIEW *viewPtr, RT64_VIEW_CONFIG viewConfig);
|
||||
typedef RT64_INSTANCE* (*GetViewRaytracedInstanceAtPtr)(RT64_VIEW *viewPtr, int x, int y);
|
||||
typedef void(*DestroyViewPtr)(RT64_VIEW* viewPtr);
|
||||
typedef RT64_SCENE* (*CreateScenePtr)(RT64_DEVICE* devicePtr);
|
||||
|
@ -229,6 +235,7 @@ typedef struct {
|
|||
DestroyDevicePtr DestroyDevice;
|
||||
CreateViewPtr CreateView;
|
||||
SetViewPerspectivePtr SetViewPerspective;
|
||||
SetViewConfigurationPtr SetViewConfiguration;
|
||||
GetViewRaytracedInstanceAtPtr GetViewRaytracedInstanceAt;
|
||||
DestroyViewPtr DestroyView;
|
||||
CreateScenePtr CreateScene;
|
||||
|
@ -265,6 +272,7 @@ inline RT64_LIBRARY RT64_LoadLibrary() {
|
|||
lib.DestroyDevice = (DestroyDevicePtr)(GetProcAddress(lib.handle, "RT64_DestroyDevice"));
|
||||
lib.CreateView = (CreateViewPtr)(GetProcAddress(lib.handle, "RT64_CreateView"));
|
||||
lib.SetViewPerspective = (SetViewPerspectivePtr)(GetProcAddress(lib.handle, "RT64_SetViewPerspective"));
|
||||
lib.SetViewConfiguration = (SetViewConfigurationPtr)(GetProcAddress(lib.handle, "RT64_SetViewConfiguration"));
|
||||
lib.GetViewRaytracedInstanceAt = (GetViewRaytracedInstanceAtPtr)(GetProcAddress(lib.handle, "RT64_GetViewRaytracedInstanceAt"));
|
||||
lib.DestroyView = (DestroyViewPtr)(GetProcAddress(lib.handle, "RT64_DestroyView"));
|
||||
lib.CreateScene = (CreateScenePtr)(GetProcAddress(lib.handle, "RT64_CreateScene"));
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"presets" : [
|
||||
{
|
||||
"name": "Simple",
|
||||
"lightSampleSettings": [
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Soft",
|
||||
"lightSampleSettings": [
|
||||
{
|
||||
"groupBits": 1,
|
||||
"minSamples": 8,
|
||||
"maxSamples": 32
|
||||
},
|
||||
{
|
||||
"groupBits": 2,
|
||||
"minSamples": 8,
|
||||
"maxSamples": 16
|
||||
},
|
||||
{
|
||||
"groupBits": 16,
|
||||
"minSamples": 8,
|
||||
"maxSamples": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -55,6 +55,7 @@ static const u8 optSmallStr[][32] = {
|
|||
static const u8 menuStr[][32] = {
|
||||
{ TEXT_OPT_OPTIONS },
|
||||
{ TEXT_OPT_CAMERA },
|
||||
{ TEXT_OPT_RT64 },
|
||||
{ TEXT_OPT_CONTROLS },
|
||||
{ TEXT_OPT_VIDEO },
|
||||
{ TEXT_OPT_AUDIO },
|
||||
|
@ -75,6 +76,16 @@ static const u8 optsCameraStr[][32] = {
|
|||
{ TEXT_OPT_CAMON },
|
||||
};
|
||||
|
||||
#ifdef RAPI_RT64
|
||||
static const u8 optsRT64Str[][32] = {
|
||||
{ TEXT_OPT_RESSCALE },
|
||||
{ TEXT_OPT_SPHEREL },
|
||||
{ TEXT_OPT_GI },
|
||||
{ TEXT_OPT_GIWEIGHT },
|
||||
{ TEXT_OPT_DENOISER },
|
||||
};
|
||||
#endif
|
||||
|
||||
static const u8 optsVideoStr[][32] = {
|
||||
{ TEXT_OPT_FSCREEN },
|
||||
{ TEXT_OPT_TEXFILTER },
|
||||
|
@ -235,6 +246,17 @@ static struct Option optsCamera[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef RAPI_RT64
|
||||
static struct Option optsRT64[] = {
|
||||
DEF_OPT_SCROLL( optsRT64Str[0], &configRT64ResScale, 10, 200, 1 ),
|
||||
DEF_OPT_TOGGLE( optsRT64Str[1], &configRT64SphereLights ),
|
||||
DEF_OPT_TOGGLE( optsRT64Str[2], &configRT64GI ),
|
||||
DEF_OPT_SCROLL( optsRT64Str[3], &configRT64GIStrength, 5, 95, 1 ),
|
||||
DEF_OPT_TOGGLE( optsRT64Str[4], &configRT64Denoiser ),
|
||||
DEF_OPT_BUTTON( optsVideoStr[9], optvideo_apply ),
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct Option optsControls[] = {
|
||||
DEF_OPT_BIND( bindStr[ 2], configKeyA ),
|
||||
DEF_OPT_BIND( bindStr[ 3], configKeyB ),
|
||||
|
@ -290,10 +312,13 @@ static struct Option optsCheats[] = {
|
|||
#ifdef BETTERCAMERA
|
||||
static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[1], optsCamera );
|
||||
#endif
|
||||
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[2], optsControls );
|
||||
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[3], optsVideo );
|
||||
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[4], optsAudio );
|
||||
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[6], optsCheats );
|
||||
#ifdef RAPI_RT64
|
||||
static struct SubMenu menuRT64 = DEF_SUBMENU( menuStr[2], optsRT64 );
|
||||
#endif
|
||||
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[3], optsControls );
|
||||
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[4], optsVideo );
|
||||
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[5], optsAudio );
|
||||
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[7], optsCheats );
|
||||
|
||||
/* main options menu definition */
|
||||
|
||||
|
@ -301,12 +326,15 @@ static struct Option optsMain[] = {
|
|||
#ifdef BETTERCAMERA
|
||||
DEF_OPT_SUBMENU( menuStr[1], &menuCamera ),
|
||||
#endif
|
||||
DEF_OPT_SUBMENU( menuStr[2], &menuControls ),
|
||||
DEF_OPT_SUBMENU( menuStr[3], &menuVideo ),
|
||||
DEF_OPT_SUBMENU( menuStr[4], &menuAudio ),
|
||||
DEF_OPT_BUTTON ( menuStr[5], optmenu_act_exit ),
|
||||
#ifdef RAPI_RT64
|
||||
DEF_OPT_SUBMENU( menuStr[2], &menuRT64 ),
|
||||
#endif
|
||||
DEF_OPT_SUBMENU( menuStr[3], &menuControls ),
|
||||
DEF_OPT_SUBMENU( menuStr[4], &menuVideo ),
|
||||
DEF_OPT_SUBMENU( menuStr[5], &menuAudio ),
|
||||
DEF_OPT_BUTTON ( menuStr[6], optmenu_act_exit ),
|
||||
// NOTE: always keep cheats the last option here because of the half-assed way I toggle them
|
||||
DEF_OPT_SUBMENU( menuStr[6], &menuCheats )
|
||||
DEF_OPT_SUBMENU( menuStr[7], &menuCheats )
|
||||
};
|
||||
|
||||
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[0], optsMain );
|
||||
|
|
|
@ -93,6 +93,13 @@ bool configHUD = true;
|
|||
#ifdef DISCORDRPC
|
||||
bool configDiscordRPC = true;
|
||||
#endif
|
||||
#ifdef RAPI_RT64
|
||||
unsigned int configRT64ResScale = 100;
|
||||
bool configRT64SphereLights = false;
|
||||
bool configRT64GI = false;
|
||||
unsigned int configRT64GIStrength = 80;
|
||||
bool configRT64Denoiser = false;
|
||||
#endif
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||
|
@ -140,7 +147,14 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "skip_intro", .type = CONFIG_TYPE_BOOL, .boolValue = &configSkipIntro},
|
||||
#ifdef DISCORDRPC
|
||||
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
|
||||
#endif
|
||||
#endif
|
||||
#ifdef RAPI_RT64
|
||||
{.name = "rt64_res_scale", .type = CONFIG_TYPE_UINT, .uintValue = &configRT64ResScale},
|
||||
{.name = "rt64_sphere_lights", .type = CONFIG_TYPE_BOOL, .boolValue = &configRT64SphereLights},
|
||||
{.name = "rt64_gi", .type = CONFIG_TYPE_BOOL, .boolValue = &configRT64GI},
|
||||
{.name = "rt64_gi_strength", .type = CONFIG_TYPE_UINT, .uintValue = &configRT64GIStrength},
|
||||
{.name = "rt64_denoiser", .type = CONFIG_TYPE_BOOL, .boolValue = &configRT64Denoiser},
|
||||
#endif
|
||||
};
|
||||
|
||||
// Reads an entire line from a file (excluding the newline character) and returns an allocated string
|
||||
|
|
|
@ -59,6 +59,13 @@ extern bool configSkipIntro;
|
|||
#ifdef DISCORDRPC
|
||||
extern bool configDiscordRPC;
|
||||
#endif
|
||||
#ifdef RAPI_RT64
|
||||
extern unsigned int configRT64ResScale;
|
||||
extern bool configRT64SphereLights;
|
||||
extern bool configRT64GI;
|
||||
extern unsigned int configRT64GIStrength;
|
||||
extern bool configRT64Denoiser;
|
||||
#endif
|
||||
|
||||
void configfile_load(const char *filename);
|
||||
void configfile_save(const char *filename);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#endif
|
||||
|
||||
extern "C" {
|
||||
# include "../configfile.h"
|
||||
# include "../../game/area.h"
|
||||
# include "../../game/level_update.h"
|
||||
# include "../fs/fs.h"
|
||||
|
@ -49,10 +50,8 @@ using json = nlohmann::json;
|
|||
#define MAX_AREAS 3
|
||||
#define MAX_LEVEL_LIGHTS 128
|
||||
#define LEVEL_LIGHTS_FILENAME FS_BASEDIR "/rt64/level_lights.json"
|
||||
#define LIGHT_SAMPLE_PRESETS_FILENAME FS_BASEDIR "/rt64/light_sample_presets.json"
|
||||
#define GEO_LAYOUT_MODS_FILENAME FS_BASEDIR "/rt64/geo_layout_mods.json"
|
||||
#define TEXTURE_MODS_FILENAME FS_BASEDIR "/rt64/texture_mods.json"
|
||||
#define LIGHT_SAMPLE_PRESET_DEFAULT "Simple"
|
||||
|
||||
struct ShaderProgram {
|
||||
uint32_t shader_id;
|
||||
|
@ -90,7 +89,6 @@ struct RecordedMod {
|
|||
};
|
||||
|
||||
// Convention of bits for different lights.
|
||||
// The tiers allow more detailed control over the performance of areas of the game that are more demanding than others.
|
||||
// 1 - Directional Tier A
|
||||
// 2 - Directional Tier B
|
||||
// 4 - Stage Tier A
|
||||
|
@ -100,16 +98,6 @@ struct RecordedMod {
|
|||
// 64 - Particles Tier A
|
||||
// 128 - Particles Tier B
|
||||
|
||||
struct LightSampleSetting {
|
||||
unsigned int groupBits;
|
||||
unsigned int minSamples;
|
||||
unsigned int maxSamples;
|
||||
};
|
||||
|
||||
struct LightSamplePreset {
|
||||
std::vector<LightSampleSetting> settings;
|
||||
};
|
||||
|
||||
struct {
|
||||
HWND hwnd;
|
||||
|
||||
|
@ -130,8 +118,6 @@ struct {
|
|||
std::unordered_map<uint64_t, RecordedMesh> dynamicMeshes;
|
||||
std::unordered_map<uint64_t, RecordedMeshKey> dynamicMeshKeys;
|
||||
std::unordered_map<uint32_t, ShaderProgram *> shaderPrograms;
|
||||
LightSamplePreset activeLightSamplePreset;
|
||||
std::map<std::string, LightSamplePreset> lightSamplePresets;
|
||||
int cachedMeshesPerFrame;
|
||||
RT64_LIGHT lights[MAX_LIGHTS];
|
||||
unsigned int lightCount;
|
||||
|
@ -219,49 +205,6 @@ void gfx_rt64_load_light(const json &jlight, RT64_LIGHT *light) {
|
|||
light->groupBits = jlight["groupBits"];
|
||||
}
|
||||
|
||||
void gfx_rt64_set_light_samples(RT64_LIGHT *light) {
|
||||
unsigned int minSamples = 1;
|
||||
unsigned int maxSamples = 1;
|
||||
for (const auto &it : RT64.activeLightSamplePreset.settings) {
|
||||
if (it.groupBits & light->groupBits) {
|
||||
minSamples = std::max(minSamples, it.minSamples);
|
||||
maxSamples = std::max(maxSamples, it.maxSamples);
|
||||
}
|
||||
}
|
||||
|
||||
light->minSamples = minSamples;
|
||||
light->maxSamples = std::max(minSamples, maxSamples);
|
||||
}
|
||||
|
||||
LightSamplePreset gfx_rt64_load_light_sample_preset(const json &jpreset) {
|
||||
LightSamplePreset preset;
|
||||
for (const json &jsetting : jpreset["lightSampleSettings"]) {
|
||||
LightSampleSetting setting;
|
||||
setting.groupBits = jsetting["groupBits"];
|
||||
setting.minSamples =jsetting["minSamples"];
|
||||
setting.maxSamples =jsetting["maxSamples"];
|
||||
preset.settings.push_back(setting);
|
||||
}
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
void gfx_rt64_load_light_sample_presets() {
|
||||
std::ifstream i(LIGHT_SAMPLE_PRESETS_FILENAME);
|
||||
if (i.is_open()) {
|
||||
json j;
|
||||
i >> j;
|
||||
|
||||
for (const json &jpreset : j["presets"]) {
|
||||
const std::string name = jpreset["name"];
|
||||
RT64.lightSamplePresets[name] = gfx_rt64_load_light_sample_preset(jpreset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unable to load " LIGHT_SAMPLE_PRESETS_FILENAME ". Defaulting to hard shadows only.\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t gfx_rt64_load_normal_map_mod(const json &jnormal) {
|
||||
return gfx_rt64_get_texture_name_hash(jnormal["name"]);
|
||||
}
|
||||
|
@ -333,16 +276,6 @@ void gfx_rt64_load_level_lights() {
|
|||
}
|
||||
}
|
||||
|
||||
void gfx_rt64_set_samples_level_lights() {
|
||||
for (int l = 0; l < MAX_LEVELS; l++) {
|
||||
for (int a = 0; a < MAX_AREAS; a++) {
|
||||
for (int i = 0; i < RT64.levelLightCounts[l][a]; i++) {
|
||||
gfx_rt64_set_light_samples(&RT64.levelLights[l][a][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_rt64_save_level_lights() {
|
||||
std::ofstream o(LEVEL_LIGHTS_FILENAME);
|
||||
if (o.is_open()) {
|
||||
|
@ -746,6 +679,16 @@ static void onkeyup(WPARAM w_param, LPARAM l_param) {
|
|||
}
|
||||
}
|
||||
|
||||
void gfx_rt64_apply_config() {
|
||||
RT64_VIEW_CONFIG config;
|
||||
config.resolutionScale = configRT64ResScale / 100.0f;
|
||||
config.softLightSamples = configRT64SphereLights ? 1 : 0;
|
||||
config.giBounces = configRT64GI ? 1 : 0;
|
||||
config.ambGiMixWeight = configRT64GIStrength / 100.0f;
|
||||
config.denoiserEnabled = configRT64Denoiser;
|
||||
RT64.lib.SetViewConfiguration(RT64.view, config);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK gfx_rt64_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
if ((RT64.inspector != nullptr) && RT64.lib.HandleMessageInspector(RT64.inspector, message, wParam, lParam)) {
|
||||
return true;
|
||||
|
@ -795,6 +738,11 @@ LRESULT CALLBACK gfx_rt64_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARA
|
|||
onkeyup(wParam, lParam);
|
||||
break;
|
||||
case WM_PAINT: {
|
||||
if (configWindow.settings_changed) {
|
||||
gfx_rt64_apply_config();
|
||||
configWindow.settings_changed = false;
|
||||
}
|
||||
|
||||
LARGE_INTEGER ElapsedMicroseconds;
|
||||
|
||||
// Run one game iteration.
|
||||
|
@ -864,7 +812,7 @@ static void gfx_rt64_wapi_init(const char *window_title) {
|
|||
wc.lpfnWndProc = gfx_rt64_wnd_proc;
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
|
||||
wc.lpszClassName = "RT64Sample";
|
||||
wc.lpszClassName = "RT64";
|
||||
RegisterClass(&wc);
|
||||
|
||||
// Create window.
|
||||
|
@ -1001,13 +949,8 @@ static void gfx_rt64_wapi_init(const char *window_title) {
|
|||
}
|
||||
}
|
||||
|
||||
// Load the light sample presets and choose the default preset.
|
||||
gfx_rt64_load_light_sample_presets();
|
||||
RT64.activeLightSamplePreset = RT64.lightSamplePresets[LIGHT_SAMPLE_PRESET_DEFAULT];
|
||||
|
||||
// Load the global lights from a file.
|
||||
gfx_rt64_load_level_lights();
|
||||
gfx_rt64_set_samples_level_lights();
|
||||
|
||||
// Initialize camera.
|
||||
RT64.viewMatrix = RT64.identityTransform;
|
||||
|
@ -1020,6 +963,9 @@ static void gfx_rt64_wapi_init(const char *window_title) {
|
|||
|
||||
// Load the texture mods from a file.
|
||||
gfx_rt64_load_texture_mods();
|
||||
|
||||
// Apply loaded configuration.
|
||||
gfx_rt64_apply_config();
|
||||
}
|
||||
|
||||
static void gfx_rt64_wapi_shutdown(void) {
|
||||
|
@ -1376,8 +1322,6 @@ static void gfx_rt64_add_light(RT64_LIGHT *lightMod, RT64_MATRIX4 transform) {
|
|||
auto &light = RT64.lights[RT64.lightCount++];
|
||||
light = *lightMod;
|
||||
|
||||
gfx_rt64_set_light_samples(&light);
|
||||
|
||||
light.position = transform_position_affine(transform, lightMod->position);
|
||||
|
||||
// Use a vector that points in all three axes in case the node uses non-uniform scaling to get an estimate.
|
||||
|
@ -1532,7 +1476,6 @@ static void gfx_rt64_rapi_start_frame(void) {
|
|||
RT64.lib.SetLightsInspector(RT64.inspector, lights, lightCount, MAX_LEVEL_LIGHTS);
|
||||
}
|
||||
|
||||
gfx_rt64_set_samples_level_lights();
|
||||
memcpy(RT64.lights, lights, sizeof(RT64_LIGHT) * (*lightCount));
|
||||
RT64.lightCount = *lightCount;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue