diff options
author | Stephan Unverwerth <s.unverwerth@gmx.de> | 2021-04-24 12:09:56 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-08 10:13:22 +0200 |
commit | e6c060049945ca34b7a46917a6674486deebf56e (patch) | |
tree | b3f6a3081aebd398d2819764df72b7a8176c282f /Userland/Libraries/LibGL | |
parent | eff3c8a954dc5024792aaefe07e077337390bd64 (diff) | |
download | serenity-e6c060049945ca34b7a46917a6674486deebf56e.zip |
LibGL: Add back face culling functions
Adds all needed functions to support back face culling
and implements back face culling in the SoftwareGLContext.
Diffstat (limited to 'Userland/Libraries/LibGL')
-rw-r--r-- | Userland/Libraries/LibGL/GL/gl.h | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLContext.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLUtils.cpp | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 64 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.h | 8 |
5 files changed, 112 insertions, 0 deletions
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<GLContext> 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; }; } |