summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Buhagiar <jooster669@gmail.com>2021-05-30 21:39:31 +1000
committerLinus Groh <mail@linusgroh.de>2021-05-31 14:59:47 +0100
commit8298e406a45945bbd894de005b14fac8f936ae3c (patch)
tree5ab76fc0069319f63931035965ae2fca11a7a351
parent573c1c82f7ea47a33f2899a94a4594e55a3121cc (diff)
downloadserenity-8298e406a45945bbd894de005b14fac8f936ae3c.zip
LibGL: Use Texture Units in Rasterizer and Context
The Context and Software Rasterizer now gets the array of texture units instead of a single texture object. _Technically_, we now support some primitive form of multi-texturing, though I'm not entirely sure how well it will work in its current state.
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp30
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h2
-rw-r--r--Userland/Libraries/LibGL/SoftwareRasterizer.cpp19
-rw-r--r--Userland/Libraries/LibGL/SoftwareRasterizer.h4
-rw-r--r--Userland/Libraries/LibGL/Tex/TextureUnit.h10
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;
};