diff options
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 30 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareRasterizer.cpp | 19 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareRasterizer.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/TextureUnit.h | 10 |
5 files changed, 38 insertions, 27 deletions
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index c6b2b5ff1e..c26e462d82 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -312,13 +312,7 @@ void SoftwareGLContext::gl_end() continue; } - // FIXME: Change this when we have texture units/multi-texturing - if (m_bound_texture_2d == 0) { - m_rasterizer.submit_triangle(triangle); - } else { - auto it = m_allocated_textures.find(m_bound_texture_2d); - m_rasterizer.submit_triangle(triangle, *static_ptr_cast<Texture2D>(it->value)); - } + m_rasterizer.submit_triangle(triangle, m_texture_units); } triangle_list.clear(); @@ -686,9 +680,15 @@ void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures) for (auto i = 0; i < n; i++) { GLuint name = textures[i]; - // unbind texture if it is currently bound - if (m_bound_texture_2d == name) - m_bound_texture_2d = 0; + auto texture_object = m_allocated_textures.find(name); + if (texture_object == m_allocated_textures.end() || texture_object->value.is_null()) + continue; + + // Check all texture units + for (auto& texture_unit : m_texture_units) { + if (texture_object->value == texture_unit.bound_texture()) + texture_unit.unbind_texture(GL_TEXTURE_2D); + } m_allocated_textures.remove(name); } @@ -702,7 +702,7 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern RETURN_WITH_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM); // Check if there is actually a texture bound - RETURN_WITH_ERROR_IF(target == GL_TEXTURE_2D && m_bound_texture_2d == 0, GL_INVALID_OPERATION); + RETURN_WITH_ERROR_IF(target == GL_TEXTURE_2D && m_active_texture_unit->currently_bound_target() != GL_TEXTURE_2D, GL_INVALID_OPERATION); // We only support symbolic constants for now RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA), GL_INVALID_ENUM); @@ -712,9 +712,7 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern RETURN_WITH_ERROR_IF((width & 2) != 0 || (height & 2) != 0, GL_INVALID_VALUE); RETURN_WITH_ERROR_IF(border < 0 || border > 1, GL_INVALID_VALUE); - // TODO: Load texture from the currently active texture unit - // This is to test the functionality of texture data upload - static_ptr_cast<Texture2D>(m_allocated_textures.find(1)->value)->upload_texture_data(target, level, internal_format, width, height, border, format, type, data); + m_active_texture_unit->bound_texture_2d()->upload_texture_data(target, level, internal_format, width, height, border, format, type, data); } void SoftwareGLContext::gl_front_face(GLenum face) @@ -1246,7 +1244,7 @@ void SoftwareGLContext::gl_bind_texture(GLenum target, GLuint texture) if (texture == 0) { switch (target) { case GL_TEXTURE_2D: - m_bound_texture_2d = 0; + m_active_texture_unit->unbind_texture(target); return; default: VERIFY_NOT_REACHED(); @@ -1281,7 +1279,7 @@ void SoftwareGLContext::gl_bind_texture(GLenum target, GLuint texture) switch (target) { case GL_TEXTURE_2D: - m_bound_texture_2d = texture; + m_active_texture_unit->bind_texture_to_target(target, texture_object); break; } } diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 9d207becd7..40ab70c0ed 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -131,8 +131,6 @@ private: GLenum m_current_read_buffer = GL_BACK; - GLuint m_bound_texture_2d = 0; - NonnullRefPtr<Gfx::Bitmap> m_frontbuffer; Clipper m_clipper; diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp index d9b57f4da4..41f4a48b1b 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp @@ -421,13 +421,24 @@ void SoftwareRasterizer::submit_triangle(const GLTriangle& triangle) }); } -void SoftwareRasterizer::submit_triangle(const GLTriangle& triangle, const Texture2D& texture) +void SoftwareRasterizer::submit_triangle(const GLTriangle& triangle, const Array<TextureUnit, 32>& texture_units) { - rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [&texture](const FloatVector2& uv, const FloatVector4& color) -> FloatVector4 { + rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [&texture_units](const FloatVector2& uv, const FloatVector4& color) -> FloatVector4 { // TODO: We'd do some kind of multitexturing/blending here // Construct a vector for the texel we want to sample - FloatVector4 texel = texture.sample_texel(uv); - return texel * color; + FloatVector4 texel = color; + + for (const auto& texture_unit : texture_units) { + + // No texture is bound to this texture unit + if (!texture_unit.is_bound()) + continue; + + // FIXME: Don't assume Texture2D, _and_ work out how we blend/do multitexturing properly..... + texel = texel * static_ptr_cast<Texture2D>(texture_unit.bound_texture())->sample_texel(uv); + } + + return texel; }); } diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.h b/Userland/Libraries/LibGL/SoftwareRasterizer.h index c7bd803276..19f7ce1c84 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.h +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.h @@ -10,6 +10,8 @@ #include "GL/gl.h" #include "GLStruct.h" #include "Tex/Texture2D.h" +#include "Tex/TextureUnit.h" +#include <AK/Array.h> #include <AK/OwnPtr.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Vector4.h> @@ -31,7 +33,7 @@ class SoftwareRasterizer final { public: SoftwareRasterizer(const Gfx::IntSize& min_size); - void submit_triangle(const GLTriangle& triangle, const Texture2D& texture); + void submit_triangle(const GLTriangle& triangle, const Array<TextureUnit, 32>& texture_units); void submit_triangle(const GLTriangle& triangle); void resize(const Gfx::IntSize& min_size); void clear_color(const FloatVector4&); diff --git a/Userland/Libraries/LibGL/Tex/TextureUnit.h b/Userland/Libraries/LibGL/Tex/TextureUnit.h index df760cf48f..d54341d194 100644 --- a/Userland/Libraries/LibGL/Tex/TextureUnit.h +++ b/Userland/Libraries/LibGL/Tex/TextureUnit.h @@ -17,14 +17,16 @@ public: void bind_texture_to_target(GLenum texture_target, const RefPtr<Texture>& texture); void unbind_texture(GLenum texture_target); - const RefPtr<Texture>& get_bound_texture() const { return m_currently_bound_texture; } + + RefPtr<Texture2D>& bound_texture_2d() const { return m_texture_target_2d; } + RefPtr<Texture>& bound_texture() const { return m_currently_bound_texture; } GLenum currently_bound_target() const { return m_currently_bound_target; } - bool is_bound() const { return m_currently_bound_texture != nullptr; } + bool is_bound() const { return !m_currently_bound_texture.is_null(); } private: - RefPtr<Texture2D> m_texture_target_2d { nullptr }; - RefPtr<Texture> m_currently_bound_texture { nullptr }; + mutable RefPtr<Texture2D> m_texture_target_2d { nullptr }; + mutable RefPtr<Texture> m_currently_bound_texture { nullptr }; GLenum m_currently_bound_target; }; |