-fixed code do cross compiling to android -fixed build with GCC (workaround) -added little benchmark -several small fixes -updated meson build (demos building, working with GCC, LDC and DMD) -added some meson options -added ImGUI bind for OpenGL3
895 lines
No EOL
30 KiB
D
895 lines
No EOL
30 KiB
D
module app;
|
|
|
|
import bindbc.sdl;
|
|
|
|
import cimgui.cimgui;
|
|
|
|
import game_core.job_updater;
|
|
|
|
import bubel.ecs.manager;
|
|
import bubel.ecs.core;
|
|
import bubel.ecs.std;
|
|
|
|
import ecs_utils.gfx.renderer;
|
|
import ecs_utils.imgui_bind;
|
|
import ecs_utils.imgui_styles;
|
|
import ecs_utils.math.vector;
|
|
import ecs_utils.utils;
|
|
|
|
import glad.gl.gl;
|
|
import glad.gl.gles2;
|
|
import glad.gl.loader;
|
|
|
|
import gui.manager;
|
|
|
|
extern (C) :
|
|
|
|
enum Tool
|
|
{
|
|
entity_spawner,
|
|
component_manipulator,
|
|
selector
|
|
}
|
|
|
|
__gshared const (char)*[3] tool_strings = ["Entity spawner", "Component manipulator", "Selector"];
|
|
|
|
struct Mouse
|
|
{
|
|
vec2 position;
|
|
bool left, right, middle;
|
|
}
|
|
|
|
struct Launcher
|
|
{
|
|
ECSJobUpdater* job_updater;
|
|
GUIManager* gui_manager;
|
|
ImGuiContext* context;
|
|
SDL_Window* window;
|
|
SDL_GLContext gl_context;
|
|
EntityManager* manager;
|
|
bool function() loop;
|
|
void function() end;
|
|
void function(SDL_Event*) event;
|
|
void function(vec2, Tool, int) tool;
|
|
float scalling;
|
|
ivec2 window_size = ivec2(1024,768);
|
|
Renderer renderer;
|
|
ubyte[] keys;
|
|
uint style = 3;
|
|
uint entities_count;
|
|
bool multithreading;
|
|
int threads = 1;
|
|
ulong timer_freq;
|
|
double delta_time;
|
|
uint fps;
|
|
vec2 render_position;
|
|
|
|
Tool used_tool;
|
|
int tool_size = 0;
|
|
float tool_repeat = 0;
|
|
float repeat_time = 0;
|
|
|
|
bool swap_interval = true;
|
|
|
|
float windows_alpha = 0.75;
|
|
|
|
const (char)* tips;
|
|
|
|
bool show_stat_wnd = true;
|
|
bool show_tips = true;
|
|
bool show_demo_wnd = true;
|
|
bool show_virtual_keys_wnd = false;
|
|
bool show_profile_wnd = true;
|
|
|
|
int plot_index;
|
|
PlotStruct[] plot_values;
|
|
|
|
Mouse mouse;
|
|
|
|
struct PlotStruct
|
|
{
|
|
float delta_time = 0;
|
|
float loop_time = 0;
|
|
float draw_time = 0;
|
|
}
|
|
|
|
void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, void function(vec2, Tool, int) tool, const (char)* tips)
|
|
{
|
|
gui_manager.clear();
|
|
//launcher.ent
|
|
|
|
if(this.end)this.end();
|
|
|
|
manager.begin();
|
|
manager.update("clean");
|
|
manager.end();
|
|
|
|
foreach(ref system; manager.systems)
|
|
{
|
|
if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable();
|
|
}
|
|
|
|
/*launcher.manager.getSystem(CountSystem.system_id).enable();
|
|
launcher.manager.getSystem(CleanSystem.system_id).enable();//*/
|
|
|
|
if(start)start();
|
|
this.loop = loop;
|
|
this.end = end;
|
|
this.event = event;
|
|
this.tips = tips;
|
|
this.tool = tool;
|
|
}
|
|
|
|
bool getKeyState(SDL_Scancode key)
|
|
{
|
|
if(keys[key])return true;
|
|
else return false;
|
|
}
|
|
|
|
void setStyle(uint index)
|
|
{
|
|
style = index;
|
|
.setStyle(index);
|
|
}
|
|
|
|
double getTime()
|
|
{
|
|
ulong local_freq = timer_freq / 1000_000;
|
|
//return cast(double)(SDL_GetPerformanceCounter() & 0x00FFFFFF) / timer_freq;
|
|
if(local_freq == 0)return cast(double)(SDL_GetPerformanceCounter() / timer_freq * 1000);
|
|
else return cast(double)(SDL_GetPerformanceCounter() / local_freq) / 1000;
|
|
}
|
|
}
|
|
|
|
__gshared Launcher launcher;
|
|
|
|
struct CountSystem
|
|
{
|
|
mixin ECS.System!1;
|
|
|
|
struct EntitiesData
|
|
{
|
|
uint length;
|
|
const (Entity)[] entity;
|
|
}
|
|
|
|
bool onBegin()
|
|
{
|
|
launcher.entities_count = 0;
|
|
return true;
|
|
}
|
|
|
|
void onUpdate(EntitiesData data)
|
|
{
|
|
launcher.entities_count += data.length;
|
|
}
|
|
}
|
|
|
|
struct CleanSystem
|
|
{
|
|
mixin ECS.System!64;
|
|
|
|
struct EntitiesData
|
|
{
|
|
uint length;
|
|
Entity[] entities;
|
|
}
|
|
|
|
void onUpdate(EntitiesData data)
|
|
{
|
|
foreach(i; 0..data.length)
|
|
{
|
|
launcher.manager.removeEntity(data.entities[i].id);
|
|
}
|
|
}
|
|
}
|
|
|
|
void mainLoop(void* arg)
|
|
{
|
|
__gshared double time = 0;
|
|
launcher.delta_time = launcher.getTime() - time;
|
|
time = launcher.getTime();
|
|
|
|
if(launcher.delta_time > 1000)launcher.delta_time = 1000;
|
|
|
|
__gshared uint temp_fps = 0;
|
|
__gshared double fps_time = 0;
|
|
temp_fps++;
|
|
fps_time += launcher.delta_time;
|
|
while(fps_time > 1000)
|
|
{
|
|
fps_time -= 1000;
|
|
launcher.fps = temp_fps;
|
|
temp_fps = 0;
|
|
}
|
|
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event))
|
|
{
|
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
|
if(launcher.event)launcher.event(&event);
|
|
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) {
|
|
quit();
|
|
*cast(bool*)arg = false;
|
|
return;
|
|
}
|
|
else if(event.type == SDL_WINDOWEVENT)
|
|
{
|
|
switch(event.window.event)
|
|
{
|
|
case SDL_WINDOWEVENT_RESIZED:
|
|
//launcher.renderer.resize(ivec2(event.window.data1,event.window.data2));
|
|
launcher.window_size = ivec2(event.window.data1,event.window.data2);
|
|
break;
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
//launcher.renderer.resize(ivec2(event.window.data1,event.window.data2));
|
|
launcher.window_size = ivec2(event.window.data1,event.window.data2);
|
|
break;
|
|
default:break;
|
|
}
|
|
}
|
|
else if(event.type == SDL_MOUSEBUTTONDOWN)
|
|
{
|
|
switch(event.button.button)
|
|
{
|
|
case SDL_BUTTON_LEFT:launcher.mouse.left = true;break;
|
|
case SDL_BUTTON_RIGHT:launcher.mouse.right = true;break;
|
|
case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break;
|
|
default:break;
|
|
}
|
|
if(launcher.tool && event.button.button == SDL_BUTTON_LEFT && launcher.tool_repeat == 0 && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
|
{
|
|
launcher.tool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position, launcher.used_tool, launcher.tool_size);
|
|
}
|
|
}
|
|
else if(event.type == SDL_MOUSEBUTTONUP)
|
|
{
|
|
switch(event.button.button)
|
|
{
|
|
case SDL_BUTTON_LEFT:launcher.mouse.left = false;break;
|
|
case SDL_BUTTON_RIGHT:launcher.mouse.right = false;break;
|
|
case SDL_BUTTON_MIDDLE:launcher.mouse.middle = false;break;
|
|
default:break;
|
|
}
|
|
}
|
|
else if(event.type == SDL_MOUSEMOTION)
|
|
{
|
|
launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y);
|
|
}
|
|
}
|
|
|
|
if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow))
|
|
{
|
|
float range = 500.0 / cast(float)launcher.tool_repeat;
|
|
launcher.repeat_time += launcher.delta_time;
|
|
while(launcher.repeat_time > range)
|
|
{
|
|
launcher.repeat_time -= range;
|
|
launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size);
|
|
}
|
|
}
|
|
|
|
version(WebAssembly)
|
|
{
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
ImGui_ImplSDL2_NewFrame(launcher.window);
|
|
}
|
|
else
|
|
{
|
|
//ImGuiImplOpenGL2NewFrame();
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
ImGuiImplSDL2NewFrame(launcher.window);
|
|
}
|
|
|
|
igNewFrame();
|
|
|
|
if(igBeginMainMenuBar())
|
|
{
|
|
if(igBeginMenu("File",true))
|
|
{
|
|
if(igMenuItemBool("Close","esc",false,true))
|
|
{
|
|
quit();
|
|
*cast(bool*)arg = false;
|
|
return;
|
|
}
|
|
igEndMenu();
|
|
}
|
|
if(igBeginMenu("Demos",true))
|
|
{
|
|
if(igMenuItemBool("Simpe",null,false,true))
|
|
{
|
|
import demos.simple;
|
|
launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips);
|
|
}
|
|
if(igMenuItemBool("Snake",null,false,true))
|
|
{
|
|
import demos.snake;
|
|
launcher.switchDemo(&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,&snakeTool,Snake.tips);
|
|
}
|
|
if(igMenuItemBool("Space invaders",null,false,true))
|
|
{
|
|
import demos.space_invaders;
|
|
launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips);
|
|
}
|
|
igEndMenu();
|
|
}
|
|
if(igBeginMenu("Options",true))
|
|
{
|
|
if(igMenuItemBool("VSync", null, launcher.swap_interval, true))
|
|
{
|
|
launcher.swap_interval = !launcher.swap_interval;
|
|
SDL_GL_SetSwapInterval(launcher.swap_interval);
|
|
}
|
|
if(igMenuItemBool("Multithreading", null, launcher.multithreading, true))
|
|
{
|
|
launcher.multithreading = !launcher.multithreading;
|
|
if(launcher.multithreading)
|
|
{
|
|
launcher.job_updater.pool.setThreadsNum(launcher.threads);
|
|
}
|
|
else
|
|
{
|
|
launcher.job_updater.pool.setThreadsNum(1);
|
|
}
|
|
}
|
|
igSetNextItemWidth(0);
|
|
igLabelText("Threads:",null);
|
|
igSameLine(0,4);
|
|
if(igSliderInt("##Threads",&launcher.threads, 1, 32, null))//"Multithreading", null, launcher.multithreading, true))
|
|
{
|
|
launcher.job_updater.pool.setThreadsNum(launcher.threads);
|
|
//launcher.threads = !launcher.multithreading;
|
|
}
|
|
if(igBeginMenu("Show",true))
|
|
{
|
|
if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true))
|
|
{
|
|
launcher.show_stat_wnd = !launcher.show_stat_wnd;
|
|
}
|
|
else if(igMenuItemBool("Demo",null,launcher.show_demo_wnd,true))
|
|
{
|
|
launcher.show_demo_wnd = !launcher.show_demo_wnd;
|
|
}
|
|
else if(igMenuItemBool("Tips",null,launcher.show_tips,true))
|
|
{
|
|
launcher.show_tips = !launcher.show_tips;
|
|
}
|
|
else if(igMenuItemBool("Virual keys",null,launcher.show_virtual_keys_wnd,true))
|
|
{
|
|
launcher.show_virtual_keys_wnd = !launcher.show_virtual_keys_wnd;
|
|
}
|
|
igEndMenu();
|
|
}
|
|
if(igBeginMenu("Style",true))
|
|
{
|
|
if(igMenuItemBool("Classic",null,launcher.style == 0,true))
|
|
{
|
|
launcher.setStyle(0);
|
|
}
|
|
else if(igMenuItemBool("Dark",null,launcher.style == 1,true))
|
|
{
|
|
launcher.setStyle(1);
|
|
}
|
|
else if(igMenuItemBool("Light",null,launcher.style == 2,true))
|
|
{
|
|
launcher.setStyle(2);
|
|
}
|
|
else if(igMenuItemBool("Default",null,launcher.style == 3,true))
|
|
{
|
|
launcher.setStyle(3);
|
|
}
|
|
igEndMenu();
|
|
}
|
|
igEndMenu();
|
|
}
|
|
igEndMainMenuBar();
|
|
}
|
|
|
|
if(launcher.show_virtual_keys_wnd)
|
|
{
|
|
igSetNextWindowPos(ImVec2(launcher.window_size.x - 400, launcher.window_size.y - 200), ImGuiCond_Once, ImVec2(0,0));
|
|
igSetNextWindowSize(ImVec2(64*4+128, 168), ImGuiCond_Once);
|
|
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
|
ImGuiStyle * style = igGetStyle();
|
|
style.Colors[ImGuiCol_Button].w = 0.8;
|
|
if(igBegin("Virtual keys",&launcher.show_virtual_keys_wnd, 0))
|
|
{
|
|
igColumns(2,null,0);
|
|
igSetColumnWidth(0,64*3+16);
|
|
igIndent(64+4);
|
|
if(igButton("W",ImVec2(64,64)) || igIsItemDeactivated())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_W] = false;
|
|
}
|
|
else if(igIsItemActive())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_W] = true;
|
|
}
|
|
igUnindent(64+4);
|
|
if(igButton("A",ImVec2(64,64)) || igIsItemDeactivated())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_A] = false;
|
|
}
|
|
else if(igIsItemActive())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_A] = true;
|
|
}
|
|
igSameLine(0,4);
|
|
if(igButton("S",ImVec2(64,64)) || igIsItemDeactivated())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_S] = false;
|
|
}
|
|
else if(igIsItemActive())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_S] = true;
|
|
}
|
|
igSameLine(0,4);
|
|
if(igButton("D",ImVec2(64,64)) || igIsItemDeactivated())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_D] = false;
|
|
}
|
|
else if(igIsItemActive())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_D] = true;
|
|
}
|
|
igNextColumn();
|
|
if(igButton("Space",ImVec2(-1,128)) || igIsItemDeactivated())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_SPACE] = false;
|
|
}
|
|
else if(igIsItemActive())
|
|
{
|
|
launcher.keys[SDL_SCANCODE_SPACE] = true;
|
|
}
|
|
igColumns(1,null,0);
|
|
}
|
|
igEnd();
|
|
style.Colors[ImGuiCol_Button].w = 1.0;
|
|
}
|
|
|
|
if(launcher.show_tips)
|
|
{
|
|
igSetNextWindowPos(ImVec2(launcher.window_size.x - 550, 80), ImGuiCond_Once, ImVec2(0,0));
|
|
igSetNextWindowSize(ImVec2(300, 0), ImGuiCond_Once);
|
|
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
|
if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings))
|
|
{
|
|
igTextWrapped(launcher.tips);
|
|
}
|
|
igEnd();
|
|
}
|
|
|
|
if(launcher.show_demo_wnd)
|
|
{
|
|
igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
|
igSetNextWindowSize(ImVec2(250, 500), ImGuiCond_Once);
|
|
if(igBegin("Demo",&launcher.show_demo_wnd,0))
|
|
{
|
|
ImDrawList* draw_list = igGetWindowDrawList();
|
|
//igBeginGroup();
|
|
launcher.gui_manager.gui();
|
|
//igEndGroup();
|
|
//ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1);
|
|
//igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow);
|
|
//igBeginChild("Tool frame",ImVec2(-1,-1),true,0);
|
|
if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth))
|
|
{
|
|
igIndent(8);
|
|
igBeginGroup();
|
|
if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0))
|
|
{
|
|
if(igSelectable("Entity spawner",false,0,ImVec2(0,0)))
|
|
{
|
|
launcher.used_tool = Tool.entity_spawner;
|
|
}
|
|
if(igSelectable("Component manipulator",false,0,ImVec2(0,0)))
|
|
{
|
|
launcher.used_tool = Tool.component_manipulator;
|
|
}
|
|
if(igSelectable("Selector",false,0,ImVec2(0,0)))
|
|
{
|
|
launcher.used_tool = Tool.selector;
|
|
}
|
|
igEndCombo();
|
|
}
|
|
|
|
igSliderInt("Tool size", &launcher.tool_size, 0, 256, null);
|
|
igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4);
|
|
launcher.gui_manager.toolGui();
|
|
igEndGroup();
|
|
ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1);
|
|
igUnindent(8);
|
|
}
|
|
|
|
//igEndChild();
|
|
//igEndChildFrame();
|
|
if(igButton("Clear",ImVec2(-1,0)))
|
|
{
|
|
launcher.manager.begin();
|
|
launcher.manager.update("clean");
|
|
launcher.manager.end();
|
|
}
|
|
}
|
|
igEnd();
|
|
}
|
|
|
|
if(launcher.show_profile_wnd)
|
|
{
|
|
igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0));
|
|
igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once);
|
|
if(igBegin("Profile",&launcher.show_profile_wnd,0))
|
|
{
|
|
if(igBeginTabBar("ProfileTabBar",ImGuiTabBarFlags_FittingPolicyScroll))
|
|
{
|
|
|
|
if(igBeginTabItem("Plots", null, 0))
|
|
{
|
|
if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0))
|
|
{
|
|
igPlotLines("Delta time",&launcher.plot_values[0].delta_time,100,launcher.plot_index,"Delta time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof);
|
|
igPlotLines("Loop time",&launcher.plot_values[0].loop_time,100,launcher.plot_index,"Loop time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof);
|
|
igPlotLines("Draw time",&launcher.plot_values[0].draw_time,100,launcher.plot_index,"Draw time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof);
|
|
}
|
|
igEndChild();
|
|
igEndTabItem();
|
|
}
|
|
if(igBeginTabItem("Multithreading graph", null, 0))
|
|
{
|
|
if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0))
|
|
{
|
|
igText("Work in proggress");
|
|
}
|
|
igEndChild();
|
|
igEndTabItem();
|
|
}
|
|
|
|
igEndTabBar();
|
|
}
|
|
}
|
|
igEnd();
|
|
}
|
|
|
|
launcher.renderer.resize(launcher.window_size);
|
|
//launcher.renderer.view(vec2(0,0),vec2(launcher.window_size.x,launcher.window_size.y));
|
|
//if(384, 768, 1152, 1536)
|
|
//576 960 1344 1728
|
|
//float scalling;
|
|
if(launcher.window_size.y < 360)launcher.scalling = 1;
|
|
else launcher.scalling = 1.0 / ((launcher.window_size.y+120)/360);
|
|
launcher.renderer.view(launcher.render_position,vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling);
|
|
//launcher.renderer.view(vec2(0,0),vec2(1024*launcher.window_size.x/launcher.window_size.y,768));
|
|
//glClear(GL_COLOR_BUFFER_BIT);
|
|
launcher.renderer.clear();
|
|
|
|
double loop_time = launcher.getTime();
|
|
launcher.job_updater.pool.tryWaitCount = 10000;
|
|
if(launcher.loop && !launcher.loop())
|
|
{
|
|
quit();
|
|
*cast(bool*)arg = false;
|
|
}
|
|
launcher.job_updater.pool.tryWaitCount = 0;
|
|
|
|
loop_time = launcher.getTime() - loop_time;
|
|
|
|
double draw_time = launcher.getTime();
|
|
launcher.renderer.present();
|
|
draw_time = launcher.getTime() - draw_time;
|
|
|
|
__gshared float plot_time = 0;
|
|
__gshared uint plot_samples = 0;
|
|
plot_time += launcher.delta_time;
|
|
plot_samples++;
|
|
launcher.plot_values[100].delta_time += launcher.delta_time;
|
|
launcher.plot_values[100].loop_time += loop_time;
|
|
launcher.plot_values[100].draw_time += draw_time;
|
|
if(plot_time > 100)
|
|
{
|
|
launcher.plot_values[launcher.plot_index].delta_time = launcher.plot_values[100].delta_time / cast(float)plot_samples;
|
|
launcher.plot_values[launcher.plot_index].loop_time = launcher.plot_values[100].loop_time / cast(float)plot_samples;
|
|
launcher.plot_values[launcher.plot_index].draw_time = launcher.plot_values[100].draw_time / cast(float)plot_samples;
|
|
launcher.plot_values[100].delta_time = 0;
|
|
launcher.plot_values[100].loop_time = 0;
|
|
launcher.plot_values[100].draw_time = 0;
|
|
|
|
plot_samples = 0;
|
|
plot_time -= 100;
|
|
launcher.plot_index++;
|
|
if(launcher.plot_index >= 100)launcher.plot_index = 0;
|
|
}
|
|
|
|
if(launcher.show_stat_wnd)
|
|
{
|
|
igSetNextWindowPos(ImVec2(10, 30), ImGuiCond_Appearing, ImVec2(0,0));
|
|
igSetNextWindowContentSize(ImVec2(150, 0.0f));
|
|
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
|
if(igBegin("Statistics", &launcher.show_stat_wnd, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize))
|
|
{
|
|
igColumns(2,null,0);
|
|
igSetColumnWidth(0,100);
|
|
igText("FPS: ");
|
|
igText("Entities: ");
|
|
igText("Loop time: ");
|
|
igText("Draw time: ");
|
|
igText("Delta time: ");
|
|
igNextColumn();
|
|
igText("%u",launcher.fps);
|
|
igText("%u",launcher.entities_count);
|
|
igText("%2.2fms",loop_time);
|
|
igText("%2.2fms",draw_time);
|
|
igText("%2.2fms",launcher.delta_time);
|
|
igColumns(1,null,0);
|
|
}
|
|
igEnd();
|
|
}
|
|
|
|
glUseProgram(0);
|
|
import ecs_utils.gfx.buffer;
|
|
Buffer.unbind(Buffer.BindTarget.array);
|
|
Buffer.unbind(Buffer.BindTarget.element_array);
|
|
|
|
igRender();
|
|
version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
|
else version(Android)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
|
else ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
|
//ImGuiImplOpenGL2RenderDrawData(igGetDrawData());
|
|
|
|
//launcher.renderer.clear();
|
|
//launcher.renderer.present();
|
|
|
|
SDL_GL_SwapWindow(launcher.window);
|
|
|
|
}
|
|
|
|
void quit()
|
|
{
|
|
launcher.gui_manager.clear();
|
|
Mallocator.dispose(launcher.gui_manager);
|
|
|
|
launcher.manager.destroy();
|
|
launcher.manager = null;
|
|
|
|
version(WebAssembly)emscripten_cancel_main_loop();
|
|
}
|
|
|
|
version(Android)
|
|
{
|
|
export extern (C) int SDL_main(int argc, char** args)
|
|
{
|
|
return app_main(argc,args);
|
|
}
|
|
|
|
import ldc.attributes;
|
|
|
|
extern (C) __gshared
|
|
{
|
|
@section(".tdata")
|
|
int _tlsstart = 0;
|
|
@section(".tcommon")
|
|
int _tlsend = 0;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
extern (C) int main(int argc, char** argv)
|
|
{
|
|
return app_main(argc,argv);
|
|
}
|
|
}
|
|
|
|
int app_main(int argc, char** argv)
|
|
//int main(int argc, char** argv)
|
|
{
|
|
|
|
version(BindSDL_Static){}
|
|
else
|
|
{
|
|
loadSDL();
|
|
loadSDLImage();
|
|
}
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
|
{
|
|
printf("SDL could not initialize! SDL_Error: %s", SDL_GetError());
|
|
return -1;
|
|
}
|
|
SDL_version sdl_version;
|
|
SDL_GetVersion(&sdl_version);
|
|
printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED,
|
|
SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
|
|
|
launcher.gl_context = SDL_GL_CreateContext(launcher.window);
|
|
launcher.context = igCreateContext(null);
|
|
launcher.timer_freq = SDL_GetPerformanceFrequency();
|
|
|
|
launcher.plot_values = Mallocator.makeArray!(Launcher.PlotStruct)(101);
|
|
|
|
SDL_GetWindowSize(launcher.window, &launcher.window_size.x, &launcher.window_size.y);
|
|
|
|
version(WebAssembly)
|
|
{
|
|
gladLoadGLES2(x => SDL_GL_GetProcAddress(x));
|
|
if(!ImGui_ImplSDL2_InitForOpenGL(launcher.window,launcher.gl_context))
|
|
{
|
|
printf("ImGui initialization failed!");
|
|
return -2;
|
|
}
|
|
if(!ImGui_ImplOpenGL3_Init())
|
|
{
|
|
printf("ImGui OpenGL initialization failed!");
|
|
return -3;
|
|
}
|
|
}
|
|
else version(Android)
|
|
{
|
|
//gladLoadGL();
|
|
gladLoadGLES2(x => SDL_GL_GetProcAddress(x));
|
|
if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context))
|
|
{
|
|
printf("ImGui initialization failed!");
|
|
return -2;
|
|
}
|
|
if(!ImGui_ImplOpenGL3_Init("#version 100"))
|
|
{
|
|
printf("ImGui OpenGL initialization failed!");
|
|
return -3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gladLoadGL();
|
|
if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context))
|
|
{
|
|
printf("ImGui initialization failed!");
|
|
return -2;
|
|
}
|
|
//if(!ImGuiImplOpenGL2Init())
|
|
if(!ImGui_ImplOpenGL3_Init("#version 120"))
|
|
{
|
|
printf("ImGui OpenGL initialization failed!");
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
ImFontConfig* config = ImFontConfig_ImFontConfig();
|
|
ImGuiIO* io = igGetIO();
|
|
const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts);
|
|
ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, config, font_ranges);
|
|
|
|
setStyle(3);
|
|
|
|
launcher.job_updater = Mallocator.make!ECSJobUpdater(1);
|
|
//launcher.job_updater.onCreate();
|
|
|
|
EntityManager.initialize(32, 1<<16);
|
|
launcher.manager = EntityManager.instance;
|
|
|
|
//launcher.manager.m_thread_id_func = &launcher.job_updater.getThreadID;
|
|
//launcher.manager.setJobDispachFunc(&launcher.job_updater.dispatch);
|
|
launcher.manager.setMultithreadingCallbacks(&launcher.job_updater.dispatch, &launcher.job_updater.getThreadID);
|
|
|
|
launcher.manager.beginRegister();
|
|
|
|
launcher.manager.registerPass("clean");
|
|
|
|
launcher.manager.registerSystem!CountSystem(10000);
|
|
launcher.manager.registerSystem!CleanSystem(0,"clean");
|
|
|
|
launcher.manager.endRegister();
|
|
|
|
loadGFX();
|
|
|
|
launcher.renderer.initialize();
|
|
|
|
import mmutils.thread_pool : ThreadPool;
|
|
launcher.threads = ThreadPool.getCPUCoresCount();
|
|
if(launcher.threads < 2)launcher.threads = 2;
|
|
|
|
launcher.gui_manager = Mallocator.make!GUIManager();
|
|
|
|
{
|
|
import demos.simple;
|
|
import demos.space_invaders;
|
|
// launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips);
|
|
launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips);
|
|
}
|
|
|
|
int key_num;
|
|
ubyte* keys = SDL_GetKeyboardState(&key_num);
|
|
launcher.keys = keys[0..key_num];
|
|
|
|
version(WebAssembly)
|
|
{
|
|
/*EmscriptenFullscreenStrategy strategy;
|
|
strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
|
|
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
|
|
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST;*/
|
|
|
|
//int result = emscripten_request_fullscreen_strategy(null, true, &strategy);
|
|
//emscripten_enter_soft_fullscreen(null, &strategy);
|
|
//printf("Fullscreen request: %s.\n", emscripten_result_to_string(result));
|
|
emscripten_set_main_loop_arg(&mainLoop, null, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
bool arg = true;
|
|
while(arg == true)
|
|
{
|
|
mainLoop(&arg);
|
|
}
|
|
}
|
|
|
|
EntityManager.destroy();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void loadGFX()
|
|
{
|
|
import ecs_utils.gfx.texture;
|
|
import ecs_utils.gfx.vertex;
|
|
import ecs_utils.gfx.shader;
|
|
import ecs_utils.gfx.material;
|
|
import ecs_utils.gfx.config;
|
|
import ecs_utils.gfx.mesh;
|
|
|
|
Texture.__loadBackend();
|
|
Renderer.__loadBackend();
|
|
|
|
GfxConfig.materials = Mallocator.makeArray!Material(1);
|
|
GfxConfig.meshes = Mallocator.makeArray!Mesh(1);
|
|
|
|
float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0];
|
|
GfxConfig.meshes[0].vertices = Mallocator.makeArray(vertices);
|
|
ushort[6] indices = [0,1,2,1,2,3];
|
|
GfxConfig.meshes[0].indices = Mallocator.makeArray(indices);
|
|
GfxConfig.meshes[0].uploadData();
|
|
|
|
Shader vsh;
|
|
vsh.create();
|
|
vsh.load("assets/shaders/base.vp");
|
|
vsh.compile();
|
|
|
|
Shader fsh;
|
|
fsh.create();
|
|
fsh.load("assets/shaders/base.fp");
|
|
fsh.compile();
|
|
|
|
GfxConfig.materials[0].create();
|
|
GfxConfig.materials[0].data.blend_mode = Material.BlendMode.opaque;
|
|
GfxConfig.materials[0].data.mode = Material.TransformMode.position;
|
|
Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)];
|
|
GfxConfig.materials[0].attachModules(modules);
|
|
//GfxConfig.materials[0].
|
|
//GfxConfig.materials[0].load(load_data.materials[i].str);
|
|
GfxConfig.materials[0].compile();
|
|
GfxConfig.materials[0].bindAttribLocation("positions",0);
|
|
GfxConfig.materials[0].bindAttribLocation("tex_coords",1);
|
|
GfxConfig.materials[0].bindAttribLocation("depth",2);
|
|
GfxConfig.materials[0].bindAttribLocation("vcolor",3);
|
|
GfxConfig.materials[0].link();
|
|
|
|
/* import std.stdio;
|
|
writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions"));
|
|
writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords"));
|
|
writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth"));
|
|
writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/
|
|
|
|
GfxConfig.materials[0].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3);
|
|
GfxConfig.materials[0].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0);
|
|
GfxConfig.materials[0].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16);
|
|
GfxConfig.materials[0].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32);
|
|
GfxConfig.materials[0].data.bindings = Mallocator.makeArray!(int)(1);
|
|
GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex");
|
|
|
|
|
|
/*glUseProgram(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/
|
|
} |