Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan hoffstadt committed May 3, 2024
1 parent 2d15b8a commit 6bd9781
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 48 deletions.
45 changes: 1 addition & 44 deletions apps/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,10 @@ typedef struct plAppData_t
bool bFreezeCullCamera;
plEntity tCullCamera;
plEntity tMainCamera;
plEntity tMainCamera2;

// views
uint32_t uSceneHandle0;
uint32_t uSceneHandle1;
uint32_t uViewHandle0;
uint32_t uViewHandle1;
uint32_t uViewHandle2;

// drawing
plDrawLayer* ptDrawLayer;
Expand Down Expand Up @@ -221,18 +217,13 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
ptAppData->atSempahore[i] = gptDevice->create_semaphore(&gptRenderer->get_graphics()->tDevice, false);

ptAppData->uSceneHandle0 = gptRenderer->create_scene();
ptAppData->uSceneHandle1 = gptRenderer->create_scene();

pl_begin_profile_sample("load environments");
const plMat4 tTransform0 = pl_mat4_translate_xyz(2.0f, 1.0f, 0.0f);
gptRenderer->load_skybox_from_panorama(ptAppData->uSceneHandle0, "../data/glTF-Sample-Environments-main/field.jpg", 1024);
gptRenderer->load_skybox_from_panorama(ptAppData->uSceneHandle1, "../data/glTF-Sample-Environments-main/field.jpg", 1024);
pl_end_profile_sample();

pl_begin_profile_sample("create scene views");
ptAppData->uViewHandle0 = gptRenderer->create_view(ptAppData->uSceneHandle0, (plVec2){ptIO->afMainViewportSize[0] , ptIO->afMainViewportSize[1]});
ptAppData->uViewHandle1 = gptRenderer->create_view(ptAppData->uSceneHandle0, (plVec2){500.0f, 500.0f});
ptAppData->uViewHandle2 = gptRenderer->create_view(ptAppData->uSceneHandle1, (plVec2){500.0f, 500.0f});
pl_end_profile_sample();

// temporary draw layer for submitting fullscreen quad of offscreen render
Expand All @@ -249,16 +240,12 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
gptCamera->set_pitch_yaw(gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tCullCamera), 0.0f, PL_PI);
gptCamera->update(gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tCullCamera));

plComponentLibrary* ptSecondaryComponentLibrary = gptRenderer->get_component_library(ptAppData->uSceneHandle1);
ptAppData->tMainCamera2 = gptEcs->create_perspective_camera(ptSecondaryComponentLibrary, "secondary camera", (plVec3){-3.265f, 2.967f, 0.311f}, PL_PI_3, 1.0f, 0.01f, 400.0f);
gptCamera->set_pitch_yaw(gptEcs->get_component(ptSecondaryComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tMainCamera2), -0.535f, 1.737f);
gptCamera->update(gptEcs->get_component(ptSecondaryComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tMainCamera2));

// load models

plModelLoaderData tLoaderData0 = {0};

pl_begin_profile_sample("load models 0");
plMat4 tTransform0 = pl_mat4_translate_xyz(2, 2, 0);
// gptModelLoader->load_gltf(ptMainComponentLibrary, "../data/glTF-Sample-Assets-main/Models/FlightHelmet/glTF/FlightHelmet.gltf", NULL, &tLoaderData0);
gptModelLoader->load_gltf(ptMainComponentLibrary, "../data/glTF-Sample-Assets-main/Models/CesiumMan/glTF/CesiumMan.gltf", NULL, &tLoaderData0);
// gptModelLoader->load_gltf(ptMainComponentLibrary, "../data/glTF-Sample-Assets-main/Models/DamagedHelmet/glTF/DamagedHelmet.gltf", NULL, &tLoaderData0);
Expand All @@ -268,21 +255,10 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
gptModelLoader->free_data(&tLoaderData0);
pl_end_profile_sample();

pl_begin_profile_sample("load models 1");
gptModelLoader->load_gltf(ptSecondaryComponentLibrary, "../data/glTF-Sample-Assets-main/Models/CesiumMan/glTF/CesiumMan.gltf", NULL, &tLoaderData0);
gptModelLoader->load_stl(ptSecondaryComponentLibrary, "../data/pilotlight-assets-master/meshes/monkey.stl", (plVec4){1.0f, 0.0f, 0.0f, 0.80f}, &tTransform0, &tLoaderData0);
gptRenderer->add_drawable_objects_to_scene(ptAppData->uSceneHandle1, tLoaderData0.uOpaqueCount, tLoaderData0.atOpaqueObjects, tLoaderData0.uTransparentCount, tLoaderData0.atTransparentObjects);
gptModelLoader->free_data(&tLoaderData0);
pl_end_profile_sample();

pl_begin_profile_sample("finalize scene 0");
gptRenderer->finalize_scene(ptAppData->uSceneHandle0);
pl_end_profile_sample();

pl_begin_profile_sample("finalize scene 1");
gptRenderer->finalize_scene(ptAppData->uSceneHandle1);
pl_end_profile_sample();

pl_end_profile_frame();

// temporary for profiling loading procedures
Expand Down Expand Up @@ -377,10 +353,8 @@ pl_app_update(plAppData* ptAppData)

// handle input
plComponentLibrary* ptMainComponentLibrary = gptRenderer->get_component_library(ptAppData->uSceneHandle0);
plComponentLibrary* ptSecondaryComponentLibrary = gptRenderer->get_component_library(ptAppData->uSceneHandle1);

plCameraComponent* ptCamera = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tMainCamera);
plCameraComponent* ptCamera2 = gptEcs->get_component(ptSecondaryComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tMainCamera2);
plCameraComponent* ptCullCamera = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_CAMERA, ptAppData->tCullCamera);

static const float fCameraTravelSpeed = 4.0f;
Expand Down Expand Up @@ -409,12 +383,10 @@ pl_app_update(plAppData* ptAppData)
}

gptCamera->update(ptCamera);
gptCamera->update(ptCamera2);
gptCamera->update(ptCullCamera);

// run ecs system
gptRenderer->run_ecs(ptAppData->uSceneHandle0);
gptRenderer->run_ecs(ptAppData->uSceneHandle1);

// new ui frame
pl_new_frame();
Expand All @@ -438,7 +410,6 @@ pl_app_update(plAppData* ptAppData)
plCommandBuffer tCommandBuffer = gptGfx->begin_command_recording(ptGraphics, &tBeginInfo0);

gptRenderer->update_skin_textures(tCommandBuffer, ptAppData->uSceneHandle0);
gptRenderer->update_skin_textures(tCommandBuffer, ptAppData->uSceneHandle1);
gptGfx->end_command_recording(ptGraphics, &tCommandBuffer);

const plSubmitInfo tSubmitInfo0 = {
Expand All @@ -456,7 +427,6 @@ pl_app_update(plAppData* ptAppData)
tCommandBuffer = gptGfx->begin_command_recording(ptGraphics, &tBeginInfo00);

gptRenderer->perform_skinning(tCommandBuffer, ptAppData->uSceneHandle0);
gptRenderer->perform_skinning(tCommandBuffer, ptAppData->uSceneHandle1);
gptGfx->end_command_recording(ptGraphics, &tCommandBuffer);

const plSubmitInfo tSubmitInfo00 = {
Expand All @@ -475,15 +445,6 @@ pl_app_update(plAppData* ptAppData)
.ptCullCamera = ptAppData->bFrustumCulling ? ptCamera : NULL
};

plViewOptions tViewOptions2 = {
.bShowAllBoundingBoxes = ptAppData->bDrawAllBoundingBoxes,
.bShowVisibleBoundingBoxes = ptAppData->bDrawVisibleBoundingBoxes,
.bShowOrigin = false,
.bCullStats = false,
.ptViewCamera = ptCamera2,
.ptCullCamera = ptCamera2
};

if(ptAppData->bFrustumCulling && ptAppData->bFreezeCullCamera)
tViewOptions.ptCullCamera = ptCullCamera;

Expand All @@ -497,8 +458,6 @@ pl_app_update(plAppData* ptAppData)
};
tCommandBuffer = gptGfx->begin_command_recording(ptGraphics, &tBeginInfo1);
gptRenderer->render_scene(tCommandBuffer, ptAppData->uSceneHandle0, ptAppData->uViewHandle0, tViewOptions);
gptRenderer->render_scene(tCommandBuffer, ptAppData->uSceneHandle0, ptAppData->uViewHandle1, tViewOptions2);
gptRenderer->render_scene(tCommandBuffer, ptAppData->uSceneHandle1, ptAppData->uViewHandle2, tViewOptions2);

