Skip to content

Instantly share code, notes, and snippets.

@TurtleP
Last active September 3, 2023 16:27
Show Gist options
  • Save TurtleP/9130aa7683bde4c33297d138636dcebb to your computer and use it in GitHub Desktop.
Save TurtleP/9130aa7683bde4c33297d138636dcebb to your computer and use it in GitHub Desktop.
void Renderer<Console::CTR>::BindFramebuffer(Texture<Console::ALL>* texture)
{
if (!IsActiveScreenValid())
return;
this->EnsureInFrame();
FlushVertices();
this->context.target = this->targets[love::GetActiveScreen()].GetTarget();
Rect viewport = this->targets[love::GetActiveScreen()].GetViewport();
if (texture != nullptr && texture->IsRenderTarget())
{
auto* _texture = (Texture<Console::CTR>*)texture;
this->context.target = _texture->GetRenderTargetHandle();
viewport = { 0, 0, _texture->GetPixelWidth(), _texture->GetPixelHeight() };
}
C3D_FrameDrawOn(this->context.target);
this->SetViewport(viewport, this->context.target->linked);
}
void Renderer<Console::CTR>::SetViewport(const Rect& rect, bool tilt)
{
Rect newView = rect;
if (newView.h == GSP_SCREEN_WIDTH && tilt)
{
if (newView.w == GSP_SCREEN_HEIGHT_TOP || newView.w == GSP_SCREEN_HEIGHT_TOP_2X)
{
Mtx_Copy(&this->context.projection, &this->targets[0].GetProjView());
return;
}
else if (newView.w == GSP_SCREEN_HEIGHT_BOTTOM)
{
Mtx_Copy(&this->context.projection, &this->targets[2].GetProjView());
return;
}
}
auto* ortho = tilt ? Mtx_OrthoTilt : Mtx_Ortho;
ortho(&this->context.projection, 0.0f, newView.w, newView.h, 0.0f, Z_NEAR, Z_FAR, true);
if (tilt)
std::swap(newView.w, newView.h);
C3D_SetViewport(0, 0, newView.w, newView.h);
}
static void createFramebufferObject(C3D_RenderTarget*& target, C3D_Tex*& texture, uint16_t width,
uint16_t height)
{
const auto _width = NextPo2(width);
const auto _height = NextPo2(height);
texture = new C3D_Tex();
if (!C3D_TexInitVRAM(texture, _height, _width, GPU_RGBA8))
throw love::Exception("Failed to create framebuffer Texture");
target = C3D_RenderTargetCreateFromTex(texture, GPU_TEXFACE_2D, 0, GPU_RB_DEPTH16);
}
static Vector2 getVertex(const float x, const float y, const Vector2& virtualDim,
const Vector2& physicalDim)
{
const auto u = (virtualDim.y - y) / physicalDim.x;
const auto v = (x + (physicalDim.y - virtualDim.x)) / physicalDim.y;
return Vector2(u, v);
}
static void setQuad(StrongReference<Quad> quad, const Quad::Viewport& viewport,
const Vector2& virtualDim, const Vector2& physicalDim, bool isRenderTarget)
{
if (quad == nullptr)
throw love::Exception("Invalid quad (is nullptr).");
if (isRenderTarget)
{
quad->SetVertexTextureCoord(0, getVertex(0.0f, 0.0f, virtualDim, physicalDim));
quad->SetVertexTextureCoord(1, getVertex(0.0f, virtualDim.y, virtualDim, physicalDim));
quad->SetVertexTextureCoord(2,
getVertex(virtualDim.x, virtualDim.y, virtualDim, physicalDim));
quad->SetVertexTextureCoord(3, getVertex(virtualDim.x, 0.0f, virtualDim, physicalDim));
return;
}
quad.Set(new Quad(viewport, physicalDim.x, physicalDim.y), Acquire::NORETAIN);
}
void Texture<Console::CTR>::Draw(Graphics<Console::CTR>& graphics, Quad* quad,
const Matrix4<Console::CTR>& matrix)
{
if (!this->readable)
throw love::Exception("Textures with non-readable formats cannot be drawn.");
if (this->renderTarget && graphics.IsRenderTargetActive(this))
throw love::Exception("Cannot render a Texture to itself.");
const Quad::Viewport& viewport = quad->GetViewport();
setQuad(this->quad, viewport, { this->pixelWidth, this->pixelHeight },
{ this->texture->width, this->texture->height }, this->renderTarget);
const auto& transform = graphics.GetTransform();
bool is2D = transform.IsAffine2DTransform();
Matrix4<Console::CTR> translated(graphics.GetTransform(), matrix);
DrawCommand<Console::CTR> command(0x04, vertex::PRIMITIVE_TRIANGLE_FAN);
command.handles = { this->texture };
command.format = CommonFormat::TEXTURE;
if (is2D)
translated.TransformXY(command.Positions().get(), this->quad->GetVertexPositions(),
command.count);
const auto* coords = this->quad->GetVertexTextureCoords();
command.FillVertices(graphics.GetColor(), coords);
Renderer<Console::CTR>::Instance().Render(command);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment