diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index b2fdbd4b70..8cd9dbdb42 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -110,7 +110,6 @@ public: virtual void gl_normal(GLfloat nx, GLfloat ny, GLfloat nz) = 0; virtual void gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer) = 0; virtual void gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0; - virtual void gl_materialv(GLenum face, GLenum pname, GLfloat const* params) = 0; virtual void gl_line_width(GLfloat width) = 0; virtual void gl_push_attrib(GLbitfield mask) = 0; virtual void gl_pop_attrib() = 0; @@ -123,6 +122,8 @@ public: virtual void gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params) = 0; virtual void gl_lightf(GLenum light, GLenum pname, GLfloat param) = 0; virtual void gl_lightfv(GLenum light, GLenum pname, GLfloat const* params) = 0; + virtual void gl_materialf(GLenum face, GLenum pname, GLfloat param) = 0; + virtual void gl_materialfv(GLenum face, GLenum pname, GLfloat const* params) = 0; virtual void present() = 0; }; diff --git a/Userland/Libraries/LibGL/GLLights.cpp b/Userland/Libraries/LibGL/GLLights.cpp index cb11fe56e5..bb95f74a99 100644 --- a/Userland/Libraries/LibGL/GLLights.cpp +++ b/Userland/Libraries/LibGL/GLLights.cpp @@ -51,12 +51,12 @@ void glLightModeli(GLenum pname, GLint param) void glMaterialf(GLenum face, GLenum pname, GLfloat param) { - g_gl_context->gl_materialv(face, pname, ¶m); + g_gl_context->gl_materialf(face, pname, param); } void glMaterialfv(GLenum face, GLenum pname, GLfloat const* params) { - g_gl_context->gl_materialv(face, pname, params); + g_gl_context->gl_materialfv(face, pname, params); } void glShadeModel(GLenum mode) diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index cfe6549ea7..322196c95c 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -2649,47 +2649,6 @@ void SoftwareGLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w m_current_raster_position.clip_coordinate_value = w; } -void SoftwareGLContext::gl_materialv(GLenum face, GLenum pname, GLfloat const* params) -{ - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_materialv, face, pname, params); - - RETURN_WITH_ERROR_IF(!(face == GL_FRONT || face == GL_BACK || face == GL_FRONT_AND_BACK), GL_INVALID_ENUM); - - RETURN_WITH_ERROR_IF(!(pname == GL_AMBIENT - || pname == GL_DIFFUSE - || pname == GL_SPECULAR - || pname == GL_EMISSION - || pname == GL_SHININESS - || pname == GL_AMBIENT_AND_DIFFUSE - || pname == GL_COLOR_INDEXES), - GL_INVALID_ENUM); - - GLfloat x, y, z, w; - - switch (pname) { - case GL_SHININESS: - x = params[0]; - y = 0.0f; - z = 0.0f; - w = 0.0f; - break; - case GL_COLOR_INDEXES: - x = params[0]; - y = params[1]; - z = params[2]; - w = 0.0f; - break; - default: - x = params[0]; - y = params[1]; - z = params[2]; - w = params[3]; - } - - // FIXME: implement this method - dbgln_if(GL_DEBUG, "gl_materialv({}, {}, {}, {}, {}, {}): unimplemented", face, pname, x, y, z, w); -} - void SoftwareGLContext::gl_line_width(GLfloat width) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_line_width, width); @@ -3018,6 +2977,23 @@ void SoftwareGLContext::sync_light_state() m_rasterizer.set_light_state(light_id, light); } + + for (auto material_id = 0u; material_id < 2u; material_id++) { + SoftGPU::Material material; + auto const& current_material_state = m_material_states.at(material_id); + + material.ambient = current_material_state.ambient; + material.diffuse = current_material_state.diffuse; + material.specular = current_material_state.specular; + material.emissive = current_material_state.emissive; + material.shininess = current_material_state.shininess; + material.specular_exponent = current_material_state.specular_exponent; + material.ambient_color_index = current_material_state.ambient_color_index; + material.diffuse_color_index = current_material_state.diffuse_color_index; + material.specular_color_index = current_material_state.specular_color_index; + + m_rasterizer.set_material_state(material_id, material); + } } void SoftwareGLContext::sync_device_texcoord_config() @@ -3166,4 +3142,77 @@ void SoftwareGLContext::gl_lightfv(GLenum light, GLenum pname, GLfloat const* pa m_light_state_is_dirty = true; } + +void SoftwareGLContext::gl_materialf(GLenum face, GLenum pname, GLfloat param) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_materialf, face, pname, param); + RETURN_WITH_ERROR_IF(!(face == GL_FRONT || face == GL_BACK || face == GL_FRONT_AND_BACK), GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(pname != GL_SHININESS, GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(param > 128.0f, GL_INVALID_VALUE); + + switch (face) { + case GL_FRONT: + m_material_states.at(to_underlying(MaterialFace::Front)).shininess = param; + break; + case GL_BACK: + m_material_states.at(to_underlying(MaterialFace::Back)).shininess = param; + break; + case GL_FRONT_AND_BACK: + m_material_states.at(to_underlying(MaterialFace::Front)).shininess = param; + m_material_states.at(to_underlying(MaterialFace::Back)).shininess = param; + break; + default: + VERIFY_NOT_REACHED(); + } + + m_light_state_is_dirty = true; +} + +void SoftwareGLContext::gl_materialfv(GLenum face, GLenum pname, GLfloat const* params) +{ + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_materialfv, face, pname, params); + RETURN_WITH_ERROR_IF(!(face == GL_FRONT || face == GL_BACK || face == GL_FRONT_AND_BACK), GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF(!(pname == GL_AMBIENT || pname == GL_DIFFUSE || pname == GL_SPECULAR || pname == GL_EMISSION || pname == GL_SHININESS || pname == GL_AMBIENT_AND_DIFFUSE), GL_INVALID_ENUM); + RETURN_WITH_ERROR_IF((pname == GL_SHININESS && *params > 128.0f), GL_INVALID_VALUE); + + auto update_material = [](SoftGPU::Material& material, GLenum pname, GLfloat const* params) { + switch (pname) { + case GL_AMBIENT: + material.ambient = { params[0], params[1], params[2], params[3] }; + break; + case GL_DIFFUSE: + material.diffuse = { params[0], params[1], params[2], params[3] }; + break; + case GL_SPECULAR: + material.specular = { params[0], params[1], params[2], params[3] }; + break; + case GL_EMISSION: + material.emissive = { params[0], params[1], params[2], params[3] }; + break; + case GL_SHININESS: + material.shininess = *params; + break; + case GL_AMBIENT_AND_DIFFUSE: + material.ambient = { params[0], params[1], params[2], params[3] }; + material.diffuse = { params[0], params[1], params[2], params[3] }; + break; + } + }; + + switch (face) { + case GL_FRONT: + update_material(m_material_states.at(to_underlying(MaterialFace::Front)), pname, params); + break; + case GL_BACK: + update_material(m_material_states.at(to_underlying(MaterialFace::Back)), pname, params); + break; + case GL_FRONT_AND_BACK: + update_material(m_material_states.at(to_underlying(MaterialFace::Front)), pname, params); + update_material(m_material_states.at(to_underlying(MaterialFace::Back)), pname, params); + break; + } + + m_light_state_is_dirty = true; +} + } diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index e131eaebf0..81b77fefd0 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -41,6 +41,11 @@ struct ContextParameter { } value; }; +enum class MaterialFace : u8 { + Front = 0, + Back = 1, +}; + class SoftwareGLContext : public GLContext { public: SoftwareGLContext(Gfx::Bitmap&); @@ -126,7 +131,6 @@ public: virtual void gl_normal(GLfloat nx, GLfloat ny, GLfloat nz) override; virtual void gl_normal_pointer(GLenum type, GLsizei stride, void const* pointer) override; virtual void gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) override; - virtual void gl_materialv(GLenum face, GLenum pname, GLfloat const* params) override; virtual void gl_line_width(GLfloat width) override; virtual void gl_push_attrib(GLbitfield mask) override; virtual void gl_pop_attrib() override; @@ -139,7 +143,8 @@ public: virtual void gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params) override; virtual void gl_lightf(GLenum light, GLenum pname, GLfloat param) override; virtual void gl_lightfv(GLenum light, GLenum pname, GLfloat const* params) override; - + virtual void gl_materialf(GLenum face, GLenum pname, GLfloat param) override; + virtual void gl_materialfv(GLenum face, GLenum pname, GLfloat const* params) override; virtual void present() override; private: @@ -358,7 +363,6 @@ private: decltype(&SoftwareGLContext::gl_stencil_op_separate), decltype(&SoftwareGLContext::gl_normal), decltype(&SoftwareGLContext::gl_raster_pos), - decltype(&SoftwareGLContext::gl_materialv), decltype(&SoftwareGLContext::gl_line_width), decltype(&SoftwareGLContext::gl_push_attrib), decltype(&SoftwareGLContext::gl_pop_attrib), @@ -372,7 +376,9 @@ private: decltype(&SoftwareGLContext::gl_fogfv), decltype(&SoftwareGLContext::gl_fogi), decltype(&SoftwareGLContext::gl_lightf), - decltype(&SoftwareGLContext::gl_lightfv)>; + decltype(&SoftwareGLContext::gl_lightfv), + decltype(&SoftwareGLContext::gl_materialf), + decltype(&SoftwareGLContext::gl_materialfv)>; using ExtraSavedArguments = Variant< FloatMatrix4x4>; @@ -428,6 +434,7 @@ private: GLfloat m_light_model_two_side { 0.0f }; Vector m_light_states; + Array m_material_states; }; } diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index e20b3b819f..99ab79913a 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -1009,4 +1009,9 @@ void Device::set_light_state(unsigned int light_id, Light const& light) m_lights.at(light_id) = light; } +void Device::set_material_state(unsigned int material_id, Material const& material) +{ + m_materials.at(material_id) = material; +} + } diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index 23e1b4a5ec..1b78aba6a6 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ public: void set_sampler_config(unsigned, SamplerConfig const&); void set_light_state(unsigned, Light const&); + void set_material_state(unsigned, Material const&); private: void draw_statistics_overlay(Gfx::Bitmap&); @@ -115,6 +117,7 @@ private: Vector m_enabled_texture_units; AlphaBlendFactors m_alpha_blend_factors; Array m_lights; + Array m_materials; }; } diff --git a/Userland/Libraries/LibSoftGPU/Light/Material.h b/Userland/Libraries/LibSoftGPU/Light/Material.h new file mode 100644 index 0000000000..fc8a313ca0 --- /dev/null +++ b/Userland/Libraries/LibSoftGPU/Light/Material.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022, Jesse Buhagiar + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace SoftGPU { + +struct Material { + Vector4 ambient { 0.2f, 0.2f, 0.2f, 1.0f }; + Vector4 diffuse { 0.8f, 0.8f, 0.8f, 1.0f }; + Vector4 specular { 0.0f, 0.0f, 0.0f, 1.0f }; + Vector4 emissive { 0.0f, 0.0f, 0.0f, 1.0f }; + float shininess { 0.0f }; + float specular_exponent { 0.0f }; + float ambient_color_index { 0.0f }; + float diffuse_color_index = { 1.0f }; + float specular_color_index = { 1.0f }; +}; + +}