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
|
"rebuild on tick begin": false
|
||||||
},
|
},
|
||||||
"pipelines": {
|
"pipelines": {
|
||||||
"culling": true
|
"culling": false
|
||||||
},
|
},
|
||||||
"experimental": {
|
"experimental": {
|
||||||
"rebuild on tick begin": false,
|
"rebuild on tick begin": false,
|
||||||
@ -353,11 +353,11 @@
|
|||||||
"max": 0.1 // 0.2
|
"max": 0.1 // 0.2
|
||||||
},
|
},
|
||||||
"debug draw": {
|
"debug draw": {
|
||||||
"static": true,
|
"static": false,
|
||||||
"dynamic": true,
|
"dynamic": false,
|
||||||
"trigger": false,
|
"trigger": false,
|
||||||
"contacts": false,
|
"contacts": false,
|
||||||
"constraints": true,
|
"constraints": false,
|
||||||
"rays": false,
|
"rays": false,
|
||||||
"depthTest": true
|
"depthTest": true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
// "import": "./rp_downtown_v2.json"
|
// "import": "./rp_downtown_v2.json"
|
||||||
// "import": "./ss2_medsci1.json"
|
// "import": "./ss2_medsci1.json"
|
||||||
// "import": "./mds_mcdonalds.json"
|
"import": "./mds_mcdonalds.json"
|
||||||
"import": "./cs_office.json"
|
// "import": "./cs_office.json"
|
||||||
// "import": "./de_dust2.json"
|
// "import": "./de_dust2.json"
|
||||||
// "import": "./gm_construct.json"
|
// "import": "./gm_construct.json"
|
||||||
}
|
}
|
||||||
@ -40,6 +40,7 @@ namespace ext {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
uf::stl::vector<Buffer> buffers;
|
uf::stl::vector<Buffer> buffers;
|
||||||
|
uf::stl::vector<Texture> textures;
|
||||||
} transient;
|
} transient;
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|||||||
@ -86,6 +86,7 @@ namespace ext {
|
|||||||
// extern UF_API RenderMode* currentRenderMode;
|
// extern UF_API RenderMode* currentRenderMode;
|
||||||
extern UF_API uf::stl::vector<RenderMode*> renderModes;
|
extern UF_API uf::stl::vector<RenderMode*> renderModes;
|
||||||
extern UF_API uf::ThreadUnique<RenderMode*> currentRenderMode;
|
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 );
|
bool UF_API hasRenderMode( const uf::stl::string&, bool = true );
|
||||||
RenderMode& UF_API addRenderMode( RenderMode*, const uf::stl::string& = "" );
|
RenderMode& UF_API addRenderMode( RenderMode*, const uf::stl::string& = "" );
|
||||||
|
|||||||
@ -11,6 +11,7 @@ namespace ext {
|
|||||||
bool execute = false;
|
bool execute = false;
|
||||||
bool executed = false;
|
bool executed = false;
|
||||||
bool rebuild = false;
|
bool rebuild = false;
|
||||||
|
bool rerecord = false;
|
||||||
bool resized = false;
|
bool resized = false;
|
||||||
|
|
||||||
uint32_t width = 0;
|
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 ) {
|
if ( material.modeCull == pod::Material::CullMode::NONE ) {
|
||||||
tag["renderer"]["cull mode"] = "none";
|
tag["renderer"]["cull mode"] = "none";
|
||||||
}
|
}
|
||||||
#if UF_USE_VULKAN
|
|
||||||
if ( material.modeAlpha == pod::Material::AlphaMode::BLEND ) {
|
if ( material.modeAlpha == pod::Material::AlphaMode::BLEND ) {
|
||||||
graphic.descriptor.renderTarget = 1;
|
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(glMatrixMode(GL_PROJECTION));
|
||||||
GL_ERROR_CHECK(glLoadMatrixf( &projection[0] ));
|
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
|
// 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
|
// more convenient to just work around the regression since later builds have working opengl backends
|
||||||
GL_ERROR_CHECK(glEnable(GL_ALPHA_TEST));
|
GL_ERROR_CHECK(glEnable(GL_ALPHA_TEST));
|
||||||
|
|||||||
@ -297,8 +297,9 @@ bool ext::opengl::Graphic::updateMesh( uf::Mesh& mesh ) {
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rebuild = true;
|
// to-do: deduce if the "buffer" would resize to trigger a command buffer invalidation
|
||||||
ext::opengl::states::rebuild = true;
|
bool rebuild = false;
|
||||||
|
//ext::opengl::states::rebuild = true;
|
||||||
// we actually don't buffer anything directly at the moment so this will always fail
|
// 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
|
// 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) ) {
|
if ( uniformBufferSize == sizeof(pod::Camera::Viewports) ) {
|
||||||
drawCommandInfoBase.matrices.view = &viewports->matrices[0].view;
|
auto viewIndex = descriptor.aux * 2;
|
||||||
drawCommandInfoBase.matrices.projection = &viewports->matrices[0].projection;
|
drawCommandInfoBase.matrices.view = &viewports->matrices[viewIndex].view;
|
||||||
|
drawCommandInfoBase.matrices.projection = &viewports->matrices[viewIndex].projection;
|
||||||
} else if ( uniformBufferSize == sizeof(pod::Uniform) ) {
|
} else if ( uniformBufferSize == sizeof(pod::Uniform) ) {
|
||||||
drawCommandInfoBase.matrices.model = &uniforms->modelView;
|
drawCommandInfoBase.matrices.model = &uniforms->modelView;
|
||||||
drawCommandInfoBase.matrices.projection = &uniforms->projection;
|
drawCommandInfoBase.matrices.projection = &uniforms->projection;
|
||||||
@ -461,73 +463,68 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
|||||||
|
|
||||||
// const bool optimize = false;
|
// const bool optimize = false;
|
||||||
uf::stl::unordered_map<size_t, uf::stl::vector<CommandBuffer::InfoDraw>> pool;
|
uf::stl::unordered_map<size_t, uf::stl::vector<CommandBuffer::InfoDraw>> pool;
|
||||||
for ( auto i = 0; i < descriptor.inputs.indirect.count; ++i ) {
|
for ( auto drawID = 0; drawID < descriptor.inputs.indirect.count; ++drawID ) {
|
||||||
auto& drawCommand = drawCommands[i];
|
auto& drawCommand = drawCommands[drawID];
|
||||||
auto instanceID = drawCommand.instanceID;
|
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 objectID = instance.objectID;
|
||||||
auto materialID = instance.materialID;
|
auto materialID = instance.materialID;
|
||||||
auto lightmapID = instance.lightmapID;
|
auto lightmapID = instance.lightmapID;
|
||||||
|
|
||||||
auto& object = objects[objectID];
|
auto& object = objects[objectID];
|
||||||
|
|
||||||
auto& material = materials[materialID];
|
auto& material = materials[materialID];
|
||||||
auto textureID = material.indexAlbedo;
|
auto textureID = material.indexAlbedo;
|
||||||
|
|
||||||
auto& infos = pool[textureID];
|
auto& infos = pool[textureID];
|
||||||
CommandBuffer::InfoDraw& drawCommandInfo = infos.emplace_back( drawCommandInfoBase );
|
CommandBuffer::InfoDraw& drawCommandInfo = infos.emplace_back( drawCommandInfoBase );
|
||||||
// CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase;
|
// CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase;
|
||||||
|
|
||||||
drawCommandInfo.descriptor.inputs.index.first = drawCommand.indexID;
|
drawCommandInfo.descriptor.inputs.index.first = drawCommand.indexID;
|
||||||
drawCommandInfo.descriptor.inputs.index.count = drawCommand.indices;
|
drawCommandInfo.descriptor.inputs.index.count = drawCommand.indices;
|
||||||
|
|
||||||
drawCommandInfo.descriptor.inputs.vertex.first = drawCommand.vertexID;
|
drawCommandInfo.descriptor.inputs.vertex.first = drawCommand.vertexID;
|
||||||
drawCommandInfo.descriptor.inputs.vertex.count = drawCommand.vertices;
|
drawCommandInfo.descriptor.inputs.vertex.count = drawCommand.vertices;
|
||||||
|
|
||||||
drawCommandInfo.attributes.instance.pointer = (uint8_t*) (void*) &instance;
|
drawCommandInfo.attributes.instance.pointer = (uint8_t*) (void*) &instance;
|
||||||
drawCommandInfo.attributes.instance.length = sizeof(instance);
|
drawCommandInfo.attributes.instance.length = sizeof(instance);
|
||||||
|
|
||||||
drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand;
|
drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand;
|
||||||
drawCommandInfo.attributes.indirect.length = sizeof(drawCommand);
|
drawCommandInfo.attributes.indirect.length = sizeof(drawCommand);
|
||||||
|
|
||||||
drawCommandInfo.matrices.model = &object.model;
|
drawCommandInfo.matrices.model = &object.model;
|
||||||
|
|
||||||
drawCommandInfo.blend.modeAlpha = material.modeAlpha;
|
drawCommandInfo.blend.modeAlpha = material.modeAlpha;
|
||||||
drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff;
|
drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff;
|
||||||
|
|
||||||
drawCommandInfo.color.value = object.color * material.colorBase; // to-do: blend properly
|
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.enabled = drawCommandInfo.color.value != pod::Vector4f{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
if ( drawCommandInfo.color.value.w == 0.0f ) {
|
if ( drawCommandInfo.color.value.w == 0.0f ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 0 <= textureID ) {
|
if ( 0 <= textureID ) {
|
||||||
auto texture2DID = textures[textureID].index;
|
auto texture2DID = textures[textureID].index;
|
||||||
drawCommandInfo.textures.primary = this->material.textures.at(texture2DID).descriptor;
|
drawCommandInfo.textures.primary = this->material.textures.at(texture2DID).descriptor;
|
||||||
}
|
}
|
||||||
if ( 0 <= lightmapID ) {
|
if ( 0 <= lightmapID ) {
|
||||||
auto textureID = lightmapID;
|
auto textureID = lightmapID;
|
||||||
auto texture2DID = textures[lightmapID].index;
|
auto texture2DID = textures[lightmapID].index;
|
||||||
drawCommandInfo.textures.secondary = this->material.textures.at(texture2DID).descriptor;
|
drawCommandInfo.textures.secondary = this->material.textures.at(texture2DID).descriptor;
|
||||||
}
|
}
|
||||||
switch ( drawCommandInfo.blend.modeAlpha ) {
|
if ( drawCommandInfo.blend.modeAlpha == pod::Material::AlphaMode::BLEND ) {
|
||||||
case pod::Material::AlphaMode::BLEND: drawCommandInfos.translucents.emplace_back(drawCommandInfo); break;
|
drawCommandInfo.descriptor.renderTarget = 1;
|
||||||
default: drawCommandInfos.opaques.emplace_back(drawCommandInfo); break;
|
}
|
||||||
|
commandBuffer.record( drawCommandInfo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase;
|
CommandBuffer::InfoDraw drawCommandInfo = drawCommandInfoBase;
|
||||||
|
|
||||||
// ???
|
|
||||||
/*
|
|
||||||
drawCommandInfoBase.matrices.model = NULL;
|
|
||||||
drawCommandInfoBase.matrices.view = NULL;
|
|
||||||
drawCommandInfoBase.matrices.projection = NULL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( !material.textures.empty() ) {
|
if ( !material.textures.empty() ) {
|
||||||
auto& texture = material.textures.front();
|
auto& texture = material.textures.front();
|
||||||
drawCommandInfo.textures.primary = texture.descriptor;
|
drawCommandInfo.textures.primary = texture.descriptor;
|
||||||
@ -543,13 +540,17 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commandBuffer.record( drawCommandInfo );
|
||||||
|
/*
|
||||||
switch ( drawCommandInfo.blend.modeAlpha ) {
|
switch ( drawCommandInfo.blend.modeAlpha ) {
|
||||||
case 0: drawCommandInfos.opaques.emplace_back(drawCommandInfo); break;
|
case 0: drawCommandInfos.opaques.emplace_back(drawCommandInfo); break;
|
||||||
default: drawCommandInfos.translucents.emplace_back(drawCommandInfo); break;
|
default: drawCommandInfos.translucents.emplace_back(drawCommandInfo); break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if ( uf::matrix::reverseInfiniteProjection ) {
|
if ( uf::matrix::reverseInfiniteProjection ) {
|
||||||
for ( auto it = drawCommandInfos.opaques.rbegin(); it != drawCommandInfos.opaques.rend(); ++it ) {
|
for ( auto it = drawCommandInfos.opaques.rbegin(); it != drawCommandInfos.opaques.rend(); ++it ) {
|
||||||
auto& drawCommandInfo = (*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.opaques ) commandBuffer.record(drawCommandInfo);
|
||||||
for ( auto& drawCommandInfo : drawCommandInfos.translucents ) commandBuffer.record(drawCommandInfo);
|
for ( auto& drawCommandInfo : drawCommandInfos.translucents ) commandBuffer.record(drawCommandInfo);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// UF_MSG_DEBUG("END")
|
// UF_MSG_DEBUG("END")
|
||||||
}
|
}
|
||||||
void ext::opengl::Graphic::destroy() {
|
void ext::opengl::Graphic::destroy() {
|
||||||
|
|||||||
@ -87,13 +87,67 @@ uint32_t ext::opengl::states::currentBuffer = 0;
|
|||||||
uint32_t ext::opengl::states::frameAccumulate = 0;
|
uint32_t ext::opengl::states::frameAccumulate = 0;
|
||||||
bool ext::opengl::states::frameAccumulateReset = false;
|
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 = {
|
uf::stl::vector<ext::opengl::RenderMode*> ext::opengl::renderModes = {
|
||||||
new ext::opengl::BaseRenderMode,
|
new ext::opengl::BaseRenderMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uf::stl::unordered_map<uf::stl::string, ext::opengl::RenderMode*> ext::opengl::renderModesMap;
|
||||||
|
|
||||||
uf::stl::string ext::opengl::errorString() {
|
uf::stl::string ext::opengl::errorString() {
|
||||||
return ext::opengl::errorString(glGetError());
|
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 ) {
|
bool ext::opengl::hasRenderMode( const uf::stl::string& name, bool isName ) {
|
||||||
for ( auto& renderMode: ext::opengl::renderModes ) {
|
if ( isName && ext::opengl::renderModesMap.count(name) > 0 ) return true;
|
||||||
if ( isName ) { if ( renderMode->getName() == name ) return true;
|
auto renderModes = ::fetchRenderModes();
|
||||||
} else if ( renderMode->getType() == name ) return true;
|
for ( auto& renderMode: renderModes ) {
|
||||||
|
if ( isName && renderMode->getName() == name ) return true;
|
||||||
|
else if ( renderMode->getType() == name ) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext::opengl::RenderMode& ext::opengl::addRenderMode( ext::opengl::RenderMode* mode, const uf::stl::string& name ) {
|
ext::opengl::RenderMode& ext::opengl::addRenderMode( ext::opengl::RenderMode* mode, const uf::stl::string& name ) {
|
||||||
mode->metadata.name = name;
|
mode->metadata.name = name;
|
||||||
renderModes.push_back(mode);
|
renderModesMap[name] = renderModes.emplace_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() );
|
|
||||||
}
|
|
||||||
ext::opengl::states::rebuild = true;
|
ext::opengl::states::rebuild = true;
|
||||||
|
|
||||||
return *mode;
|
return *mode;
|
||||||
}
|
}
|
||||||
ext::opengl::RenderMode& ext::opengl::getRenderMode( const uf::stl::string& name, bool isName ) {
|
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];
|
RenderMode* target = renderModes[0];
|
||||||
for ( auto& renderMode: renderModes ) {
|
for ( auto& renderMode: renderModes ) {
|
||||||
if ( isName ) {
|
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;
|
return *target;
|
||||||
}
|
}
|
||||||
uf::stl::vector<ext::opengl::RenderMode*> ext::opengl::getRenderModes( const uf::stl::string& name, bool isName ) {
|
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);
|
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<ext::opengl::RenderMode*> ext::opengl::getRenderModes( const uf::stl::vector<uf::stl::string>& names, bool isName ) {
|
||||||
uf::stl::vector<RenderMode*> targets;
|
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 ) {
|
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() ) {
|
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);
|
targets.push_back(renderMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
void ext::opengl::removeRenderMode( ext::opengl::RenderMode* mode, bool free ) {
|
void ext::opengl::removeRenderMode( ext::opengl::RenderMode* mode, bool free ) {
|
||||||
if ( !mode ) return;
|
if ( !mode ) return;
|
||||||
|
uf::stl::string name = mode->getName();
|
||||||
renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() );
|
renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() );
|
||||||
|
renderModesMap.erase( name );
|
||||||
mode->destroy();
|
mode->destroy();
|
||||||
if ( free ) delete mode;
|
if ( free ) delete mode;
|
||||||
ext::opengl::states::rebuild = true;
|
ext::opengl::states::rebuild = true;
|
||||||
@ -181,6 +239,9 @@ ext::opengl::RenderMode* ext::opengl::getCurrentRenderMode() {
|
|||||||
return getCurrentRenderMode( std::this_thread::get_id() );
|
return getCurrentRenderMode( std::this_thread::get_id() );
|
||||||
}
|
}
|
||||||
ext::opengl::RenderMode* ext::opengl::getCurrentRenderMode( std::thread::id 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);
|
return ext::opengl::currentRenderMode.get(id);
|
||||||
}
|
}
|
||||||
void ext::opengl::setCurrentRenderMode( ext::opengl::RenderMode* renderMode ) {
|
void ext::opengl::setCurrentRenderMode( ext::opengl::RenderMode* renderMode ) {
|
||||||
@ -224,7 +285,7 @@ void ext::opengl::initialize() {
|
|||||||
|
|
||||||
auto tasks = uf::thread::schedule(settings::invariant::multithreadedRecording);
|
auto tasks = uf::thread::schedule(settings::invariant::multithreadedRecording);
|
||||||
for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue;
|
for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue;
|
||||||
tasks.queue([&]{
|
tasks.queue([renderMode]{
|
||||||
if ( settings::invariant::individualPipelines ) renderMode->bindPipelines();
|
if ( settings::invariant::individualPipelines ) renderMode->bindPipelines();
|
||||||
renderMode->createCommandBuffers();
|
renderMode->createCommandBuffers();
|
||||||
});
|
});
|
||||||
@ -371,11 +432,29 @@ void ext::opengl::initialize() {
|
|||||||
}
|
}
|
||||||
void ext::opengl::tick(){
|
void ext::opengl::tick(){
|
||||||
ext::opengl::mutex.lock();
|
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;
|
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 ) {
|
for ( auto entity : graph ) {
|
||||||
if ( entity->hasComponent<ext::opengl::Graphics>() ) {
|
if ( entity->hasComponent<ext::opengl::Graphics>() ) {
|
||||||
auto& graphics = entity->getComponent<ext::opengl::Graphics>();
|
auto& graphics = entity->getComponent<ext::opengl::Graphics>();
|
||||||
@ -392,27 +471,25 @@ void ext::opengl::tick(){
|
|||||||
ext::opengl::states::rebuild = true;
|
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);
|
auto tasks = uf::thread::schedule( settings::invariant::multithreadedRecording );
|
||||||
for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue;
|
for ( auto& renderMode : renderModes ) { if ( !renderMode || (renderMode->executed && !renderMode->execute) ) continue;
|
||||||
if ( ext::opengl::states::rebuild || renderMode->rebuild ) tasks.queue([&]{
|
if ( ext::opengl::states::rebuild || renderMode->rebuild ) tasks.queue([renderMode]{
|
||||||
if ( settings::invariant::individualPipelines ) renderMode->bindPipelines();
|
renderMode->bindPipelines();
|
||||||
renderMode->createCommandBuffers();
|
renderMode->createCommandBuffers();
|
||||||
});
|
});
|
||||||
}
|
else if ( renderMode->rerecord ) tasks.queue([renderMode]{
|
||||||
|
renderMode->createCommandBuffers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uf::thread::execute( tasks );
|
uf::thread::execute( tasks );
|
||||||
|
|
||||||
|
// if ( ext::opengl::states::rebuild && ext::opengl::settings::experimental::skipRenderOnRebuild ) ::skip = true;
|
||||||
|
|
||||||
ext::opengl::states::rebuild = false;
|
ext::opengl::states::rebuild = false;
|
||||||
ext::opengl::states::resized = false;
|
ext::opengl::states::resized = false;
|
||||||
|
|
||||||
ext::opengl::mutex.unlock();
|
ext::opengl::mutex.unlock();
|
||||||
}
|
}
|
||||||
void ext::opengl::render(){
|
void ext::opengl::render(){
|
||||||
@ -486,6 +563,9 @@ void ext::opengl::render(){
|
|||||||
for ( auto& buffer : transient.buffers ) buffer.destroy(false);
|
for ( auto& buffer : transient.buffers ) buffer.destroy(false);
|
||||||
transient.buffers.clear();
|
transient.buffers.clear();
|
||||||
|
|
||||||
|
for ( auto& texture : transient.textures ) texture.destroy(false);
|
||||||
|
transient.textures.clear();
|
||||||
|
|
||||||
ext::opengl::mutex.unlock();
|
ext::opengl::mutex.unlock();
|
||||||
}
|
}
|
||||||
void ext::opengl::destroy() {
|
void ext::opengl::destroy() {
|
||||||
@ -520,7 +600,7 @@ void ext::opengl::synchronize( uint8_t flag ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( flag & 0b10 ) {
|
if ( flag & 0b10 ) {
|
||||||
// vkDeviceWaitIdle( device );
|
glFlush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uf::stl::string ext::opengl::allocatorStats(){
|
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 ) {
|
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 width = this->width > 0 ? this->width : ext::opengl::settings::width;
|
||||||
float height = this->height > 0 ? this->height : ext::opengl::settings::height;
|
float height = this->height > 0 ? this->height : ext::opengl::settings::height;
|
||||||
|
|
||||||
auto& commands = getCommands();
|
auto& commands = getCommands();
|
||||||
commands.start(); {
|
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 = {};
|
CommandBuffer::InfoViewport viewportCommandInfo = {};
|
||||||
viewportCommandInfo.type = enums::Command::VIEWPORT;
|
viewportCommandInfo.type = enums::Command::VIEWPORT;
|
||||||
viewportCommandInfo.corner = pod::Vector2ui{0, 0};
|
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 currentSubpass = 0;
|
||||||
size_t currentPass = 0;
|
size_t currentPass = 0;
|
||||||
size_t currentDraw = 0;
|
size_t currentDraw = 0;
|
||||||
|
// draw skybox'd geometry
|
||||||
for ( auto graphic : graphics ) {
|
for ( auto graphic : graphics ) {
|
||||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
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);
|
GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass);
|
||||||
graphic->record( commands, descriptor, currentPass, currentDraw++ );
|
graphic->record( commands, descriptor, currentPass, currentDraw++ );
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user