summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGL
diff options
context:
space:
mode:
authorStephan Unverwerth <s.unverwerth@gmx.de>2021-04-24 12:09:56 +0200
committerAndreas Kling <kling@serenityos.org>2021-05-08 10:13:22 +0200
commite6c060049945ca34b7a46917a6674486deebf56e (patch)
treeb3f6a3081aebd398d2819764df72b7a8176c282f /Userland/Libraries/LibGL
parenteff3c8a954dc5024792aaefe07e077337390bd64 (diff)
downloadserenity-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.h16
-rw-r--r--Userland/Libraries/LibGL/GLContext.h4
-rw-r--r--Userland/Libraries/LibGL/GLUtils.cpp20
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp64
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h8
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;
};
}