1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:17:34 +00:00

LibGL: Implement glNormalPointer

Used for `glDrawArrays` and `glDrawElements`, the normal pointer should
point to sets of X, Y and Z values.
This commit is contained in:
Jelle Raaijmakers 2022-03-06 01:43:42 +01:00 committed by Andreas Kling
parent 53edb41d40
commit 287f33165e
2 changed files with 62 additions and 65 deletions

View file

@ -2008,18 +2008,18 @@ void SoftwareGLContext::gl_enable_client_state(GLenum cap)
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
switch (cap) { switch (cap) {
case GL_VERTEX_ARRAY:
m_client_side_vertex_array_enabled = true;
break;
case GL_COLOR_ARRAY: case GL_COLOR_ARRAY:
m_client_side_color_array_enabled = true; m_client_side_color_array_enabled = true;
break; break;
case GL_NORMAL_ARRAY:
m_client_side_normal_array_enabled = true;
break;
case GL_TEXTURE_COORD_ARRAY: case GL_TEXTURE_COORD_ARRAY:
m_client_side_texture_coord_array_enabled[m_client_active_texture] = true; m_client_side_texture_coord_array_enabled[m_client_active_texture] = true;
break; break;
case GL_VERTEX_ARRAY:
m_client_side_vertex_array_enabled = true;
break;
default: default:
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
} }
@ -2030,18 +2030,18 @@ void SoftwareGLContext::gl_disable_client_state(GLenum cap)
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
switch (cap) { switch (cap) {
case GL_VERTEX_ARRAY:
m_client_side_vertex_array_enabled = false;
break;
case GL_COLOR_ARRAY: case GL_COLOR_ARRAY:
m_client_side_color_array_enabled = false; m_client_side_color_array_enabled = false;
break; break;
case GL_NORMAL_ARRAY:
m_client_side_normal_array_enabled = false;
break;
case GL_TEXTURE_COORD_ARRAY: case GL_TEXTURE_COORD_ARRAY:
m_client_side_texture_coord_array_enabled[m_client_active_texture] = false; m_client_side_texture_coord_array_enabled[m_client_active_texture] = false;
break; break;
case GL_VERTEX_ARRAY:
m_client_side_vertex_array_enabled = false;
break;
default: default:
RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(true, GL_INVALID_ENUM);
} }
@ -2057,57 +2057,54 @@ void SoftwareGLContext::gl_client_active_texture(GLenum target)
void SoftwareGLContext::gl_vertex_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) void SoftwareGLContext::gl_vertex_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer)
{ {
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
RETURN_WITH_ERROR_IF(!(size == 2 || size == 3 || size == 4), GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(!(size == 2 || size == 3 || size == 4), GL_INVALID_VALUE);
RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE);
m_client_vertex_pointer.size = size; m_client_vertex_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer };
m_client_vertex_pointer.type = type;
m_client_vertex_pointer.stride = stride;
m_client_vertex_pointer.pointer = pointer;
} }
void SoftwareGLContext::gl_color_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) void SoftwareGLContext::gl_color_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer)
{ {
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
RETURN_WITH_ERROR_IF(!(size == 3 || size == 4), GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(!(size == 3 || size == 4), GL_INVALID_VALUE);
RETURN_WITH_ERROR_IF(type != GL_BYTE
RETURN_WITH_ERROR_IF(!(type == GL_BYTE && type != GL_UNSIGNED_BYTE
|| type == GL_UNSIGNED_BYTE && type != GL_SHORT
|| type == GL_SHORT && type != GL_UNSIGNED_SHORT
|| type == GL_UNSIGNED_SHORT && type != GL_INT
|| type == GL_INT && type != GL_UNSIGNED_INT
|| type == GL_UNSIGNED_INT && type != GL_FLOAT
|| type == GL_FLOAT && type != GL_DOUBLE,
|| type == GL_DOUBLE),
GL_INVALID_ENUM); GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE);
m_client_color_pointer.size = size; m_client_color_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer };
m_client_color_pointer.type = type;
m_client_color_pointer.stride = stride;
m_client_color_pointer.pointer = pointer;
} }
void SoftwareGLContext::gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer) void SoftwareGLContext::gl_tex_coord_pointer(GLint size, GLenum type, GLsizei stride, const void* pointer)
{ {
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
RETURN_WITH_ERROR_IF(!(size == 1 || size == 2 || size == 3 || size == 4), GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(!(size == 1 || size == 2 || size == 3 || size == 4), GL_INVALID_VALUE);
RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(!(type == GL_SHORT || type == GL_INT || type == GL_FLOAT || type == GL_DOUBLE), GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE);
auto& tex_coord_pointer = m_client_tex_coord_pointer[m_client_active_texture]; auto& tex_coord_pointer = m_client_tex_coord_pointer[m_client_active_texture];
tex_coord_pointer = { .size = size, .type = type, .stride = stride, .pointer = pointer };
}
tex_coord_pointer.size = size; void SoftwareGLContext::gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer)
tex_coord_pointer.type = type; {
tex_coord_pointer.stride = stride; RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
tex_coord_pointer.pointer = pointer; RETURN_WITH_ERROR_IF(type != GL_BYTE
&& type != GL_SHORT
&& type != GL_INT
&& type != GL_FLOAT
&& type != GL_DOUBLE,
GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE);
m_client_normal_pointer = { .size = 3, .type = type, .stride = stride, .pointer = pointer };
} }
void SoftwareGLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param) void SoftwareGLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param)
@ -2160,6 +2157,12 @@ void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count)
auto last = first + count; auto last = first + count;
gl_begin(mode); gl_begin(mode);
for (int i = first; i < last; i++) { for (int i = first; i < last; i++) {
if (m_client_side_color_array_enabled) {
float color[4] { 0, 0, 0, 1 };
read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true);
gl_color(color[0], color[1], color[2], color[3]);
}
for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) { for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) {
if (m_client_side_texture_coord_array_enabled[t]) { if (m_client_side_texture_coord_array_enabled[t]) {
float tex_coords[4] { 0, 0, 0, 0 }; float tex_coords[4] { 0, 0, 0, 0 };
@ -2168,10 +2171,10 @@ void SoftwareGLContext::gl_draw_arrays(GLenum mode, GLint first, GLsizei count)
} }
} }
if (m_client_side_color_array_enabled) { if (m_client_side_normal_array_enabled) {
float color[4] { 0, 0, 0, 1 }; float normal[3];
read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); read_from_vertex_attribute_pointer(m_client_normal_pointer, i, normal, false);
gl_color(color[0], color[1], color[2], color[3]); gl_normal(normal[0], normal[1], normal[2]);
} }
float vertex[4] { 0, 0, 0, 1 }; float vertex[4] { 0, 0, 0, 1 };
@ -2221,6 +2224,12 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type
break; break;
} }
if (m_client_side_color_array_enabled) {
float color[4] { 0, 0, 0, 1 };
read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true);
gl_color(color[0], color[1], color[2], color[3]);
}
for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) { for (size_t t = 0; t < m_client_tex_coord_pointer.size(); ++t) {
if (m_client_side_texture_coord_array_enabled[t]) { if (m_client_side_texture_coord_array_enabled[t]) {
float tex_coords[4] { 0, 0, 0, 0 }; float tex_coords[4] { 0, 0, 0, 0 };
@ -2229,10 +2238,10 @@ void SoftwareGLContext::gl_draw_elements(GLenum mode, GLsizei count, GLenum type
} }
} }
if (m_client_side_color_array_enabled) { if (m_client_side_normal_array_enabled) {
float color[4] { 0, 0, 0, 1 }; float normal[3];
read_from_vertex_attribute_pointer(m_client_color_pointer, i, color, true); read_from_vertex_attribute_pointer(m_client_normal_pointer, i, normal, false);
gl_color(color[0], color[1], color[2], color[3]); gl_normal(normal[0], normal[1], normal[2]);
} }
float vertex[4] { 0, 0, 0, 1 }; float vertex[4] { 0, 0, 0, 1 };
@ -2734,20 +2743,6 @@ void SoftwareGLContext::gl_normal(GLfloat nx, GLfloat ny, GLfloat nz)
m_current_vertex_normal = { nx, ny, nz }; m_current_vertex_normal = { nx, ny, nz };
} }
void SoftwareGLContext::gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer)
{
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
RETURN_WITH_ERROR_IF(type != GL_BYTE
&& type != GL_SHORT
&& type != GL_INT
&& type != GL_FLOAT
&& type != GL_DOUBLE,
GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(stride < 0, GL_INVALID_VALUE);
dbgln_if(GL_DEBUG, "gl_normal_pointer({:#x}, {}, {:p}): unimplemented", type, stride, pointer);
}
void SoftwareGLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) void SoftwareGLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{ {
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_raster_pos, x, y, z, w); APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_raster_pos, x, y, z, w);

