chore: update template for PL changes
This commit is contained in:
parent
afc696a894
commit
11723827a6
@ -18,10 +18,10 @@ if len(sys.argv) > 1:
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/" + pilotlight_location)
|
||||
|
||||
import pl_build.core as pl
|
||||
import pl_build.backend_win32 as win32
|
||||
import pl_build.backend_linux as linux
|
||||
import pl_build.backend_macos as apple
|
||||
import build.core as pl
|
||||
import build.backend_win32 as win32
|
||||
import build.backend_linux as linux
|
||||
import build.backend_macos as apple
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# [SECTION] project
|
||||
|
687
src/app.c
687
src/app.c
@ -1,20 +1,64 @@
|
||||
/*
|
||||
app.c
|
||||
- template app
|
||||
- loads only stable APIs
|
||||
example_basic_2.c
|
||||
- demonstrates loading APIs
|
||||
- demonstrates loading extensions
|
||||
- demonstrates hot reloading
|
||||
- demonstrates starter extension
|
||||
- demonstrates basic drawing extension (2D)
|
||||
- demonstrates basic screen log extension
|
||||
- demonstrates basic console extension
|
||||
- demonstrates basic UI extension
|
||||
*/
|
||||
|
||||
/*
|
||||
Index of this file:
|
||||
// [SECTION] quick notes
|
||||
// [SECTION] includes
|
||||
// [SECTION] structs
|
||||
// [SECTION] apis
|
||||
// [SECTION] helper functions forward declarations
|
||||
// [SECTION] pl_app_load
|
||||
// [SECTION] pl_app_shutdown
|
||||
// [SECTION] pl_app_resize
|
||||
// [SECTION] pl_app_update
|
||||
// [SECTION] helper functions implementations
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] quick notes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
This example is the first to introduce extensions. Extensions are just
|
||||
shared libraries that export a "load" and "unload" function. The default
|
||||
being:
|
||||
|
||||
* void pl_load_ext (plApiRegistryI*, bool reload)
|
||||
* void pl_unload_ext(plApiRegistryI*, bool reload)
|
||||
|
||||
Later examples will explain more about the details of creating an extension
|
||||
but the important thing to understand now is that an extension just provides
|
||||
an implementation of an API. The "load" function allows an extension to
|
||||
request APIs it depends on and to register any API it provides. The unload
|
||||
function just allows an extension the opportunity to unregister and perform
|
||||
any required cleanup.
|
||||
|
||||
This example is also the first to introduce the "starter" extension. This
|
||||
extension acts a bit as a helper extension to remove some common boilerplate
|
||||
but is also just useful in general for most applications only needing to use
|
||||
UI, plotting, drawing, etc. Or even to just experiment with the lower level
|
||||
graphics extension in an isolated manner. Later examples will gradually peel
|
||||
away at this extension and others. For this example, we will just demonstrate
|
||||
some of the smaller helpful extensions. These include:
|
||||
|
||||
* log
|
||||
* profile
|
||||
* stat
|
||||
* console
|
||||
* screen log
|
||||
* ui
|
||||
|
||||
This will be very light introductions with later examples going into more
|
||||
detail. Feel free to open the header file for the extension for more
|
||||
information and functionality.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -24,32 +68,21 @@ Index of this file:
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <string.h> // memset
|
||||
#include "pl.h"
|
||||
#include "pl_memory.h"
|
||||
#define PL_MATH_INCLUDE_FUNCTIONS
|
||||
|
||||
#define PL_MATH_INCLUDE_FUNCTIONS // required to expose some of the color helpers
|
||||
#include "pl_math.h"
|
||||
|
||||
// extensions
|
||||
#include "pl_log_ext.h"
|
||||
#include "pl_window_ext.h"
|
||||
#include "pl_shader_ext.h"
|
||||
#include "pl_draw_ext.h"
|
||||
#include "pl_starter_ext.h"
|
||||
#include "pl_ui_ext.h"
|
||||
#include "pl_graphics_ext.h"
|
||||
#include "pl_draw_backend_ext.h"
|
||||
#include "pl_profile_ext.h"
|
||||
#include "pl_stats_ext.h"
|
||||
#include "pl_job_ext.h"
|
||||
#include "pl_string_intern_ext.h"
|
||||
#include "pl_library_ext.h"
|
||||
#include "pl_rect_pack_ext.h"
|
||||
#include "pl_gpu_allocators_ext.h"
|
||||
#include "pl_image_ext.h"
|
||||
#include "pl_console_ext.h"
|
||||
#include "pl_screen_log_ext.h"
|
||||
#include "pl_tools_ext.h"
|
||||
#include "pl_platform_ext.h"
|
||||
#include "pl_profile_ext.h"
|
||||
#include "pl_log_ext.h"
|
||||
#include "pl_stats_ext.h"
|
||||
#include "pl_console_ext.h"
|
||||
|
||||
// example extensions
|
||||
// out extension
|
||||
#include "pl_example_ext.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -61,83 +94,34 @@ typedef struct _plAppData
|
||||
// window
|
||||
plWindow* ptWindow;
|
||||
|
||||
// drawing stuff
|
||||
plDrawList2D* ptDrawlist;
|
||||
plDrawLayer2D* ptFGLayer;
|
||||
plDrawLayer2D* ptBGLayer;
|
||||
plFont* ptDefaultFont;
|
||||
|
||||
// ui options
|
||||
bool bShowUiDebug;
|
||||
bool bShowUiStyle;
|
||||
bool* pbShowDeviceMemoryAnalyzer;
|
||||
bool* pbShowMemoryAllocations;
|
||||
bool* pbShowProfiling;
|
||||
bool* pbShowStats;
|
||||
bool* pbShowLogging;
|
||||
|
||||
// graphics & sync objects
|
||||
plDevice* ptDevice;
|
||||
plSurface* ptSurface;
|
||||
plSwapchain* ptSwapchain;
|
||||
plTimelineSemaphore* aptSemaphores[PL_MAX_FRAMES_IN_FLIGHT];
|
||||
uint64_t aulNextTimelineValue[PL_MAX_FRAMES_IN_FLIGHT];
|
||||
plCommandPool* atCmdPools[PL_MAX_FRAMES_IN_FLIGHT];
|
||||
plRenderPassHandle tMainRenderPass;
|
||||
plRenderPassLayoutHandle tMainRenderPassLayout;
|
||||
// log channel
|
||||
uint64_t uExampleLogChannel;
|
||||
|
||||
// console variable
|
||||
bool bShowHelpWindow;
|
||||
} plAppData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] apis
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const plDataRegistryI* gptDataRegistry = NULL;
|
||||
const plMemoryI* gptMemory = NULL;
|
||||
const plIOI* gptIO = NULL;
|
||||
const plWindowI* gptWindows = NULL;
|
||||
const plGraphicsI* gptGfx = NULL;
|
||||
const plDrawI* gptDraw = NULL;
|
||||
const plUiI* gptUi = NULL;
|
||||
const plShaderI* gptShader = NULL;
|
||||
const plDrawBackendI* gptDrawBackend = NULL;
|
||||
const plProfileI* gptProfile = NULL;
|
||||
const plExampleI* gptExample = NULL;
|
||||
const plStatsI* gptStats = NULL;
|
||||
const plToolsI* gptTools = NULL;
|
||||
const plImageI* gptImage = NULL;
|
||||
const plGPUAllocatorsI* gptGpuAllocators = NULL;
|
||||
const plJobI* gptJob = NULL;
|
||||
const plThreadsI* gptThreads = NULL;
|
||||
const plAtomicsI* gptAtomics = NULL;
|
||||
const plRectPackI* gptRect = NULL;
|
||||
const plFileI* gptFile = NULL;
|
||||
const plNetworkI* gptNetwork = NULL;
|
||||
const plStringInternI* gptString = NULL;
|
||||
const plLibraryI* gptLibrary = NULL;
|
||||
const plLogI* gptLog = NULL;
|
||||
const plVirtualMemoryI* gptVirtualMemory = NULL;
|
||||
const plConsoleI* gptConsole = NULL;
|
||||
const plScreenLogI* gptScreenLog = NULL;
|
||||
const plIOI* gptIO = NULL;
|
||||
const plWindowI* gptWindows = NULL;
|
||||
const plDrawI* gptDraw = NULL;
|
||||
const plStarterI* gptStarter = NULL;
|
||||
const plUiI* gptUI = NULL;
|
||||
const plScreenLogI* gptScreenLog = NULL;
|
||||
const plProfileI* gptProfile = NULL;
|
||||
const plStatsI* gptStats = NULL;
|
||||
const plMemoryI* gptMemory = NULL;
|
||||
const plLogI* gptLog = NULL;
|
||||
const plConsoleI* gptConsole = NULL;
|
||||
const plExampleI* gptExample = NULL;
|
||||
|
||||
// helpers
|
||||
#define PL_ALLOC(x) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__)
|
||||
#define PL_REALLOC(x, y) gptMemory->tracked_realloc((x), (y), __FILE__, __LINE__)
|
||||
#define PL_FREE(x) gptMemory->tracked_realloc((x), 0, __FILE__, __LINE__)
|
||||
|
||||
#define PL_DS_ALLOC(x) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__)
|
||||
#define PL_DS_ALLOC_INDIRECT(x, FILE, LINE) gptMemory->tracked_realloc(NULL, (x), FILE, LINE)
|
||||
#define PL_DS_FREE(x) gptMemory->tracked_realloc((x), 0, __FILE__, __LINE__)
|
||||
#include "pl_ds.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] helper functions forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void pl__setup_graphics_extensions (plAppData*);
|
||||
void pl__resize_graphics_extensions(plAppData*);
|
||||
void pl__resize_graphics_extensions(plAppData*);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] pl_app_load
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -145,13 +129,9 @@ void pl__resize_graphics_extensions(plAppData*);
|
||||
PL_EXPORT void*
|
||||
pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
||||
{
|
||||
// NOTE: on first load, "ptAppData" will be NULL but on reloads
|
||||
// NOTE: on first load, "pAppData" will be NULL but on reloads
|
||||
// it will be the value returned from this function
|
||||
|
||||
// retrieve the data registry API, this is the API used for sharing data
|
||||
// between extensions & the runtime
|
||||
gptDataRegistry = pl_get_api_latest(ptApiRegistry, plDataRegistryI);
|
||||
|
||||
// if "ptAppData" is a valid pointer, then this function is being called
|
||||
// during a hot reload.
|
||||
if(ptAppData)
|
||||
@ -159,140 +139,86 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
||||
|
||||
// re-retrieve the apis since we are now in
|
||||
// a different dll/so
|
||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||
gptGfx = pl_get_api_latest(ptApiRegistry, plGraphicsI);
|
||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||
gptShader = pl_get_api_latest(ptApiRegistry, plShaderI);
|
||||
gptDrawBackend = pl_get_api_latest(ptApiRegistry, plDrawBackendI);
|
||||
gptUi = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
||||
gptTools = pl_get_api_latest(ptApiRegistry, plToolsI);
|
||||
gptImage = pl_get_api_latest(ptApiRegistry, plImageI);
|
||||
gptGpuAllocators = pl_get_api_latest(ptApiRegistry, plGPUAllocatorsI);
|
||||
gptJob = pl_get_api_latest(ptApiRegistry, plJobI);
|
||||
gptThreads = pl_get_api_latest(ptApiRegistry, plThreadsI);
|
||||
gptAtomics = pl_get_api_latest(ptApiRegistry, plAtomicsI);
|
||||
gptRect = pl_get_api_latest(ptApiRegistry, plRectPackI);
|
||||
gptFile = pl_get_api_latest(ptApiRegistry, plFileI);
|
||||
gptNetwork = pl_get_api_latest(ptApiRegistry, plNetworkI);
|
||||
gptString = pl_get_api_latest(ptApiRegistry, plStringInternI);
|
||||
gptLibrary = pl_get_api_latest(ptApiRegistry, plLibraryI);
|
||||
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||
gptVirtualMemory = pl_get_api_latest(ptApiRegistry, plVirtualMemoryI);
|
||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
|
||||
gptUI = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
||||
|
||||
return ptAppData;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~apis & extensions~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// retrieve extension registry
|
||||
const plExtensionRegistryI* ptExtensionRegistry = pl_get_api_latest(ptApiRegistry, plExtensionRegistryI);
|
||||
|
||||
// load extensions
|
||||
ptExtensionRegistry->load("pl_unity_ext", NULL, NULL, false);
|
||||
ptExtensionRegistry->load("pl_platform_ext", NULL, NULL, false);
|
||||
// * first argument is the shared library name WITHOUT the extension
|
||||
// * second & third argument is the load/unload functions names (use NULL for the default of "pl_load_ext" &
|
||||
// "pl_unload_ext")
|
||||
// * fourth argument indicates if the extension is reloadable (should we check for changes and reload if changed)
|
||||
ptExtensionRegistry->load("pl_unity_ext", NULL, NULL, true);
|
||||
ptExtensionRegistry->load("pl_platform_ext", NULL, NULL, false); // provides the file API used by the drawing ext
|
||||
ptExtensionRegistry->load("pl_example_ext", NULL, NULL, true);
|
||||
|
||||
// load apis
|
||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||
gptGfx = pl_get_api_latest(ptApiRegistry, plGraphicsI);
|
||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||
gptShader = pl_get_api_latest(ptApiRegistry, plShaderI);
|
||||
gptDrawBackend = pl_get_api_latest(ptApiRegistry, plDrawBackendI);
|
||||
gptUi = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
||||
gptTools = pl_get_api_latest(ptApiRegistry, plToolsI);
|
||||
gptImage = pl_get_api_latest(ptApiRegistry, plImageI);
|
||||
gptGpuAllocators = pl_get_api_latest(ptApiRegistry, plGPUAllocatorsI);
|
||||
gptJob = pl_get_api_latest(ptApiRegistry, plJobI);
|
||||
gptThreads = pl_get_api_latest(ptApiRegistry, plThreadsI);
|
||||
gptAtomics = pl_get_api_latest(ptApiRegistry, plAtomicsI);
|
||||
gptRect = pl_get_api_latest(ptApiRegistry, plRectPackI);
|
||||
gptFile = pl_get_api_latest(ptApiRegistry, plFileI);
|
||||
gptNetwork = pl_get_api_latest(ptApiRegistry, plNetworkI);
|
||||
gptString = pl_get_api_latest(ptApiRegistry, plStringInternI);
|
||||
gptLibrary = pl_get_api_latest(ptApiRegistry, plLibraryI);
|
||||
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||
gptVirtualMemory = pl_get_api_latest(ptApiRegistry, plVirtualMemoryI);
|
||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||
// load required apis
|
||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||
|
||||
// load required apis (these are provided though extensions)
|
||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
|
||||
gptUI = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||
|
||||
// out extension
|
||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
||||
|
||||
gptExample->print_to_console("Hello from example extension");
|
||||
|
||||
// this path is taken only during first load, so we
|
||||
// allocate app memory here
|
||||
ptAppData = PL_ALLOC(sizeof(plAppData));
|
||||
memset(ptAppData, 0, sizeof(plAppData));
|
||||
|
||||
// add console variables
|
||||
gptConsole->initialize((plConsoleSettings){.tFlags = PL_CONSOLE_FLAGS_POPUP});
|
||||
// default values
|
||||
ptAppData->bShowHelpWindow = true;
|
||||
|
||||
// use window API to create a window
|
||||
plWindowDesc tWindowDesc = {
|
||||
.pcTitle = "App Template",
|
||||
.pcTitle = "Template App",
|
||||
.iXPos = 200,
|
||||
.iYPos = 200,
|
||||
.uWidth = 500,
|
||||
.uHeight = 500,
|
||||
.uWidth = 600,
|
||||
.uHeight = 600,
|
||||
};
|
||||
gptWindows->create_window(tWindowDesc, &ptAppData->ptWindow);
|
||||
gptWindows->create(tWindowDesc, &ptAppData->ptWindow);
|
||||
gptWindows->show(ptAppData->ptWindow);
|
||||
|
||||
// setup graphics extension
|
||||
pl__setup_graphics_extensions(ptAppData);
|
||||
// initialize the starter API (handles alot of boilerplate)
|
||||
plStarterInit tStarterInit = {
|
||||
.tFlags = PL_STARTER_FLAGS_ALL_EXTENSIONS,
|
||||
.ptWindow = ptAppData->ptWindow
|
||||
};
|
||||
gptStarter->initialize(tStarterInit);
|
||||
gptStarter->finalize();
|
||||
|
||||
// initialize APIs that require it
|
||||
gptTools->initialize((plToolsInit){.ptDevice = ptAppData->ptDevice});
|
||||
// add a log channel
|
||||
ptAppData->uExampleLogChannel = gptLog->add_channel("Example 2", (plLogExtChannelInit){.tType = PL_LOG_CHANNEL_TYPE_BUFFER});
|
||||
|
||||
// retrieve some console variables
|
||||
ptAppData->pbShowLogging = (bool*)gptConsole->get_variable("t.LogTool", NULL, NULL);
|
||||
ptAppData->pbShowStats = (bool*)gptConsole->get_variable("t.StatTool", NULL, NULL);
|
||||
ptAppData->pbShowProfiling = (bool*)gptConsole->get_variable("t.ProfileTool", NULL, NULL);
|
||||
ptAppData->pbShowMemoryAllocations = (bool*)gptConsole->get_variable("t.MemoryAllocationTool", NULL, NULL);
|
||||
ptAppData->pbShowDeviceMemoryAnalyzer = (bool*)gptConsole->get_variable("t.DeviceMemoryAnalyzerTool", NULL, NULL);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~setup draw extensions~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// initialize
|
||||
gptDraw->initialize(NULL);
|
||||
gptDrawBackend->initialize(ptAppData->ptDevice);
|
||||
|
||||
// create font atlas
|
||||
plFontAtlas* ptAtlas = gptDraw->create_font_atlas();
|
||||
gptDraw->set_font_atlas(ptAtlas);
|
||||
ptAppData->ptDefaultFont = gptDraw->add_default_font(ptAtlas);
|
||||
|
||||
// build font atlas
|
||||
plCommandPool* ptCmdPool = ptAppData->atCmdPools[gptGfx->get_current_frame_index()];
|
||||
plCommandBuffer* ptCmdBuffer = gptGfx->request_command_buffer(ptCmdPool);
|
||||
gptDrawBackend->build_font_atlas(ptCmdBuffer, ptAtlas);
|
||||
gptGfx->return_command_buffer(ptCmdBuffer);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~message extension~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
gptScreenLog->initialize((plScreenLogSettings){.ptFont = ptAppData->ptDefaultFont});
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ui extension~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
gptUi->initialize();
|
||||
gptUi->set_default_font(ptAppData->ptDefaultFont);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~app stuff~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// create drawlist and some layers to draw to
|
||||
ptAppData->ptDrawlist = gptDraw->request_2d_drawlist();
|
||||
ptAppData->ptFGLayer = gptDraw->request_2d_layer(ptAppData->ptDrawlist);
|
||||
ptAppData->ptBGLayer = gptDraw->request_2d_layer(ptAppData->ptDrawlist);
|
||||
|
||||
// demonstrate example extension
|
||||
gptExample->print_to_console("From example extension!");
|
||||
// add a console variable
|
||||
gptConsole->add_toggle_variable("a.HelpWindow", &ptAppData->bShowHelpWindow, "toggle help window", PL_CONSOLE_VARIABLE_FLAGS_NONE);
|
||||
|
||||
// return app memory
|
||||
return ptAppData;
|
||||
@ -305,23 +231,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
||||
PL_EXPORT void
|
||||
pl_app_shutdown(plAppData* ptAppData)
|
||||
{
|
||||
// ensure GPU is finished before cleanup
|
||||
gptGfx->flush_device(ptAppData->ptDevice);
|
||||
for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++)
|
||||
{
|
||||
gptGfx->cleanup_command_pool(ptAppData->atCmdPools[i]);
|
||||
gptGfx->cleanup_semaphore(ptAppData->aptSemaphores[i]);
|
||||
}
|
||||
gptDrawBackend->cleanup_font_atlas(NULL);
|
||||
gptUi->cleanup();
|
||||
gptDrawBackend->cleanup();
|
||||
gptScreenLog->cleanup();
|
||||
gptConsole->cleanup();
|
||||
gptGfx->cleanup_swapchain(ptAppData->ptSwapchain);
|
||||
gptGfx->cleanup_surface(ptAppData->ptSurface);
|
||||
gptGfx->cleanup_device(ptAppData->ptDevice);
|
||||
gptGfx->cleanup();
|
||||
gptWindows->destroy_window(ptAppData->ptWindow);
|
||||
gptStarter->cleanup();
|
||||
gptWindows->destroy(ptAppData->ptWindow);
|
||||
PL_FREE(ptAppData);
|
||||
}
|
||||
|
||||
@ -332,7 +243,7 @@ pl_app_shutdown(plAppData* ptAppData)
|
||||
PL_EXPORT void
|
||||
pl_app_resize(plAppData* ptAppData)
|
||||
{
|
||||
pl__resize_graphics_extensions(ptAppData);
|
||||
gptStarter->resize();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -342,284 +253,88 @@ pl_app_resize(plAppData* ptAppData)
|
||||
PL_EXPORT void
|
||||
pl_app_update(plAppData* ptAppData)
|
||||
{
|
||||
gptProfile->begin_frame();
|
||||
pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__);
|
||||
|
||||
// for convience
|
||||
plIO* ptIO = gptIO->get_io();
|
||||
|
||||
// new frame stuff
|
||||
gptIO->new_frame();
|
||||
gptDrawBackend->new_frame();
|
||||
gptUi->new_frame();
|
||||
gptStats->new_frame();
|
||||
gptGfx->begin_frame(ptAppData->ptDevice);
|
||||
plCommandPool* ptCmdPool = ptAppData->atCmdPools[gptGfx->get_current_frame_index()];
|
||||
gptGfx->reset_command_pool(ptCmdPool, 0);
|
||||
|
||||
// update statistics
|
||||
static double* pdFrameTimeCounter = NULL;
|
||||
if(!pdFrameTimeCounter)
|
||||
pdFrameTimeCounter = gptStats->get_counter("frametime (ms)");
|
||||
*pdFrameTimeCounter = (double)ptIO->fDeltaTime * 1000.0;
|
||||
|
||||
// acquire swapchain image
|
||||
if(!gptGfx->acquire_swapchain_image(ptAppData->ptSwapchain))
|
||||
{
|
||||
pl_app_resize(ptAppData);
|
||||
pl_end_cpu_sample(gptProfile, 0);
|
||||
gptProfile->end_frame();
|
||||
// this needs to be the first call when using the starter
|
||||
// extension. You must return if it returns false (usually a swapchain recreation).
|
||||
if(!gptStarter->begin_frame())
|
||||
return;
|
||||
}
|
||||
|
||||
// just some drawing
|
||||
gptDraw->add_circle(ptAppData->ptFGLayer, (plVec2){100.0f, 100.0f}, 50.0f, 12, (plDrawLineOptions){.fThickness = 2.0f, .uColor = PL_COLOR_32_RGBA(1.0f, 0.0f, 1.0f, 1.0f)});
|
||||
|
||||
if(gptIO->is_key_pressed(PL_KEY_F1, false))
|
||||
gptConsole->open();
|
||||
|
||||
gptConsole->update();
|
||||
|
||||
if(gptUi->begin_window("Pilot Light", NULL, false))
|
||||
{
|
||||
|
||||
const float pfRatios[] = {1.0f};
|
||||
gptUi->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatios);
|
||||
if(gptUi->begin_collapsing_header("Information", 0))
|
||||
{
|
||||
|
||||
gptUi->text("Pilot Light %s", PILOT_LIGHT_VERSION_STRING);
|
||||
gptUi->end_collapsing_header();
|
||||
}
|
||||
if(gptUi->begin_collapsing_header("Tools", 0))
|
||||
{
|
||||
gptUi->checkbox("Device Memory Analyzer", ptAppData->pbShowDeviceMemoryAnalyzer);
|
||||
gptUi->checkbox("Memory Allocations", ptAppData->pbShowMemoryAllocations);
|
||||
gptUi->checkbox("Profiling", ptAppData->pbShowProfiling);
|
||||
gptUi->checkbox("Statistics", ptAppData->pbShowStats);
|
||||
gptUi->checkbox("Logging", ptAppData->pbShowLogging);
|
||||
gptUi->end_collapsing_header();
|
||||
}
|
||||
if(gptUi->begin_collapsing_header("User Interface", 0))
|
||||
{
|
||||
gptUi->checkbox("UI Debug", &ptAppData->bShowUiDebug);
|
||||
gptUi->checkbox("UI Style", &ptAppData->bShowUiStyle);
|
||||
gptUi->end_collapsing_header();
|
||||
}
|
||||
gptUi->end_window();
|
||||
}
|
||||
|
||||
if(ptAppData->bShowUiStyle)
|
||||
gptUi->show_style_editor_window(&ptAppData->bShowUiStyle);
|
||||
|
||||
if(ptAppData->bShowUiDebug)
|
||||
gptUi->show_debug_window(&ptAppData->bShowUiDebug);
|
||||
|
||||
gptTools->update();
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~graphics work~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const uint32_t uCurrentFrameIndex = gptGfx->get_current_frame_index();
|
||||
|
||||
plCommandBuffer* ptCommandBuffer = gptGfx->request_command_buffer(ptCmdPool);
|
||||
|
||||
const plBeginCommandInfo tBeginInfo = {
|
||||
.uWaitSemaphoreCount = 1,
|
||||
.atWaitSempahores = {ptAppData->aptSemaphores[uCurrentFrameIndex]},
|
||||
.auWaitSemaphoreValues = {ptAppData->aulNextTimelineValue[uCurrentFrameIndex]},
|
||||
};
|
||||
gptGfx->begin_command_recording(ptCommandBuffer, &tBeginInfo);
|
||||
|
||||
// begin main renderpass (directly to swapchain)
|
||||
plRenderEncoder* ptEncoder = gptGfx->begin_render_pass(ptCommandBuffer, ptAppData->tMainRenderPass, NULL);
|
||||
|
||||
// submit our layers & drawlist
|
||||
gptDraw->submit_2d_layer(ptAppData->ptBGLayer);
|
||||
gptDraw->submit_2d_layer(ptAppData->ptFGLayer);
|
||||
gptDrawBackend->submit_2d_drawlist(ptAppData->ptDrawlist, ptEncoder, ptIO->tMainViewportSize.x, ptIO->tMainViewportSize.y, gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tSampleCount);
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~stats API~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// submits UI layers
|
||||
gptUi->end_frame();
|
||||
// rather than have to lookup the counter every frame, its best to "store" it
|
||||
// like this. To update it, just deference it and set the value.
|
||||
static double* pdExample2Counter = NULL;
|
||||
if(!pdExample2Counter)
|
||||
pdExample2Counter = gptStats->get_counter("example 2 counter");
|
||||
|
||||
// submit UI drawlists
|
||||
gptDrawBackend->submit_2d_drawlist(gptUi->get_draw_list(), ptEncoder, ptIO->tMainViewportSize.x, ptIO->tMainViewportSize.y, gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tSampleCount);
|
||||
gptDrawBackend->submit_2d_drawlist(gptUi->get_debug_draw_list(), ptEncoder, ptIO->tMainViewportSize.x, ptIO->tMainViewportSize.y, gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tSampleCount);
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~drawing & profile API~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
plDrawList2D* ptMessageDrawlist = gptScreenLog->get_drawlist(ptIO->tMainViewportSize.x, ptIO->tMainViewportSize.y);
|
||||
gptDrawBackend->submit_2d_drawlist(ptMessageDrawlist, ptEncoder, ptIO->tMainViewportSize.x, ptIO->tMainViewportSize.y, gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tSampleCount);
|
||||
gptProfile->begin_sample(0, "example drawing");
|
||||
|
||||
plDrawLayer2D* ptFGLayer = gptStarter->get_foreground_layer();
|
||||
gptDraw->add_line(ptFGLayer,
|
||||
(plVec2){0.0f, 0.0f},
|
||||
(plVec2){500.0f, 500.0f}, (plDrawLineOptions){ .fThickness = 1.0f, .uColor = PL_COLOR_32_MAGENTA});
|
||||
|
||||
plDrawLayer2D* ptBGLayer = gptStarter->get_background_layer();
|
||||
gptDraw->add_triangle_filled(ptBGLayer,
|
||||
(plVec2){50.0f, 100.0f},
|
||||
(plVec2){200.0f},
|
||||
(plVec2){100.0f, 200.0f}, (plDrawSolidOptions){.uColor = PL_COLOR_32_RGBA(0.0f, 0.5f, 1.0f, 0.5f)});
|
||||
|
||||
// end render pass
|
||||
gptGfx->end_render_pass(ptEncoder);
|
||||
gptProfile->end_sample(0);
|
||||
|
||||
// end recording
|
||||
gptGfx->end_command_recording(ptCommandBuffer);
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~UI & Screen Log API~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~submit work to GPU & present~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const plSubmitInfo tSubmitInfo = {
|
||||
.uSignalSemaphoreCount = 1,
|
||||
.atSignalSempahores = {ptAppData->aptSemaphores[uCurrentFrameIndex]},
|
||||
.auSignalSemaphoreValues = {++ptAppData->aulNextTimelineValue[uCurrentFrameIndex]},
|
||||
};
|
||||
|
||||
if(!gptGfx->present(ptCommandBuffer, &tSubmitInfo, &ptAppData->ptSwapchain, 1))
|
||||
pl_app_resize(ptAppData);
|
||||
|
||||
gptGfx->return_command_buffer(ptCommandBuffer);
|
||||
|
||||
pl_end_cpu_sample(gptProfile, 0);
|
||||
gptProfile->end_frame();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] helper functions implementations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
pl__setup_graphics_extensions(plAppData* ptAppData)
|
||||
{
|
||||
// initialize shader extension (shader compiler)
|
||||
static const plShaderOptions tDefaultShaderOptions = {
|
||||
.apcIncludeDirectories = {
|
||||
"../shaders/"
|
||||
},
|
||||
.apcDirectories = {
|
||||
"../shaders/"
|
||||
},
|
||||
.tFlags = PL_SHADER_FLAGS_AUTO_OUTPUT
|
||||
};
|
||||
gptShader->initialize(&tDefaultShaderOptions);
|
||||
|
||||
// initialize graphics system
|
||||
const plGraphicsInit tGraphicsInit = {
|
||||
.tFlags = PL_GRAPHICS_INIT_FLAGS_VALIDATION_ENABLED | PL_GRAPHICS_INIT_FLAGS_SWAPCHAIN_ENABLED
|
||||
};
|
||||
gptGfx->initialize(&tGraphicsInit);
|
||||
ptAppData->ptSurface = gptGfx->create_surface(ptAppData->ptWindow);
|
||||
|
||||
// find suitable device
|
||||
uint32_t uDeviceCount = 16;
|
||||
plDeviceInfo atDeviceInfos[16] = {0};
|
||||
gptGfx->enumerate_devices(atDeviceInfos, &uDeviceCount);
|
||||
|
||||
// we will prefer discrete, then integrated
|
||||
int iBestDvcIdx = 0;
|
||||
int iDiscreteGPUIdx = -1;
|
||||
int iIntegratedGPUIdx = -1;
|
||||
for(uint32_t i = 0; i < uDeviceCount; i++)
|
||||
// creating a window
|
||||
if(ptAppData->bShowHelpWindow)
|
||||
{
|
||||
|
||||
if(atDeviceInfos[i].tType == PL_DEVICE_TYPE_DISCRETE)
|
||||
iDiscreteGPUIdx = i;
|
||||
else if(atDeviceInfos[i].tType == PL_DEVICE_TYPE_INTEGRATED)
|
||||
iIntegratedGPUIdx = i;
|
||||
}
|
||||
|
||||
if(iDiscreteGPUIdx > -1)
|
||||
iBestDvcIdx = iDiscreteGPUIdx;
|
||||
else if(iIntegratedGPUIdx > -1)
|
||||
iBestDvcIdx = iIntegratedGPUIdx;
|
||||
|
||||
// create device
|
||||
const plDeviceInit tDeviceInit = {
|
||||
.uDeviceIdx = iBestDvcIdx,
|
||||
.ptSurface = ptAppData->ptSurface
|
||||
};
|
||||
ptAppData->ptDevice = gptGfx->create_device(&tDeviceInit);
|
||||
|
||||
// create command pools
|
||||
for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++)
|
||||
ptAppData->atCmdPools[i] = gptGfx->create_command_pool(ptAppData->ptDevice, NULL);
|
||||
|
||||
// create swapchain
|
||||
plSwapchainInit tSwapInit = {
|
||||
.tSampleCount = PL_SAMPLE_COUNT_1
|
||||
};
|
||||
ptAppData->ptSwapchain = gptGfx->create_swapchain(ptAppData->ptDevice, ptAppData->ptSurface, &tSwapInit);
|
||||
|
||||
uint32_t uImageCount = 0;
|
||||
plTextureHandle* atSwapchainImages = gptGfx->get_swapchain_images(ptAppData->ptSwapchain, &uImageCount);
|
||||
|
||||
// create main render pass layout
|
||||
const plRenderPassLayoutDesc tMainRenderPassLayoutDesc = {
|
||||
.atRenderTargets = {
|
||||
{ .tFormat = gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tFormat }, // swapchain
|
||||
},
|
||||
.atSubpasses = {
|
||||
{
|
||||
.uRenderTargetCount = 1,
|
||||
.auRenderTargets = {0}
|
||||
}
|
||||
},
|
||||
.atSubpassDependencies = {
|
||||
{
|
||||
.uSourceSubpass = UINT32_MAX,
|
||||
.uDestinationSubpass = 0,
|
||||
.tSourceStageMask = PL_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT | PL_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS | PL_PIPELINE_STAGE_LATE_FRAGMENT_TESTS | PL_PIPELINE_STAGE_COMPUTE_SHADER,
|
||||
.tDestinationStageMask = PL_PIPELINE_STAGE_FRAGMENT_SHADER | PL_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT | PL_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS | PL_PIPELINE_STAGE_LATE_FRAGMENT_TESTS,
|
||||
.tSourceAccessMask = PL_ACCESS_COLOR_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ,
|
||||
.tDestinationAccessMask = PL_ACCESS_SHADER_READ | PL_ACCESS_COLOR_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ,
|
||||
},
|
||||
{
|
||||
.uSourceSubpass = 0,
|
||||
.uDestinationSubpass = UINT32_MAX,
|
||||
.tSourceStageMask = PL_PIPELINE_STAGE_FRAGMENT_SHADER | PL_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT | PL_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS | PL_PIPELINE_STAGE_LATE_FRAGMENT_TESTS,
|
||||
.tDestinationStageMask = PL_PIPELINE_STAGE_FRAGMENT_SHADER | PL_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT | PL_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS | PL_PIPELINE_STAGE_LATE_FRAGMENT_TESTS | PL_PIPELINE_STAGE_COMPUTE_SHADER,
|
||||
.tSourceAccessMask = PL_ACCESS_SHADER_READ | PL_ACCESS_COLOR_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ,
|
||||
.tDestinationAccessMask = PL_ACCESS_SHADER_READ | PL_ACCESS_COLOR_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE | PL_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ,
|
||||
},
|
||||
if(gptUI->begin_window("Help", NULL, PL_UI_WINDOW_FLAGS_AUTO_SIZE | PL_UI_WINDOW_FLAGS_NO_COLLAPSE))
|
||||
{
|
||||
gptUI->layout_static(0.0f, 500.0f, 1);
|
||||
gptUI->text("Press F1 to bring up console.");
|
||||
gptUI->text("Look for t.StatsTool (we added a stat)");
|
||||
gptUI->text("Look for t.LogTool (we added a log channel)");
|
||||
gptUI->text("Look for t.ProfileTool");
|
||||
gptUI->text("Look for t.MemoryAllocationTool and look for example 2!");
|
||||
gptUI->text("Look for a.HelpWindow (console variable we added)");
|
||||
gptUI->end_window();
|
||||
}
|
||||
};
|
||||
ptAppData->tMainRenderPassLayout = gptGfx->create_render_pass_layout(ptAppData->ptDevice, &tMainRenderPassLayoutDesc);
|
||||
|
||||
// create main render pass
|
||||
const plRenderPassDesc tMainRenderPassDesc = {
|
||||
.tLayout = ptAppData->tMainRenderPassLayout,
|
||||
.atColorTargets = {
|
||||
{
|
||||
.tLoadOp = PL_LOAD_OP_CLEAR,
|
||||
.tStoreOp = PL_STORE_OP_STORE,
|
||||
.tCurrentUsage = PL_TEXTURE_USAGE_UNSPECIFIED,
|
||||
.tNextUsage = PL_TEXTURE_USAGE_PRESENT,
|
||||
.tClearColor = {0.0f, 0.0f, 0.0f, 1.0f}
|
||||
}
|
||||
},
|
||||
.tDimensions = {(float)gptGfx->get_swapchain_info(ptAppData->ptSwapchain).uWidth, (float)gptGfx->get_swapchain_info(ptAppData->ptSwapchain).uHeight},
|
||||
.ptSwapchain = ptAppData->ptSwapchain
|
||||
};
|
||||
|
||||
plRenderPassAttachments atMainAttachmentSets[16] = {0};
|
||||
for(uint32_t i = 0; i < uImageCount; i++)
|
||||
{
|
||||
atMainAttachmentSets[i].atViewAttachments[0] = atSwapchainImages[i];
|
||||
}
|
||||
ptAppData->tMainRenderPass = gptGfx->create_render_pass(ptAppData->ptDevice, &tMainRenderPassDesc, atMainAttachmentSets);
|
||||
|
||||
// create timeline semaphores to syncronize GPU work submission
|
||||
for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++)
|
||||
ptAppData->aptSemaphores[i] = gptGfx->create_semaphore(ptAppData->ptDevice, false);
|
||||
}
|
||||
|
||||
void
|
||||
pl__resize_graphics_extensions(plAppData* ptAppData)
|
||||
{
|
||||
plIO* ptIO = gptIO->get_io();
|
||||
plSwapchainInit tDesc = {
|
||||
.bVSync = true,
|
||||
.uWidth = (uint32_t)ptIO->tMainViewportSize.x,
|
||||
.uHeight = (uint32_t)ptIO->tMainViewportSize.y,
|
||||
.tSampleCount = gptGfx->get_swapchain_info(ptAppData->ptSwapchain).tSampleCount,
|
||||
};
|
||||
gptGfx->recreate_swapchain(ptAppData->ptSwapchain, &tDesc);
|
||||
|
||||
uint32_t uImageCount = 0;
|
||||
plTextureHandle* atSwapchainImages = gptGfx->get_swapchain_images(ptAppData->ptSwapchain, &uImageCount);
|
||||
|
||||
plRenderPassAttachments atMainAttachmentSets[16] = {0};
|
||||
for(uint32_t i = 0; i < uImageCount; i++)
|
||||
// creating another window
|
||||
if(gptUI->begin_window("Pilot Light", NULL, PL_UI_WINDOW_FLAGS_NONE))
|
||||
{
|
||||
atMainAttachmentSets[i].atViewAttachments[0] = atSwapchainImages[i];
|
||||
gptUI->text("Pilot Light %s", PILOT_LIGHT_VERSION_STRING);
|
||||
|
||||
if(gptUI->button("Log"))
|
||||
{
|
||||
gptLog->trace(ptAppData->uExampleLogChannel, "Log");
|
||||
gptLog->debug(ptAppData->uExampleLogChannel, "Log");
|
||||
gptLog->info(ptAppData->uExampleLogChannel, "Log");
|
||||
gptLog->warn(ptAppData->uExampleLogChannel, "Log");
|
||||
gptLog->error(ptAppData->uExampleLogChannel, "Log");
|
||||
gptLog->fatal(ptAppData->uExampleLogChannel, "Log");
|
||||
}
|
||||
|
||||
static int iCounter = 0;
|
||||
gptUI->slider_int("Stat Counter Example", &iCounter, -10, 10, 0);
|
||||
*pdExample2Counter = iCounter; // setting our stat variable
|
||||
|
||||
gptUI->layout_row_begin(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 2); // got to pl_ui_ext.h to see layout systems
|
||||
|
||||
gptUI->layout_row_push(0.3f);
|
||||
if(gptUI->button("Log To Screen"))
|
||||
gptScreenLog->add_message(5.0, "Cool Message!");
|
||||
|
||||
gptUI->layout_row_push(0.3f);
|
||||
if(gptUI->button("Big Log To Screen"))
|
||||
gptScreenLog->add_message_ex(0, 5, PL_COLOR_32_GREEN, 3.0f, "%s", "Bigger & Greener!");
|
||||
|
||||
gptUI->layout_row_end();
|
||||
|
||||
gptUI->end_window();
|
||||
}
|
||||
gptGfx->update_render_pass_attachments(ptAppData->ptDevice, ptAppData->tMainRenderPass, gptIO->get_io()->tMainViewportSize, atMainAttachmentSets);
|
||||
|
||||
// must be the last function called when using the starter extension
|
||||
gptStarter->end_frame();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user