mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +00:00
LibGL: Set GL error on some calls during begin/end
According to the OpenGL 2.x spec, some calls will set the current global error to `GL_INVALID_OPERATION` if they are used during a `glBegin`/`glEnd` block.
This commit is contained in:
parent
e537e2690a
commit
1959efe063
2 changed files with 73 additions and 0 deletions
|
@ -129,17 +129,28 @@ static void clip_triangle_against_frustum(Vector<FloatVector4>& in_vec)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_begin(GLenum mode)
|
void SoftwareGLContext::gl_begin(GLenum mode)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode < GL_TRIANGLES || mode > GL_POLYGON) {
|
if (mode < GL_TRIANGLES || mode > GL_POLYGON) {
|
||||||
m_error = GL_INVALID_ENUM;
|
m_error = GL_INVALID_ENUM;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_current_draw_mode = mode;
|
m_current_draw_mode = mode;
|
||||||
|
m_in_draw_state = true; // Certain commands will now generate an error
|
||||||
m_error = GL_NO_ERROR;
|
m_error = GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_clear(GLbitfield mask)
|
void SoftwareGLContext::gl_clear(GLbitfield mask)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mask & GL_COLOR_BUFFER_BIT) {
|
if (mask & GL_COLOR_BUFFER_BIT) {
|
||||||
uint8_t r = static_cast<uint8_t>(floor(m_clear_color.x() * 255.0f));
|
uint8_t r = static_cast<uint8_t>(floor(m_clear_color.x() * 255.0f));
|
||||||
uint8_t g = static_cast<uint8_t>(floor(m_clear_color.y() * 255.0f));
|
uint8_t g = static_cast<uint8_t>(floor(m_clear_color.y() * 255.0f));
|
||||||
|
@ -155,6 +166,11 @@ void SoftwareGLContext::gl_clear(GLbitfield mask)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
void SoftwareGLContext::gl_clear_color(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_clear_color = { red, green, blue, alpha };
|
m_clear_color = { red, green, blue, alpha };
|
||||||
m_error = GL_NO_ERROR;
|
m_error = GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +197,12 @@ void SoftwareGLContext::gl_end()
|
||||||
float scr_width = 640.0f;
|
float scr_width = 640.0f;
|
||||||
float scr_height = 480.0f;
|
float scr_height = 480.0f;
|
||||||
|
|
||||||
|
// Make sure we had a `glBegin` before this call...
|
||||||
|
if (!m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Let's construct some triangles
|
// Let's construct some triangles
|
||||||
if (m_current_draw_mode == GL_TRIANGLES) {
|
if (m_current_draw_mode == GL_TRIANGLES) {
|
||||||
GLTriangle triangle;
|
GLTriangle triangle;
|
||||||
|
@ -385,11 +407,17 @@ void SoftwareGLContext::gl_end()
|
||||||
processed_triangles.clear();
|
processed_triangles.clear();
|
||||||
vertex_list.clear();
|
vertex_list.clear();
|
||||||
|
|
||||||
|
m_in_draw_state = false;
|
||||||
m_error = GL_NO_ERROR;
|
m_error = GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)
|
void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Let's do some math!
|
// Let's do some math!
|
||||||
// FIXME: Are we losing too much precision by doing this?
|
// FIXME: Are we losing too much precision by doing this?
|
||||||
float a = static_cast<float>((right + left) / (right - left));
|
float a = static_cast<float>((right + left) / (right - left));
|
||||||
|
@ -416,11 +444,20 @@ void SoftwareGLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble botto
|
||||||
|
|
||||||
GLenum SoftwareGLContext::gl_get_error()
|
GLenum SoftwareGLContext::gl_get_error()
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
return GL_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
return m_error;
|
return m_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case GL_VENDOR:
|
case GL_VENDOR:
|
||||||
return reinterpret_cast<GLubyte*>(const_cast<char*>("The SerenityOS Developers"));
|
return reinterpret_cast<GLubyte*>(const_cast<char*>("The SerenityOS Developers"));
|
||||||
|
@ -439,6 +476,11 @@ GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_load_identity()
|
void SoftwareGLContext::gl_load_identity()
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_PROJECTION)
|
if (m_current_matrix_mode == GL_PROJECTION)
|
||||||
m_projection_matrix = FloatMatrix4x4::identity();
|
m_projection_matrix = FloatMatrix4x4::identity();
|
||||||
else if (m_current_matrix_mode == GL_MODELVIEW)
|
else if (m_current_matrix_mode == GL_MODELVIEW)
|
||||||
|
@ -451,6 +493,11 @@ void SoftwareGLContext::gl_load_identity()
|
||||||
|
|
||||||
void SoftwareGLContext::gl_matrix_mode(GLenum mode)
|
void SoftwareGLContext::gl_matrix_mode(GLenum mode)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode < GL_MODELVIEW || mode > GL_PROJECTION) {
|
if (mode < GL_MODELVIEW || mode > GL_PROJECTION) {
|
||||||
m_error = GL_INVALID_ENUM;
|
m_error = GL_INVALID_ENUM;
|
||||||
return;
|
return;
|
||||||
|
@ -462,6 +509,11 @@ void SoftwareGLContext::gl_matrix_mode(GLenum mode)
|
||||||
|
|
||||||
void SoftwareGLContext::gl_push_matrix()
|
void SoftwareGLContext::gl_push_matrix()
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "glPushMatrix(): Pushing matrix to the matrix stack (matrix_mode {})", m_current_matrix_mode);
|
dbgln_if(GL_DEBUG, "glPushMatrix(): Pushing matrix to the matrix stack (matrix_mode {})", m_current_matrix_mode);
|
||||||
|
|
||||||
switch (m_current_matrix_mode) {
|
switch (m_current_matrix_mode) {
|
||||||
|
@ -481,6 +533,11 @@ void SoftwareGLContext::gl_push_matrix()
|
||||||
|
|
||||||
void SoftwareGLContext::gl_pop_matrix()
|
void SoftwareGLContext::gl_pop_matrix()
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dbgln_if(GL_DEBUG, "glPopMatrix(): Popping matrix from matrix stack (matrix_mode = {})", m_current_matrix_mode);
|
dbgln_if(GL_DEBUG, "glPopMatrix(): Popping matrix from matrix stack (matrix_mode = {})", m_current_matrix_mode);
|
||||||
|
|
||||||
// FIXME: Make sure stack::top() doesn't cause any nasty issues if it's empty (that could result in a lockup/hang)
|
// FIXME: Make sure stack::top() doesn't cause any nasty issues if it's empty (that could result in a lockup/hang)
|
||||||
|
@ -501,6 +558,11 @@ void SoftwareGLContext::gl_pop_matrix()
|
||||||
|
|
||||||
void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
|
void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FloatVector3 axis = { (float)x, (float)y, (float)z };
|
FloatVector3 axis = { (float)x, (float)y, (float)z };
|
||||||
axis.normalize();
|
axis.normalize();
|
||||||
auto rotation_mat = FloatMatrix4x4::rotate(axis, angle);
|
auto rotation_mat = FloatMatrix4x4::rotate(axis, angle);
|
||||||
|
@ -515,6 +577,11 @@ void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdoub
|
||||||
|
|
||||||
void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z)
|
void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_current_matrix_mode == GL_MODELVIEW) {
|
if (m_current_matrix_mode == GL_MODELVIEW) {
|
||||||
m_model_view_matrix = m_model_view_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z });
|
m_model_view_matrix = m_model_view_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z });
|
||||||
} else if (m_current_matrix_mode == GL_PROJECTION) {
|
} else if (m_current_matrix_mode == GL_PROJECTION) {
|
||||||
|
@ -548,6 +615,11 @@ void SoftwareGLContext::gl_vertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w
|
||||||
|
|
||||||
void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
||||||
{
|
{
|
||||||
|
if (m_in_draw_state) {
|
||||||
|
m_error = GL_INVALID_OPERATION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
(void)(x);
|
(void)(x);
|
||||||
(void)(y);
|
(void)(y);
|
||||||
(void)(width);
|
(void)(width);
|
||||||
|
|
|
@ -52,6 +52,7 @@ private:
|
||||||
Vector<GLTriangle> processed_triangles;
|
Vector<GLTriangle> processed_triangles;
|
||||||
|
|
||||||
GLenum m_error = GL_NO_ERROR;
|
GLenum m_error = GL_NO_ERROR;
|
||||||
|
bool m_in_draw_state = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue