mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:07:44 +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)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode < GL_TRIANGLES || mode > GL_POLYGON) {
|
||||
m_error = GL_INVALID_ENUM;
|
||||
return;
|
||||
}
|
||||
|
||||
m_current_draw_mode = mode;
|
||||
m_in_draw_state = true; // Certain commands will now generate an error
|
||||
m_error = GL_NO_ERROR;
|
||||
}
|
||||
|
||||
void SoftwareGLContext::gl_clear(GLbitfield mask)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mask & GL_COLOR_BUFFER_BIT) {
|
||||
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));
|
||||
|
@ -155,6 +166,11 @@ void SoftwareGLContext::gl_clear(GLbitfield mask)
|
|||
|
||||
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_error = GL_NO_ERROR;
|
||||
}
|
||||
|
@ -181,6 +197,12 @@ void SoftwareGLContext::gl_end()
|
|||
float scr_width = 640.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
|
||||
if (m_current_draw_mode == GL_TRIANGLES) {
|
||||
GLTriangle triangle;
|
||||
|
@ -385,11 +407,17 @@ void SoftwareGLContext::gl_end()
|
|||
processed_triangles.clear();
|
||||
vertex_list.clear();
|
||||
|
||||
m_in_draw_state = false;
|
||||
m_error = GL_NO_ERROR;
|
||||
}
|
||||
|
||||
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!
|
||||
// FIXME: Are we losing too much precision by doing this?
|
||||
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()
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
return m_error;
|
||||
}
|
||||
|
||||
GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
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()
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_current_matrix_mode == GL_PROJECTION)
|
||||
m_projection_matrix = FloatMatrix4x4::identity();
|
||||
else if (m_current_matrix_mode == GL_MODELVIEW)
|
||||
|
@ -451,6 +493,11 @@ void SoftwareGLContext::gl_load_identity()
|
|||
|
||||
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) {
|
||||
m_error = GL_INVALID_ENUM;
|
||||
return;
|
||||
|
@ -462,6 +509,11 @@ void SoftwareGLContext::gl_matrix_mode(GLenum mode)
|
|||
|
||||
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);
|
||||
|
||||
switch (m_current_matrix_mode) {
|
||||
|
@ -481,6 +533,11 @@ void SoftwareGLContext::gl_push_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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
FloatVector3 axis = { (float)x, (float)y, (float)z };
|
||||
axis.normalize();
|
||||
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)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_current_matrix_mode == GL_MODELVIEW) {
|
||||
m_model_view_matrix = m_model_view_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z });
|
||||
} 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)
|
||||
{
|
||||
if (m_in_draw_state) {
|
||||
m_error = GL_INVALID_OPERATION;
|
||||
return;
|
||||
}
|
||||
|
||||
(void)(x);
|
||||
(void)(y);
|
||||
(void)(width);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue