From fa5f4211408d0df4b346769a3ebf53b4d58a4458 Mon Sep 17 00:00:00 2001 From: ecker Date: Thu, 2 Jul 2026 19:22:07 -0500 Subject: [PATCH] more opengl related fixes (like proper instancing), disabled signaling a command buffer rebuild on graphic.updateMesh (to-do: properly handle this strictly for immediate-mode debug draw, or just do some lambda memery) --- bin/data/config.json | 8 +- .../scenes/sourceengine/sourceengine.json | 4 +- engine/inc/uf/ext/opengl/device.h | 1 + engine/inc/uf/ext/opengl/opengl.h | 1 + engine/inc/uf/ext/opengl/rendermode.h | 1 + engine/src/engine/graph/graph.cpp | 2 - engine/src/ext/opengl/commands.cpp | 2 +- engine/src/ext/opengl/graphic.cpp | 110 ++++++------ engine/src/ext/opengl/opengl.cpp | 162 +++++++++++++----- .../src/ext/opengl/rendermodes/deferred.cpp | 36 +++- 10 files changed, 214 insertions(+), 113 deletions(-) diff --git a/bin/data/config.json b/bin/data/config.json index 9d623896..2f04109a 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -274,7 +274,7 @@ "rebuild on tick begin": false }, "pipelines": { - "culling": true + "culling": false }, "experimental": { "rebuild on tick begin": false, @@ -353,11 +353,11 @@ "max": 0.1 // 0.2 }, "debug draw": { - "static": true, - "dynamic": true, + "static": false, + "dynamic": false, "trigger": false, "contacts": false, - "constraints": true, + "constraints": false, "rays": false, "depthTest": true }, diff --git a/bin/data/scenes/sourceengine/sourceengine.json b/bin/data/scenes/sourceengine/sourceengine.json index 89c57145..f7a5e99b 100644 --- a/bin/data/scenes/sourceengine/sourceengine.json +++ b/bin/data/scenes/sourceengine/sourceengine.json @@ -1,8 +1,8 @@ { // "import": "./rp_downtown_v2.json" // "import": "./ss2_medsci1.json" -// "import": "./mds_mcdonalds.json" - "import": "./cs_office.json" + "import": "./mds_mcdonalds.json" +// "import": "./cs_office.json" // "import": "./de_dust2.json" // "import": "./gm_construct.json" } \ No newline at end of file diff --git a/engine/inc/uf/ext/opengl/device.h b/engine/inc/uf/ext/opengl/device.h index 1d885851..a38d719f 100644 --- a/engine/inc/uf/ext/opengl/device.h +++ b/engine/inc/uf/ext/opengl/device.h @@ -40,6 +40,7 @@ namespace ext { struct { uf::stl::vector buffers; + uf::stl::vector textures; } transient; void initialize(); diff --git a/engine/inc/uf/ext/opengl/opengl.h b/engine/inc/uf/ext/opengl/opengl.h index 85f3d806..d6be3605 100644 --- a/engine/inc/uf/ext/opengl/opengl.h +++ b/engine/inc/uf/ext/opengl/opengl.h @@ -86,6 +86,7 @@ namespace ext { // extern UF_API RenderMode* currentRenderMode; extern UF_API uf::stl::vector renderModes; extern UF_API uf::ThreadUnique currentRenderMode; + extern UF_API uf::stl::unordered_map renderModesMap; bool UF_API hasRenderMode( const uf::stl::string&, bool = true ); RenderMode& UF_API addRenderMode( RenderMode*, const uf::stl::string& = "" ); diff --git a/engine/inc/uf/ext/opengl/rendermode.h b/engine/inc/uf/ext/opengl/rendermode.h index 2465ca86..e9e66d17 100644 --- a/engine/inc/uf/ext/opengl/rendermode.h +++ b/engine/inc/uf/ext/opengl/rendermode.h @@ -11,6 +11,7 @@ namespace ext { bool execute = false; bool executed = false; bool rebuild = false; + bool rerecord = false; bool resized = false; uint32_t width = 0; diff --git a/engine/src/engine/graph/graph.cpp b/engine/src/engine/graph/graph.cpp index d6ea0515..0d2cfd6f 100644 --- a/engine/src/engine/graph/graph.cpp +++ b/engine/src/engine/graph/graph.cpp @@ -748,11 +748,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M if ( material.modeCull == pod::Material::CullMode::NONE ) { tag["renderer"]["cull mode"] = "none"; } - #if UF_USE_VULKAN if ( material.modeAlpha == pod::Material::AlphaMode::BLEND ) { graphic.descriptor.renderTarget = 1; } - #endif } } } diff --git a/engine/src/ext/opengl/commands.cpp b/engine/src/ext/opengl/commands.cpp index c0c6c049..e59ed424 100644 --- a/engine/src/ext/opengl/commands.cpp +++ b/engine/src/ext/opengl/commands.cpp @@ -252,7 +252,7 @@ void ext::opengl::CommandBuffer::drawIndexed( const ext::opengl::CommandBuffer:: GL_ERROR_CHECK(glMatrixMode(GL_PROJECTION)); GL_ERROR_CHECK(glLoadMatrixf( &projection[0] )); -#if UF_ENV_DREAMCAST +#if 0 && UF_ENV_DREAMCAST // washingtondc has a regression where non-alpha-tested polys do not render // more convenient to just work around the regression since later builds have working opengl backends GL_ERROR_CHECK(glEnable(GL_ALPHA_TEST)); diff --git a/engine/src/ext/opengl/graphic.cpp b/engine/src/ext/opengl/graphic.cpp index eb11ecbc..5b8af05b 100644 --- a/engine/src/ext/opengl/graphic.cpp +++ b/engine/src/ext/opengl/graphic.cpp @@ -297,8 +297,9 @@ bool ext::opengl::Graphic::updateMesh( uf::Mesh& mesh ) { }\ } - bool rebuild = true; - ext::opengl::states::rebuild = true; + // to-do: deduce if the "buffer" would resize to trigger a command buffer invalidation + bool rebuild = false; + //ext::opengl::states::rebuild = true; // we actually don't buffer anything directly at the moment so this will always fail // as vertex data is directly read from the mesh object /* @@ -409,8 +410,9 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe } if ( uniformBufferSize == sizeof(pod::Camera::Viewports) ) { - drawCommandInfoBase.matrices.view = &viewports->matrices[0].view; - drawCommandInfoBase.matrices.projection = &viewports->matrices[0].projection; + auto viewIndex = descriptor.aux * 2; + drawCommandInfoBase.matrices.view = &viewports->matrices[viewIndex].view; + drawCommandInfoBase.matrices.projection = &viewports->matrices[viewIndex].projection; } else if ( uniformBufferSize == sizeof(pod::Uniform) ) { drawCommandInfoBase.matrices.model = &uniforms->modelView; drawCommandInfoBase.matrices.projection = &uniforms->projection; @@ -461,73 +463,68 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe // const bool optimize = false; uf::stl::unordered_map> pool; - for ( auto i = 0; i < descriptor.inputs.indirect.count; ++i ) { - auto& drawCommand = drawCommands[i]; - auto instanceID = drawCommand.instanceID; + for ( auto drawID = 0; drawID < descriptor.inputs.indirect.count; ++drawID ) { + auto& drawCommand = drawCommands[drawID]; + for ( auto instanceOffset = 0; instanceOffset < drawCommand.instances; ++instanceOffset ) { + auto instanceID = drawCommand.instanceID + instanceOffset; - auto& instance = instances[instanceID]; + auto& instance = instances[instanceID]; - auto objectID = instance.objectID; - auto materialID = instance.materialID; - auto lightmapID = instance.lightmapID; + auto objectID = instance.objectID; + auto materialID = instance.materialID; + auto lightmapID = instance.lightmapID; - auto& object = objects[objectID]; + auto& object = objects[objectID]; - auto& material = materials[materialID]; - auto textureID = material.indexAlbedo; + auto& material = materials[materialID]; + auto textureID = material.indexAlbedo; - auto& infos = pool[textureID]; - CommandBuffer::InfoDraw& drawCommandInfo = infos.emplace_back( drawCommandInfoBase ); - // CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase; + auto& infos = pool[textureID]; + CommandBuffer::InfoDraw& drawCommandInfo = infos.emplace_back( drawCommandInfoBase ); + // CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase; - drawCommandInfo.descriptor.inputs.index.first = drawCommand.indexID; - drawCommandInfo.descriptor.inputs.index.count = drawCommand.indices; - - drawCommandInfo.descriptor.inputs.vertex.first = drawCommand.vertexID; - drawCommandInfo.descriptor.inputs.vertex.count = drawCommand.vertices; + drawCommandInfo.descriptor.inputs.index.first = drawCommand.indexID; + drawCommandInfo.descriptor.inputs.index.count = drawCommand.indices; + + drawCommandInfo.descriptor.inputs.vertex.first = drawCommand.vertexID; + drawCommandInfo.descriptor.inputs.vertex.count = drawCommand.vertices; - drawCommandInfo.attributes.instance.pointer = (uint8_t*) (void*) &instance; - drawCommandInfo.attributes.instance.length = sizeof(instance); + drawCommandInfo.attributes.instance.pointer = (uint8_t*) (void*) &instance; + drawCommandInfo.attributes.instance.length = sizeof(instance); - drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand; - drawCommandInfo.attributes.indirect.length = sizeof(drawCommand); + drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand; + drawCommandInfo.attributes.indirect.length = sizeof(drawCommand); - drawCommandInfo.matrices.model = &object.model; + drawCommandInfo.matrices.model = &object.model; - drawCommandInfo.blend.modeAlpha = material.modeAlpha; - drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff; + drawCommandInfo.blend.modeAlpha = material.modeAlpha; + drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff; - drawCommandInfo.color.value = object.color * material.colorBase; // to-do: blend properly - drawCommandInfo.color.enabled = drawCommandInfo.color.value != pod::Vector4f{1.0f, 1.0f, 1.0f, 1.0f}; + drawCommandInfo.color.value = object.color * material.colorBase; // to-do: blend properly + drawCommandInfo.color.enabled = drawCommandInfo.color.value != pod::Vector4f{1.0f, 1.0f, 1.0f, 1.0f}; - if ( drawCommandInfo.color.value.w == 0.0f ) { - continue; - } + if ( drawCommandInfo.color.value.w == 0.0f ) { + continue; + } - if ( 0 <= textureID ) { - auto texture2DID = textures[textureID].index; - drawCommandInfo.textures.primary = this->material.textures.at(texture2DID).descriptor; - } - if ( 0 <= lightmapID ) { - auto textureID = lightmapID; - auto texture2DID = textures[lightmapID].index; - drawCommandInfo.textures.secondary = this->material.textures.at(texture2DID).descriptor; - } - switch ( drawCommandInfo.blend.modeAlpha ) { - case pod::Material::AlphaMode::BLEND: drawCommandInfos.translucents.emplace_back(drawCommandInfo); break; - default: drawCommandInfos.opaques.emplace_back(drawCommandInfo); break; + if ( 0 <= textureID ) { + auto texture2DID = textures[textureID].index; + drawCommandInfo.textures.primary = this->material.textures.at(texture2DID).descriptor; + } + if ( 0 <= lightmapID ) { + auto textureID = lightmapID; + auto texture2DID = textures[lightmapID].index; + drawCommandInfo.textures.secondary = this->material.textures.at(texture2DID).descriptor; + } + if ( drawCommandInfo.blend.modeAlpha == pod::Material::AlphaMode::BLEND ) { + drawCommandInfo.descriptor.renderTarget = 1; + } + commandBuffer.record( drawCommandInfo ); } } } else { CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase; - // ??? - /* - drawCommandInfoBase.matrices.model = NULL; - drawCommandInfoBase.matrices.view = NULL; - drawCommandInfoBase.matrices.projection = NULL; - */ - if ( !material.textures.empty() ) { auto& texture = material.textures.front(); drawCommandInfo.textures.primary = texture.descriptor; @@ -543,13 +540,17 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe break; } } - + + commandBuffer.record( drawCommandInfo ); + /* switch ( drawCommandInfo.blend.modeAlpha ) { case 0: drawCommandInfos.opaques.emplace_back(drawCommandInfo); break; default: drawCommandInfos.translucents.emplace_back(drawCommandInfo); break; } + */ } +/* if ( uf::matrix::reverseInfiniteProjection ) { for ( auto it = drawCommandInfos.opaques.rbegin(); it != drawCommandInfos.opaques.rend(); ++it ) { auto& drawCommandInfo = (*it); @@ -563,6 +564,7 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe for ( auto& drawCommandInfo : drawCommandInfos.opaques ) commandBuffer.record(drawCommandInfo); for ( auto& drawCommandInfo : drawCommandInfos.translucents ) commandBuffer.record(drawCommandInfo); } +*/ // UF_MSG_DEBUG("END") } void ext::opengl::Graphic::destroy() { diff --git a/engine/src/ext/opengl/opengl.cpp b/engine/src/ext/opengl/opengl.cpp index 69a05a26..b51db9f5 100644 --- a/engine/src/ext/opengl/opengl.cpp +++ b/engine/src/ext/opengl/opengl.cpp @@ -87,13 +87,67 @@ uint32_t ext::opengl::states::currentBuffer = 0; uint32_t ext::opengl::states::frameAccumulate = 0; bool ext::opengl::states::frameAccumulateReset = false; -uf::ThreadUnique ext::opengl::currentRenderMode; +namespace { + uf::stl::vector fetchRenderModes( bool initGraphics = false ) { + auto& scene = uf::scene::getCurrentScene(); + auto/*&*/ graph = scene.getGraph(); + uf::stl::vector renderModes = ext::opengl::renderModes; + for ( auto entity : graph ) { + if ( entity->hasComponent() ) { + auto& renderMode = entity->getComponent(); + if ( std::find( renderModes.begin(), renderModes.end(), &renderMode ) == renderModes.end() ) + renderModes.emplace_back(&renderMode); + } + if ( entity->hasComponent() ) { + auto& renderMode = entity->getComponent(); + if ( std::find( renderModes.begin(), renderModes.end(), &renderMode ) == renderModes.end() ) + renderModes.emplace_back(&renderMode); + } + } + + // group by category + uf::stl::unordered_map> renderModesMap; + for ( auto* renderMode : renderModes ) { + renderModesMap[renderMode->getName()].emplace_back( renderMode ); + } + + // empty + renderModes = {}; + + // order the end rendermodes in a specific way: Gui -> Deferred -> Swapchain + uf::stl::vector end; + + if ( renderModesMap.count("Gui") > 0 ) { + end.insert( end.end(), renderModesMap["Gui"].begin(), renderModesMap["Gui"].end() ); + renderModesMap.erase("Gui"); + } + if ( renderModesMap.count("") > 0 ) { + end.insert( end.end(), renderModesMap[""].begin(), renderModesMap[""].end() ); + renderModesMap.erase(""); + } + if ( renderModesMap.count("Swapchain") > 0 ) { + end.insert( end.end(), renderModesMap["Swapchain"].begin(), renderModesMap["Swapchain"].end() ); + renderModesMap.erase("Swapchain"); + } + + for ( auto& pair : renderModesMap ) { + renderModes.insert( renderModes.end(), pair.second.begin(), pair.second.end() ); + } + renderModes.insert( renderModes.end(), end.begin(), end.end() ); + + return renderModes; + } +} + +uf::ThreadUnique ext::opengl::currentRenderMode; uf::stl::vector ext::opengl::renderModes = { new ext::opengl::BaseRenderMode, }; +uf::stl::unordered_map ext::opengl::renderModesMap; + uf::stl::string ext::opengl::errorString() { return ext::opengl::errorString(glGetError()); } @@ -110,37 +164,25 @@ uf::stl::string ext::opengl::errorString( GLenum error ) { ///// bool ext::opengl::hasRenderMode( const uf::stl::string& name, bool isName ) { - for ( auto& renderMode: ext::opengl::renderModes ) { - if ( isName ) { if ( renderMode->getName() == name ) return true; - } else if ( renderMode->getType() == name ) return true; + if ( isName && ext::opengl::renderModesMap.count(name) > 0 ) return true; + auto renderModes = ::fetchRenderModes(); + for ( auto& renderMode: renderModes ) { + if ( isName && renderMode->getName() == name ) return true; + else if ( renderMode->getType() == name ) return true; } return false; } ext::opengl::RenderMode& ext::opengl::addRenderMode( ext::opengl::RenderMode* mode, const uf::stl::string& name ) { mode->metadata.name = name; - renderModes.push_back(mode); - if ( ext::opengl::settings::validation::enabled ) UF_MSG_DEBUG("Adding RenderMode: {}: {}", name, mode->getType()); - // reorder - if ( hasRenderMode("", true) ) { - RenderMode& primary = getRenderMode("", true); - auto it = std::find( renderModes.begin(), renderModes.end(), &primary ); - if ( it + 1 != renderModes.end() ) std::rotate( it, it + 1, renderModes.end() ); - } else { - RenderMode& primary = getRenderMode("Swapchain", true); - auto it = std::find( renderModes.begin(), renderModes.end(), &primary ); - if ( it + 1 != renderModes.end() ) std::rotate( it, it + 1, renderModes.end() ); - } - if ( hasRenderMode("Gui", true) ) { - RenderMode& primary = getRenderMode("Gui", true); - auto it = std::find( renderModes.begin(), renderModes.end(), &primary ); - if ( it + 1 != renderModes.end() ) std::rotate( it, it + 1, renderModes.end() ); - } + renderModesMap[name] = renderModes.emplace_back(mode); + ext::opengl::states::rebuild = true; - return *mode; } ext::opengl::RenderMode& ext::opengl::getRenderMode( const uf::stl::string& name, bool isName ) { + if ( isName && renderModesMap.count(name) > 0 ) return *renderModesMap[name]; + auto renderModes = ::fetchRenderModes(); RenderMode* target = renderModes[0]; for ( auto& renderMode: renderModes ) { if ( isName ) { @@ -156,23 +198,39 @@ ext::opengl::RenderMode& ext::opengl::getRenderMode( const uf::stl::string& name } } } +// VK_VALIDATION_MESSAGE("Requesting RenderMode `" << name << "`, got `" << target->getName() << "` (" << target->getType() << ")"); return *target; } uf::stl::vector ext::opengl::getRenderModes( const uf::stl::string& name, bool isName ) { + if ( isName && renderModesMap.count(name) > 0 ) return { renderModesMap[name] }; return ext::opengl::getRenderModes(uf::stl::vector{name}, isName); } uf::stl::vector ext::opengl::getRenderModes( const uf::stl::vector& names, bool isName ) { uf::stl::vector targets; + auto renderModes = ::fetchRenderModes(); +#if 1 + // this way keeps the render mode ordered as requested + for ( auto& name : names ) { + for ( auto& renderMode: renderModes ) { + if ( (isName && renderMode->getName() == name) || (!isName && renderMode->getType() == name) ) { + targets.emplace_back( renderMode ); + } + } + } +#else for ( auto& renderMode: renderModes ) { if ( ( isName && std::find(names.begin(), names.end(), renderMode->getName()) != names.end() ) || std::find(names.begin(), names.end(), renderMode->getType()) != names.end() ) { targets.push_back(renderMode); } } +#endif return targets; } void ext::opengl::removeRenderMode( ext::opengl::RenderMode* mode, bool free ) { if ( !mode ) return; + uf::stl::string name = mode->getName(); renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() ); + renderModesMap.erase( name ); mode->destroy(); if ( free ) delete mode; ext::opengl::states::rebuild = true; @@ -181,6 +239,9 @@ ext::opengl::RenderMode* ext::opengl::getCurrentRenderMode() { return getCurrentRenderMode( std::this_thread::get_id() ); } ext::opengl::RenderMode* ext::opengl::getCurrentRenderMode( std::thread::id id ) { +// bool exists = ext::opengl::currentRenderMode.has(id); +// auto& currentRenderMode = ext::opengl::currentRenderMode.get(id); +// return currentRenderMode; return ext::opengl::currentRenderMode.get(id); } void ext::opengl::setCurrentRenderMode( ext::opengl::RenderMode* renderMode ) { @@ -224,7 +285,7 @@ void ext::opengl::initialize() { auto tasks = uf::thread::schedule(settings::invariant::multithreadedRecording); for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue; - tasks.queue([&]{ + tasks.queue([renderMode]{ if ( settings::invariant::individualPipelines ) renderMode->bindPipelines(); renderMode->createCommandBuffers(); }); @@ -371,11 +432,29 @@ void ext::opengl::initialize() { } void ext::opengl::tick(){ ext::opengl::mutex.lock(); - if ( ext::opengl::states::resized || ext::opengl::settings::experimental::rebuildOnTickBegin ) { + + if ( ext::opengl::states::resized ) { + synchronize(0b11); + ext::opengl::states::rebuild = true; + // ::skip = true; + } + if ( ext::opengl::settings::experimental::rebuildOnTickBegin ) { ext::opengl::states::rebuild = true; } - auto& scene = uf::scene::getCurrentScene(); - auto& graph = scene.getGraph(); + + auto renderModes = ::fetchRenderModes(); + for ( auto& renderMode : renderModes ) { + if ( !renderMode ) continue; + if ( renderMode->executed && !renderMode->execute ) continue; + if ( !renderMode->device ) { + renderMode->initialize(ext::opengl::device); + ext::opengl::states::rebuild = true; + } + renderMode->tick(); + } + + auto& scene = uf::scene::getCurrentScene(); + auto/*&*/ graph = scene.getGraph(); for ( auto entity : graph ) { if ( entity->hasComponent() ) { auto& graphics = entity->getComponent(); @@ -392,27 +471,25 @@ void ext::opengl::tick(){ ext::opengl::states::rebuild = true; } } - for ( auto& renderMode : renderModes ) { - if ( !renderMode ) continue; - if ( !renderMode->device ) { - renderMode->initialize(ext::opengl::device); - ext::opengl::states::rebuild = true; - } - renderMode->tick(); - } - auto tasks = uf::thread::schedule(settings::invariant::multithreadedRecording); - for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue; - if ( ext::opengl::states::rebuild || renderMode->rebuild ) tasks.queue([&]{ - if ( settings::invariant::individualPipelines ) renderMode->bindPipelines(); + auto tasks = uf::thread::schedule( settings::invariant::multithreadedRecording ); + for ( auto& renderMode : renderModes ) { if ( !renderMode || (renderMode->executed && !renderMode->execute) ) continue; + if ( ext::opengl::states::rebuild || renderMode->rebuild ) tasks.queue([renderMode]{ + renderMode->bindPipelines(); renderMode->createCommandBuffers(); }); - } + else if ( renderMode->rerecord ) tasks.queue([renderMode]{ + renderMode->createCommandBuffers(); + }); + } + uf::thread::execute( tasks ); - +// if ( ext::opengl::states::rebuild && ext::opengl::settings::experimental::skipRenderOnRebuild ) ::skip = true; + ext::opengl::states::rebuild = false; ext::opengl::states::resized = false; + ext::opengl::mutex.unlock(); } void ext::opengl::render(){ @@ -486,6 +563,9 @@ void ext::opengl::render(){ for ( auto& buffer : transient.buffers ) buffer.destroy(false); transient.buffers.clear(); + for ( auto& texture : transient.textures ) texture.destroy(false); + transient.textures.clear(); + ext::opengl::mutex.unlock(); } void ext::opengl::destroy() { @@ -520,7 +600,7 @@ void ext::opengl::synchronize( uint8_t flag ) { } } if ( flag & 0b10 ) { - // vkDeviceWaitIdle( device ); + glFlush(); } } uf::stl::string ext::opengl::allocatorStats(){ diff --git a/engine/src/ext/opengl/rendermodes/deferred.cpp b/engine/src/ext/opengl/rendermodes/deferred.cpp index e3fde3af..568e98bc 100644 --- a/engine/src/ext/opengl/rendermodes/deferred.cpp +++ b/engine/src/ext/opengl/rendermodes/deferred.cpp @@ -34,17 +34,9 @@ void ext::opengl::DeferredRenderMode::destroy() { void ext::opengl::DeferredRenderMode::createCommandBuffers( const uf::stl::vector& graphics ) { float width = this->width > 0 ? this->width : ext::opengl::settings::width; float height = this->height > 0 ? this->height : ext::opengl::settings::height; - + auto& commands = getCommands(); commands.start(); { - #if 0 - CommandBuffer::InfoClear clearCommandInfo = {}; - clearCommandInfo.type = enums::Command::CLEAR; - clearCommandInfo.color = {0.0f, 0.0f, 0.0f, 0.0f}; - clearCommandInfo.depth = uf::Camera::USE_REVERSE_INFINITE_PROJECTION ? 0.0f : 1.0f; - clearCommandInfo.bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; - commands.record(clearCommandInfo); - #endif CommandBuffer::InfoViewport viewportCommandInfo = {}; viewportCommandInfo.type = enums::Command::VIEWPORT; viewportCommandInfo.corner = pod::Vector2ui{0, 0}; @@ -54,8 +46,34 @@ void ext::opengl::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto size_t currentSubpass = 0; size_t currentPass = 0; size_t currentDraw = 0; + // draw skybox'd geometry for ( auto graphic : graphics ) { if ( graphic->descriptor.renderMode != this->getName() ) continue; + if ( graphic->descriptor.aux != 1 ) continue; + GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); + graphic->record( commands, descriptor, currentPass, currentDraw++ ); + } + // clear depth + if ( currentDraw > 0 ) { + CommandBuffer::InfoClear clearCommandInfo = {}; + clearCommandInfo.type = enums::Command::CLEAR; + clearCommandInfo.bits = GL_DEPTH_BUFFER_BIT; + clearCommandInfo.depth = uf::matrix::reverseInfiniteProjection ? 0.0f : 1.0f; + commands.record(clearCommandInfo); + } + // draw normal geometry + for ( auto graphic : graphics ) { + if ( graphic->descriptor.renderMode != this->getName() ) continue; + if ( graphic->descriptor.aux != 0 ) continue; + if ( graphic->descriptor.renderTarget != 0 ) continue; + GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); + graphic->record( commands, descriptor, currentPass, currentDraw++ ); + } + // draw transparency + for ( auto graphic : graphics ) { + if ( graphic->descriptor.renderMode != this->getName() ) continue; + if ( graphic->descriptor.aux != 0 ) continue; + if ( graphic->descriptor.renderTarget != 1 ) continue; GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); graphic->record( commands, descriptor, currentPass, currentDraw++ ); }