gptGfx->end_command_recording(ptGraphics, &tCommandBuffer);

Expand Down Expand Up @@ -603,8 +562,6 @@ pl_app_update(plAppData* ptAppData)

// add full screen quad for offscreen render
pl_add_image(ptAppData->ptDrawLayer, gptRenderer->get_view_texture_id(ptAppData->uSceneHandle0, ptAppData->uViewHandle0), (plVec2){0}, (plVec2){ptIO->afMainViewportSize[0], ptIO->afMainViewportSize[1]});
pl_add_image(ptAppData->ptDrawLayer, gptRenderer->get_view_texture_id(ptAppData->uSceneHandle0, ptAppData->uViewHandle1), (plVec2){0}, (plVec2){500.0f, 500.0f});
pl_add_image(ptAppData->ptDrawLayer, gptRenderer->get_view_texture_id(ptAppData->uSceneHandle1, ptAppData->uViewHandle2), (plVec2){0.0f, 500.0f}, (plVec2){500.0f, 1000.0f});
pl_submit_layer(ptAppData->ptDrawLayer);

plRenderEncoder tEncoder = gptGfx->begin_render_pass(ptGraphics, &tCommandBuffer, ptGraphics->tMainRenderPass);
Expand Down
1 change: 1 addition & 0 deletions extensions/pl_model_loader_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pl__load_stl(plComponentLibrary* ptLibrary, const char* pcPath, plVec4 tColor, c
plMaterialComponent* ptMaterial = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_MATERIAL, ptMesh->tMaterial);
ptMaterial->tBaseColor = tColor;
ptMaterial->tBlendMode = PL_BLEND_MODE_ALPHA;
ptMaterial->tFlags |= PL_MATERIAL_FLAG_OUTLINE;

// load STL model
plStlInfo tInfo = {0};
Expand Down
167 changes: 165 additions & 2 deletions extensions/pl_ref_renderer_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ typedef struct _plRefScene
// drawables (per scene, will be culled by views)
plDrawable* sbtOpaqueDrawables;
plDrawable* sbtTransparentDrawables;
plDrawable* sbtOutlineDrawables;

} plRefScene;

Expand All @@ -242,6 +243,7 @@ typedef struct _plRefRendererData
plShaderHandle tOpaqueShader;
plShaderHandle tTransparentShader;
plShaderHandle tSkyboxShader;
plShaderHandle tOutlineShader;

// graphics shader variant system
uint32_t uVariantCount;
Expand Down Expand Up @@ -652,6 +654,58 @@ pl_refr_initialize(plWindow* ptWindow)
tTransparentShaderDescription.atConstants[i].tType = PL_DATA_TYPE_INT;
}
gptData->tTransparentShader = gptDevice->create_shader(&gptData->tGraphics.tDevice, &tTransparentShaderDescription);

plShaderDescription tOutlineShaderDescription = {

#ifdef PL_METAL_BACKEND
.pcVertexShader = "../shaders/metal/outline.metal",
.pcPixelShader = "../shaders/metal/outline.metal",
#else
.pcVertexShader = "outline.vert.spv",
.pcPixelShader = "outline.frag.spv",
#endif
.tGraphicsState = {
.ulDepthWriteEnabled = 0,
.ulDepthMode = PL_COMPARE_MODE_ALWAYS,
.ulCullMode = PL_CULL_MODE_CULL_FRONT,
.ulWireframe = 0,
.ulStencilMode = PL_COMPARE_MODE_LESS_OR_EQUAL,
.ulStencilRef = 128,
.ulStencilMask = 0xff,
.ulStencilOpFail = PL_STENCIL_OP_KEEP,
.ulStencilOpDepthFail = PL_STENCIL_OP_KEEP,
.ulStencilOpPass = PL_STENCIL_OP_KEEP
},
.tVertexBufferBinding = {
.uByteStride = sizeof(float) * 3,
.atAttributes = { {.uByteOffset = 0, .tFormat = PL_FORMAT_R32G32B32_FLOAT}}
},
.uConstantCount = 2,
.pTempConstantData = aiConstantData,
.atBlendStates = {
pl__get_blend_state(PL_BLEND_MODE_ALPHA)
},
.uBlendStateCount = 1,
.tRenderPassLayout = gptData->tRenderPassLayout,
.uSubpassIndex = 2,
.uBindGroupLayoutCount = 1,
.atBindGroupLayouts = {
{
.uBufferBindingCount = 2,
.aBufferBindings = {
{ .uSlot = 0, .tType = PL_BUFFER_BINDING_TYPE_UNIFORM, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL},
{ .uSlot = 1, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}
},
}
}
};
for(uint32_t i = 0; i < tOutlineShaderDescription.uConstantCount; i++)
{
tOutlineShaderDescription.atConstants[i].uID = i;
tOutlineShaderDescription.atConstants[i].uOffset = i * sizeof(int);
tOutlineShaderDescription.atConstants[i].tType = PL_DATA_TYPE_INT;
}
gptData->tOutlineShader = gptDevice->create_shader(&gptData->tGraphics.tDevice, &tOutlineShaderDescription);
}