View file

@ -211,9 +211,9 @@ private:
float m_clear_depth { 1.f }; float m_clear_depth { 1.f };
u8 m_clear_stencil { 0 }; u8 m_clear_stencil { 0 };
FloatVector4 m_current_vertex_color = { 1.0f, 1.0f, 1.0f, 1.0f }; FloatVector4 m_current_vertex_color { 1.0f, 1.0f, 1.0f, 1.0f };
Vector<FloatVector4> m_current_vertex_tex_coord; Vector<FloatVector4> m_current_vertex_tex_coord;
FloatVector3 m_current_vertex_normal = { 0.0f, 0.0f, 1.0f }; FloatVector3 m_current_vertex_normal { 0.0f, 0.0f, 1.0f };
Vector<SoftGPU::Vertex> m_vertex_list; Vector<SoftGPU::Vertex> m_vertex_list;
@ -261,10 +261,11 @@ private:
GLenum m_current_draw_buffer = GL_BACK; GLenum m_current_draw_buffer = GL_BACK;
// Client side arrays // Client side arrays
bool m_client_side_vertex_array_enabled = false; bool m_client_side_vertex_array_enabled { false };
bool m_client_side_color_array_enabled = false; bool m_client_side_color_array_enabled { false };
Vector<bool> m_client_side_texture_coord_array_enabled; Vector<bool> m_client_side_texture_coord_array_enabled;
size_t m_client_active_texture = 0; size_t m_client_active_texture = 0;
bool m_client_side_normal_array_enabled { false };
NonnullRefPtr<Gfx::Bitmap> m_frontbuffer; NonnullRefPtr<Gfx::Bitmap> m_frontbuffer;
@ -413,6 +414,7 @@ private:
VertexAttribPointer m_client_vertex_pointer; VertexAttribPointer m_client_vertex_pointer;
VertexAttribPointer m_client_color_pointer; VertexAttribPointer m_client_color_pointer;
Vector<VertexAttribPointer> m_client_tex_coord_pointer; Vector<VertexAttribPointer> m_client_tex_coord_pointer;
VertexAttribPointer m_client_normal_pointer;
u8 m_pack_alignment { 4 }; u8 m_pack_alignment { 4 };
GLsizei m_unpack_row_length { 0 }; GLsizei m_unpack_row_length { 0 };