mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2026-04-25 07:27:53 -05:00
Implement input based shaders
Some checks are pending
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux32 flags:32 name:Linux GCC 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux64 flags:64 name:Linux GCC x64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm32 flags:arm32 name:Linux GCC ARM 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm64 flags:arm64 name:Linux GCC ARM 64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:macos name:macOS Apple Silicon os:macos-14]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win32 flags:-A Win32 name:Windows VS2022 Win32 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win64 flags:-A x64 name:Windows VS2022 x64 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:winarm64 flags:-A ARM64 name:Windows VS2022 ARM os:windows-2022]) (push) Waiting to run
CD / Create Pi Mono Setup (push) Blocked by required conditions
CD / Publishing (push) Blocked by required conditions
Some checks are pending
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux32 flags:32 name:Linux GCC 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linux64 flags:64 name:Linux GCC x64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm32 flags:arm32 name:Linux GCC ARM 32 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:linuxarm64 flags:arm64 name:Linux GCC ARM 64 os:ubuntu-latest]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:macos name:macOS Apple Silicon os:macos-14]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win32 flags:-A Win32 name:Windows VS2022 Win32 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:win64 flags:-A x64 name:Windows VS2022 x64 os:windows-2022]) (push) Waiting to run
CD / ${{ matrix.platform.name }} ${{ matrix.config.name }} (map[flags:-DBUILD_SHARED_LIBS=FALSE name:Static], map[artifact_name:winarm64 flags:-A ARM64 name:Windows VS2022 ARM os:windows-2022]) (push) Waiting to run
CD / Create Pi Mono Setup (push) Blocked by required conditions
CD / Publishing (push) Blocked by required conditions
This commit is contained in:
parent
4fb88bb057
commit
a9df82b89b
|
|
@ -399,7 +399,7 @@ if(MSVC)
|
|||
else()
|
||||
set_source_files_properties(source/conversions.cpp PROPERTIES COMPILE_OPTIONS "-O3")
|
||||
endif()
|
||||
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/CaptureDataBuffers.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${SOURCE_CPP_EXTRA_FILES})
|
||||
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES})
|
||||
|
||||
|
||||
if(NOT ("${EXTRA_DEPENDENCIES}" STREQUAL ""))
|
||||
|
|
@ -426,6 +426,16 @@ add_custom_command(
|
|||
DEPENDS ${CMAKE_SOURCE_DIR}/data/font.ttf ${TOOLS_DATA_DIR}/CMakeBin2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
set(SHADERS_LIST "")
|
||||
list(APPEND SHADERS_LIST ${CMAKE_SOURCE_DIR}/shaders/bit_crusher_fragment_shader.2_to_x_1_7.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_crusher_fragment_shader.2_to_x_1_6.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_crusher_fragment_shader_7.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_fragment_shader.2_to_x_0_6.frag ${CMAKE_SOURCE_DIR}/shaders/bit_merger_fragment_shader_7.frag ${CMAKE_SOURCE_DIR}/shaders/frame_blending_bit_crusher_fragment_shader.2_to_x_1_7.frag ${CMAKE_SOURCE_DIR}/shaders/frame_blending_fragment_shader.frag ${CMAKE_SOURCE_DIR}/shaders/no_effect_fragment_shader.frag)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${TOOLS_DATA_DIR}/shaders_list.cpp
|
||||
COMMENT "Prepare shaders list"
|
||||
COMMAND ${TOOLS_DATA_DIR}/CMakeShader2C${HOST_FINAL_EXTENSION} ${CMAKE_SOURCE_DIR}/shaders ${CMAKE_SOURCE_DIR}/source/shaders_list_template.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/source/shaders_list_template.cpp ${SHADERS_LIST} ${TOOLS_DATA_DIR}/CMakeShader2C${HOST_FINAL_EXTENSION}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
if(N3DSXL_LOOPY_SUPPORT AND WINDOWS_FTD3XX_USE_SHARED_LIB)
|
||||
add_custom_command(
|
||||
|
|
|
|||
39
include/Menus/VideoEffectsMenu.hpp
Normal file
39
include/Menus/VideoEffectsMenu.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __VIDEOEFFECTSMENU_HPP
|
||||
#define __VIDEOEFFECTSMENU_HPP
|
||||
|
||||
#include "OptionSelectionMenu.hpp"
|
||||
#include <chrono>
|
||||
|
||||
#include "TextRectangle.hpp"
|
||||
#include "sfml_gfx_structs.hpp"
|
||||
#include "display_structs.hpp"
|
||||
|
||||
enum VideoEffectsMenuOutAction{
|
||||
VIDEO_EFFECTS_MENU_NO_ACTION,
|
||||
VIDEO_EFFECTS_MENU_BACK,
|
||||
VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_INC,
|
||||
VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_DEC,
|
||||
VIDEO_EFFECTS_MENU_FRAME_BLENDING_INC,
|
||||
VIDEO_EFFECTS_MENU_FRAME_BLENDING_DEC,
|
||||
};
|
||||
|
||||
class VideoEffectsMenu : public OptionSelectionMenu {
|
||||
public:
|
||||
VideoEffectsMenu(bool font_load_success, sf::Font &text_font);
|
||||
~VideoEffectsMenu();
|
||||
void prepare(float scaling_factor, int view_size_x, int view_size_y, ScreenInfo *info);
|
||||
void insert_data();
|
||||
VideoEffectsMenuOutAction selected_index = VideoEffectsMenuOutAction::VIDEO_EFFECTS_MENU_NO_ACTION;
|
||||
void reset_output_option();
|
||||
protected:
|
||||
bool is_option_selectable(int index, int action);
|
||||
bool is_option_inc_dec(int index);
|
||||
void set_output_option(int index, int action);
|
||||
int get_num_options();
|
||||
std::string get_string_option(int index, int action);
|
||||
void class_setup();
|
||||
private:
|
||||
int *options_indexes;
|
||||
int num_enabled_options;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -39,6 +39,7 @@ enum VideoMenuOutAction{
|
|||
VIDEO_MENU_NON_INT_SCALING,
|
||||
VIDEO_MENU_SCALING_RATIO_SETTINGS,
|
||||
VIDEO_MENU_CHANGE_TITLEBAR,
|
||||
VIDEO_MENU_VIDEO_EFFECTS_SETTINGS,
|
||||
};
|
||||
|
||||
class VideoMenu : public OptionSelectionMenu {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
|
||||
#include "utils.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
#include "shaders_list.hpp"
|
||||
|
||||
enum ScreenType { TOP, BOTTOM, JOINT };
|
||||
enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END };
|
||||
enum NonIntegerScalingModes { SMALLER_PRIORITY, INVERSE_PROPORTIONAL_PRIORITY, EQUAL_PRIORITY, PROPORTIONAL_PRIORITY, BIGGER_PRIORITY, END_NONINT_SCALE_MODES };
|
||||
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE };
|
||||
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE, VIDEO_EFFECTS_MENU_TYPE };
|
||||
enum InputColorspaceMode { FULL_COLORSPACE, DS_COLORSPACE, GBA_COLORSPACE, INPUT_COLORSPACE_END };
|
||||
enum FrameBlendingMode { NO_FRAME_BLENDING, FULL_FRAME_BLENDING, DS_3D_BOTH_SCREENS_FRAME_BLENDING, FRAME_BLENDING_END };
|
||||
|
||||
struct ScreenInfo {
|
||||
bool is_blurred;
|
||||
|
|
@ -39,6 +42,10 @@ struct ScreenInfo {
|
|||
bool use_non_integer_scaling_bottom;
|
||||
bool failed_fullscreen;
|
||||
bool have_titlebar;
|
||||
InputColorspaceMode in_colorspace_top;
|
||||
InputColorspaceMode in_colorspace_bot;
|
||||
FrameBlendingMode frame_blending_top;
|
||||
FrameBlendingMode frame_blending_bot;
|
||||
};
|
||||
|
||||
struct DisplayData {
|
||||
|
|
|
|||
|
|
@ -31,9 +31,11 @@
|
|||
#include "ActionSelectionMenu.hpp"
|
||||
#include "ScalingRatioMenu.hpp"
|
||||
#include "ISNitroMenu.hpp"
|
||||
#include "VideoEffectsMenu.hpp"
|
||||
#include "display_structs.hpp"
|
||||
#include "WindowCommands.hpp"
|
||||
#include "event_structs.hpp"
|
||||
#include "shaders_list.hpp"
|
||||
|
||||
struct HeldTime {
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
|
||||
|
|
@ -152,6 +154,7 @@ private:
|
|||
ActionSelectionMenu *action_selection_menu;
|
||||
ISNitroMenu *is_nitro_menu;
|
||||
ScalingRatioMenu *scaling_ratio_menu;
|
||||
VideoEffectsMenu *video_effects_menu;
|
||||
std::vector<const CropData*> possible_crops;
|
||||
std::vector<const CropData*> possible_crops_ds;
|
||||
std::vector<const CropData*> possible_crops_with_games;
|
||||
|
|
@ -170,6 +173,7 @@ private:
|
|||
FPSArray poll_fps;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_poll_time;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_menu_change_time;
|
||||
int curr_frame_texture_pos = 0;
|
||||
|
||||
sf::Texture in_tex;
|
||||
|
||||
|
|
@ -180,7 +184,7 @@ private:
|
|||
volatile bool scheduled_work_on_window;
|
||||
volatile bool is_thread_done;
|
||||
|
||||
sf::Shader *in_top_shader, *in_bot_shader, *top_shader, *bot_shader;
|
||||
bool was_last_frame_null;
|
||||
sf::RectangleShape m_in_rect_top, m_in_rect_bot;
|
||||
out_rect_data m_out_rect_top, m_out_rect_bot;
|
||||
ScreenType m_stype;
|
||||
|
|
@ -239,6 +243,8 @@ private:
|
|||
void non_int_scaling_change(bool target_top);
|
||||
void non_int_mode_change(bool positive);
|
||||
void titlebar_change();
|
||||
void input_colorspace_mode_change(bool positive);
|
||||
void frame_blending_mode_change(bool positive);
|
||||
bool query_reset_request();
|
||||
void reset_held_times();
|
||||
void poll_window(bool do_everything);
|
||||
|
|
@ -249,8 +255,11 @@ private:
|
|||
bool window_needs_work();
|
||||
void window_factory(bool is_main_thread);
|
||||
void update_texture();
|
||||
int _choose_shader(bool is_input, bool is_top);
|
||||
int choose_shader(bool is_input, bool is_top);
|
||||
void pre_texture_conversion_processing();
|
||||
void post_texture_conversion_processing(out_rect_data &rect_data, const sf::RectangleShape &in_rect, bool actually_draw, bool is_top, bool is_debug);
|
||||
void draw_rect_to_window(const sf::RectangleShape &out_rect, bool is_top);
|
||||
void window_bg_processing();
|
||||
void display_data_to_window(bool actually_draw, bool is_debug = false);
|
||||
void window_render_call();
|
||||
|
|
@ -299,6 +308,7 @@ private:
|
|||
void setup_relative_pos_menu(bool reset_data = true);
|
||||
void setup_scaling_ratio_menu(bool reset_data = true);
|
||||
void setup_is_nitro_menu(bool reset_data = true);
|
||||
void setup_video_effects_menu(bool reset_data = true);
|
||||
void update_connection();
|
||||
};
|
||||
|
||||
|
|
@ -327,5 +337,7 @@ void update_connected_3ds_ds(FrontendData* frontend_data, const CaptureDevice &o
|
|||
void update_connected_specific_settings(FrontendData* frontend_data, const CaptureDevice &cc_device);
|
||||
void screen_display_thread(WindowScreen *screen);
|
||||
std::string get_name_non_int_mode(NonIntegerScalingModes input);
|
||||
std::string get_name_frame_blending_mode(FrameBlendingMode input);
|
||||
std::string get_name_input_colorspace_mode(InputColorspaceMode input);
|
||||
void default_sleep(float wanted_ms = -1);
|
||||
#endif
|
||||
|
|
|
|||
45
include/shaders_list.hpp
Normal file
45
include/shaders_list.hpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef __SHADERS_LIST_HPP
|
||||
#define __SHADERS_LIST_HPP
|
||||
|
||||
#include<string>
|
||||
|
||||
enum shader_list_enum {
|
||||
NO_EFFECT_FRAGMENT_SHADER,
|
||||
FRAME_BLENDING_FRAGMENT_SHADER,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_1,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_2,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_3,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_4,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_5,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_6,
|
||||
BIT_CRUSHER_FRAGMENT_SHADER_7,
|
||||
BIT_MERGER_FRAGMENT_SHADER_0,
|
||||
BIT_MERGER_FRAGMENT_SHADER_1,
|
||||
BIT_MERGER_FRAGMENT_SHADER_2,
|
||||
BIT_MERGER_FRAGMENT_SHADER_3,
|
||||
BIT_MERGER_FRAGMENT_SHADER_4,
|
||||
BIT_MERGER_FRAGMENT_SHADER_5,
|
||||
BIT_MERGER_FRAGMENT_SHADER_6,
|
||||
BIT_MERGER_FRAGMENT_SHADER_7,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_1,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_2,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_3,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_4,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_5,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_6,
|
||||
BIT_MERGER_CRUSHER_FRAGMENT_SHADER_7,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_1,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_2,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_3,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_4,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_5,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_6,
|
||||
FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_7,
|
||||
|
||||
TOTAL_NUM_SHADERS
|
||||
};
|
||||
|
||||
std::string get_shader_string(shader_list_enum requested_shader);
|
||||
void shader_strings_init();
|
||||
|
||||
#endif
|
||||
9
shaders/bit_crusher_fragment_shader.2_to_x_1_7.frag
Normal file
9
shaders/bit_crusher_fragment_shader.2_to_x_1_7.frag
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uniform sampler2D Texture0;
|
||||
|
||||
const float inner_divisor = x;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
const float normalizer = inner_divisor * (255.0 / (256.0 - inner_divisor)) / 255.0;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = clamp(floor(texture2D(Texture0, gl_TexCoord[0].xy) * bit_crusher) * normalizer, 0.0, 1.0);
|
||||
};
|
||||
19
shaders/bit_merger_crusher_fragment_shader.2_to_x_1_6.frag
Normal file
19
shaders/bit_merger_crusher_fragment_shader.2_to_x_1_6.frag
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
const float inner_divisor = x;
|
||||
const float inner_divisor_greater = inner_divisor * 2.0;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
const float bit_crusher_greater = 255.0 / inner_divisor_greater;
|
||||
const float normalizer = inner_divisor * (255.0 / (256.0 - inner_divisor)) / 255.0;
|
||||
|
||||
vec4 get_nth_bit_component(vec4 colors) {
|
||||
return (floor(colors * bit_crusher) * inner_divisor) - (floor(colors * bit_crusher_greater) * inner_divisor_greater);
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
vec4 actual_nth_bit_component = get_nth_bit_component(gl_FragColor);
|
||||
vec4 old_nth_bit_component = get_nth_bit_component(OldFragColor);
|
||||
gl_FragColor = clamp((((floor(gl_FragColor * bit_crusher_greater) * inner_divisor_greater) + ((actual_nth_bit_component + old_nth_bit_component) / 2.0)) / inner_divisor) * normalizer, 0.0, 1.0);
|
||||
};
|
||||
17
shaders/bit_merger_crusher_fragment_shader_7.frag
Normal file
17
shaders/bit_merger_crusher_fragment_shader_7.frag
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
const float inner_divisor = 128.0;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
const float normalizer = inner_divisor * (255.0 / (256.0 - inner_divisor)) / 255.0;
|
||||
|
||||
vec4 get_nth_bit_component(vec4 colors) {
|
||||
return floor(colors * bit_crusher) * inner_divisor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
vec4 actual_nth_bit_component = get_nth_bit_component(gl_FragColor);
|
||||
vec4 old_nth_bit_component = get_nth_bit_component(OldFragColor);
|
||||
gl_FragColor = clamp(((((actual_nth_bit_component + old_nth_bit_component) / 2.0)) / inner_divisor) * normalizer, 0.0, 1.0);
|
||||
};
|
||||
19
shaders/bit_merger_fragment_shader.2_to_x_0_6.frag
Normal file
19
shaders/bit_merger_fragment_shader.2_to_x_0_6.frag
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
const float inner_divisor = x;
|
||||
const float inner_divisor_greater = inner_divisor * 2.0;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
const float bit_crusher_greater = 255.0 / inner_divisor_greater;
|
||||
|
||||
vec4 get_nth_bit_component(vec4 colors) {
|
||||
return (floor(colors * bit_crusher) * inner_divisor) - (floor(colors * bit_crusher_greater) * inner_divisor_greater);
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
vec4 actual_nth_bit_component = get_nth_bit_component(gl_FragColor);
|
||||
vec4 old_nth_bit_component = get_nth_bit_component(OldFragColor);
|
||||
gl_FragColor = clamp((floor(gl_FragColor * 255.0) - actual_nth_bit_component + ((actual_nth_bit_component + old_nth_bit_component) / 2.0)) / 255.0, 0.0, 1.0);
|
||||
};
|
||||
16
shaders/bit_merger_fragment_shader_7.frag
Normal file
16
shaders/bit_merger_fragment_shader_7.frag
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
const float inner_divisor = 128.0;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
|
||||
vec4 get_nth_bit_component(vec4 colors) {
|
||||
return floor(colors * bit_crusher) * inner_divisor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
vec4 actual_nth_bit_component = get_nth_bit_component(gl_FragColor);
|
||||
vec4 old_nth_bit_component = get_nth_bit_component(OldFragColor);
|
||||
gl_FragColor = clamp((floor(gl_FragColor * 255.0) - actual_nth_bit_component + ((actual_nth_bit_component + old_nth_bit_component) / 2.0)) / 255.0, 0.0, 1.0);
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
|
||||
const float inner_divisor = x;
|
||||
const float bit_crusher = 255.0 / inner_divisor;
|
||||
const float normalizer = inner_divisor * (255.0 / (256.0 - inner_divisor)) / 255.0;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
gl_FragColor = clamp(floor(gl_FragColor * bit_crusher) * normalizer, 0.0, 1.0);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
OldFragColor = clamp(floor(OldFragColor * bit_crusher) * normalizer, 0.0, 1.0);
|
||||
gl_FragColor = (gl_FragColor + OldFragColor) / 2.0;
|
||||
};
|
||||
8
shaders/frame_blending_fragment_shader.frag
Normal file
8
shaders/frame_blending_fragment_shader.frag
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
uniform sampler2D Texture0;
|
||||
uniform vec2 old_frame_offset;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
vec4 OldFragColor = texture2D(Texture0, gl_TexCoord[0].xy + old_frame_offset);
|
||||
gl_FragColor = (gl_FragColor + OldFragColor) / 2.0;
|
||||
};
|
||||
5
shaders/no_effect_fragment_shader.frag
Normal file
5
shaders/no_effect_fragment_shader.frag
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
uniform sampler2D Texture0;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);
|
||||
};
|
||||
126
source/Menus/VideoEffectsMenu.cpp
Normal file
126
source/Menus/VideoEffectsMenu.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include "VideoEffectsMenu.hpp"
|
||||
#include "frontend.hpp"
|
||||
|
||||
#define NUM_TOTAL_MENU_OPTIONS (sizeof(pollable_options)/sizeof(pollable_options[0]))
|
||||
|
||||
struct VideoEffectsMenuOptionInfo {
|
||||
const std::string base_name;
|
||||
const std::string false_name;
|
||||
const bool is_selectable;
|
||||
const bool is_inc;
|
||||
const std::string dec_str;
|
||||
const std::string inc_str;
|
||||
const VideoEffectsMenuOutAction inc_out_action;
|
||||
const VideoEffectsMenuOutAction out_action;
|
||||
};
|
||||
|
||||
static const VideoEffectsMenuOptionInfo input_colorspace_option = {
|
||||
.base_name = "Input Colors", .false_name = "", .is_selectable = true,
|
||||
.is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_INC,
|
||||
.out_action = VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_DEC};
|
||||
|
||||
static const VideoEffectsMenuOptionInfo frame_blending_option = {
|
||||
.base_name = "Frame Blending", .false_name = "", .is_selectable = true,
|
||||
.is_inc = true, .dec_str = "<", .inc_str = ">", .inc_out_action = VIDEO_EFFECTS_MENU_FRAME_BLENDING_INC,
|
||||
.out_action = VIDEO_EFFECTS_MENU_FRAME_BLENDING_DEC};
|
||||
|
||||
static const VideoEffectsMenuOptionInfo* pollable_options[] = {
|
||||
&input_colorspace_option,
|
||||
&frame_blending_option,
|
||||
};
|
||||
|
||||
VideoEffectsMenu::VideoEffectsMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){
|
||||
this->options_indexes = new int[NUM_TOTAL_MENU_OPTIONS];
|
||||
this->initialize(font_load_success, text_font);
|
||||
this->num_enabled_options = 0;
|
||||
}
|
||||
|
||||
VideoEffectsMenu::~VideoEffectsMenu() {
|
||||
delete []this->options_indexes;
|
||||
}
|
||||
|
||||
void VideoEffectsMenu::class_setup() {
|
||||
this->num_options_per_screen = 5;
|
||||
this->min_elements_text_scaling_factor = num_options_per_screen + 2;
|
||||
this->width_factor_menu = 16;
|
||||
this->width_divisor_menu = 9;
|
||||
this->base_height_factor_menu = 12;
|
||||
this->base_height_divisor_menu = 6;
|
||||
this->min_text_size = 0.3;
|
||||
this->max_width_slack = 1.1;
|
||||
this->menu_color = sf::Color(30, 30, 60, 192);
|
||||
this->title = "Video Effects Settings";
|
||||
this->show_back_x = true;
|
||||
this->show_x = false;
|
||||
this->show_title = true;
|
||||
}
|
||||
|
||||
void VideoEffectsMenu::insert_data() {
|
||||
this->num_enabled_options = 0;
|
||||
for(int i = 0; i < NUM_TOTAL_MENU_OPTIONS; i++) {
|
||||
this->options_indexes[this->num_enabled_options] = i;
|
||||
this->num_enabled_options++;
|
||||
}
|
||||
this->prepare_options();
|
||||
}
|
||||
|
||||
void VideoEffectsMenu::reset_output_option() {
|
||||
this->selected_index = VideoEffectsMenuOutAction::VIDEO_EFFECTS_MENU_NO_ACTION;
|
||||
}
|
||||
|
||||
void VideoEffectsMenu::set_output_option(int index, int action) {
|
||||
if(index == BACK_X_OUTPUT_OPTION)
|
||||
this->selected_index = VIDEO_EFFECTS_MENU_BACK;
|
||||
else if((action == INC_ACTION) && this->is_option_inc_dec(index))
|
||||
this->selected_index = pollable_options[this->options_indexes[index]]->inc_out_action;
|
||||
else
|
||||
this->selected_index = pollable_options[this->options_indexes[index]]->out_action;
|
||||
}
|
||||
|
||||
int VideoEffectsMenu::get_num_options() {
|
||||
return this->num_enabled_options;
|
||||
}
|
||||
|
||||
std::string VideoEffectsMenu::get_string_option(int index, int action) {
|
||||
if((action == INC_ACTION) && this->is_option_inc_dec(index))
|
||||
return pollable_options[this->options_indexes[index]]->inc_str;
|
||||
if((action == DEC_ACTION) && this->is_option_inc_dec(index))
|
||||
return pollable_options[this->options_indexes[index]]->dec_str;
|
||||
if(action == FALSE_ACTION)
|
||||
return pollable_options[this->options_indexes[index]]->false_name;
|
||||
return pollable_options[this->options_indexes[index]]->base_name;
|
||||
}
|
||||
|
||||
bool VideoEffectsMenu::is_option_selectable(int index, int action) {
|
||||
return pollable_options[this->options_indexes[index]]->is_selectable;
|
||||
}
|
||||
|
||||
bool VideoEffectsMenu::is_option_inc_dec(int index) {
|
||||
return pollable_options[this->options_indexes[index]]->is_inc;
|
||||
}
|
||||
|
||||
void VideoEffectsMenu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y, ScreenInfo *info) {
|
||||
int num_pages = this->get_num_pages();
|
||||
if(this->future_data.page >= num_pages)
|
||||
this->future_data.page = num_pages - 1;
|
||||
int start = this->future_data.page * this->num_options_per_screen;
|
||||
for(int i = 0; i < this->num_options_per_screen + 1; i++) {
|
||||
int index = (i * this->single_option_multiplier) + this->elements_start_id;
|
||||
if(!this->future_enabled_labels[index])
|
||||
continue;
|
||||
int real_index = start + i;
|
||||
int option_index = this->options_indexes[real_index];
|
||||
switch(pollable_options[option_index]->out_action) {
|
||||
case VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_DEC:
|
||||
this->labels[index]->setText(this->setTextOptionString(real_index, get_name_input_colorspace_mode(info->in_colorspace_top)));
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_FRAME_BLENDING_DEC:
|
||||
this->labels[index]->setText(this->setTextOptionString(real_index, get_name_frame_blending_mode(info->frame_blending_top)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->base_prepare(menu_scaling_factor, view_size_x, view_size_y);
|
||||
}
|
||||
|
|
@ -179,6 +179,13 @@ static const VideoMenuOptionInfo titlebar_change_option = {
|
|||
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = VIDEO_MENU_NO_ACTION,
|
||||
.out_action = VIDEO_MENU_CHANGE_TITLEBAR};
|
||||
|
||||
static const VideoMenuOptionInfo video_effects_settings_option = {
|
||||
.base_name = "Video Effects Settings", .false_name = "",
|
||||
.active_fullscreen = true, .active_windowed_screen = true, .requires_titlebar_possible = false,
|
||||
.active_joint_screen = true, .active_top_screen = true, .active_bottom_screen = true,
|
||||
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = VIDEO_MENU_NO_ACTION,
|
||||
.out_action = VIDEO_MENU_VIDEO_EFFECTS_SETTINGS};
|
||||
|
||||
static const VideoMenuOptionInfo* pollable_options[] = {
|
||||
&crop_option,
|
||||
&window_scaling_option,
|
||||
|
|
@ -195,6 +202,7 @@ static const VideoMenuOptionInfo* pollable_options[] = {
|
|||
&rotation_settings_option,
|
||||
&top_one_rotation_option,
|
||||
&bottom_one_rotation_option,
|
||||
&video_effects_settings_option,
|
||||
&top_par_option,
|
||||
&bot_par_option,
|
||||
&one_par_option,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <SFML/OpenGL.hpp>
|
||||
#include <cstring>
|
||||
#include "font_ttf.h"
|
||||
#include "shaders_list.hpp"
|
||||
#include "devicecapture.hpp"
|
||||
|
||||
#define LEFT_ROUNDED_PADDING 5
|
||||
|
|
@ -15,16 +16,20 @@
|
|||
#define FALLBACK_FS_RESOLUTION_HEIGHT 1080
|
||||
#define FALLBACK_FS_RESOLUTION_BPP 32
|
||||
|
||||
const std::string no_effect_fragment_shader = \
|
||||
"uniform sampler2D Texture0;" \
|
||||
"" \
|
||||
"void main() {" \
|
||||
" gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);" \
|
||||
"}";
|
||||
#define NUM_FRAMES_BLENDED 2
|
||||
|
||||
static bool loaded_shaders = false;
|
||||
static int n_shader_refs = 0;
|
||||
static sf::Shader *base_shader = NULL;
|
||||
|
||||
struct shader_and_data {
|
||||
shader_and_data(shader_list_enum value) : shader(sf::Shader()), is_valid(false), shader_enum(value) {}
|
||||
|
||||
sf::Shader shader;
|
||||
bool is_valid;
|
||||
shader_list_enum shader_enum;
|
||||
};
|
||||
|
||||
static std::vector<shader_and_data> usable_shaders;
|
||||
|
||||
WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts, ConsumerMutex *draw_lock, bool created_proper_folder) {
|
||||
this->draw_lock = draw_lock;
|
||||
|
|
@ -46,7 +51,7 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp
|
|||
FPSArrayInit(&this->in_fps);
|
||||
FPSArrayInit(&this->draw_fps);
|
||||
FPSArrayInit(&this->poll_fps);
|
||||
(void)this->in_tex.resize({MAX_IN_VIDEO_WIDTH, MAX_IN_VIDEO_HEIGHT});
|
||||
(void)this->in_tex.resize({MAX_IN_VIDEO_WIDTH, MAX_IN_VIDEO_HEIGHT * NUM_FRAMES_BLENDED});
|
||||
this->m_in_rect_top.setTexture(&this->in_tex);
|
||||
this->m_in_rect_bot.setTexture(&this->in_tex);
|
||||
this->display_data = display_data;
|
||||
|
|
@ -71,15 +76,23 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp
|
|||
if(this->display_data->mono_app_mode && this->m_stype == ScreenType::JOINT)
|
||||
this->m_info.is_fullscreen = true;
|
||||
if(sf::Shader::isAvailable() && (!loaded_shaders)) {
|
||||
base_shader = new sf::Shader();
|
||||
if(base_shader->loadFromMemory(no_effect_fragment_shader, sf::Shader::Type::Fragment))
|
||||
loaded_shaders = true;
|
||||
shader_strings_init();
|
||||
for(int i = 0; i < TOTAL_NUM_SHADERS; i++) {
|
||||
usable_shaders.emplace_back(static_cast<shader_list_enum>(i));
|
||||
shader_and_data* current_shader = &usable_shaders[usable_shaders.size()-1];
|
||||
if(current_shader->shader.loadFromMemory(get_shader_string(current_shader->shader_enum), sf::Shader::Type::Fragment)) {
|
||||
current_shader->is_valid = true;
|
||||
auto* const defaultStreamBuffer = sf::err().rdbuf();
|
||||
sf::err().rdbuf(nullptr);
|
||||
sf::Glsl::Vec2 old_pos = {0.0, 0.0};
|
||||
current_shader->shader.setUniform("old_frame_offset", old_pos);
|
||||
sf::err().rdbuf(defaultStreamBuffer);
|
||||
}
|
||||
}
|
||||
loaded_shaders = true;
|
||||
}
|
||||
n_shader_refs += 1;
|
||||
this->in_top_shader = base_shader;
|
||||
this->in_bot_shader = base_shader;
|
||||
this->top_shader = base_shader;
|
||||
this->bot_shader = base_shader;
|
||||
this->was_last_frame_null = true;
|
||||
this->created_proper_folder = created_proper_folder;
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +106,8 @@ WindowScreen::~WindowScreen() {
|
|||
FPSArrayDestroy(&this->draw_fps);
|
||||
FPSArrayDestroy(&this->poll_fps);
|
||||
if(sf::Shader::isAvailable() && (n_shader_refs == 1)) {
|
||||
delete base_shader;
|
||||
while(!usable_shaders.empty())
|
||||
usable_shaders.pop_back();
|
||||
loaded_shaders = false;
|
||||
}
|
||||
n_shader_refs -= 1;
|
||||
|
|
@ -212,6 +226,7 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) {
|
|||
this->last_poll_time = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
if(this->m_win.isOpen() || this->loaded_operations.call_create) {
|
||||
this->curr_frame_texture_pos = (this->curr_frame_texture_pos + 1) % NUM_FRAMES_BLENDED;
|
||||
auto curr_time = std::chrono::high_resolution_clock::now();
|
||||
const std::chrono::duration<double> diff = curr_time - this->last_draw_time;
|
||||
FPSArrayInsertElement(&draw_fps, diff.count());
|
||||
|
|
@ -219,8 +234,10 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) {
|
|||
WindowScreen::reset_operations(future_operations);
|
||||
if(out_buf != NULL)
|
||||
memcpy(this->saved_buf, out_buf, sizeof(VideoOutputData));
|
||||
else
|
||||
else {
|
||||
memset(this->saved_buf, 0, sizeof(VideoOutputData));
|
||||
this->was_last_frame_null = true;
|
||||
}
|
||||
loaded_info = m_info;
|
||||
this->notification->setTextFactor(this->loaded_info.menu_scaling_factor);
|
||||
this->notification->prepareRenderText();
|
||||
|
|
@ -244,6 +261,8 @@ void WindowScreen::draw(double frame_time, VideoOutputData* out_buf) {
|
|||
if(!this->loaded_info.async)
|
||||
this->display_call(true);
|
||||
}
|
||||
else
|
||||
this->was_last_frame_null = true;
|
||||
}
|
||||
|
||||
void WindowScreen::update_connection() {
|
||||
|
|
@ -460,7 +479,7 @@ void WindowScreen::update_texture() {
|
|||
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
if(this->capture_status->device.video_data_type == VIDEO_DATA_BGR16)
|
||||
type = GL_UNSIGNED_SHORT_5_6_5_REV;
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(0), static_cast<GLint>(0), static_cast<GLsizei>(this->capture_status->device.width), static_cast<GLsizei>(this->capture_status->device.height), format, type, this->saved_buf);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(0), static_cast<GLint>(this->curr_frame_texture_pos * MAX_IN_VIDEO_HEIGHT), static_cast<GLsizei>(this->capture_status->device.width), static_cast<GLsizei>(this->capture_status->device.height), format, type, this->saved_buf);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
// Force an OpenGL flush, so that the texture data will appear updated
|
||||
|
|
@ -480,6 +499,61 @@ void WindowScreen::pre_texture_conversion_processing() {
|
|||
this->draw_lock->unlock();
|
||||
}
|
||||
|
||||
int WindowScreen::_choose_shader(bool is_input, bool is_top) {
|
||||
if(!is_input)
|
||||
return NO_EFFECT_FRAGMENT_SHADER;
|
||||
if(this->was_last_frame_null) {
|
||||
this->was_last_frame_null = false;
|
||||
return NO_EFFECT_FRAGMENT_SHADER;
|
||||
}
|
||||
InputColorspaceMode *in_colorspace = &this->loaded_info.in_colorspace_top;
|
||||
FrameBlendingMode *frame_blending = &this->loaded_info.frame_blending_top;
|
||||
if(!is_top) {
|
||||
in_colorspace = &this->loaded_info.in_colorspace_bot;
|
||||
frame_blending = &this->loaded_info.frame_blending_bot;
|
||||
}
|
||||
|
||||
switch(*frame_blending) {
|
||||
case FULL_FRAME_BLENDING:
|
||||
switch(*in_colorspace) {
|
||||
case DS_COLORSPACE:
|
||||
return FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_2;
|
||||
case GBA_COLORSPACE:
|
||||
return FRAME_BLENDING_BIT_CRUSHER_FRAGMENT_SHADER_3;
|
||||
default:
|
||||
return FRAME_BLENDING_FRAGMENT_SHADER;
|
||||
}
|
||||
break;
|
||||
case DS_3D_BOTH_SCREENS_FRAME_BLENDING:
|
||||
switch(*in_colorspace) {
|
||||
case DS_COLORSPACE:
|
||||
return BIT_MERGER_CRUSHER_FRAGMENT_SHADER_2;
|
||||
case GBA_COLORSPACE:
|
||||
return BIT_CRUSHER_FRAGMENT_SHADER_3;
|
||||
default:
|
||||
return BIT_MERGER_FRAGMENT_SHADER_2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch(*in_colorspace) {
|
||||
case DS_COLORSPACE:
|
||||
return BIT_CRUSHER_FRAGMENT_SHADER_2;
|
||||
case GBA_COLORSPACE:
|
||||
return BIT_CRUSHER_FRAGMENT_SHADER_3;
|
||||
default:
|
||||
return NO_EFFECT_FRAGMENT_SHADER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int WindowScreen::choose_shader(bool is_input, bool is_top) {
|
||||
int chosen_shader = _choose_shader(is_input, is_top);
|
||||
if((chosen_shader >= 0) && (chosen_shader < usable_shaders.size()) && usable_shaders[chosen_shader].is_valid)
|
||||
return chosen_shader;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void WindowScreen::post_texture_conversion_processing(out_rect_data &rect_data, const sf::RectangleShape &in_rect, bool actually_draw, bool is_top, bool is_debug) {
|
||||
if((is_top && this->m_stype == ScreenType::BOTTOM) || ((!is_top) && this->m_stype == ScreenType::TOP))
|
||||
return;
|
||||
|
|
@ -494,21 +568,50 @@ void WindowScreen::post_texture_conversion_processing(out_rect_data &rect_data,
|
|||
}
|
||||
else {
|
||||
rect_data.out_tex.clear();
|
||||
sf::RectangleShape final_in_rect = in_rect;
|
||||
sf::IntRect text_coords_rect = final_in_rect.getTextureRect();
|
||||
text_coords_rect.position.y += this->curr_frame_texture_pos * MAX_IN_VIDEO_HEIGHT;
|
||||
final_in_rect.setTextureRect(text_coords_rect);
|
||||
if(this->capture_status->connected && actually_draw) {
|
||||
bool use_default_shader = true;
|
||||
if(sf::Shader::isAvailable()) {
|
||||
sf::Shader* chosen_shader = this->in_top_shader;
|
||||
if(!is_top)
|
||||
chosen_shader = this->in_bot_shader;
|
||||
rect_data.out_tex.draw(in_rect, chosen_shader);
|
||||
int chosen_shader = choose_shader(true, is_top);
|
||||
if(chosen_shader >= 0) {
|
||||
float old_frame_pos_y = 1.0 / NUM_FRAMES_BLENDED;
|
||||
if(this->curr_frame_texture_pos == 1)
|
||||
old_frame_pos_y = -1.0 / NUM_FRAMES_BLENDED;
|
||||
sf::Glsl::Vec2 old_pos = {0.0, old_frame_pos_y};
|
||||
usable_shaders[chosen_shader].shader.setUniform("old_frame_offset", old_pos);
|
||||
rect_data.out_tex.draw(final_in_rect, &usable_shaders[chosen_shader].shader);
|
||||
use_default_shader = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
rect_data.out_tex.draw(in_rect);
|
||||
if(use_default_shader)
|
||||
rect_data.out_tex.draw(final_in_rect);
|
||||
//Place postprocessing effects here
|
||||
}
|
||||
}
|
||||
rect_data.out_tex.display();
|
||||
}
|
||||
|
||||
void WindowScreen::draw_rect_to_window(const sf::RectangleShape &out_rect, bool is_top) {
|
||||
if((is_top && this->m_stype == ScreenType::BOTTOM) || ((!is_top) && this->m_stype == ScreenType::TOP))
|
||||
return;
|
||||
if(this->loaded_menu == CONNECT_MENU_TYPE)
|
||||
return;
|
||||
|
||||
bool use_default_shader = true;
|
||||
if(sf::Shader::isAvailable()) {
|
||||
int chosen_shader = choose_shader(false, is_top);
|
||||
if(chosen_shader >= 0) {
|
||||
this->m_win.draw(out_rect, &usable_shaders[chosen_shader].shader);
|
||||
use_default_shader = false;
|
||||
}
|
||||
}
|
||||
if(use_default_shader)
|
||||
this->m_win.draw(out_rect);
|
||||
}
|
||||
|
||||
void WindowScreen::window_bg_processing() {
|
||||
//Place BG processing here
|
||||
}
|
||||
|
|
@ -523,20 +626,8 @@ void WindowScreen::display_data_to_window(bool actually_draw, bool is_debug) {
|
|||
else
|
||||
this->m_win.clear();
|
||||
this->window_bg_processing();
|
||||
if(this->loaded_menu != CONNECT_MENU_TYPE) {
|
||||
if (this->m_stype != ScreenType::BOTTOM) {
|
||||
if (sf::Shader::isAvailable())
|
||||
this->m_win.draw(this->m_out_rect_top.out_rect, this->top_shader);
|
||||
else
|
||||
this->m_win.draw(this->m_out_rect_top.out_rect);
|
||||
}
|
||||
if (this->m_stype != ScreenType::TOP) {
|
||||
if (sf::Shader::isAvailable())
|
||||
this->m_win.draw(this->m_out_rect_bot.out_rect, this->bot_shader);
|
||||
else
|
||||
this->m_win.draw(this->m_out_rect_bot.out_rect);
|
||||
}
|
||||
}
|
||||
this->draw_rect_to_window(this->m_out_rect_top.out_rect, true);
|
||||
this->draw_rect_to_window(this->m_out_rect_bot.out_rect, false);
|
||||
this->execute_menu_draws();
|
||||
this->notification->draw(this->m_win);
|
||||
this->m_win.display();
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ void WindowScreen::init_menus() {
|
|||
this->action_selection_menu = new ActionSelectionMenu(this->font_load_success, this->text_font);
|
||||
this->scaling_ratio_menu = new ScalingRatioMenu(this->font_load_success, this->text_font);
|
||||
this->is_nitro_menu = new ISNitroMenu(this->font_load_success, this->text_font);
|
||||
this->video_effects_menu = new VideoEffectsMenu(this->font_load_success, this->text_font);
|
||||
}
|
||||
|
||||
void WindowScreen::destroy_menus() {
|
||||
|
|
@ -132,6 +133,7 @@ void WindowScreen::destroy_menus() {
|
|||
delete this->action_selection_menu;
|
||||
delete this->scaling_ratio_menu;
|
||||
delete this->is_nitro_menu;
|
||||
delete this->video_effects_menu;
|
||||
}
|
||||
|
||||
void WindowScreen::set_close(int ret_val) {
|
||||
|
|
@ -371,6 +373,22 @@ void WindowScreen::titlebar_change() {
|
|||
this->future_operations.call_titlebar = true;
|
||||
}
|
||||
|
||||
void WindowScreen::input_colorspace_mode_change(bool positive) {
|
||||
int change = 1;
|
||||
if(!positive)
|
||||
change = INPUT_COLORSPACE_END - 1;
|
||||
this->m_info.in_colorspace_top = static_cast<InputColorspaceMode>((this->m_info.in_colorspace_top + change) % INPUT_COLORSPACE_END);
|
||||
this->m_info.in_colorspace_bot = this->m_info.in_colorspace_top;
|
||||
}
|
||||
|
||||
void WindowScreen::frame_blending_mode_change(bool positive) {
|
||||
int change = 1;
|
||||
if(!positive)
|
||||
change = FRAME_BLENDING_END - 1;
|
||||
this->m_info.frame_blending_top = static_cast<FrameBlendingMode>((this->m_info.frame_blending_top + change) % FRAME_BLENDING_END);
|
||||
this->m_info.frame_blending_bot = this->m_info.frame_blending_top;
|
||||
}
|
||||
|
||||
bool WindowScreen::can_execute_cmd(const WindowCommand* window_cmd, bool is_extra, bool is_always) {
|
||||
if((!window_cmd->usable_always) && is_always)
|
||||
return false;
|
||||
|
|
@ -936,6 +954,18 @@ void WindowScreen::setup_is_nitro_menu(bool reset_data) {
|
|||
}
|
||||
}
|
||||
|
||||
void WindowScreen::setup_video_effects_menu(bool reset_data) {
|
||||
if(!this->can_setup_menu())
|
||||
return;
|
||||
if(this->curr_menu != VIDEO_EFFECTS_MENU_TYPE) {
|
||||
this->curr_menu = VIDEO_EFFECTS_MENU_TYPE;
|
||||
if(reset_data)
|
||||
this->video_effects_menu->reset_data();
|
||||
this->video_effects_menu->insert_data();
|
||||
this->last_menu_change_time = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowScreen::update_save_menu() {
|
||||
if(this->curr_menu == SAVE_MENU_TYPE) {
|
||||
this->curr_menu = DEFAULT_MENU_TYPE;
|
||||
|
|
@ -1466,6 +1496,9 @@ void WindowScreen::poll(bool do_everything) {
|
|||
case VIDEO_MENU_CHANGE_TITLEBAR:
|
||||
this->titlebar_change();
|
||||
break;
|
||||
case VIDEO_MENU_VIDEO_EFFECTS_SETTINGS:
|
||||
this->setup_video_effects_menu();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1844,6 +1877,34 @@ void WindowScreen::poll(bool do_everything) {
|
|||
continue;
|
||||
}
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_TYPE:
|
||||
if(this->video_effects_menu->poll(event_data)) {
|
||||
switch(this->video_effects_menu->selected_index) {
|
||||
case VIDEO_EFFECTS_MENU_BACK:
|
||||
this->setup_video_menu(false);
|
||||
done = true;
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_NO_ACTION:
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_INC:
|
||||
this->input_colorspace_mode_change(true);
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_INPUT_COLORSPACE_DEC:
|
||||
this->input_colorspace_mode_change(false);
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_FRAME_BLENDING_INC:
|
||||
this->frame_blending_mode_change(true);
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_FRAME_BLENDING_DEC:
|
||||
this->frame_blending_mode_change(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->video_effects_menu->reset_output_option();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2077,6 +2138,9 @@ void WindowScreen::prepare_menu_draws(int view_size_x, int view_size_y) {
|
|||
case ISN_MENU_TYPE:
|
||||
this->is_nitro_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->capture_status);
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_TYPE:
|
||||
this->video_effects_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, &this->loaded_info);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2147,6 +2211,9 @@ void WindowScreen::execute_menu_draws() {
|
|||
case ISN_MENU_TYPE:
|
||||
this->is_nitro_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
|
||||
break;
|
||||
case VIDEO_EFFECTS_MENU_TYPE:
|
||||
this->video_effects_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -437,6 +437,22 @@ void reset_screen_info(ScreenInfo &info) {
|
|||
info.use_non_integer_scaling_bottom = false;
|
||||
info.failed_fullscreen = false;
|
||||
info.have_titlebar = true;
|
||||
info.in_colorspace_top = FULL_COLORSPACE;
|
||||
info.in_colorspace_bot = FULL_COLORSPACE;
|
||||
info.frame_blending_top = NO_FRAME_BLENDING;
|
||||
info.frame_blending_bot = NO_FRAME_BLENDING;
|
||||
}
|
||||
|
||||
static InputColorspaceMode input_colorspace_sanitization(int value) {
|
||||
if((value < 0) || (value >= INPUT_COLORSPACE_END))
|
||||
return FULL_COLORSPACE;
|
||||
return static_cast<InputColorspaceMode>(value);
|
||||
}
|
||||
|
||||
static FrameBlendingMode frame_blending_sanitization(int value) {
|
||||
if((value < 0) || (value >= FRAME_BLENDING_END))
|
||||
return NO_FRAME_BLENDING;
|
||||
return static_cast<FrameBlendingMode>(value);
|
||||
}
|
||||
|
||||
static float offset_sanitization(float value) {
|
||||
|
|
@ -599,6 +615,22 @@ bool load_screen_info(std::string key, std::string value, std::string base, Scre
|
|||
info.have_titlebar = std::stoi(value);
|
||||
return true;
|
||||
}
|
||||
if(key == (base + "in_colorspace_top")) {
|
||||
info.in_colorspace_top = input_colorspace_sanitization(std::stoi(value));
|
||||
return true;
|
||||
}
|
||||
if(key == (base + "in_colorspace_bot")) {
|
||||
info.in_colorspace_bot = input_colorspace_sanitization(std::stoi(value));
|
||||
return true;
|
||||
}
|
||||
if(key == (base + "frame_blending_top")) {
|
||||
info.frame_blending_top = frame_blending_sanitization(std::stoi(value));
|
||||
return true;
|
||||
}
|
||||
if(key == (base + "frame_blending_bot")) {
|
||||
info.frame_blending_bot = frame_blending_sanitization(std::stoi(value));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -635,6 +667,10 @@ std::string save_screen_info(std::string base, const ScreenInfo &info) {
|
|||
out += base + "use_non_integer_scaling_top=" + std::to_string(info.use_non_integer_scaling_top) + "\n";
|
||||
out += base + "use_non_integer_scaling_bottom=" + std::to_string(info.use_non_integer_scaling_bottom) + "\n";
|
||||
out += base + "have_titlebar=" + std::to_string(info.have_titlebar) + "\n";
|
||||
out += base + "in_colorspace_top=" + std::to_string(info.in_colorspace_top) + "\n";
|
||||
out += base + "in_colorspace_bot=" + std::to_string(info.in_colorspace_bot) + "\n";
|
||||
out += base + "frame_blending_top=" + std::to_string(info.frame_blending_top) + "\n";
|
||||
out += base + "frame_blending_bot=" + std::to_string(info.frame_blending_bot) + "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -828,3 +864,39 @@ std::string get_name_non_int_mode(NonIntegerScalingModes input) {
|
|||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string get_name_frame_blending_mode(FrameBlendingMode input) {
|
||||
std::string output = "";
|
||||
switch(input) {
|
||||
case NO_FRAME_BLENDING:
|
||||
output = "Off";
|
||||
break;
|
||||
case FULL_FRAME_BLENDING:
|
||||
output = "On";
|
||||
break;
|
||||
case DS_3D_BOTH_SCREENS_FRAME_BLENDING:
|
||||
output = "3D on DS";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string get_name_input_colorspace_mode(InputColorspaceMode input) {
|
||||
std::string output = "";
|
||||
switch(input) {
|
||||
case FULL_COLORSPACE:
|
||||
output = "Full";
|
||||
break;
|
||||
case DS_COLORSPACE:
|
||||
output = "DS";
|
||||
break;
|
||||
case GBA_COLORSPACE:
|
||||
output = "GBA";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
|
|
|||
12
source/shaders_list_template.cpp
Normal file
12
source/shaders_list_template.cpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "shaders_list.hpp"
|
||||
|
||||
static std::string shader_strings[TOTAL_NUM_SHADERS];
|
||||
|
||||
std::string get_shader_string(shader_list_enum requested_shader) {
|
||||
if((requested_shader < 0) || (requested_shader >= TOTAL_NUM_SHADERS))
|
||||
return "";
|
||||
return shader_strings[requested_shader];
|
||||
}
|
||||
|
||||
// This is a template
|
||||
void shader_strings_init() {
|
||||
|
|
@ -1,14 +1,28 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
unset(ENV{CC})
|
||||
unset(ENV{CXX})
|
||||
project(CMakeBin2C VERSION 1.0.0 LANGUAGES CXX)
|
||||
set(OUTPUT_NAME CMakeBin2C)
|
||||
project(${OUTPUT_NAME} VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
add_executable(CMakeBin2C bin2c.cpp)
|
||||
target_compile_features(CMakeBin2C PRIVATE cxx_std_17)
|
||||
add_executable(${OUTPUT_NAME} bin2c.cpp)
|
||||
target_compile_features(${OUTPUT_NAME} PRIVATE cxx_std_17)
|
||||
|
||||
add_custom_command(
|
||||
TARGET CMakeBin2C
|
||||
TARGET ${OUTPUT_NAME}
|
||||
COMMENT "Copy Output"
|
||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:CMakeBin2C> ${CMAKE_BINARY_DIR}
|
||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${OUTPUT_NAME}> ${CMAKE_BINARY_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(OUTPUT_NAME CMakeShader2C)
|
||||
project(${OUTPUT_NAME} VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
add_executable(${OUTPUT_NAME} shader2c.cpp)
|
||||
target_compile_features(${OUTPUT_NAME} PRIVATE cxx_std_17)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${OUTPUT_NAME}
|
||||
COMMENT "Copy Output"
|
||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${OUTPUT_NAME}> ${CMAKE_BINARY_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
|
|
|
|||
141
tools/shader2c.cpp
Normal file
141
tools/shader2c.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#if (!defined(_MSC_VER)) || (_MSC_VER > 1916)
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
#endif
|
||||
|
||||
#define ENUM_NAME_STR_IDENTIFIER_POS 0
|
||||
#define OPERATION_POS 1
|
||||
#define MIN_DOT_SEPARATED_STRINGS 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum shader_operations { NO_OPERATION, POWER_OF_2_OPERATION };
|
||||
|
||||
vector<string> split_str_by_char(string str_to_split, char split_char) {
|
||||
stringstream str_stream(str_to_split);
|
||||
vector<string> result;
|
||||
|
||||
while(str_stream.good())
|
||||
{
|
||||
string substr;
|
||||
getline(str_stream, substr, split_char);
|
||||
result.push_back(substr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool str_ends_with(string const &value, string const &ending)
|
||||
{
|
||||
if(ending.size() > value.size()) return false;
|
||||
return equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
int process_file(filesystem::path input_path, ofstream &output) {
|
||||
string final_path = input_path.filename().string();
|
||||
int first = -1;
|
||||
int last = -1;
|
||||
shader_operations loaded_operation = NO_OPERATION;
|
||||
|
||||
vector<string> dot_separated_names = split_str_by_char(final_path, '.');
|
||||
if(dot_separated_names.size() < MIN_DOT_SEPARATED_STRINGS) {
|
||||
cout << "Badly formatted input name!" << endl;
|
||||
return -3;
|
||||
}
|
||||
|
||||
transform(dot_separated_names[ENUM_NAME_STR_IDENTIFIER_POS].begin(), dot_separated_names[ENUM_NAME_STR_IDENTIFIER_POS].end(), dot_separated_names[ENUM_NAME_STR_IDENTIFIER_POS].begin(), ::toupper);
|
||||
|
||||
ifstream input(input_path, ios::in);
|
||||
if(!input) {
|
||||
cout << "Couldn't open input file!" << endl;
|
||||
return -2;
|
||||
}
|
||||
vector<string> file_lines;
|
||||
string single_str = "";
|
||||
while (getline(input, single_str))
|
||||
file_lines.push_back(single_str);
|
||||
|
||||
input.close();
|
||||
|
||||
if(dot_separated_names[OPERATION_POS].rfind("2_to_x", 0) == 0) {
|
||||
vector<string> underscore_separated_values = split_str_by_char(final_path, '_');
|
||||
first = stoi(underscore_separated_values[underscore_separated_values.size()-2]);
|
||||
last = stoi(underscore_separated_values[underscore_separated_values.size()-1]);
|
||||
loaded_operation = POWER_OF_2_OPERATION;
|
||||
}
|
||||
|
||||
bool first_pass = true;
|
||||
do {
|
||||
if(!first_pass)
|
||||
first += 1;
|
||||
first_pass = false;
|
||||
string enum_str = dot_separated_names[ENUM_NAME_STR_IDENTIFIER_POS];
|
||||
output << "shader_strings[" << dot_separated_names[ENUM_NAME_STR_IDENTIFIER_POS];
|
||||
if(first != -1)
|
||||
output << "_" << first;
|
||||
output << "] = \\" << endl;
|
||||
|
||||
for(int i = 0; i < file_lines.size(); i++) {
|
||||
string line = file_lines[i];
|
||||
if((loaded_operation == POWER_OF_2_OPERATION) && (str_ends_with(line, "= x;"))) {
|
||||
vector<string> x_split_line = split_str_by_char(line, 'x');
|
||||
string new_line = "";
|
||||
for(int j = 0; j < x_split_line.size() - 1; j++) {
|
||||
new_line += x_split_line[j];
|
||||
if(j < x_split_line.size() - 2)
|
||||
new_line += "x";
|
||||
}
|
||||
new_line += to_string((float)(1 << first)) + ";";
|
||||
line = new_line;
|
||||
}
|
||||
output << "\"" << line << "\" \\" <<endl;
|
||||
}
|
||||
output << "\"\";" << endl;
|
||||
} while(first != last);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc < 4) {
|
||||
cout << "Usage: " << argv[0] << " shaders_folder cpp_template_file output_file_name" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifstream input(argv[2], ios::in);
|
||||
if(!input) {
|
||||
cout << "Couldn't open template file!" << endl;
|
||||
return -4;
|
||||
}
|
||||
vector<string> file_lines;
|
||||
string single_str = "";
|
||||
while (getline(input, single_str))
|
||||
file_lines.push_back(single_str);
|
||||
|
||||
input.close();
|
||||
|
||||
ofstream output(argv[3], ios::out);
|
||||
if(!output) {
|
||||
cout << "Couldn't open output cpp file!" << endl;
|
||||
return -5;
|
||||
}
|
||||
for(int i = 0; i < file_lines.size(); i++)
|
||||
output << file_lines[i] << endl;
|
||||
|
||||
for(const auto & entry : filesystem::directory_iterator(argv[1])) {
|
||||
int result = process_file(entry.path(), output);
|
||||
if(result != 0)
|
||||
return result;
|
||||
}
|
||||
output<<"}"<<endl;
|
||||
|
||||
output.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user