static uint32_t
Expand Down Expand Up @@ -1922,10 +1976,46 @@ pl_refr_finalize_scene(uint32_t uSceneHandle)
PL_INFO_MATERIAL_METALLICROUGHNESS,
iSceneWideRenderingFlags
};


plGraphicsState tVariantTemp = atTemplateVariants[uDrawableBatchIndex];

if(ptMaterial->tFlags & PL_MATERIAL_FLAG_OUTLINE)
{
// write into stencil buffer
tVariantTemp.ulStencilMode = PL_COMPARE_MODE_GREATER;
tVariantTemp.ulStencilRef = 0xff;
tVariantTemp.ulStencilMask = 0xff;
tVariantTemp.ulStencilOpFail = PL_STENCIL_OP_REPLACE;
tVariantTemp.ulStencilOpDepthFail = PL_STENCIL_OP_REPLACE;
tVariantTemp.ulStencilOpPass = PL_STENCIL_OP_REPLACE;

// use stencil buffer
const plGraphicsState tOutlineVariantTemp = {
.ulDepthWriteEnabled = 0,
.ulDepthMode = PL_COMPARE_MODE_ALWAYS,
.ulCullMode = PL_CULL_MODE_CULL_FRONT,
.ulWireframe = 0,
.ulStencilMode = PL_COMPARE_MODE_GREATER,
.ulStencilRef = 128,
.ulStencilMask = 0xff,
.ulStencilOpFail = PL_STENCIL_OP_KEEP,
.ulStencilOpDepthFail = PL_STENCIL_OP_KEEP,
.ulStencilOpPass = PL_STENCIL_OP_KEEP
};

const plShaderVariant tOutlineVariant = {
.pTempConstantData = aiConstantData0,
.tGraphicsState = tOutlineVariantTemp
};

plShaderHandle tOutlineShader = pl__get_shader_variant(uSceneHandle, gptData->tOutlineShader, &tOutlineVariant);
pl_sb_push(ptScene->sbtOutlineDrawables, (sbtDrawables[uDrawableBatchIndex])[i]);
ptScene->sbtOutlineDrawables[pl_sb_size(ptScene->sbtOutlineDrawables) - 1].uShader = tOutlineShader.uIndex;
}

const plShaderVariant tVariant = {
.pTempConstantData = aiConstantData0,
.tGraphicsState = atTemplateVariants[uDrawableBatchIndex]
.tGraphicsState = tVariantTemp
};

(sbtDrawables[uDrawableBatchIndex])[i].uShader = pl__get_shader_variant(uSceneHandle, atTemplateShaders[uDrawableBatchIndex], &tVariant).uIndex;
Expand Down Expand Up @@ -2565,6 +2655,79 @@ pl_refr_render_scene(plCommandBuffer tCommandBuffer, uint32_t uSceneHandle, uint
}
gptGfx->draw_stream(&tEncoder, 1, &tArea);

const uint32_t uOutlineDrawableCount = pl_sb_size(ptScene->sbtOutlineDrawables);
if(uOutlineDrawableCount > 0)
{

gptGfx->reset_draw_stream(ptStream);

typedef struct _plOutlineDynamicData
{
plVec4 tColor;
float fThickness;
int iDataOffset;
int iVertexOffset;
int iPadding[1];
plMat4 tModel;
} plOutlineDynamicData;

for(uint32_t i = 0; i < uOutlineDrawableCount; i++)
{
const plDrawable tDrawable = ptScene->sbtOutlineDrawables[i];
plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity);
plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform);

