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)
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/" + pilotlight_location)
|
||||||
|
|
||||||
import pl_build.core as pl
|
import build.core as pl
|
||||||
import pl_build.backend_win32 as win32
|
import build.backend_win32 as win32
|
||||||
import pl_build.backend_linux as linux
|
import build.backend_linux as linux
|
||||||
import pl_build.backend_macos as apple
|
import build.backend_macos as apple
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# [SECTION] project
|
# [SECTION] project
|
||||||
|
645
src/app.c
645
src/app.c
@ -1,20 +1,64 @@
|
|||||||
/*
|
/*
|
||||||
app.c
|
example_basic_2.c
|
||||||
- template app
|
- demonstrates loading APIs
|
||||||
- loads only stable 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:
|
Index of this file:
|
||||||
|
// [SECTION] quick notes
|
||||||
// [SECTION] includes
|
// [SECTION] includes
|
||||||
// [SECTION] structs
|
// [SECTION] structs
|
||||||
// [SECTION] apis
|
// [SECTION] apis
|
||||||
// [SECTION] helper functions forward declarations
|
|
||||||
// [SECTION] pl_app_load
|
// [SECTION] pl_app_load
|
||||||
// [SECTION] pl_app_shutdown
|
// [SECTION] pl_app_shutdown
|
||||||
// [SECTION] pl_app_resize
|
// [SECTION] pl_app_resize
|
||||||
// [SECTION] pl_app_update
|
// [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 <stdlib.h> // malloc, free
|
||||||
#include <string.h> // memset
|
#include <string.h> // memset
|
||||||
#include "pl.h"
|
#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"
|
#include "pl_math.h"
|
||||||
|
|
||||||
// extensions
|
// extensions
|
||||||
#include "pl_log_ext.h"
|
|
||||||
#include "pl_window_ext.h"
|
|
||||||
#include "pl_shader_ext.h"
|
|
||||||
#include "pl_draw_ext.h"
|
#include "pl_draw_ext.h"
|
||||||
|
#include "pl_starter_ext.h"
|
||||||
#include "pl_ui_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_screen_log_ext.h"
|
||||||
#include "pl_tools_ext.h"
|
#include "pl_profile_ext.h"
|
||||||
#include "pl_platform_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"
|
#include "pl_example_ext.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -61,83 +94,34 @@ typedef struct _plAppData
|
|||||||
// window
|
// window
|
||||||
plWindow* ptWindow;
|
plWindow* ptWindow;
|
||||||
|
|
||||||
// drawing stuff
|
// log channel
|
||||||
plDrawList2D* ptDrawlist;
|
uint64_t uExampleLogChannel;
|
||||||
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;
|
|
||||||
|
|
||||||
|
// console variable
|
||||||
|
bool bShowHelpWindow;
|
||||||
} plAppData;
|
} plAppData;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] apis
|
// [SECTION] apis
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
const plDataRegistryI* gptDataRegistry = NULL;
|
|
||||||
const plMemoryI* gptMemory = NULL;
|
|
||||||
const plIOI* gptIO = NULL;
|
const plIOI* gptIO = NULL;
|
||||||
const plWindowI* gptWindows = NULL;
|
const plWindowI* gptWindows = NULL;
|
||||||
const plGraphicsI* gptGfx = NULL;
|
|
||||||
const plDrawI* gptDraw = NULL;
|
const plDrawI* gptDraw = NULL;
|
||||||
const plUiI* gptUi = NULL;
|
const plStarterI* gptStarter = NULL;
|
||||||
const plShaderI* gptShader = NULL;
|
const plUiI* gptUI = 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 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_ALLOC(x) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__)
|
||||||
#define PL_REALLOC(x, y) gptMemory->tracked_realloc((x), (y), __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_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
|
// [SECTION] pl_app_load
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -145,13 +129,9 @@ void pl__resize_graphics_extensions(plAppData*);
|
|||||||
PL_EXPORT void*
|
PL_EXPORT void*
|
||||||
pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
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
|
// 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
|
// if "ptAppData" is a valid pointer, then this function is being called
|
||||||
// during a hot reload.
|
// during a hot reload.
|
||||||
if(ptAppData)
|
if(ptAppData)
|
||||||
@ -159,140 +139,86 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
|||||||
|
|
||||||
// re-retrieve the apis since we are now in
|
// re-retrieve the apis since we are now in
|
||||||
// a different dll/so
|
// a different dll/so
|
||||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
|
||||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||||
gptGfx = pl_get_api_latest(ptApiRegistry, plGraphicsI);
|
|
||||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||||
gptShader = pl_get_api_latest(ptApiRegistry, plShaderI);
|
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
|
||||||
gptDrawBackend = pl_get_api_latest(ptApiRegistry, plDrawBackendI);
|
gptUI = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||||
gptUi = pl_get_api_latest(ptApiRegistry, plUiI);
|
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||||
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);
|
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||||
gptVirtualMemory = pl_get_api_latest(ptApiRegistry, plVirtualMemoryI);
|
|
||||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
||||||
|
|
||||||
return ptAppData;
|
return ptAppData;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~apis & extensions~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
// retrieve extension registry
|
// retrieve extension registry
|
||||||
const plExtensionRegistryI* ptExtensionRegistry = pl_get_api_latest(ptApiRegistry, plExtensionRegistryI);
|
const plExtensionRegistryI* ptExtensionRegistry = pl_get_api_latest(ptApiRegistry, plExtensionRegistryI);
|
||||||
|
|
||||||
// load extensions
|
// load extensions
|
||||||
ptExtensionRegistry->load("pl_unity_ext", NULL, NULL, false);
|
// * first argument is the shared library name WITHOUT the extension
|
||||||
ptExtensionRegistry->load("pl_platform_ext", NULL, NULL, false);
|
// * 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);
|
ptExtensionRegistry->load("pl_example_ext", NULL, NULL, true);
|
||||||
|
|
||||||
// load apis
|
// load required apis
|
||||||
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
|
||||||
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
gptIO = pl_get_api_latest(ptApiRegistry, plIOI);
|
||||||
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
gptWindows = pl_get_api_latest(ptApiRegistry, plWindowI);
|
||||||
gptGfx = pl_get_api_latest(ptApiRegistry, plGraphicsI);
|
|
||||||
|
// load required apis (these are provided though extensions)
|
||||||
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI);
|
||||||
gptShader = pl_get_api_latest(ptApiRegistry, plShaderI);
|
gptStarter = pl_get_api_latest(ptApiRegistry, plStarterI);
|
||||||
gptDrawBackend = pl_get_api_latest(ptApiRegistry, plDrawBackendI);
|
gptUI = pl_get_api_latest(ptApiRegistry, plUiI);
|
||||||
gptUi = pl_get_api_latest(ptApiRegistry, plUiI);
|
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
||||||
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI);
|
||||||
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
gptStats = pl_get_api_latest(ptApiRegistry, plStatsI);
|
||||||
gptExample = pl_get_api_latest(ptApiRegistry, plExampleI);
|
gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI);
|
||||||
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);
|
gptLog = pl_get_api_latest(ptApiRegistry, plLogI);
|
||||||
gptVirtualMemory = pl_get_api_latest(ptApiRegistry, plVirtualMemoryI);
|
|
||||||
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
gptConsole = pl_get_api_latest(ptApiRegistry, plConsoleI);
|
||||||
gptScreenLog = pl_get_api_latest(ptApiRegistry, plScreenLogI);
|
|
||||||
|
// 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
|
// this path is taken only during first load, so we
|
||||||
// allocate app memory here
|
// allocate app memory here
|
||||||
ptAppData = PL_ALLOC(sizeof(plAppData));
|
ptAppData = PL_ALLOC(sizeof(plAppData));
|
||||||
memset(ptAppData, 0, sizeof(plAppData));
|
memset(ptAppData, 0, sizeof(plAppData));
|
||||||
|
|
||||||
// add console variables
|
// default values
|
||||||
gptConsole->initialize((plConsoleSettings){.tFlags = PL_CONSOLE_FLAGS_POPUP});
|
ptAppData->bShowHelpWindow = true;
|
||||||
|
|
||||||
// use window API to create a window
|
// use window API to create a window
|
||||||
plWindowDesc tWindowDesc = {
|
plWindowDesc tWindowDesc = {
|
||||||
.pcTitle = "App Template",
|
.pcTitle = "Template App",
|
||||||
.iXPos = 200,
|
.iXPos = 200,
|
||||||
.iYPos = 200,
|
.iYPos = 200,
|
||||||
.uWidth = 500,
|
.uWidth = 600,
|
||||||
.uHeight = 500,
|
.uHeight = 600,
|
||||||
};
|
};
|
||||||
gptWindows->create_window(tWindowDesc, &ptAppData->ptWindow);
|
gptWindows->create(tWindowDesc, &ptAppData->ptWindow);
|
||||||
|
gptWindows->show(ptAppData->ptWindow);
|
||||||
|
|
||||||
// setup graphics extension
|
// initialize the starter API (handles alot of boilerplate)
|
||||||
pl__setup_graphics_extensions(ptAppData);
|
plStarterInit tStarterInit = {
|
||||||
|
.tFlags = PL_STARTER_FLAGS_ALL_EXTENSIONS,
|
||||||
|
.ptWindow = ptAppData->ptWindow
|
||||||
|
};
|
||||||
|
gptStarter->initialize(tStarterInit);
|
||||||
|
gptStarter->finalize();
|
||||||
|
|
||||||
// initialize APIs that require it
|
// add a log channel
|
||||||
gptTools->initialize((plToolsInit){.ptDevice = ptAppData->ptDevice});
|
ptAppData->uExampleLogChannel = gptLog->add_channel("Example 2", (plLogExtChannelInit){.tType = PL_LOG_CHANNEL_TYPE_BUFFER});
|
||||||
|
|
||||||
// retrieve some console variables
|
// add a console variable
|
||||||
ptAppData->pbShowLogging = (bool*)gptConsole->get_variable("t.LogTool", NULL, NULL);
|
gptConsole->add_toggle_variable("a.HelpWindow", &ptAppData->bShowHelpWindow, "toggle help window", PL_CONSOLE_VARIABLE_FLAGS_NONE);
|
||||||
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!");
|
|
||||||
|
|
||||||
// return app memory
|
// return app memory
|
||||||
return ptAppData;
|
return ptAppData;
|
||||||
@ -305,23 +231,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
|
|||||||
PL_EXPORT void
|
PL_EXPORT void
|
||||||
pl_app_shutdown(plAppData* ptAppData)
|
pl_app_shutdown(plAppData* ptAppData)
|
||||||
{
|
{
|
||||||
// ensure GPU is finished before cleanup
|
gptStarter->cleanup();
|
||||||
gptGfx->flush_device(ptAppData->ptDevice);
|
gptWindows->destroy(ptAppData->ptWindow);
|
||||||
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);
|
|
||||||
PL_FREE(ptAppData);
|
PL_FREE(ptAppData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +243,7 @@ pl_app_shutdown(plAppData* ptAppData)
|
|||||||
PL_EXPORT void
|
PL_EXPORT void
|
||||||
pl_app_resize(plAppData* ptAppData)
|
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_EXPORT void
|
||||||
pl_app_update(plAppData* ptAppData)
|
pl_app_update(plAppData* ptAppData)
|
||||||
{
|
{
|
||||||
gptProfile->begin_frame();
|
// this needs to be the first call when using the starter
|
||||||
pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__);
|
// extension. You must return if it returns false (usually a swapchain recreation).
|
||||||
|
if(!gptStarter->begin_frame())
|
||||||
// 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();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// just some drawing
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~stats API~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
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))
|
// rather than have to lookup the counter every frame, its best to "store" it
|
||||||
gptConsole->open();
|
// 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");
|
||||||
|
|
||||||
gptConsole->update();
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~drawing & profile API~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if(gptUi->begin_window("Pilot Light", NULL, false))
|
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)});
|
||||||
|
|
||||||
|
gptProfile->end_sample(0);
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~UI & Screen Log API~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// creating a window
|
||||||
|
if(ptAppData->bShowHelpWindow)
|
||||||
{
|
{
|
||||||
|
if(gptUI->begin_window("Help", NULL, PL_UI_WINDOW_FLAGS_AUTO_SIZE | PL_UI_WINDOW_FLAGS_NO_COLLAPSE))
|
||||||
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->layout_static(0.0f, 500.0f, 1);
|
||||||
gptUi->text("Pilot Light %s", PILOT_LIGHT_VERSION_STRING);
|
gptUI->text("Press F1 to bring up console.");
|
||||||
gptUi->end_collapsing_header();
|
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();
|
||||||
}
|
}
|
||||||
if(gptUi->begin_collapsing_header("Tools", 0))
|
}
|
||||||
|
|
||||||
|
// creating another window
|
||||||
|
if(gptUI->begin_window("Pilot Light", NULL, PL_UI_WINDOW_FLAGS_NONE))
|
||||||
{
|
{
|
||||||
gptUi->checkbox("Device Memory Analyzer", ptAppData->pbShowDeviceMemoryAnalyzer);
|
gptUI->text("Pilot Light %s", PILOT_LIGHT_VERSION_STRING);
|
||||||
gptUi->checkbox("Memory Allocations", ptAppData->pbShowMemoryAllocations);
|
|
||||||
gptUi->checkbox("Profiling", ptAppData->pbShowProfiling);
|
if(gptUI->button("Log"))
|
||||||
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);
|
gptLog->trace(ptAppData->uExampleLogChannel, "Log");
|
||||||
gptUi->checkbox("UI Style", &ptAppData->bShowUiStyle);
|
gptLog->debug(ptAppData->uExampleLogChannel, "Log");
|
||||||
gptUi->end_collapsing_header();
|
gptLog->info(ptAppData->uExampleLogChannel, "Log");
|
||||||
}
|
gptLog->warn(ptAppData->uExampleLogChannel, "Log");
|
||||||
gptUi->end_window();
|
gptLog->error(ptAppData->uExampleLogChannel, "Log");
|
||||||
|
gptLog->fatal(ptAppData->uExampleLogChannel, "Log");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ptAppData->bShowUiStyle)
|
static int iCounter = 0;
|
||||||
gptUi->show_style_editor_window(&ptAppData->bShowUiStyle);
|
gptUI->slider_int("Stat Counter Example", &iCounter, -10, 10, 0);
|
||||||
|
*pdExample2Counter = iCounter; // setting our stat variable
|
||||||
|
|
||||||
if(ptAppData->bShowUiDebug)
|
gptUI->layout_row_begin(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 2); // got to pl_ui_ext.h to see layout systems
|
||||||
gptUi->show_debug_window(&ptAppData->bShowUiDebug);
|
|
||||||
|
|
||||||
gptTools->update();
|
gptUI->layout_row_push(0.3f);
|
||||||
|
if(gptUI->button("Log To Screen"))
|
||||||
|
gptScreenLog->add_message(5.0, "Cool Message!");
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~graphics work~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
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!");
|
||||||
|
|
||||||
const uint32_t uCurrentFrameIndex = gptGfx->get_current_frame_index();
|
gptUI->layout_row_end();
|
||||||
|
|
||||||
plCommandBuffer* ptCommandBuffer = gptGfx->request_command_buffer(ptCmdPool);
|
gptUI->end_window();
|
||||||
|
}
|
||||||
|
|
||||||
const plBeginCommandInfo tBeginInfo = {
|
// must be the last function called when using the starter extension
|
||||||
.uWaitSemaphoreCount = 1,
|
gptStarter->end_frame();
|
||||||
.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);
|
|
||||||
|
|
||||||
// submits UI layers
|
|
||||||
gptUi->end_frame();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
// end render pass
|
|
||||||
gptGfx->end_render_pass(ptEncoder);
|
|
||||||
|
|
||||||
// end recording
|
|
||||||
gptGfx->end_command_recording(ptCommandBuffer);
|
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~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++)
|
|
||||||
{
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
atMainAttachmentSets[i].atViewAttachments[0] = atSwapchainImages[i];
|
|
||||||
}
|
|
||||||
gptGfx->update_render_pass_attachments(ptAppData->ptDevice, ptAppData->tMainRenderPass, gptIO->get_io()->tMainViewportSize, atMainAttachmentSets);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user