1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:47:34 +00:00

LibGL: Add back face culling functions

Adds all needed functions to support back face culling
and implements back face culling in the SoftwareGLContext.
This commit is contained in:
Stephan Unverwerth 2021-04-24 12:09:56 +02:00 committed by Andreas Kling
parent eff3c8a954
commit e6c0600499
5 changed files with 112 additions and 0 deletions

View file

@ -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
}

View file

@ -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();

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;
};
}