plDynamicBinding tDynamicBinding = gptDevice->allocate_dynamic_data(ptDevice, sizeof(plOutlineDynamicData));

plOutlineDynamicData* ptDynamicData = (plOutlineDynamicData*)tDynamicBinding.pcData;
ptDynamicData->iDataOffset = tDrawable.uDataOffset;
ptDynamicData->iVertexOffset = tDrawable.uVertexOffset;
ptDynamicData->tModel = ptTransform->tWorld;
ptDynamicData->fThickness = 0.015f;
ptDynamicData->tColor = (plVec4){1.0f, 0.0f, 0.0f, 1.0f};

gptGfx->add_to_stream(ptStream, (plStreamDraw)
{
.uShaderVariant = tDrawable.uShader,
.uDynamicBuffer = tDynamicBinding.uBufferHandle,
.uVertexBuffer = ptScene->tVertexBuffer.uIndex,
.uIndexBuffer = tDrawable.uIndexCount == 0 ? UINT32_MAX : ptScene->tIndexBuffer.uIndex,
.uIndexOffset = tDrawable.uIndexOffset,
.uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3,
.uBindGroup1 = UINT32_MAX,
.uBindGroup2 = UINT32_MAX,
.uDynamicBufferOffset = tDynamicBinding.uByteOffset,
.uInstanceStart = 0,
.uInstanceCount = 1
});
}

plBindGroupLayout tOutlineBindGroupLayout0 = {
.uBufferBindingCount = 2,
.aBufferBindings = {
{ .uSlot = 0, .tType = PL_BUFFER_BINDING_TYPE_UNIFORM, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL},
{ .uSlot = 1, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}
},
};
plBindGroupHandle tOutlineGlobalBG = gptDevice->get_temporary_bind_group(ptDevice, &tOutlineBindGroupLayout0, "temporary outline global bind group");

const plBindGroupUpdateBufferData atOutlineBufferData[] =
{
{ .uSlot = 0, .tBuffer = ptView->atGlobalBuffers[ptGraphics->uCurrentFrameIndex], .szBufferRange = sizeof(BindGroup_0)},
{ .uSlot = 1, .tBuffer = ptScene->tStorageBuffer, .szBufferRange = sizeof(plVec4) * pl_sb_size(ptScene->sbtVertexDataBuffer)},

};

plBindGroupUpdateData tOutlineBGData0 = {
.uBufferCount = 2,
.atBuffers = atOutlineBufferData,
};
gptDevice->update_bind_group(&ptGraphics->tDevice, tOutlineGlobalBG, &tOutlineBGData0);

tArea.uBindGroup0 = tOutlineGlobalBG.uIndex;
gptGfx->draw_stream(&tEncoder, 1, &tArea);
}

if(tOptions.bShowAllBoundingBoxes)
{
for(uint32_t i = 0; i < uOpaqueDrawableCount; i++)
Expand Down
2 changes: 1 addition & 1 deletion extensions/pl_vulkan_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,7 @@ pl_create_shader(plDevice* ptDevice, const plShaderDescription* ptDescription)
.back.failOp = pl__vulkan_stencil_op((plStencilOp)ptDescription->tGraphicsState.ulStencilOpFail),
.back.depthFailOp = pl__vulkan_stencil_op((plStencilOp)ptDescription->tGraphicsState.ulStencilOpDepthFail),
.back.passOp = pl__vulkan_stencil_op((plStencilOp)ptDescription->tGraphicsState.ulStencilOpPass),
.back.compareMask = 0xff,
.back.compareMask = (uint32_t)ptDescription->tGraphicsState.ulStencilMask,
.back.writeMask = (uint32_t)ptDescription->tGraphicsState.ulStencilMask,
.back.reference = (uint32_t)ptDescription->tGraphicsState.ulStencilRef
};
Expand Down
4 changes: 3 additions & 1 deletion scripts/gen_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ def add_plugin_to_metal_app(name, reloadable, objc = False, binary_name = None):
"draw_3d_line.vert",
"panorama_to_cubemap.comp",
"filter_environment.comp",
"skinning.comp"
"skinning.comp",
"outline.vert",
"outline.frag",
]

metal_shaders = [
Expand Down
Loading

0 comments on commit 6bd9781

Please sign in to comment.