mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	@ -89,13 +89,16 @@ endif()
 | 
			
		||||
# Link and create SDL2 Definition if we're using it
 | 
			
		||||
if (SDL2_ENABLED)
 | 
			
		||||
	add_compile_definitions(BLAH_USE_SDL2)
 | 
			
		||||
 | 
			
		||||
	if (NOT DEFINED SDL2_INCLUDE_DIRS OR NOT DEFINED SDL2_LIBRARIES)
 | 
			
		||||
		find_package(SDL2 REQUIRED)
 | 
			
		||||
	if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
 | 
			
		||||
  		set_target_properties(blah PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
 | 
			
		||||
	else()
 | 
			
		||||
		if (NOT DEFINED SDL2_INCLUDE_DIRS OR NOT DEFINED SDL2_LIBRARIES)
 | 
			
		||||
			find_package(SDL2 REQUIRED)
 | 
			
		||||
		endif()
 | 
			
		||||
		
 | 
			
		||||
		target_include_directories(blah PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
 | 
			
		||||
		set(LIBS ${LIBS} ${SDL2_LIBRARIES})
 | 
			
		||||
	endif()
 | 
			
		||||
	
 | 
			
		||||
	target_include_directories(blah PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
 | 
			
		||||
	set(LIBS ${LIBS} ${SDL2_LIBRARIES})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries(blah PUBLIC ${LIBS})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										163
									
								
								src/core/app.cpp
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								src/core/app.cpp
									
									
									
									
									
								
							@ -7,13 +7,20 @@
 | 
			
		||||
#include "../internal/graphics_backend.h"
 | 
			
		||||
#include "../internal/input_backend.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
#include <emscripten.h>
 | 
			
		||||
#include <emscripten/html5.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace Blah;
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
	Config app_config;
 | 
			
		||||
	bool app_is_running = false;
 | 
			
		||||
	bool app_is_exiting = false;
 | 
			
		||||
	static Config app_config;
 | 
			
		||||
	static bool app_is_running = false;
 | 
			
		||||
	static bool app_is_exiting = false;
 | 
			
		||||
	static uint64_t time_last;
 | 
			
		||||
	static uint64_t time_accumulator = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Config::Config()
 | 
			
		||||
@ -34,6 +41,79 @@ Config::Config()
 | 
			
		||||
	on_error = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
void loop_iteration() {
 | 
			
		||||
	// poll system events
 | 
			
		||||
	PlatformBackend::frame();
 | 
			
		||||
 | 
			
		||||
	// update at a fixed timerate
 | 
			
		||||
	// TODO: allow a non-fixed step update?
 | 
			
		||||
	{
 | 
			
		||||
		uint64_t time_target = (uint64_t)((1.0f / app_config.target_framerate) * 1000);
 | 
			
		||||
		uint64_t time_curr = PlatformBackend::time();
 | 
			
		||||
		uint64_t time_diff = time_curr - time_last;
 | 
			
		||||
		time_last = time_curr;
 | 
			
		||||
		time_accumulator += time_diff;
 | 
			
		||||
 | 
			
		||||
		// do not let us run too fast
 | 
			
		||||
		while (time_accumulator < time_target)
 | 
			
		||||
		{
 | 
			
		||||
			PlatformBackend::sleep((int)(time_target - time_accumulator));
 | 
			
		||||
 | 
			
		||||
			time_curr = PlatformBackend::time();
 | 
			
		||||
			time_diff = time_curr - time_last;
 | 
			
		||||
			time_last = time_curr;
 | 
			
		||||
			time_accumulator += time_diff;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Do not allow us to fall behind too many updates
 | 
			
		||||
		// (otherwise we'll get spiral of death)
 | 
			
		||||
		uint64_t time_maximum = app_config.max_updates * time_target;
 | 
			
		||||
		if (time_accumulator > time_maximum)
 | 
			
		||||
			time_accumulator = time_maximum;
 | 
			
		||||
 | 
			
		||||
		// do as many updates as we can
 | 
			
		||||
		while (time_accumulator >= time_target)
 | 
			
		||||
		{
 | 
			
		||||
			time_accumulator -= time_target;
 | 
			
		||||
 | 
			
		||||
			Time::delta = (1.0f / app_config.target_framerate);
 | 
			
		||||
 | 
			
		||||
			if (Time::pause_timer > 0)
 | 
			
		||||
			{
 | 
			
		||||
				Time::pause_timer -= Time::delta;
 | 
			
		||||
				if (Time::pause_timer <= -0.0001f)
 | 
			
		||||
					Time::delta = -Time::pause_timer;
 | 
			
		||||
				else
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Time::milliseconds += time_target;
 | 
			
		||||
			Time::previous_elapsed = Time::elapsed;
 | 
			
		||||
			Time::elapsed += Time::delta;
 | 
			
		||||
 | 
			
		||||
			InputBackend::frame();
 | 
			
		||||
			GraphicsBackend::frame();
 | 
			
		||||
 | 
			
		||||
			if (app_config.on_update != nullptr)
 | 
			
		||||
				app_config.on_update();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// render
 | 
			
		||||
	{
 | 
			
		||||
		GraphicsBackend::before_render();
 | 
			
		||||
 | 
			
		||||
		if (app_config.on_render != nullptr)
 | 
			
		||||
			app_config.on_render();
 | 
			
		||||
 | 
			
		||||
		GraphicsBackend::after_render();
 | 
			
		||||
		PlatformBackend::present();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
bool App::run(const Config* c)
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(!app_is_running, "The Application is already running");
 | 
			
		||||
@ -68,83 +148,20 @@ bool App::run(const Config* c)
 | 
			
		||||
	if (app_config.on_startup != nullptr)
 | 
			
		||||
		app_config.on_startup();
 | 
			
		||||
 | 
			
		||||
	uint64_t time_last = PlatformBackend::time();
 | 
			
		||||
	uint64_t time_accumulator = 0;
 | 
			
		||||
	time_last = PlatformBackend::time();
 | 
			
		||||
	time_accumulator = 0;
 | 
			
		||||
 | 
			
		||||
	// display window
 | 
			
		||||
	PlatformBackend::ready();
 | 
			
		||||
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
	emscripten_set_main_loop(loop_iteration, 0, 1);
 | 
			
		||||
#else
 | 
			
		||||
	while (!app_is_exiting)
 | 
			
		||||
	{
 | 
			
		||||
		// poll system events
 | 
			
		||||
		PlatformBackend::frame();
 | 
			
		||||
 | 
			
		||||
		// update at a fixed timerate
 | 
			
		||||
		// TODO: allow a non-fixed step update?
 | 
			
		||||
		{
 | 
			
		||||
			uint64_t time_target = (uint64_t)((1.0f / app_config.target_framerate) * 1000);
 | 
			
		||||
			uint64_t time_curr = PlatformBackend::time();
 | 
			
		||||
			uint64_t time_diff = time_curr - time_last;
 | 
			
		||||
			time_last = time_curr;
 | 
			
		||||
			time_accumulator += time_diff;
 | 
			
		||||
 | 
			
		||||
			// do not let us run too fast
 | 
			
		||||
			while (time_accumulator < time_target)
 | 
			
		||||
			{
 | 
			
		||||
				PlatformBackend::sleep((int)(time_target - time_accumulator));
 | 
			
		||||
 | 
			
		||||
				time_curr = PlatformBackend::time();
 | 
			
		||||
				time_diff = time_curr - time_last;
 | 
			
		||||
				time_last = time_curr;
 | 
			
		||||
				time_accumulator += time_diff;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Do not allow us to fall behind too many updates
 | 
			
		||||
			// (otherwise we'll get spiral of death)
 | 
			
		||||
			uint64_t time_maximum = app_config.max_updates * time_target;
 | 
			
		||||
			if (time_accumulator > time_maximum)
 | 
			
		||||
				time_accumulator = time_maximum;
 | 
			
		||||
 | 
			
		||||
			// do as many updates as we can
 | 
			
		||||
			while (time_accumulator >= time_target)
 | 
			
		||||
			{
 | 
			
		||||
				time_accumulator -= time_target;
 | 
			
		||||
 | 
			
		||||
				Time::delta = (1.0f / app_config.target_framerate);
 | 
			
		||||
 | 
			
		||||
				if (Time::pause_timer > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Time::pause_timer -= Time::delta;
 | 
			
		||||
					if (Time::pause_timer <= -0.0001f)
 | 
			
		||||
						Time::delta = -Time::pause_timer;
 | 
			
		||||
					else
 | 
			
		||||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Time::milliseconds += time_target;
 | 
			
		||||
				Time::previous_elapsed = Time::elapsed;
 | 
			
		||||
				Time::elapsed += Time::delta;
 | 
			
		||||
 | 
			
		||||
				InputBackend::frame();
 | 
			
		||||
				GraphicsBackend::frame();
 | 
			
		||||
 | 
			
		||||
				if (app_config.on_update != nullptr)
 | 
			
		||||
					app_config.on_update();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// render
 | 
			
		||||
		{
 | 
			
		||||
			GraphicsBackend::before_render();
 | 
			
		||||
 | 
			
		||||
			if (app_config.on_render != nullptr)
 | 
			
		||||
				app_config.on_render();
 | 
			
		||||
 | 
			
		||||
			GraphicsBackend::after_render();
 | 
			
		||||
			PlatformBackend::present();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		loop_iteration();
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// shutdown
 | 
			
		||||
	if (app_config.on_shutdown != nullptr)
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,11 @@ namespace
 | 
			
		||||
 | 
			
		||||
	const ShaderData shader_data = {
 | 
			
		||||
		// vertex shader
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
		"#version 300 es\n"
 | 
			
		||||
#else
 | 
			
		||||
		"#version 330\n"
 | 
			
		||||
#endif
 | 
			
		||||
		"uniform mat4 u_matrix;\n"
 | 
			
		||||
		"layout(location=0) in vec2 a_position;\n"
 | 
			
		||||
		"layout(location=1) in vec2 a_tex;\n"
 | 
			
		||||
@ -37,7 +41,12 @@ namespace
 | 
			
		||||
		"}",
 | 
			
		||||
 | 
			
		||||
		// fragment shader
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
		"#version 300 es\n"
 | 
			
		||||
		"precision mediump float;\n"
 | 
			
		||||
#else
 | 
			
		||||
		"#version 330\n"
 | 
			
		||||
#endif
 | 
			
		||||
		"uniform sampler2D u_texture;\n"
 | 
			
		||||
		"in vec2 v_tex;\n"
 | 
			
		||||
		"in vec4 v_col;\n"
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,10 @@ bool PlatformBackend::init(const Config* config)
 | 
			
		||||
	{
 | 
			
		||||
		flags |= SDL_WINDOW_OPENGL;
 | 
			
		||||
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
 | 
			
		||||
#else
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
 | 
			
		||||
@ -93,6 +97,7 @@ bool PlatformBackend::init(const Config* config)
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	// enable DirectX
 | 
			
		||||
	else if (App::renderer() == Renderer::D3D11)
 | 
			
		||||
@ -140,9 +145,11 @@ bool PlatformBackend::init(const Config* config)
 | 
			
		||||
 | 
			
		||||
void PlatformBackend::ready()
 | 
			
		||||
{
 | 
			
		||||
#ifndef __EMSCRIPTEN__
 | 
			
		||||
	// enable V-Sync
 | 
			
		||||
	if (App::renderer() == Renderer::OpenGL)
 | 
			
		||||
		SDL_GL_SetSwapInterval(1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PlatformBackend::shutdown()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user