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)
This commit is contained in:
parent
65a08839f9
commit
fa5f421140
@ -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
|
||||
},
|
||||
|
||||
@ -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"
|
||||
}
|
||||
@ -40,6 +40,7 @@ namespace ext {
|
||||
|
||||
struct {
|
||||
uf::stl::vector<Buffer> buffers;
|
||||
uf::stl::vector<Texture> textures;
|
||||
} transient;
|
||||
|
||||
void initialize();
|
||||
|
||||
@ -86,6 +86,7 @@ namespace ext {
|
||||
// extern UF_API RenderMode* currentRenderMode;
|
||||
extern UF_API uf::stl::vector<RenderMode*> renderModes;
|
||||
extern UF_API uf::ThreadUnique<RenderMode*> currentRenderMode;
|
||||
extern UF_API uf::stl::unordered_map<uf::stl::string, ext::opengl::RenderMode*> renderModesMap;
|
||||
|
||||
bool UF_API hasRenderMode( const uf::stl::string&, bool = true );
|
||||
RenderMode& UF_API addRenderMode( RenderMode*, const uf::stl::string& = "" );
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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<size_t, uf::stl::vector<CommandBuffer::InfoDraw>> 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() {
|
||||
|
||||
@ -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::RenderMode*> ext::opengl::currentRenderMode;
|
||||
namespace {
|
||||
uf::stl::vector<ext::opengl::RenderMode*> fetchRenderModes( bool initGraphics = false ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto/*&*/ graph = scene.getGraph();
|
||||
|
||||
uf::stl::vector<uf::renderer::RenderMode*> renderModes = ext::opengl::renderModes;
|
||||
for ( auto entity : graph ) {
|
||||
if ( entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
if ( std::find( renderModes.begin(), renderModes.end(), &renderMode ) == renderModes.end() )
|
||||
renderModes.emplace_back(&renderMode);
|
||||
}
|
||||
if ( entity->hasComponent<uf::renderer::DeferredRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::DeferredRenderMode>();
|
||||
if ( std::find( renderModes.begin(), renderModes.end(), &renderMode ) == renderModes.end() )
|
||||
renderModes.emplace_back(&renderMode);
|
||||
}
|
||||
}
|
||||
|
||||
// group by category
|
||||
uf::stl::unordered_map<uf::stl::string, uf::stl::vector<uf::renderer::RenderMode*>> 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<uf::renderer::RenderMode*> 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::RenderMode*> ext::opengl::currentRenderMode;
|
||||
|
||||
uf::stl::vector<ext::opengl::RenderMode*> ext::opengl::renderModes = {
|
||||
new ext::opengl::BaseRenderMode,
|
||||
};
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, ext::opengl::RenderMode*> 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::RenderMode*> 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<uf::stl::string>{name}, isName);
|
||||
}
|
||||
uf::stl::vector<ext::opengl::RenderMode*> ext::opengl::getRenderModes( const uf::stl::vector<uf::stl::string>& names, bool isName ) {
|
||||
uf::stl::vector<RenderMode*> 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<ext::opengl::Graphics>() ) {
|
||||
auto& graphics = entity->getComponent<ext::opengl::Graphics>();
|
||||
@ -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(){
|
||||
|
||||
@ -34,17 +34,9 @@ void ext::opengl::DeferredRenderMode::destroy() {
|
||||
void ext::opengl::DeferredRenderMode::createCommandBuffers( const uf::stl::vector<ext::opengl::Graphic*>& 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++ );
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user