mirror of
https://github.com/RGBCube/serenity
synced 2025-05-23 15:15:07 +00:00
LibGL: Implement glStencil*
functions
This implements the context state for stencil testing functions and operations. No rasterization is implemented.
This commit is contained in:
parent
729349ce78
commit
ea6bcda79c
7 changed files with 135 additions and 1 deletions
|
@ -11,6 +11,7 @@ set(SOURCES
|
||||||
GLLights.cpp
|
GLLights.cpp
|
||||||
GLLists.cpp
|
GLLists.cpp
|
||||||
GLMat.cpp
|
GLMat.cpp
|
||||||
|
GLStencil.cpp
|
||||||
GLTexture.cpp
|
GLTexture.cpp
|
||||||
GLUtils.cpp
|
GLUtils.cpp
|
||||||
GLVert.cpp
|
GLVert.cpp
|
||||||
|
|
|
@ -192,7 +192,13 @@ extern "C" {
|
||||||
#define GL_UNSIGNED_BYTE 0x1401
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
|
|
||||||
// Stencil buffer operations
|
// Stencil buffer operations
|
||||||
|
#define GL_KEEP 0x1E00
|
||||||
#define GL_REPLACE 0x1E01
|
#define GL_REPLACE 0x1E01
|
||||||
|
#define GL_INCR 0x1E02
|
||||||
|
#define GL_INCR_WRAP 0x8507
|
||||||
|
#define GL_DECR 0x1E03
|
||||||
|
#define GL_DECR_WRAP 0x8508
|
||||||
|
#define GL_INVERT 0x150A
|
||||||
|
|
||||||
// Texture targets
|
// Texture targets
|
||||||
#define GL_TEXTURE_1D 0x0DE0
|
#define GL_TEXTURE_1D 0x0DE0
|
||||||
|
@ -439,6 +445,10 @@ GLAPI void glPixelStorei(GLenum pname, GLint param);
|
||||||
GLAPI void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
GLAPI void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
GLAPI void glLightf(GLenum light, GLenum pname, GLfloat param);
|
GLAPI void glLightf(GLenum light, GLenum pname, GLfloat param);
|
||||||
GLAPI void glLightfv(GLenum light, GLenum pname, GLfloat* param);
|
GLAPI void glLightfv(GLenum light, GLenum pname, GLfloat* param);
|
||||||
|
GLAPI void glStencilFunc(GLenum func, GLint ref, GLuint mask);
|
||||||
|
GLAPI void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||||
|
GLAPI void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||||
|
GLAPI void glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
virtual void gl_fogi(GLenum pname, GLint param) = 0;
|
virtual void gl_fogi(GLenum pname, GLint param) = 0;
|
||||||
virtual void gl_pixel_storei(GLenum pname, GLint param) = 0;
|
virtual void gl_pixel_storei(GLenum pname, GLint param) = 0;
|
||||||
virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
|
virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
|
||||||
|
virtual void gl_stencil_func_separate(GLenum face, GLenum func, GLint ref, GLuint mask) = 0;
|
||||||
|
virtual void gl_stencil_op_separate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) = 0;
|
||||||
|
|
||||||
virtual void present() = 0;
|
virtual void present() = 0;
|
||||||
};
|
};
|
||||||
|
|
30
Userland/Libraries/LibGL/GLStencil.cpp
Normal file
30
Userland/Libraries/LibGL/GLStencil.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Jelle Raaijmakers <jelle@gmta.nl>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GL/gl.h"
|
||||||
|
#include "GLContext.h"
|
||||||
|
|
||||||
|
extern GL::GLContext* g_gl_context;
|
||||||
|
|
||||||
|
void glStencilFunc(GLenum func, GLint ref, GLuint mask)
|
||||||
|
{
|
||||||
|
g_gl_context->gl_stencil_func_separate(GL_FRONT_AND_BACK, func, ref, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
|
||||||
|
{
|
||||||
|
g_gl_context->gl_stencil_func_separate(face, func, ref, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
|
||||||
|
{
|
||||||
|
g_gl_context->gl_stencil_op_separate(GL_FRONT_AND_BACK, sfail, dpfail, dppass);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
|
||||||
|
{
|
||||||
|
g_gl_context->gl_stencil_op_separate(face, sfail, dpfail, dppass);
|
||||||
|
}
|
|
@ -2172,6 +2172,74 @@ void SoftwareGLContext::gl_scissor(GLint x, GLint y, GLsizei width, GLsizei heig
|
||||||
m_rasterizer.set_options(options);
|
m_rasterizer.set_options(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftwareGLContext::gl_stencil_func_separate(GLenum face, GLenum func, GLint ref, GLuint mask)
|
||||||
|
{
|
||||||
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_stencil_func_separate, face, func, ref, mask);
|
||||||
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
|
|
||||||
|
RETURN_WITH_ERROR_IF(!(face == GL_FRONT || face == GL_BACK || face == GL_FRONT_AND_BACK), GL_INVALID_ENUM);
|
||||||
|
|
||||||
|
RETURN_WITH_ERROR_IF(!(func == GL_NEVER
|
||||||
|
|| func == GL_LESS
|
||||||
|
|| func == GL_LEQUAL
|
||||||
|
|| func == GL_GREATER
|
||||||
|
|| func == GL_GEQUAL
|
||||||
|
|| func == GL_EQUAL
|
||||||
|
|| func == GL_NOTEQUAL
|
||||||
|
|| func == GL_ALWAYS),
|
||||||
|
GL_INVALID_ENUM);
|
||||||
|
|
||||||
|
// FIXME: "ref is clamped to the range 02^n - 1 , where n is the number of bitplanes in the stencil buffer"
|
||||||
|
|
||||||
|
StencilFunctionOptions new_options = { func, ref, mask };
|
||||||
|
if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
|
||||||
|
m_stencil_frontfacing_func = new_options;
|
||||||
|
if (face == GL_BACK || face == GL_FRONT_AND_BACK)
|
||||||
|
m_stencil_backfacing_func = new_options;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareGLContext::gl_stencil_op_separate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
|
||||||
|
{
|
||||||
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_stencil_op_separate, face, sfail, dpfail, dppass);
|
||||||
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
|
|
||||||
|
RETURN_WITH_ERROR_IF(!(face == GL_FRONT || face == GL_BACK || face == GL_FRONT_AND_BACK), GL_INVALID_ENUM);
|
||||||
|
|
||||||
|
RETURN_WITH_ERROR_IF(!(sfail == GL_KEEP
|
||||||
|
|| sfail == GL_ZERO
|
||||||
|
|| sfail == GL_REPLACE
|
||||||
|
|| sfail == GL_INCR
|
||||||
|
|| sfail == GL_INCR_WRAP
|
||||||
|
|| sfail == GL_DECR
|
||||||
|
|| sfail == GL_DECR_WRAP
|
||||||
|
|| sfail == GL_INVERT),
|
||||||
|
GL_INVALID_ENUM);
|
||||||
|
RETURN_WITH_ERROR_IF(!(dpfail == GL_KEEP
|
||||||
|
|| dpfail == GL_ZERO
|
||||||
|
|| dpfail == GL_REPLACE
|
||||||
|
|| dpfail == GL_INCR
|
||||||
|
|| dpfail == GL_INCR_WRAP
|
||||||
|
|| dpfail == GL_DECR
|
||||||
|
|| dpfail == GL_DECR_WRAP
|
||||||
|
|| dpfail == GL_INVERT),
|
||||||
|
GL_INVALID_ENUM);
|
||||||
|
RETURN_WITH_ERROR_IF(!(dppass == GL_KEEP
|
||||||
|
|| dppass == GL_ZERO
|
||||||
|
|| dppass == GL_REPLACE
|
||||||
|
|| dppass == GL_INCR
|
||||||
|
|| dppass == GL_INCR_WRAP
|
||||||
|
|| dppass == GL_DECR
|
||||||
|
|| dppass == GL_DECR_WRAP
|
||||||
|
|| dppass == GL_INVERT),
|
||||||
|
GL_INVALID_ENUM);
|
||||||
|
|
||||||
|
StencilOperationOptions new_options = { sfail, dpfail, dppass };
|
||||||
|
if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
|
||||||
|
m_stencil_frontfacing_op = new_options;
|
||||||
|
if (face == GL_BACK || face == GL_FRONT_AND_BACK)
|
||||||
|
m_stencil_backfacing_op = new_options;
|
||||||
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::present()
|
void SoftwareGLContext::present()
|
||||||
{
|
{
|
||||||
m_rasterizer.blit_to(*m_frontbuffer);
|
m_rasterizer.blit_to(*m_frontbuffer);
|
||||||
|
|
|
@ -102,6 +102,8 @@ public:
|
||||||
virtual void gl_fogi(GLenum pname, GLint param) override;
|
virtual void gl_fogi(GLenum pname, GLint param) override;
|
||||||
virtual void gl_pixel_storei(GLenum pname, GLint param) override;
|
virtual void gl_pixel_storei(GLenum pname, GLint param) override;
|
||||||
virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
|
virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
|
||||||
|
virtual void gl_stencil_func_separate(GLenum face, GLenum func, GLint ref, GLuint mask) override;
|
||||||
|
virtual void gl_stencil_op_separate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) override;
|
||||||
virtual void present() override;
|
virtual void present() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -164,8 +166,25 @@ private:
|
||||||
GLenum m_alpha_test_func = GL_ALWAYS;
|
GLenum m_alpha_test_func = GL_ALWAYS;
|
||||||
GLclampf m_alpha_test_ref_value = 0;
|
GLclampf m_alpha_test_ref_value = 0;
|
||||||
|
|
||||||
|
// Stencil configuration
|
||||||
bool m_stencil_test_enabled { false };
|
bool m_stencil_test_enabled { false };
|
||||||
|
|
||||||
|
struct StencilFunctionOptions {
|
||||||
|
GLenum func { GL_ALWAYS };
|
||||||
|
GLint reference_value { 0 };
|
||||||
|
GLuint mask { NumericLimits<GLuint>::max() };
|
||||||
|
};
|
||||||
|
StencilFunctionOptions m_stencil_backfacing_func;
|
||||||
|
StencilFunctionOptions m_stencil_frontfacing_func;
|
||||||
|
|
||||||
|
struct StencilOperationOptions {
|
||||||
|
GLenum op_fail { GL_KEEP };
|
||||||
|
GLenum op_depth_fail { GL_KEEP };
|
||||||
|
GLenum op_pass { GL_KEEP };
|
||||||
|
};
|
||||||
|
StencilOperationOptions m_stencil_backfacing_op;
|
||||||
|
StencilOperationOptions m_stencil_frontfacing_op;
|
||||||
|
|
||||||
GLenum m_current_read_buffer = GL_BACK;
|
GLenum m_current_read_buffer = GL_BACK;
|
||||||
GLenum m_current_draw_buffer = GL_BACK;
|
GLenum m_current_draw_buffer = GL_BACK;
|
||||||
|
|
||||||
|
@ -245,7 +264,9 @@ private:
|
||||||
decltype(&SoftwareGLContext::gl_draw_elements),
|
decltype(&SoftwareGLContext::gl_draw_elements),
|
||||||
decltype(&SoftwareGLContext::gl_depth_range),
|
decltype(&SoftwareGLContext::gl_depth_range),
|
||||||
decltype(&SoftwareGLContext::gl_polygon_offset),
|
decltype(&SoftwareGLContext::gl_polygon_offset),
|
||||||
decltype(&SoftwareGLContext::gl_scissor)>;
|
decltype(&SoftwareGLContext::gl_scissor),
|
||||||
|
decltype(&SoftwareGLContext::gl_stencil_func_separate),
|
||||||
|
decltype(&SoftwareGLContext::gl_stencil_op_separate)>;
|
||||||
|
|
||||||
using ExtraSavedArguments = Variant<
|
using ExtraSavedArguments = Variant<
|
||||||
FloatMatrix4x4>;
|
FloatMatrix4x4>;
|
||||||
|
|
|
@ -204,6 +204,8 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re
|
||||||
|
|
||||||
FloatVector4 pixel_buffer[RASTERIZER_BLOCK_SIZE][RASTERIZER_BLOCK_SIZE];
|
FloatVector4 pixel_buffer[RASTERIZER_BLOCK_SIZE][RASTERIZER_BLOCK_SIZE];
|
||||||
|
|
||||||
|
// FIXME: implement stencil testing
|
||||||
|
|
||||||
// Iterate over all blocks within the bounds of the triangle
|
// Iterate over all blocks within the bounds of the triangle
|
||||||
for (int by = by0; by < by1; by++) {
|
for (int by = by0; by < by1; by++) {
|
||||||
for (int bx = bx0; bx < bx1; bx++) {
|
for (int bx = bx0; bx < bx1; bx++) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue