GPU: Implement basic rectangle rendering
This commit is contained in:
parent
f47d44c151
commit
46870c6a7a
|
@ -322,7 +322,7 @@ bool GPU::HandleRenderCommand()
|
||||||
case Primitive::Rectangle:
|
case Primitive::Rectangle:
|
||||||
{
|
{
|
||||||
words_per_vertex =
|
words_per_vertex =
|
||||||
1 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.rectangle_size == DrawRectangleSize::Variable);
|
2 + BoolToUInt8(rc.texture_enable) + BoolToUInt8(rc.rectangle_size == DrawRectangleSize::Variable);
|
||||||
num_vertices = 1;
|
num_vertices = 1;
|
||||||
total_words = words_per_vertex;
|
total_words = words_per_vertex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ GPU_HW::~GPU_HW() = default;
|
||||||
|
|
||||||
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices)
|
void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices)
|
||||||
{
|
{
|
||||||
|
// TODO: Move this to the GPU..
|
||||||
switch (rc.primitive)
|
switch (rc.primitive)
|
||||||
{
|
{
|
||||||
case Primitive::Polygon:
|
case Primitive::Polygon:
|
||||||
|
@ -48,6 +49,53 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Primitive::Rectangle:
|
||||||
|
{
|
||||||
|
u32 buffer_pos = 1;
|
||||||
|
|
||||||
|
const bool textured = rc.texture_enable;
|
||||||
|
const u32 color = rc.color_for_first_vertex;
|
||||||
|
const VertexPosition vp{m_GP0_command[buffer_pos++]};
|
||||||
|
const s32 pos_left = vp.x();
|
||||||
|
const s32 pos_top = vp.y();
|
||||||
|
const auto [tex_left, tex_top] =
|
||||||
|
HWVertex::DecodeTexcoord(rc.texture_enable ? Truncate16(m_GP0_command[buffer_pos++]) : 0);
|
||||||
|
s32 rectangle_width;
|
||||||
|
s32 rectangle_height;
|
||||||
|
switch (rc.rectangle_size)
|
||||||
|
{
|
||||||
|
case DrawRectangleSize::R1x1:
|
||||||
|
rectangle_width = 1;
|
||||||
|
rectangle_height = 1;
|
||||||
|
break;
|
||||||
|
case DrawRectangleSize::R8x8:
|
||||||
|
rectangle_width = 8;
|
||||||
|
rectangle_height = 8;
|
||||||
|
break;
|
||||||
|
case DrawRectangleSize::R16x16:
|
||||||
|
rectangle_width = 16;
|
||||||
|
rectangle_height = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rectangle_width = static_cast<s32>(m_GP0_command[buffer_pos] & UINT32_C(0xFFFF));
|
||||||
|
rectangle_height = static_cast<s32>(m_GP0_command[buffer_pos] >> 16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This should repeat the texcoords instead of stretching
|
||||||
|
const s32 pos_right = pos_left + (rectangle_width - 1);
|
||||||
|
const s32 pos_bottom = pos_top + (rectangle_height - 1);
|
||||||
|
const u8 tex_right = static_cast<u8>(tex_left + (rectangle_width - 1));
|
||||||
|
const u8 tex_bottom = static_cast<u8>(tex_top + (rectangle_height - 1));
|
||||||
|
|
||||||
|
m_batch_vertices.push_back(HWVertex{pos_left, pos_top, color, HWVertex::EncodeTexcoord(tex_left, tex_top)});
|
||||||
|
m_batch_vertices.push_back(HWVertex{pos_right, pos_top, color, HWVertex::EncodeTexcoord(tex_right, tex_top)});
|
||||||
|
m_batch_vertices.push_back(HWVertex{pos_left, pos_bottom, color, HWVertex::EncodeTexcoord(tex_left, tex_bottom)});
|
||||||
|
m_batch_vertices.push_back(
|
||||||
|
HWVertex{pos_right, pos_bottom, color, HWVertex::EncodeTexcoord(tex_right, tex_bottom)});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UnreachableCode();
|
UnreachableCode();
|
||||||
break;
|
break;
|
||||||
|
@ -272,6 +320,12 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
|
||||||
else
|
else
|
||||||
m_texture_config.SetFromPolygonTexcoord(m_GP0_command[2], m_GP0_command[4]);
|
m_texture_config.SetFromPolygonTexcoord(m_GP0_command[2], m_GP0_command[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Primitive::Rectangle:
|
||||||
|
{
|
||||||
|
m_texture_config.SetFromRectangleTexcoord(m_GP0_command[2]);
|
||||||
|
m_texture_config.SetFromPageAttribute(Truncate16(m_GPUSTAT.bits));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gpu.h"
|
#include "gpu.h"
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class GPU_HW : public GPU
|
class GPU_HW : public GPU
|
||||||
|
@ -18,6 +18,12 @@ protected:
|
||||||
u32 color;
|
u32 color;
|
||||||
u16 texcoord;
|
u16 texcoord;
|
||||||
u16 padding;
|
u16 padding;
|
||||||
|
|
||||||
|
static std::tuple<u8, u8> DecodeTexcoord(u16 texcoord)
|
||||||
|
{
|
||||||
|
return std::make_tuple(static_cast<u8>(texcoord), static_cast<u8>(texcoord >> 8));
|
||||||
|
}
|
||||||
|
static u16 EncodeTexcoord(u8 x, u8 y) { return ZeroExtend16(x) | (ZeroExtend16(y) << 8); }
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void UpdateTexturePageTexture();
|
virtual void UpdateTexturePageTexture();
|
||||||
|
@ -42,4 +48,3 @@ private:
|
||||||
|
|
||||||
void LoadVertices(RenderCommand rc, u32 num_vertices);
|
void LoadVertices(RenderCommand rc, u32 num_vertices);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -283,8 +283,9 @@ void GPU_HW_OpenGL::FlushRender()
|
||||||
glVertexAttribPointer(2, 2, GL_UNSIGNED_BYTE, true, sizeof(HWVertex),
|
glVertexAttribPointer(2, 2, GL_UNSIGNED_BYTE, true, sizeof(HWVertex),
|
||||||
reinterpret_cast<void*>(offsetof(HWVertex, texcoord)));
|
reinterpret_cast<void*>(offsetof(HWVertex, texcoord)));
|
||||||
|
|
||||||
glDrawArrays(m_batch_command.quad_polygon ? GL_TRIANGLE_STRIP : GL_TRIANGLES, 0,
|
const bool is_strip = ((m_batch_command.primitive == Primitive::Polygon && m_batch_command.quad_polygon) ||
|
||||||
static_cast<GLsizei>(m_batch_vertices.size()));
|
m_batch_command.primitive == Primitive::Rectangle);
|
||||||
|
glDrawArrays(is_strip ? GL_TRIANGLE_STRIP : GL_TRIANGLES, 0, static_cast<GLsizei>(m_batch_vertices.size()));
|
||||||
|
|
||||||
m_batch_vertices.clear();
|
m_batch_vertices.clear();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue