mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 15:17:36 +00:00
LibGL+LibGPU+LibSoftGPU: Implement matrix stack per texture unit
Each texture unit now has its own texture transformation matrix stack. Introduce a new texture unit configuration that is synced when changed. Because we're no longer passing a silly `Vector` when drawing each primitive, this results in a slightly improved frames per second :^)
This commit is contained in:
parent
1540c56e6c
commit
00d46e5d77
22 changed files with 208 additions and 152 deletions
|
@ -22,7 +22,7 @@ void GLContext::gl_clip_plane(GLenum plane, GLdouble const* equation)
|
|||
auto plane_idx = static_cast<size_t>(plane) - GL_CLIP_PLANE0;
|
||||
|
||||
auto eqn = FloatVector4(equation[0], equation[1], equation[2], equation[3]);
|
||||
m_clip_plane_attributes.eye_clip_plane[plane_idx] = m_model_view_matrix * eqn;
|
||||
m_clip_plane_attributes.eye_clip_plane[plane_idx] = model_view_matrix() * eqn;
|
||||
m_clip_planes_dirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,25 +276,29 @@ void GLContext::gl_disable(GLenum capability)
|
|||
case GL_TEXTURE_1D:
|
||||
m_active_texture_unit->set_texture_1d_enabled(false);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
m_active_texture_unit->set_texture_2d_enabled(false);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
m_active_texture_unit->set_texture_3d_enabled(false);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
m_active_texture_unit->set_texture_cube_map_enabled(false);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_GEN_Q:
|
||||
case GL_TEXTURE_GEN_R:
|
||||
case GL_TEXTURE_GEN_S:
|
||||
case GL_TEXTURE_GEN_T:
|
||||
texture_coordinate_generation(m_active_texture_unit_index, capability).enabled = false;
|
||||
m_texcoord_generation_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
default:
|
||||
dbgln_if(GL_DEBUG, "gl_disable({:#x}): unknown parameter", capability);
|
||||
|
@ -426,25 +430,29 @@ void GLContext::gl_enable(GLenum capability)
|
|||
case GL_TEXTURE_1D:
|
||||
m_active_texture_unit->set_texture_1d_enabled(true);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
m_active_texture_unit->set_texture_2d_enabled(true);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
m_active_texture_unit->set_texture_3d_enabled(true);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
m_active_texture_unit->set_texture_cube_map_enabled(true);
|
||||
m_sampler_config_is_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
case GL_TEXTURE_GEN_Q:
|
||||
case GL_TEXTURE_GEN_R:
|
||||
case GL_TEXTURE_GEN_S:
|
||||
case GL_TEXTURE_GEN_T:
|
||||
texture_coordinate_generation(m_active_texture_unit_index, capability).enabled = true;
|
||||
m_texcoord_generation_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
break;
|
||||
default:
|
||||
dbgln_if(GL_DEBUG, "gl_enable({:#x}): unknown parameter", capability);
|
||||
|
@ -522,10 +530,10 @@ void GLContext::get_floating_point(GLenum pname, T* params)
|
|||
};
|
||||
switch (pname) {
|
||||
case GL_MODELVIEW_MATRIX:
|
||||
flatten_and_assign_matrix(m_model_view_matrix);
|
||||
flatten_and_assign_matrix(model_view_matrix());
|
||||
return;
|
||||
case GL_PROJECTION_MATRIX:
|
||||
flatten_and_assign_matrix(m_projection_matrix);
|
||||
flatten_and_assign_matrix(projection_matrix());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,14 +59,14 @@ GLContext::GLContext(RefPtr<GPU::Driver> driver, NonnullOwnPtr<GPU::Device> devi
|
|||
// coordinate generation config.
|
||||
m_texture_coordinate_generation.resize(m_device_info.num_texture_units);
|
||||
for (auto& texture_coordinate_generation : m_texture_coordinate_generation) {
|
||||
texture_coordinate_generation[0].object_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[0].eye_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[1].object_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[1].eye_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[2].object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[2].eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[3].object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[3].eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
texture_coordinate_generation[0].object_plane_coefficients = { 1.f, 0.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[0].eye_plane_coefficients = { 1.f, 0.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[1].object_plane_coefficients = { 0.f, 1.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[1].eye_plane_coefficients = { 0.f, 1.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[2].object_plane_coefficients = { 0.f, 0.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[2].eye_plane_coefficients = { 0.f, 0.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[3].object_plane_coefficients = { 0.f, 0.f, 0.f, 0.f };
|
||||
texture_coordinate_generation[3].eye_plane_coefficients = { 0.f, 0.f, 0.f, 0.f };
|
||||
}
|
||||
|
||||
build_extension_string();
|
||||
|
@ -134,12 +134,6 @@ void GLContext::gl_end()
|
|||
RETURN_WITH_ERROR_IF(!m_in_draw_state, GL_INVALID_OPERATION);
|
||||
m_in_draw_state = false;
|
||||
|
||||
Vector<size_t, 32> enabled_texture_units;
|
||||
for (size_t i = 0; i < m_texture_units.size(); ++i) {
|
||||
if (m_texture_units[i].texture_2d_enabled())
|
||||
enabled_texture_units.append(i);
|
||||
}
|
||||
|
||||
sync_device_config();
|
||||
|
||||
GPU::PrimitiveType primitive_type;
|
||||
|
@ -174,7 +168,7 @@ void GLContext::gl_end()
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
m_rasterizer->draw_primitives(primitive_type, m_model_view_matrix, m_projection_matrix, m_texture_matrix, m_vertex_list, enabled_texture_units);
|
||||
m_rasterizer->draw_primitives(primitive_type, model_view_matrix(), projection_matrix(), m_vertex_list);
|
||||
m_vertex_list.clear_with_capacity();
|
||||
}
|
||||
|
||||
|
@ -832,7 +826,7 @@ void GLContext::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);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
m_rasterizer->set_raster_position({ x, y, z, w }, m_model_view_matrix, m_projection_matrix);
|
||||
m_rasterizer->set_raster_position({ x, y, z, w }, model_view_matrix(), projection_matrix());
|
||||
}
|
||||
|
||||
void GLContext::gl_line_width(GLfloat width)
|
||||
|
@ -913,7 +907,7 @@ void GLContext::present()
|
|||
void GLContext::sync_device_config()
|
||||
{
|
||||
sync_device_sampler_config();
|
||||
sync_device_texcoord_config();
|
||||
sync_device_texture_units();
|
||||
sync_light_state();
|
||||
sync_stencil_configuration();
|
||||
sync_clip_planes();
|
||||
|
|
|
@ -217,7 +217,7 @@ public:
|
|||
private:
|
||||
void sync_device_config();
|
||||
void sync_device_sampler_config();
|
||||
void sync_device_texcoord_config();
|
||||
void sync_device_texture_units();
|
||||
void sync_light_state();
|
||||
void sync_stencil_configuration();
|
||||
void sync_clip_planes();
|
||||
|
@ -256,16 +256,22 @@ private:
|
|||
|
||||
GLenum m_current_draw_mode;
|
||||
GLenum m_current_matrix_mode { GL_MODELVIEW };
|
||||
FloatMatrix4x4 m_projection_matrix { FloatMatrix4x4::identity() };
|
||||
FloatMatrix4x4 m_model_view_matrix { FloatMatrix4x4::identity() };
|
||||
FloatMatrix4x4 m_texture_matrix { FloatMatrix4x4::identity() };
|
||||
FloatMatrix4x4* m_current_matrix { &m_model_view_matrix };
|
||||
|
||||
Vector<FloatMatrix4x4> m_projection_matrix_stack;
|
||||
Vector<FloatMatrix4x4> m_model_view_matrix_stack;
|
||||
// FIXME: implement multi-texturing: the texture matrix stack should live inside a texture unit
|
||||
Vector<FloatMatrix4x4> m_texture_matrix_stack;
|
||||
FloatMatrix4x4& projection_matrix() { return m_projection_matrix_stack.last(); }
|
||||
FloatMatrix4x4& model_view_matrix() { return m_model_view_matrix_stack.last(); }
|
||||
|
||||
Vector<FloatMatrix4x4> m_projection_matrix_stack { FloatMatrix4x4::identity() };
|
||||
Vector<FloatMatrix4x4> m_model_view_matrix_stack { FloatMatrix4x4::identity() };
|
||||
Vector<FloatMatrix4x4>* m_current_matrix_stack { &m_model_view_matrix_stack };
|
||||
FloatMatrix4x4* m_current_matrix { &m_current_matrix_stack->last() };
|
||||
|
||||
ALWAYS_INLINE void update_current_matrix(FloatMatrix4x4 const& new_matrix)
|
||||
{
|
||||
*m_current_matrix = new_matrix;
|
||||
|
||||
if (m_current_matrix_mode == GL_TEXTURE)
|
||||
m_texture_units_dirty = true;
|
||||
}
|
||||
|
||||
Gfx::IntRect m_viewport;
|
||||
|
||||
|
@ -353,6 +359,7 @@ private:
|
|||
Vector<TextureUnit> m_texture_units;
|
||||
TextureUnit* m_active_texture_unit;
|
||||
size_t m_active_texture_unit_index { 0 };
|
||||
bool m_texture_units_dirty { true };
|
||||
|
||||
// Texture coordinate generation state
|
||||
struct TextureCoordinateGeneration {
|
||||
|
@ -362,8 +369,6 @@ private:
|
|||
FloatVector4 eye_plane_coefficients { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
};
|
||||
Vector<Array<TextureCoordinateGeneration, 4>> m_texture_coordinate_generation;
|
||||
bool m_texcoord_generation_dirty { true };
|
||||
|
||||
ALWAYS_INLINE TextureCoordinateGeneration& texture_coordinate_generation(size_t texture_unit, GLenum capability)
|
||||
{
|
||||
return m_texture_coordinate_generation[texture_unit][capability - GL_TEXTURE_GEN_S];
|
||||
|
|
|
@ -249,7 +249,7 @@ void GLContext::gl_lightfv(GLenum light, GLenum pname, GLfloat const* params)
|
|||
break;
|
||||
case GL_POSITION:
|
||||
light_state.position = { params[0], params[1], params[2], params[3] };
|
||||
light_state.position = m_model_view_matrix * light_state.position;
|
||||
light_state.position = model_view_matrix() * light_state.position;
|
||||
break;
|
||||
case GL_CONSTANT_ATTENUATION:
|
||||
RETURN_WITH_ERROR_IF(params[0] < 0.f, GL_INVALID_VALUE);
|
||||
|
@ -277,7 +277,7 @@ void GLContext::gl_lightfv(GLenum light, GLenum pname, GLfloat const* params)
|
|||
}
|
||||
case GL_SPOT_DIRECTION: {
|
||||
FloatVector4 direction_vector = { params[0], params[1], params[2], 0.f };
|
||||
direction_vector = m_model_view_matrix * direction_vector;
|
||||
direction_vector = model_view_matrix() * direction_vector;
|
||||
light_state.spotlight_direction = direction_vector.xyz();
|
||||
break;
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ void GLContext::gl_lightiv(GLenum light, GLenum pname, GLint const* params)
|
|||
break;
|
||||
case GL_POSITION:
|
||||
light_state.position = to_float_vector(params[0], params[1], params[2], params[3]);
|
||||
light_state.position = m_model_view_matrix * light_state.position;
|
||||
light_state.position = model_view_matrix() * light_state.position;
|
||||
break;
|
||||
case GL_CONSTANT_ATTENUATION:
|
||||
RETURN_WITH_ERROR_IF(params[0] < 0, GL_INVALID_VALUE);
|
||||
|
@ -341,7 +341,7 @@ void GLContext::gl_lightiv(GLenum light, GLenum pname, GLint const* params)
|
|||
}
|
||||
case GL_SPOT_DIRECTION: {
|
||||
auto direction_vector = to_float_vector(params[0], params[1], params[2], 0.0f);
|
||||
direction_vector = m_model_view_matrix * direction_vector;
|
||||
direction_vector = model_view_matrix() * direction_vector;
|
||||
light_state.spotlight_direction = direction_vector.xyz();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ void GLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdou
|
|||
0, 0, c, d,
|
||||
0, 0, -1, 0
|
||||
};
|
||||
*m_current_matrix = *m_current_matrix * frustum;
|
||||
update_current_matrix(*m_current_matrix * frustum);
|
||||
}
|
||||
|
||||
void GLContext::gl_load_identity()
|
||||
|
@ -53,7 +53,7 @@ void GLContext::gl_load_identity()
|
|||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_load_identity);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
*m_current_matrix = FloatMatrix4x4::identity();
|
||||
update_current_matrix(FloatMatrix4x4::identity());
|
||||
}
|
||||
|
||||
void GLContext::gl_load_matrix(FloatMatrix4x4 const& matrix)
|
||||
|
@ -61,7 +61,7 @@ void GLContext::gl_load_matrix(FloatMatrix4x4 const& matrix)
|
|||
APPEND_TO_CALL_LIST_WITH_ARG_AND_RETURN_IF_NEEDED(gl_load_matrix, matrix);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
*m_current_matrix = matrix;
|
||||
update_current_matrix(matrix);
|
||||
}
|
||||
|
||||
void GLContext::gl_matrix_mode(GLenum mode)
|
||||
|
@ -73,20 +73,18 @@ void GLContext::gl_matrix_mode(GLenum mode)
|
|||
m_current_matrix_mode = mode;
|
||||
switch (mode) {
|
||||
case GL_MODELVIEW:
|
||||
m_current_matrix = &m_model_view_matrix;
|
||||
m_current_matrix_stack = &m_model_view_matrix_stack;
|
||||
break;
|
||||
case GL_PROJECTION:
|
||||
m_current_matrix = &m_projection_matrix;
|
||||
m_current_matrix_stack = &m_projection_matrix_stack;
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
m_current_matrix = &m_texture_matrix;
|
||||
m_current_matrix_stack = &m_texture_matrix_stack;
|
||||
m_current_matrix_stack = &m_active_texture_unit->texture_matrix_stack();
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
m_current_matrix = &m_current_matrix_stack->last();
|
||||
}
|
||||
|
||||
void GLContext::gl_mult_matrix(FloatMatrix4x4 const& matrix)
|
||||
|
@ -94,7 +92,7 @@ void GLContext::gl_mult_matrix(FloatMatrix4x4 const& matrix)
|
|||
APPEND_TO_CALL_LIST_WITH_ARG_AND_RETURN_IF_NEEDED(gl_mult_matrix, matrix);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
*m_current_matrix = *m_current_matrix * matrix;
|
||||
update_current_matrix(*m_current_matrix * matrix);
|
||||
}
|
||||
|
||||
void GLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)
|
||||
|
@ -117,25 +115,27 @@ void GLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdoubl
|
|||
0, 0, static_cast<float>(-2 / fn), static_cast<float>(tz),
|
||||
0, 0, 0, 1
|
||||
};
|
||||
*m_current_matrix = *m_current_matrix * projection;
|
||||
update_current_matrix(*m_current_matrix * projection);
|
||||
}
|
||||
|
||||
void GLContext::gl_pop_matrix()
|
||||
{
|
||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_pop_matrix);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
RETURN_WITH_ERROR_IF((*m_current_matrix_stack).is_empty(), GL_STACK_UNDERFLOW);
|
||||
RETURN_WITH_ERROR_IF(m_current_matrix_stack->size() <= 1, GL_STACK_UNDERFLOW);
|
||||
|
||||
*m_current_matrix = (*m_current_matrix_stack).take_last();
|
||||
m_current_matrix_stack->take_last();
|
||||
m_current_matrix = &m_current_matrix_stack->last();
|
||||
}
|
||||
|
||||
void GLContext::gl_push_matrix()
|
||||
{
|
||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_push_matrix);
|
||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
RETURN_WITH_ERROR_IF((*m_current_matrix_stack).size() >= matrix_stack_limit(m_current_matrix_mode), GL_STACK_OVERFLOW);
|
||||
RETURN_WITH_ERROR_IF(m_current_matrix_stack->size() >= matrix_stack_limit(m_current_matrix_mode), GL_STACK_OVERFLOW);
|
||||
|
||||
(*m_current_matrix_stack).append(*m_current_matrix);
|
||||
m_current_matrix_stack->append(*m_current_matrix);
|
||||
m_current_matrix = &m_current_matrix_stack->last();
|
||||
}
|
||||
|
||||
void GLContext::gl_rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
|
||||
|
@ -147,7 +147,7 @@ void GLContext::gl_rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
|
|||
if (axis.length() > 0.f)
|
||||
axis.normalize();
|
||||
auto rotation_mat = Gfx::rotation_matrix(axis, angle * static_cast<float>(M_PI * 2 / 360));
|
||||
*m_current_matrix = *m_current_matrix * rotation_mat;
|
||||
update_current_matrix(*m_current_matrix * rotation_mat);
|
||||
}
|
||||
|
||||
void GLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z)
|
||||
|
@ -156,7 +156,7 @@ void GLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z)
|
|||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
auto scale_matrix = Gfx::scale_matrix(FloatVector3 { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) });
|
||||
*m_current_matrix = *m_current_matrix * scale_matrix;
|
||||
update_current_matrix(*m_current_matrix * scale_matrix);
|
||||
}
|
||||
|
||||
void GLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z)
|
||||
|
@ -165,7 +165,7 @@ void GLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z)
|
|||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||
|
||||
auto translation_matrix = Gfx::translation_matrix(FloatVector3 { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) });
|
||||
*m_current_matrix = *m_current_matrix * translation_matrix;
|
||||
update_current_matrix(*m_current_matrix * translation_matrix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGL/Tex/Texture2D.h>
|
||||
#include <LibGfx/Matrix4x4.h>
|
||||
|
||||
namespace GL {
|
||||
|
||||
|
@ -49,6 +51,9 @@ public:
|
|||
bool texture_cube_map_enabled() const { return m_texture_cube_map_enabled; };
|
||||
void set_texture_cube_map_enabled(bool texture_cube_map_enabled) { m_texture_cube_map_enabled = texture_cube_map_enabled; }
|
||||
|
||||
FloatMatrix4x4& texture_matrix() { return m_texture_matrix_stack.last(); }
|
||||
Vector<FloatMatrix4x4>& texture_matrix_stack() { return m_texture_matrix_stack; }
|
||||
|
||||
private:
|
||||
GLenum m_alpha_combinator { GL_MODULATE };
|
||||
Array<GLenum, 3> m_alpha_operand { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA };
|
||||
|
@ -69,6 +74,9 @@ private:
|
|||
bool m_texture_2d_enabled { false };
|
||||
bool m_texture_3d_enabled { false };
|
||||
bool m_texture_cube_map_enabled { false };
|
||||
|
||||
// Matrix stack for this unit
|
||||
Vector<FloatMatrix4x4> m_texture_matrix_stack { FloatMatrix4x4::identity() };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@ void GLContext::gl_active_texture(GLenum texture)
|
|||
|
||||
m_active_texture_unit_index = texture - GL_TEXTURE0;
|
||||
m_active_texture_unit = &m_texture_units.at(m_active_texture_unit_index);
|
||||
|
||||
if (m_current_matrix_mode == GL_TEXTURE) {
|
||||
m_current_matrix_stack = &m_active_texture_unit->texture_matrix_stack();
|
||||
m_current_matrix = &m_current_matrix_stack->last();
|
||||
}
|
||||
}
|
||||
|
||||
void GLContext::gl_bind_texture(GLenum target, GLuint texture)
|
||||
|
@ -471,7 +476,7 @@ void GLContext::gl_tex_gen(GLenum coord, GLenum pname, GLint param)
|
|||
|
||||
GLenum const capability = GL_TEXTURE_GEN_S + (coord - GL_S);
|
||||
texture_coordinate_generation(m_active_texture_unit_index, capability).generation_mode = param;
|
||||
m_texcoord_generation_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
}
|
||||
|
||||
void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params)
|
||||
|
@ -506,7 +511,7 @@ void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* par
|
|||
texture_coordinate_generation(m_active_texture_unit_index, capability).object_plane_coefficients = { params[0], params[1], params[2], params[3] };
|
||||
break;
|
||||
case GL_EYE_PLANE: {
|
||||
auto const& inverse_model_view = m_model_view_matrix.inverse();
|
||||
auto const& inverse_model_view = model_view_matrix().inverse();
|
||||
auto input_coefficients = FloatVector4 { params[0], params[1], params[2], params[3] };
|
||||
|
||||
// Note: we are allowed to store transformed coefficients here, according to the documentation on
|
||||
|
@ -522,7 +527,7 @@ void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* par
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
m_texcoord_generation_dirty = true;
|
||||
m_texture_units_dirty = true;
|
||||
}
|
||||
|
||||
void GLContext::gl_tex_image_2d(GLenum target, GLint level, GLint internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid const* data)
|
||||
|
@ -909,39 +914,41 @@ void GLContext::sync_device_sampler_config()
|
|||
}
|
||||
}
|
||||
|
||||
void GLContext::sync_device_texcoord_config()
|
||||
void GLContext::sync_device_texture_units()
|
||||
{
|
||||
if (!m_texcoord_generation_dirty)
|
||||
if (!m_texture_units_dirty)
|
||||
return;
|
||||
m_texcoord_generation_dirty = false;
|
||||
m_texture_units_dirty = false;
|
||||
|
||||
auto options = m_rasterizer->options();
|
||||
|
||||
for (size_t i = 0; i < m_device_info.num_texture_units; ++i) {
|
||||
for (GPU::TextureUnitIndex i = 0; i < m_device_info.num_texture_units; ++i) {
|
||||
GPU::TextureUnitConfiguration texture_unit_configuration;
|
||||
texture_unit_configuration.enabled = m_texture_units[i].texture_2d_enabled();
|
||||
texture_unit_configuration.transformation_matrix = m_texture_units[i].texture_matrix();
|
||||
|
||||
// Tex coord generation
|
||||
u8 enabled_coordinates = GPU::TexCoordGenerationCoordinate::None;
|
||||
for (GLenum capability = GL_TEXTURE_GEN_S; capability <= GL_TEXTURE_GEN_Q; ++capability) {
|
||||
auto const context_coordinate_config = texture_coordinate_generation(i, capability);
|
||||
if (!context_coordinate_config.enabled)
|
||||
continue;
|
||||
|
||||
GPU::TexCoordGenerationConfig* texcoord_generation_config;
|
||||
GPU::TexCoordGeneration* texcoord_generation;
|
||||
switch (capability) {
|
||||
case GL_TEXTURE_GEN_S:
|
||||
enabled_coordinates |= GPU::TexCoordGenerationCoordinate::S;
|
||||
texcoord_generation_config = &options.texcoord_generation_config[i][0];
|
||||
texcoord_generation = &texture_unit_configuration.tex_coord_generation[0];
|
||||
break;
|
||||
case GL_TEXTURE_GEN_T:
|
||||
enabled_coordinates |= GPU::TexCoordGenerationCoordinate::T;
|
||||
texcoord_generation_config = &options.texcoord_generation_config[i][1];
|
||||
texcoord_generation = &texture_unit_configuration.tex_coord_generation[1];
|
||||
break;
|
||||
case GL_TEXTURE_GEN_R:
|
||||
enabled_coordinates |= GPU::TexCoordGenerationCoordinate::R;
|
||||
texcoord_generation_config = &options.texcoord_generation_config[i][2];
|
||||
texcoord_generation = &texture_unit_configuration.tex_coord_generation[2];
|
||||
break;
|
||||
case GL_TEXTURE_GEN_Q:
|
||||
enabled_coordinates |= GPU::TexCoordGenerationCoordinate::Q;
|
||||
texcoord_generation_config = &options.texcoord_generation_config[i][3];
|
||||
texcoord_generation = &texture_unit_configuration.tex_coord_generation[3];
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -949,28 +956,30 @@ void GLContext::sync_device_texcoord_config()
|
|||
|
||||
switch (context_coordinate_config.generation_mode) {
|
||||
case GL_OBJECT_LINEAR:
|
||||
texcoord_generation_config->mode = GPU::TexCoordGenerationMode::ObjectLinear;
|
||||
texcoord_generation_config->coefficients = context_coordinate_config.object_plane_coefficients;
|
||||
texcoord_generation->mode = GPU::TexCoordGenerationMode::ObjectLinear;
|
||||
texcoord_generation->coefficients = context_coordinate_config.object_plane_coefficients;
|
||||
break;
|
||||
case GL_EYE_LINEAR:
|
||||
texcoord_generation_config->mode = GPU::TexCoordGenerationMode::EyeLinear;
|
||||
texcoord_generation_config->coefficients = context_coordinate_config.eye_plane_coefficients;
|
||||
texcoord_generation->mode = GPU::TexCoordGenerationMode::EyeLinear;
|
||||
texcoord_generation->coefficients = context_coordinate_config.eye_plane_coefficients;
|
||||
break;
|
||||
case GL_SPHERE_MAP:
|
||||
texcoord_generation_config->mode = GPU::TexCoordGenerationMode::SphereMap;
|
||||
texcoord_generation->mode = GPU::TexCoordGenerationMode::SphereMap;
|
||||
break;
|
||||
case GL_REFLECTION_MAP:
|
||||
texcoord_generation_config->mode = GPU::TexCoordGenerationMode::ReflectionMap;
|
||||
texcoord_generation->mode = GPU::TexCoordGenerationMode::ReflectionMap;
|
||||
break;
|
||||
case GL_NORMAL_MAP:
|
||||
texcoord_generation_config->mode = GPU::TexCoordGenerationMode::NormalMap;
|
||||
texcoord_generation->mode = GPU::TexCoordGenerationMode::NormalMap;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
options.texcoord_generation_enabled_coordinates[i] = enabled_coordinates;
|
||||
texture_unit_configuration.tex_coord_generation_enabled = enabled_coordinates;
|
||||
|
||||
m_rasterizer->set_texture_unit_configuration(i, texture_unit_configuration);
|
||||
}
|
||||
|
||||
m_rasterizer->set_options(options);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue