diff --git a/src/rhi/gl3_core/gl3_core_rhi.cpp b/src/rhi/gl3_core/gl3_core_rhi.cpp index 18985ac43..eab28f852 100644 --- a/src/rhi/gl3_core/gl3_core_rhi.cpp +++ b/src/rhi/gl3_core/gl3_core_rhi.cpp @@ -1414,26 +1414,32 @@ void GlCoreRhi::bind_pipeline(Handle ctx, Handle pipe if (desc.depth_stencil_state->stencil_test) { gl_->Enable(GL_STENCIL_TEST); + stencil_front_reference_ = 0; + stencil_back_reference_ = 0; + stencil_front_compare_mask_ = 0xFF; + stencil_back_compare_mask_ = 0xFF; + stencil_front_write_mask_ = 0xFF; + stencil_back_write_mask_ = 0xFF; GL_ASSERT; gl_->StencilFuncSeparate( GL_FRONT, map_compare_func(desc.depth_stencil_state->front.stencil_compare), - desc.depth_stencil_state->front.reference, - desc.depth_stencil_state->front.compare_mask + stencil_front_reference_, + stencil_front_compare_mask_ ); GL_ASSERT; gl_->StencilFuncSeparate( GL_BACK, map_compare_func(desc.depth_stencil_state->back.stencil_compare), - desc.depth_stencil_state->back.reference, - desc.depth_stencil_state->back.compare_mask + stencil_back_reference_, + stencil_back_compare_mask_ ); GL_ASSERT; - gl_->StencilMaskSeparate(GL_FRONT, desc.depth_stencil_state->front.write_mask); + gl_->StencilMaskSeparate(GL_FRONT, stencil_front_write_mask_); GL_ASSERT; - gl_->StencilMaskSeparate(GL_BACK, desc.depth_stencil_state->back.write_mask); + gl_->StencilMaskSeparate(GL_BACK, stencil_back_write_mask_); GL_ASSERT; } else @@ -1732,6 +1738,87 @@ void GlCoreRhi::read_pixels(Handle ctx, const Rect& rect, Pixel gl_->ReadPixels(rect.x, rect.y, rect.w, rect.h, layout, type, out.data()); } +void GlCoreRhi::set_stencil_reference(Handle ctx, CullMode face, uint8_t reference) +{ + SRB2_ASSERT(face != CullMode::kNone); + SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); + SRB2_ASSERT(current_render_pass_.has_value()); + SRB2_ASSERT(current_pipeline_.has_value()); + + auto& pl = pipeline_slab_[*current_pipeline_]; + + if (face == CullMode::kFront) + { + stencil_front_reference_ = reference; + gl_->StencilFuncSeparate( + GL_FRONT, + map_compare_func(pl.desc.depth_stencil_state->front.stencil_compare), + stencil_front_reference_, + stencil_front_compare_mask_ + ); + } + else if (face == CullMode::kBack) + { + stencil_back_reference_ = reference; + gl_->StencilFuncSeparate( + GL_BACK, + map_compare_func(pl.desc.depth_stencil_state->back.stencil_compare), + stencil_back_reference_, + stencil_back_compare_mask_ + ); + } +} + +void GlCoreRhi::set_stencil_compare_mask(Handle ctx, CullMode face, uint8_t compare_mask) +{ + SRB2_ASSERT(face != CullMode::kNone); + SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); + SRB2_ASSERT(current_render_pass_.has_value()); + SRB2_ASSERT(current_pipeline_.has_value()); + + auto& pl = pipeline_slab_[*current_pipeline_]; + + if (face == CullMode::kFront) + { + stencil_front_compare_mask_ = compare_mask; + gl_->StencilFuncSeparate( + GL_FRONT, + map_compare_func(pl.desc.depth_stencil_state->front.stencil_compare), + stencil_front_reference_, + stencil_front_compare_mask_ + ); + } + else if (face == CullMode::kBack) + { + stencil_back_compare_mask_ = compare_mask; + gl_->StencilFuncSeparate( + GL_BACK, + map_compare_func(pl.desc.depth_stencil_state->back.stencil_compare), + stencil_back_reference_, + stencil_back_compare_mask_ + ); + } +} + +void GlCoreRhi::set_stencil_write_mask(Handle ctx, CullMode face, uint8_t write_mask) +{ + SRB2_ASSERT(face != CullMode::kNone); + SRB2_ASSERT(graphics_context_active_ == true && graphics_context_generation_ == ctx.generation()); + SRB2_ASSERT(current_render_pass_.has_value()); + SRB2_ASSERT(current_pipeline_.has_value()); + + if (face == CullMode::kFront) + { + stencil_front_write_mask_ = write_mask; + gl_->StencilMaskSeparate(GL_FRONT, stencil_front_write_mask_); + } + else if (face == CullMode::kBack) + { + stencil_back_write_mask_ = write_mask; + gl_->StencilMaskSeparate(GL_BACK, stencil_back_write_mask_); + } +} + TextureDetails GlCoreRhi::get_texture_details(Handle texture) { SRB2_ASSERT(texture_slab_.is_valid(texture)); diff --git a/src/rhi/gl3_core/gl3_core_rhi.hpp b/src/rhi/gl3_core/gl3_core_rhi.hpp index 8814ac36f..31e85ad1d 100644 --- a/src/rhi/gl3_core/gl3_core_rhi.hpp +++ b/src/rhi/gl3_core/gl3_core_rhi.hpp @@ -164,6 +164,13 @@ class GlCoreRhi final : public Rhi uint32_t index_buffer_offset_ = 0; uint32_t transfer_context_generation_ = 0; + uint8_t stencil_front_reference_ = 0; + uint8_t stencil_front_compare_mask_ = 0xFF; + uint8_t stencil_front_write_mask_ = 0xFF; + uint8_t stencil_back_reference_ = 0; + uint8_t stencil_back_compare_mask_ = 0xFF; + uint8_t stencil_back_write_mask_ = 0xFF; + std::vector> disposal_; public: @@ -225,6 +232,9 @@ public: virtual void draw_indexed(Handle ctx, uint32_t index_count, uint32_t first_index) override; virtual void read_pixels(Handle ctx, const Rect& rect, PixelFormat format, tcb::span out) override; + virtual void set_stencil_reference(Handle ctx, CullMode face, uint8_t reference) override; + virtual void set_stencil_compare_mask(Handle ctx, CullMode face, uint8_t mask) override; + virtual void set_stencil_write_mask(Handle ctx, CullMode face, uint8_t mask) override; virtual void present() override; diff --git a/src/rhi/rhi.hpp b/src/rhi/rhi.hpp index 0187cf9fc..20f0bb7ae 100644 --- a/src/rhi/rhi.hpp +++ b/src/rhi/rhi.hpp @@ -424,9 +424,6 @@ struct PipelineStencilOpStateDesc StencilOp pass; StencilOp depth_fail; CompareFunc stencil_compare; - uint32_t compare_mask; - uint32_t write_mask; - uint32_t reference; }; struct PipelineDepthStencilStateDesc @@ -648,6 +645,9 @@ struct Rhi virtual void draw_indexed(Handle ctx, uint32_t index_count, uint32_t first_index) = 0; virtual void read_pixels(Handle ctx, const Rect& rect, PixelFormat format, tcb::span out) = 0; + virtual void set_stencil_reference(Handle ctx, CullMode face, uint8_t reference) = 0; + virtual void set_stencil_compare_mask(Handle ctx, CullMode face, uint8_t mask) = 0; + virtual void set_stencil_write_mask(Handle ctx, CullMode face, uint8_t mask) = 0; virtual void present() = 0;