From e6c060049945ca34b7a46917a6674486deebf56e Mon Sep 17 00:00:00 2001 From: Stephan Unverwerth Date: Sat, 24 Apr 2021 12:09:56 +0200 Subject: LibGL: Add back face culling functions Adds all needed functions to support back face culling and implements back face culling in the SoftwareGLContext. --- Userland/Libraries/LibGL/GL/gl.h | 16 +++++++ Userland/Libraries/LibGL/GLContext.h | 4 ++ Userland/Libraries/LibGL/GLUtils.cpp | 20 ++++++++ Userland/Libraries/LibGL/SoftwareGLContext.cpp | 64 ++++++++++++++++++++++++++ Userland/Libraries/LibGL/SoftwareGLContext.h | 8 ++++ 5 files changed, 112 insertions(+) (limited to 'Userland/Libraries/LibGL') diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 173c6186ee..3c9fa58bd3 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -32,11 +32,19 @@ extern "C" { // Buffer bits #define GL_COLOR_BUFFER_BIT 0x0200 +// Enable capabilities +#define GL_CULL_FACE 0x0B44 + // Utility #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 +// Culled face side +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + // Error codes #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x500 @@ -47,6 +55,10 @@ extern "C" { #define GL_OUT_OF_MEMORY 0x505 #define GL_INVALID_FRAMEBUFFER_OPERATION 0x506 +// Triangle winding order +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + // // OpenGL typedefs // @@ -96,6 +108,10 @@ GLAPI void glVertex2fv(const GLfloat* v); GLAPI void glVertex3f(GLfloat x, GLfloat y, GLfloat z); GLAPI void glVertex3fv(const GLfloat* v); GLAPI void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void glEnable(GLenum cap); +GLAPI void glDisable(GLenum cap); +GLAPI void glCullFace(GLenum mode); +GLAPI void glFrontFace(GLenum mode); #ifdef __cplusplus } diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index dc7f75288c..612a4ee3e0 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -36,6 +36,10 @@ public: virtual void gl_translate(GLdouble x, GLdouble y, GLdouble z) = 0; virtual void gl_vertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) = 0; virtual void gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height) = 0; + virtual void gl_enable(GLenum) = 0; + virtual void gl_disable(GLenum) = 0; + virtual void gl_front_face(GLenum) = 0; + virtual void gl_cull_face(GLenum) = 0; }; OwnPtr create_context(); diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp index e17922be68..62dfb6087a 100644 --- a/Userland/Libraries/LibGL/GLUtils.cpp +++ b/Userland/Libraries/LibGL/GLUtils.cpp @@ -10,6 +10,26 @@ extern GL::GLContext* g_gl_context; +void glEnable(GLenum cap) +{ + g_gl_context->gl_enable(cap); +} + +void glDisable(GLenum cap) +{ + g_gl_context->gl_disable(cap); +} + +void glFrontFace(GLenum mode) +{ + g_gl_context->gl_front_face(mode); +} + +void glCullFace(GLenum mode) +{ + g_gl_context->gl_cull_face(mode); +} + void glClear(GLbitfield mask) { g_gl_context->gl_clear(mask); diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 514ce2f126..0c068df34f 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -404,6 +404,16 @@ void SoftwareGLContext::gl_end() (void)(vertexBy); (void)(vertexCx); (void)(vertexCy); + + if (m_cull_faces) { + bool is_front = (m_front_face == GL_CCW ? area > 0 : area < 0); + + if (is_front && (m_culled_sides == GL_FRONT || m_culled_sides == GL_FRONT_AND_BACK)) + continue; + + if (!is_front && (m_culled_sides == GL_BACK || m_culled_sides == GL_FRONT_AND_BACK)) + continue; + } } triangle_list.clear(); @@ -714,4 +724,58 @@ void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei hei m_error = GL_NO_ERROR; } +void SoftwareGLContext::gl_enable(GLenum capability) +{ + if (m_in_draw_state) { + m_error = GL_INVALID_OPERATION; + return; + } + + switch (capability) { + case GL_CULL_FACE: + m_cull_faces = true; + break; + default: + m_error = GL_INVALID_ENUM; + break; + } +} + +void SoftwareGLContext::gl_disable(GLenum capability) +{ + if (m_in_draw_state) { + m_error = GL_INVALID_OPERATION; + return; + } + + switch (capability) { + case GL_CULL_FACE: + m_cull_faces = false; + break; + default: + m_error = GL_INVALID_ENUM; + break; + } +} + +void SoftwareGLContext::gl_front_face(GLenum face) +{ + if (face < GL_CW || face > GL_CCW) { + m_error = GL_INVALID_ENUM; + return; + } + + m_front_face = face; +} + +void SoftwareGLContext::gl_cull_face(GLenum cull_mode) +{ + if (cull_mode < GL_FRONT || cull_mode > GL_FRONT_AND_BACK) { + m_error = GL_INVALID_ENUM; + return; + } + + m_culled_sides = cull_mode; +} + } diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index d1b9bca826..c245cff5b4 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -35,6 +35,10 @@ public: virtual void gl_translate(GLdouble x, GLdouble y, GLdouble z) override; virtual void gl_vertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) override; virtual void gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height) override; + virtual void gl_enable(GLenum) override; + virtual void gl_disable(GLenum) override; + virtual void gl_front_face(GLenum) override; + virtual void gl_cull_face(GLenum) override; private: GLenum m_current_draw_mode; @@ -56,6 +60,10 @@ private: GLenum m_error = GL_NO_ERROR; bool m_in_draw_state = false; + + bool m_cull_faces = false; + GLenum m_front_face = GL_CCW; + GLenum m_culled_sides = GL_BACK; }; } -- cgit v1.2.3