From 474f9e9c69a82c5885225b07cedbca2dc78f3c7b Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Sun, 1 Jan 2023 22:41:31 +0100 Subject: [PATCH] LibGL: Implement `GL_TEXTURE_ENV_COLOR` This sets a constant color in the texture's environment for the fixed function pipeline. --- Tests/LibGL/TestRender.cpp | 20 +++++++++++ ...11_tex_env_combine_with_constant_color.qoi | Bin 0 -> 93 bytes Userland/Libraries/LibGL/GL/gl.h | 3 +- Userland/Libraries/LibGL/GLAPI.json | 27 ++++++++++++--- Userland/Libraries/LibGL/GLContext.h | 4 ++- Userland/Libraries/LibGL/Tex/TextureUnit.h | 3 ++ Userland/Libraries/LibGL/Texture.cpp | 31 ++++++++++++++++-- Userland/Libraries/LibGPU/SamplerConfig.h | 1 - 8 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 Tests/LibGL/reference-images/0011_tex_env_combine_with_constant_color.qoi diff --git a/Tests/LibGL/TestRender.cpp b/Tests/LibGL/TestRender.cpp index edd0c162ea..12193ee2c3 100644 --- a/Tests/LibGL/TestRender.cpp +++ b/Tests/LibGL/TestRender.cpp @@ -299,3 +299,23 @@ TEST_CASE(0010_test_store_data_in_buffer) context->present(); expect_bitmap_equals_reference(context->frontbuffer(), "0010_test_store_data_in_buffer"sv); } + +TEST_CASE(0011_tex_env_combine_with_constant_color) +{ + auto context = create_testing_context(64, 64); + + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); + + float color[4] = { .3f, .5f, .7f, 1.f }; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); + + glRecti(-1, -1, 1, 1); + + EXPECT_EQ(glGetError(), 0u); + + context->present(); + expect_bitmap_equals_reference(context->frontbuffer(), "0011_tex_env_combine_with_constant_color"sv); +} diff --git a/Tests/LibGL/reference-images/0011_tex_env_combine_with_constant_color.qoi b/Tests/LibGL/reference-images/0011_tex_env_combine_with_constant_color.qoi new file mode 100644 index 0000000000000000000000000000000000000000..493fe29130099c5df2d1306489170a044bbe5459 GIT binary patch literal 93 fcmXTS&rD-rU~m9o7KVR5^_%`u3=RPe0|7<=Vg5#} literal 0 HcmV?d00001 diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h index 008f88e620..6c816da59f 100644 --- a/Userland/Libraries/LibGL/GL/gl.h +++ b/Userland/Libraries/LibGL/GL/gl.h @@ -496,8 +496,9 @@ extern "C" { #define GL_ADD 0x0104 #define GL_ALPHA_SCALE 0x0D1C #define GL_MODULATE 0x2100 -#define GL_TEXTURE_ENV_MODE 0x2200 #define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 #define GL_TEXTURE_ENV 0x2300 #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 diff --git a/Userland/Libraries/LibGL/GLAPI.json b/Userland/Libraries/LibGL/GLAPI.json index 82c812512c..90d90faf27 100644 --- a/Userland/Libraries/LibGL/GLAPI.json +++ b/Userland/Libraries/LibGL/GLAPI.json @@ -978,18 +978,35 @@ "arguments": [ {"type": "GLenum", "name": "target"}, {"type": "GLenum", "name": "pname"}, - {"name": "param", "cast_to": "GLfloat"} + {"name": "param"}, + {"type": "GLenum", "expression": "@variant_gl_type@"} ], + "implementation": "tex_envv", "variants": { + "argument_counts": [1], "pointer_argument": "params", "types": { - "f": {}, - "fv": {"unimplemented": true}, - "i": {}, - "iv": {"unimplemented": true} + "fv": {}, + "iv": {} } } }, + "TexEnvf": { + "arguments": [ + {"type": "GLenum", "name": "target"}, + {"type": "GLenum", "name": "pname"}, + {"type": "GLfloat", "name": "x", "expression": "{@argument_name@, 0.f, 0.f, 0.f}"} + ], + "implementation": "tex_env" + }, + "TexEnvi": { + "arguments": [ + {"type": "GLenum", "name": "target"}, + {"type": "GLenum", "name": "pname"}, + {"type": "GLint", "name": "x", "expression": "{static_cast(@argument_name@), 0.f, 0.f, 0.f}"} + ], + "implementation": "tex_env" + }, "TexGen": { "arguments": [ {"type": "GLenum", "name": "coord"}, diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 1808a6bc4f..5fefd2678f 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -159,7 +159,8 @@ public: void gl_tex_parameterfv(GLenum target, GLenum pname, GLfloat const* params); void gl_tex_coord(GLfloat s, GLfloat t, GLfloat r, GLfloat q); void gl_multi_tex_coord(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); - void gl_tex_env(GLenum target, GLenum pname, GLfloat param); + void gl_tex_env(GLenum target, GLenum pname, FloatVector4 params); + void gl_tex_envv(GLenum target, GLenum pname, void const* params, GLenum type); void gl_bind_texture(GLenum target, GLuint texture); GLboolean gl_is_texture(GLuint texture); void gl_active_texture(GLenum texture); @@ -487,6 +488,7 @@ private: decltype(&GLContext::gl_bitmap), decltype(&GLContext::gl_copy_tex_image_2d), decltype(&GLContext::gl_rect), + decltype(&GLContext::gl_tex_env), decltype(&GLContext::gl_tex_gen), decltype(&GLContext::gl_tex_gen_floatv), decltype(&GLContext::gl_fogf), diff --git a/Userland/Libraries/LibGL/Tex/TextureUnit.h b/Userland/Libraries/LibGL/Tex/TextureUnit.h index e1782e4447..dba911a9c8 100644 --- a/Userland/Libraries/LibGL/Tex/TextureUnit.h +++ b/Userland/Libraries/LibGL/Tex/TextureUnit.h @@ -29,6 +29,8 @@ public: float alpha_scale() const { return m_alpha_scale; } void set_alpha_source(size_t index, GLenum source) { m_alpha_source[index] = source; } GLenum alpha_source(size_t index) const { return m_alpha_source[index]; } + void set_color(FloatVector4 color) { m_color = color; } + FloatVector4 color() const { return m_color; } void set_env_mode(GLenum mode) { m_env_mode = mode; } GLenum env_mode() const { return m_env_mode; } void set_level_of_detail_bias(float bias) { m_level_of_detail_bias = bias; } @@ -59,6 +61,7 @@ private: Array m_alpha_operand { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }; float m_alpha_scale { 1.f }; Array m_alpha_source { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }; + FloatVector4 m_color { 0.f, 0.f, 0.f, 0.f }; GLenum m_env_mode { GL_MODULATE }; float m_level_of_detail_bias { 0.f }; GLenum m_rgb_combinator { GL_MODULATE }; diff --git a/Userland/Libraries/LibGL/Texture.cpp b/Userland/Libraries/LibGL/Texture.cpp index 880cf2cd42..48177f2c2e 100644 --- a/Userland/Libraries/LibGL/Texture.cpp +++ b/Userland/Libraries/LibGL/Texture.cpp @@ -305,14 +305,15 @@ void GLContext::gl_tex_coord(GLfloat s, GLfloat t, GLfloat r, GLfloat q) m_current_vertex_tex_coord[0] = { s, t, r, q }; } -void GLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param) +void GLContext::gl_tex_env(GLenum target, GLenum pname, FloatVector4 params) { - APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_tex_env, target, pname, param); + APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_tex_env, target, pname, params); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); RETURN_WITH_ERROR_IF(target != GL_TEXTURE_ENV && target != GL_TEXTURE_FILTER_CONTROL, GL_INVALID_ENUM); RETURN_WITH_ERROR_IF(target == GL_TEXTURE_FILTER_CONTROL && pname != GL_TEXTURE_LOD_BIAS, GL_INVALID_ENUM); + auto const param = params[0]; switch (target) { case GL_TEXTURE_ENV: switch (pname) { @@ -422,6 +423,9 @@ void GLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param) } break; } + case GL_TEXTURE_ENV_COLOR: + m_active_texture_unit->set_color(params); + break; case GL_TEXTURE_ENV_MODE: { auto param_enum = static_cast(param); switch (param_enum) { @@ -458,6 +462,28 @@ void GLContext::gl_tex_env(GLenum target, GLenum pname, GLfloat param) m_sampler_config_is_dirty = true; } +void GLContext::gl_tex_envv(GLenum target, GLenum pname, void const* params, GLenum type) +{ + VERIFY(type == GL_FLOAT || type == GL_INT); + + auto parameters_to_vector = [&](T const* params) -> FloatVector4 { + auto parameters = (target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_COLOR) + ? Vector4 { params[0], params[1], params[2], params[3] } + : Vector4 { params[0], 0, 0, 0 }; + return parameters.template to_type(); + }; + + auto tex_env_parameters = (type == GL_FLOAT) + ? parameters_to_vector(reinterpret_cast(params)) + : parameters_to_vector(reinterpret_cast(params)); + + // Normalize integers to -1..1 + if (target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_COLOR && type == GL_INT) + tex_env_parameters = (tex_env_parameters + 2147483648.f) / 2147483647.5f - 1.f; + + gl_tex_env(target, pname, tex_env_parameters); +} + void GLContext::gl_tex_gen(GLenum coord, GLenum pname, GLint param) { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_tex_gen, coord, pname, param); @@ -822,6 +848,7 @@ void GLContext::sync_device_sampler_config() } auto& fixed_function_env = config.fixed_function_texture_environment; + fixed_function_env.color = texture_unit.color(); auto get_env_mode = [](GLenum mode) { switch (mode) { diff --git a/Userland/Libraries/LibGPU/SamplerConfig.h b/Userland/Libraries/LibGPU/SamplerConfig.h index 898bdfb3b0..d842a229ae 100644 --- a/Userland/Libraries/LibGPU/SamplerConfig.h +++ b/Userland/Libraries/LibGPU/SamplerConfig.h @@ -73,7 +73,6 @@ struct FixedFunctionTextureEnvironment final { float alpha_scale { 1.f }; Array alpha_source { TextureSource::Texture, TextureSource::Previous, TextureSource::Constant }; u8 alpha_source_texture_stage { 0 }; - // FIXME: color is never actually updated FloatVector4 color { 0.f, 0.f, 0.f, 0.f }; TextureEnvMode env_mode { TextureEnvMode::Modulate }; TextureCombinator rgb_combinator { TextureCombinator::Modulate };