Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions src/graphics/renderTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "vectorUtils.h"
#include <glm/gtc/type_ptr.hpp>
#include <variant>
#include <array>

#include <SDL_assert.h>

Expand All @@ -31,6 +32,7 @@ static std::vector<uint16_t> lines_index_data;
static std::vector<RenderTarget::VertexData> points_vertex_data;
static std::vector<uint16_t> points_index_data;

static std::vector<std::array<GLint, 4>> clip_region_stack;

struct ImageInfo
{
Expand Down Expand Up @@ -1255,7 +1257,6 @@ void RenderTarget::applyBuffer(sp::Texture* texture, std::vector<VertexData> &da

void RenderTarget::finish(sp::Texture* texture)
{

applyBuffer(texture, vertex_data, index_data, GL_TRIANGLES);
applyBuffer(texture, lines_vertex_data, lines_index_data, GL_LINES);
applyBuffer(texture, points_vertex_data, points_index_data, GL_POINTS);
Expand All @@ -1274,9 +1275,67 @@ glm::ivec2 RenderTarget::getPhysicalSize()
return physical_size;
}

glm::ivec2 RenderTarget::virtualToPixelPosition(glm::vec2 v)
glm::ivec2 RenderTarget::virtualToPixelPosition(glm::vec2 virtual_position)
{
return {virtual_position.x * physical_size.x / virtual_size.x, virtual_position.y * physical_size.y / virtual_size.y};
}

void RenderTarget::pushClipRegion(sp::Rect virtual_rect)
{
// Flush geometry
finish();

glm::ivec2 px_min = virtualToPixelPosition(virtual_rect.position);
glm::ivec2 px_max = virtualToPixelPosition(virtual_rect.position + virtual_rect.size);
GLint px = px_min.x;
GLint py = px_min.y;
GLint pw = px_max.x - px_min.x;
GLint ph = px_max.y - px_min.y;

// Convert coordinates to OpenGL bottom-left origin.
GLint py_gl = physical_size.y - (py + ph);

// Add the clip region.
std::array<GLint, 4> new_rect = {px, py_gl, pw, ph};

// If nested, intersect this rect with the previous rect in the stack.
// Newly stacked rects shouldn't expand the active clipping region.
if (!clip_region_stack.empty())
{
const auto& prev = clip_region_stack.back();
GLint ix = std::max(new_rect[0], prev[0]);
GLint iy = std::max(new_rect[1], prev[1]);
GLint ix2 = std::min(new_rect[0] + new_rect[2], prev[0] + prev[2]);
GLint iy2 = std::min(new_rect[1] + new_rect[3], prev[1] + prev[3]);
new_rect[0] = ix;
new_rect[1] = iy;
new_rect[2] = std::max(0, ix2 - ix);
new_rect[3] = std::max(0, iy2 - iy);
}

// Clip the render to the clip region.
clip_region_stack.push_back(new_rect);
glScissor(new_rect[0], new_rect[1], new_rect[2], new_rect[3]);
glEnable(GL_SCISSOR_TEST);
}

void RenderTarget::popClipRegion()
{
return {v.x * physical_size.x / virtual_size.x, v.y * physical_size.y / virtual_size.y};
// Flush geometry
finish();

// Pop the top clip region.
if (!clip_region_stack.empty()) clip_region_stack.pop_back();

// If that was the last rect, or there weren't any, stop clipping.
// Otherwise, clip to the back rect.
if (clip_region_stack.empty())
glDisable(GL_SCISSOR_TEST);
else
{
const auto& top = clip_region_stack.back();
glScissor(top[0], top[1], top[2], top[3]);
}
}

}
13 changes: 9 additions & 4 deletions src/graphics/renderTarget.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef SP_GRAPHICS_RENDERTARGET_H
#define SP_GRAPHICS_RENDERTARGET_H
#pragma once

#include <glm/vec2.hpp>
#include <glm/gtc/type_precision.hpp>
Expand Down Expand Up @@ -72,6 +71,14 @@ class RenderTarget : sp::NonCopyable
void drawStretchedHVClipped(sp::Rect rect, sp::Rect clip_rect, float corner_size, std::string_view texture, glm::u8vec4 color={255,255,255,255});

void finish();

// Functions for using rect masks with glScissor to clip a render.

// Stack nested rects to determine the clip region's bounds.
void pushClipRegion(sp::Rect virtual_rect);
// Remove a nested rect from the clip region.
void popClipRegion();

struct VertexData
{
glm::vec2 position;
Expand All @@ -91,5 +98,3 @@ class RenderTarget : sp::NonCopyable
};

}

#endif//SP_GRAPHICS_RENDERTARGET_H
Loading