Renderer: Implement and fix front face (winding order) between Vulkan / OpenGL

This commit is contained in:
Jérôme Leclercq
2021-05-28 22:58:14 +02:00
parent 299585a7de
commit ff505e9019
15 changed files with 71 additions and 30 deletions

View File

@@ -241,10 +241,7 @@ namespace Nz
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
{
states.pipeline->Apply(context);
states.pipeline->FlipY(states.shouldFlipY);
states.pipeline->Apply(context, states.shouldFlipY);
states.shaderBindings->Apply(context);
if (states.scissorRegion)

View File

@@ -16,7 +16,7 @@ namespace Nz
{
OpenGLRenderPipeline::OpenGLRenderPipeline(OpenGLDevice& device, RenderPipelineInfo pipelineInfo) :
m_pipelineInfo(std::move(pipelineInfo)),
m_isYFlipped(false)
m_isViewportFlipped(false)
{
if (!m_program.Create(device))
throw std::runtime_error("failed to create program");
@@ -39,18 +39,14 @@ namespace Nz
m_program.Uniform(m_flipYUniformLocation, 1.f);
}
void OpenGLRenderPipeline::Apply(const GL::Context& context) const
void OpenGLRenderPipeline::Apply(const GL::Context& context, bool flipViewport) const
{
context.UpdateStates(m_pipelineInfo);
context.BindProgram(m_program.GetObjectId()); //< Bind program after states
}
void OpenGLRenderPipeline::FlipY(bool shouldFlipY) const
{
if (m_isYFlipped != shouldFlipY)
context.UpdateStates(m_pipelineInfo, flipViewport);
context.BindProgram(m_program.GetObjectId()); //< Bind program after states (for shader caching)
if (m_isViewportFlipped != flipViewport)
{
m_program.Uniform(m_flipYUniformLocation, (shouldFlipY) ? -1.f : 1.f);
m_isYFlipped = shouldFlipY;
m_program.Uniform(m_flipYUniformLocation, (flipViewport) ? -1.f : 1.f);
m_isViewportFlipped = flipViewport;
}
}
}

View File

@@ -363,6 +363,8 @@ namespace Nz::GL
glGetIntegerv(GL_VIEWPORT, res.data());
m_state.viewport = { res[0], res[1], res[2], res[3] };
m_state.renderStates.frontFace = FrontFace::CounterClockwise; //< OpenGL default front face is counter-clockwise
EnableVerticalSync(false);
return true;
@@ -435,7 +437,7 @@ namespace Nz::GL
}
}
void Context::UpdateStates(const RenderStates& renderStates) const
void Context::UpdateStates(const RenderStates& renderStates, bool isViewportFlipped) const
{
if (!SetCurrentContext(this))
throw std::runtime_error("failed to activate context");
@@ -482,11 +484,21 @@ namespace Nz::GL
{
if (m_state.renderStates.cullingSide != renderStates.cullingSide)
{
glCullFace(ToOpenGL(m_state.renderStates.cullingSide));
glCullFace(ToOpenGL(renderStates.cullingSide));
m_state.renderStates.cullingSide = renderStates.cullingSide;
}
}
FrontFace targetFrontFace = renderStates.frontFace;
if (!isViewportFlipped)
targetFrontFace = (targetFrontFace == FrontFace::Clockwise) ? FrontFace::CounterClockwise : FrontFace::Clockwise;
if (m_state.renderStates.frontFace != targetFrontFace)
{
glFrontFace(ToOpenGL(targetFrontFace));
m_state.renderStates.frontFace = targetFrontFace;
}
/*
TODO: Use glPolyonMode if available (OpenGL)
if (m_state.renderStates.faceFilling != renderStates.faceFilling)

View File

@@ -140,8 +140,8 @@ namespace Nz
VkPipelineRasterizationStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
createInfo.polygonMode = ToVulkan(pipelineInfo.faceFilling);
createInfo.cullMode = ToVulkan(pipelineInfo.cullingSide);
createInfo.frontFace = VK_FRONT_FACE_CLOCKWISE; //< TODO
createInfo.cullMode = (pipelineInfo.faceCulling) ? ToVulkan(pipelineInfo.cullingSide) : VK_CULL_MODE_NONE;
createInfo.frontFace = ToVulkan(pipelineInfo.frontFace);
createInfo.lineWidth = pipelineInfo.lineWidth;
return createInfo;