mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:57:44 +00:00
LibGL+LibSoftGPU: Implement viewport support
This implements the `glViewport` API call, the coordinate transformation and the `GL_VIEWPORT` context parameter.
This commit is contained in:
parent
d236b0ed12
commit
29bbf56286
4 changed files with 33 additions and 13 deletions
|
@ -56,7 +56,8 @@ static constexpr size_t TEXTURE_MATRIX_STACK_LIMIT = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareGLContext::SoftwareGLContext(Gfx::Bitmap& frontbuffer)
|
SoftwareGLContext::SoftwareGLContext(Gfx::Bitmap& frontbuffer)
|
||||||
: m_frontbuffer(frontbuffer)
|
: m_viewport(frontbuffer.rect())
|
||||||
|
, m_frontbuffer(frontbuffer)
|
||||||
, m_rasterizer(frontbuffer.size())
|
, m_rasterizer(frontbuffer.size())
|
||||||
, m_device_info(m_rasterizer.info())
|
, m_device_info(m_rasterizer.info())
|
||||||
{
|
{
|
||||||
|
@ -159,6 +160,18 @@ Optional<ContextParameter> SoftwareGLContext::get_context_parameter(GLenum name)
|
||||||
return ContextParameter { .type = GL_INT, .value = { .integer_value = 0 } };
|
return ContextParameter { .type = GL_INT, .value = { .integer_value = 0 } };
|
||||||
case GL_UNPACK_SWAP_BYTES:
|
case GL_UNPACK_SWAP_BYTES:
|
||||||
return ContextParameter { .type = GL_BOOL, .value = { .boolean_value = false } };
|
return ContextParameter { .type = GL_BOOL, .value = { .boolean_value = false } };
|
||||||
|
case GL_VIEWPORT:
|
||||||
|
return ContextParameter {
|
||||||
|
.type = GL_INT,
|
||||||
|
.count = 4,
|
||||||
|
.value = {
|
||||||
|
.integer_list = {
|
||||||
|
m_viewport.x(),
|
||||||
|
m_viewport.y(),
|
||||||
|
m_viewport.width(),
|
||||||
|
m_viewport.height(),
|
||||||
|
} }
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
dbgln_if(GL_DEBUG, "get_context_parameter({:#x}): unknown context parameter", name);
|
dbgln_if(GL_DEBUG, "get_context_parameter({:#x}): unknown context parameter", name);
|
||||||
return {};
|
return {};
|
||||||
|
@ -577,11 +590,13 @@ void SoftwareGLContext::gl_viewport(GLint x, GLint y, GLsizei width, GLsizei hei
|
||||||
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_viewport, x, y, width, height);
|
APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_viewport, x, y, width, height);
|
||||||
|
|
||||||
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
|
||||||
|
RETURN_WITH_ERROR_IF(width < 0 || height < 0, GL_INVALID_VALUE);
|
||||||
|
|
||||||
(void)(x);
|
m_viewport = { x, y, width, height };
|
||||||
(void)(y);
|
|
||||||
(void)(width);
|
auto rasterizer_options = m_rasterizer.options();
|
||||||
(void)(height);
|
rasterizer_options.viewport = m_viewport;
|
||||||
|
m_rasterizer.set_options(rasterizer_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareGLContext::gl_enable(GLenum capability)
|
void SoftwareGLContext::gl_enable(GLenum capability)
|
||||||
|
|
|
@ -179,6 +179,8 @@ private:
|
||||||
// FIXME: implement multi-texturing: the texture matrix stack should live inside a texture unit
|
// FIXME: implement multi-texturing: the texture matrix stack should live inside a texture unit
|
||||||
Vector<FloatMatrix4x4> m_texture_matrix_stack;
|
Vector<FloatMatrix4x4> m_texture_matrix_stack;
|
||||||
|
|
||||||
|
Gfx::IntRect m_viewport;
|
||||||
|
|
||||||
FloatVector4 m_clear_color { 0.0f, 0.0f, 0.0f, 0.0f };
|
FloatVector4 m_clear_color { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
double m_clear_depth { 1.0 };
|
double m_clear_depth { 1.0 };
|
||||||
GLint m_clear_stencil { 0 };
|
GLint m_clear_stencil { 0 };
|
||||||
|
|
|
@ -468,6 +468,7 @@ Device::Device(const Gfx::IntSize& size)
|
||||||
, m_depth_buffer { adopt_own(*new DepthBuffer(size)) }
|
, m_depth_buffer { adopt_own(*new DepthBuffer(size)) }
|
||||||
{
|
{
|
||||||
m_options.scissor_box = m_render_target->rect();
|
m_options.scissor_box = m_render_target->rect();
|
||||||
|
m_options.viewport = m_render_target->rect();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceInfo Device::info() const
|
DeviceInfo Device::info() const
|
||||||
|
@ -561,9 +562,6 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
|
||||||
|
|
||||||
m_enabled_texture_units = enabled_texture_units;
|
m_enabled_texture_units = enabled_texture_units;
|
||||||
|
|
||||||
float scr_width = m_render_target->width();
|
|
||||||
float scr_height = m_render_target->height();
|
|
||||||
|
|
||||||
m_triangle_list.clear_with_capacity();
|
m_triangle_list.clear_with_capacity();
|
||||||
m_processed_triangles.clear_with_capacity();
|
m_processed_triangles.clear_with_capacity();
|
||||||
|
|
||||||
|
@ -621,6 +619,11 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now let's transform each triangle and send that to the GPU
|
// Now let's transform each triangle and send that to the GPU
|
||||||
|
auto const viewport = window_coordinates_to_target_coordinates(m_options.viewport, m_render_target->rect());
|
||||||
|
auto const viewport_half_width = viewport.width() / 2.0f;
|
||||||
|
auto const viewport_half_height = viewport.height() / 2.0f;
|
||||||
|
auto const viewport_center_x = viewport.x() + viewport_half_width;
|
||||||
|
auto const viewport_center_y = viewport.y() + viewport_half_height;
|
||||||
auto const depth_half_range = (m_options.depth_max - m_options.depth_min) / 2;
|
auto const depth_half_range = (m_options.depth_max - m_options.depth_min) / 2;
|
||||||
auto const depth_halfway = (m_options.depth_min + m_options.depth_max) / 2;
|
auto const depth_halfway = (m_options.depth_min + m_options.depth_max) / 2;
|
||||||
for (auto& triangle : m_triangle_list) {
|
for (auto& triangle : m_triangle_list) {
|
||||||
|
@ -663,12 +666,11 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
|
||||||
one_over_w,
|
one_over_w,
|
||||||
};
|
};
|
||||||
|
|
||||||
// To window coordinates
|
// To window coordinates - note that we flip the Y coordinate into target space
|
||||||
// FIXME: implement viewport functionality
|
|
||||||
vec.window_coordinates = {
|
vec.window_coordinates = {
|
||||||
scr_width / 2 + ndc_coordinates.x() * scr_width / 2,
|
viewport_center_x + ndc_coordinates.x() * viewport_half_width,
|
||||||
scr_height / 2 - ndc_coordinates.y() * scr_height / 2,
|
viewport_center_y - ndc_coordinates.y() * viewport_half_height,
|
||||||
depth_half_range * ndc_coordinates.z() + depth_halfway,
|
depth_halfway + ndc_coordinates.z() * depth_half_range,
|
||||||
ndc_coordinates.w(),
|
ndc_coordinates.w(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct RasterizerOptions {
|
||||||
bool cull_front { false };
|
bool cull_front { false };
|
||||||
u8 texcoord_generation_enabled_coordinates { TexCoordGenerationCoordinate::None };
|
u8 texcoord_generation_enabled_coordinates { TexCoordGenerationCoordinate::None };
|
||||||
Array<TexCoordGenerationConfig, 4> texcoord_generation_config {};
|
Array<TexCoordGenerationConfig, 4> texcoord_generation_config {};
|
||||||
|
Gfx::IntRect viewport;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PixelQuad;
|
struct PixelQuad;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue