Good progress. Line drawing coming along decent.
This commit is contained in:
parent
e0b31c0238
commit
9168e584ef
@ -29,6 +29,11 @@ namespace sharp
|
||||
double magnitude() const;
|
||||
|
||||
operator float2() const;
|
||||
|
||||
const int2 operator+(const int2& other) const;
|
||||
const int2 operator-(const int2& other) const;
|
||||
const int2 operator*(const int factor) const;
|
||||
const int2 operator/(const int factor) const;
|
||||
};
|
||||
struct float2
|
||||
{
|
||||
@ -40,6 +45,11 @@ namespace sharp
|
||||
double magnitude() const;
|
||||
|
||||
operator int2() const;
|
||||
|
||||
const float2 operator+(const float2& other) const;
|
||||
const float2 operator-(const float2& other) const;
|
||||
const float2 operator*(const double factor) const;
|
||||
const float2 operator/(const double factor) const;
|
||||
};
|
||||
|
||||
struct int_rect
|
||||
|
||||
@ -36,4 +36,7 @@ namespace sharp
|
||||
void start();
|
||||
void end();
|
||||
bool is_started();
|
||||
|
||||
double get_delta_time();
|
||||
double get_elapsed_time();
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ namespace sharp
|
||||
void render_iter();
|
||||
void render_loop();
|
||||
|
||||
void draw_global_pixel(const color& color, const int2& pos);
|
||||
void draw_global_line(const color& color, const int2& start, const int2& end);
|
||||
void draw_global_rectangle(const color& color, const int_rect& rect);
|
||||
void fill_global_rectangle(const color& color, const int_rect& rect);
|
||||
|
||||
@ -10,9 +10,14 @@ namespace sharp
|
||||
WINDOW_ACTIVE = 0x01,
|
||||
WINDOW_VISIBLE = 0x02,
|
||||
WINDOW_HEADER_VALIDATED = 0x04,
|
||||
WINDOW_CONTENT_VALIDATED = 0x08
|
||||
WINDOW_CONTENT_VALIDATED = 0x08,
|
||||
WINDOW_IS_IN_PAINT_MODE = 0x10
|
||||
};
|
||||
|
||||
// Can't tell if these are good ideas.
|
||||
// FIXME: Messing with the header here requires a full screen
|
||||
// invalidation triggered by the user, because I can't
|
||||
// detect when its variables are modified.
|
||||
struct window_features
|
||||
{
|
||||
static const window_features defaults;
|
||||
@ -49,6 +54,8 @@ namespace sharp
|
||||
window_features win_features;
|
||||
window_styles styles;
|
||||
|
||||
double elapsed_time;
|
||||
|
||||
void paint_header() const;
|
||||
void paint_content_back() const;
|
||||
|
||||
@ -61,6 +68,12 @@ namespace sharp
|
||||
virtual void paint() = 0;
|
||||
virtual void tick() = 0;
|
||||
|
||||
void draw_pixel(const color& color, const int2& pos);
|
||||
void draw_line(const color& color, const int2& start, const int2& end);
|
||||
//void draw_rect(const color& color, const int_rect& rect);
|
||||
|
||||
//void fill_rect(const color& color, const int_rect& rect);
|
||||
|
||||
public:
|
||||
const window_styles& style() const;
|
||||
window_styles& style();
|
||||
@ -68,6 +81,7 @@ namespace sharp
|
||||
const window_features& features() const;
|
||||
window_features& features();
|
||||
|
||||
double get_elapsed_time() const;
|
||||
const int2 get_pos() const;
|
||||
const int2 get_size() const;
|
||||
const int_rect get_content_rect() const;
|
||||
@ -83,6 +97,9 @@ namespace sharp
|
||||
void set_window_rect(const int_rect& new_rect);
|
||||
void set_title(const std::string& new_title);
|
||||
|
||||
const int2 to_screen(const int2& window_pos) const;
|
||||
const int2 to_window(const int2& screen_pos) const;
|
||||
|
||||
void invalidate();
|
||||
|
||||
void show();
|
||||
|
||||
25
src/main.cpp
25
src/main.cpp
@ -1,3 +1,4 @@
|
||||
#include <numbers>
|
||||
#include "main.h"
|
||||
#include "sharpsoft/all.hpp"
|
||||
#include "sharpsoft/basic_types.hpp"
|
||||
@ -6,12 +7,36 @@
|
||||
// This library is intended to be referenced by the prefix `sharp::`
|
||||
// Including `using namespace sharp;` is not recommended.
|
||||
|
||||
using std::numbers::pi;
|
||||
|
||||
class test_window : public sharp::window_base
|
||||
{
|
||||
protected:
|
||||
void paint() override
|
||||
{
|
||||
constexpr int points = 5;
|
||||
|
||||
int bigRadius = 100,
|
||||
smallRadius = 60;
|
||||
|
||||
sharp::int2 center = get_size() / 2;
|
||||
sharp::int2 arr[points * 2];
|
||||
|
||||
double time = get_elapsed_time();
|
||||
double offset = pi / points;
|
||||
|
||||
for (int i = 0; i < points; i++)
|
||||
{
|
||||
arr[i * 2] = sharp::int2(bigRadius * cos(time + (offset * i * 2)), bigRadius * sin(time + (offset * i * 2))) + center;
|
||||
arr[i * 2 + 1] = sharp::int2(smallRadius * cos(time + (offset * (i * 2 + 1))), smallRadius * sin(time + (offset * (i * 2 + 1)))) + center;
|
||||
}
|
||||
|
||||
for (int i = 0; i < points * 2; i++)
|
||||
{
|
||||
sharp::int2& this_point = arr[i],
|
||||
next_point = arr[(i + 1) % (points * 2)];
|
||||
draw_line(0xABCDEF, this_point, next_point);
|
||||
}
|
||||
}
|
||||
void tick() override
|
||||
{
|
||||
|
||||
@ -67,6 +67,22 @@ sharp::int2::operator float2() const
|
||||
{
|
||||
return float2(x, y);
|
||||
}
|
||||
const int2 sharp::int2::operator+(const int2& other) const
|
||||
{
|
||||
return int2(x + other.x, y + other.y);
|
||||
}
|
||||
const int2 sharp::int2::operator-(const int2& other) const
|
||||
{
|
||||
return int2(x - other.x, y - other.y);
|
||||
}
|
||||
const int2 sharp::int2::operator*(const int factor) const
|
||||
{
|
||||
return int2(x * factor, y * factor);
|
||||
}
|
||||
const int2 sharp::int2::operator/(const int factor) const
|
||||
{
|
||||
return int2(x / factor, y / factor);
|
||||
}
|
||||
|
||||
sharp::float2::float2()
|
||||
{
|
||||
@ -86,6 +102,22 @@ sharp::float2::operator int2() const
|
||||
{
|
||||
return int2(x, y);
|
||||
};
|
||||
const float2 sharp::float2::operator+(const float2& other) const
|
||||
{
|
||||
return float2(x + other.x, y + other.y);
|
||||
}
|
||||
const float2 sharp::float2::operator-(const float2& other) const
|
||||
{
|
||||
return float2(x - other.x, y - other.y);
|
||||
}
|
||||
const float2 sharp::float2::operator*(const double factor) const
|
||||
{
|
||||
return float2(x * factor, y * factor);
|
||||
}
|
||||
const float2 sharp::float2::operator/(const double factor) const
|
||||
{
|
||||
return float2(x / factor, y / factor);
|
||||
}
|
||||
|
||||
sharp::int_rect::int_rect()
|
||||
{
|
||||
|
||||
@ -22,6 +22,9 @@ color back_col;
|
||||
int render_wait_ms;
|
||||
thread* render_thread = nullptr;
|
||||
|
||||
double delta_time;
|
||||
double elapsed_time;
|
||||
|
||||
vector<window_base*> windows;
|
||||
|
||||
void sharp::initialize()
|
||||
@ -34,6 +37,8 @@ void sharp::initialize(const global_properties& props)
|
||||
|
||||
back_col = props.background_color;
|
||||
render_wait_ms = 1000 / props.refresh_rate;
|
||||
delta_time = 0;
|
||||
elapsed_time = 0;
|
||||
|
||||
init = true;
|
||||
}
|
||||
@ -49,6 +54,8 @@ void sharp::uninitialize()
|
||||
delete windows.at(i);
|
||||
}
|
||||
windows.clear();
|
||||
delta_time = 0;
|
||||
elapsed_time = 0;
|
||||
|
||||
init = false;
|
||||
}
|
||||
@ -103,15 +110,20 @@ void sharp::internal::render_iter()
|
||||
if (!HAS_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED) ||
|
||||
(!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED) && win->win_features.update_header))
|
||||
{
|
||||
ON_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||
win->paint_header();
|
||||
OFF_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||
ON_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED);
|
||||
}
|
||||
if (!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED))
|
||||
{
|
||||
ON_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||
win->paint_content_back();
|
||||
win->paint();
|
||||
OFF_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||
ON_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED);
|
||||
}
|
||||
win->elapsed_time += delta_time;
|
||||
}
|
||||
}
|
||||
void sharp::internal::render_loop()
|
||||
@ -119,6 +131,9 @@ void sharp::internal::render_loop()
|
||||
thread::delay(50); // Wait a sec for the screen to be ready.
|
||||
while (true)
|
||||
{
|
||||
// TODO: This could be improved with a proper chrono timer, but it's alright.
|
||||
delta_time = 1.0 / render_wait_ms;
|
||||
elapsed_time += delta_time;
|
||||
render_iter();
|
||||
thread::delay(render_wait_ms);
|
||||
}
|
||||
@ -151,6 +166,8 @@ void sharp::start()
|
||||
|
||||
render_thread = new thread(internal::render_loop);
|
||||
render_thread->start();
|
||||
delta_time = 0;
|
||||
elapsed_time = 0;
|
||||
|
||||
started = true;
|
||||
}
|
||||
@ -160,6 +177,8 @@ void sharp::end()
|
||||
|
||||
render_thread->stop();
|
||||
delete render_thread;
|
||||
delta_time = 0;
|
||||
elapsed_time = 0;
|
||||
|
||||
started = false;
|
||||
}
|
||||
@ -168,3 +187,12 @@ bool sharp::is_started()
|
||||
{
|
||||
return started;
|
||||
}
|
||||
|
||||
double sharp::get_delta_time()
|
||||
{
|
||||
return delta_time;
|
||||
}
|
||||
double sharp::get_elapsed_time()
|
||||
{
|
||||
return elapsed_time;
|
||||
}
|
||||
|
||||
@ -11,7 +11,12 @@
|
||||
using namespace sharp;
|
||||
|
||||
#ifdef SH_PROS_ACTIVE
|
||||
void internal::draw_global_line(const color &color, const int2 &start, const int2 &end)
|
||||
void internal::draw_global_pixel(const color& color, const int2& pos)
|
||||
{
|
||||
pros::screen::set_pen(color.get_value());
|
||||
pros::screen::draw_pixel(pos.x, pos.y);
|
||||
}
|
||||
void internal::draw_global_line(const color& color, const int2& start, const int2& end)
|
||||
{
|
||||
pros::screen::set_pen(color.get_value());
|
||||
pros::screen::draw_line(start.x, start.y, end.x, end.y);
|
||||
@ -56,3 +61,35 @@ void window_base::paint_content_back() const
|
||||
{
|
||||
internal::fill_global_rectangle(styles.background_color, get_content_rect());
|
||||
}
|
||||
|
||||
void window_base::draw_pixel(const color& color, const int2& win_pos)
|
||||
{
|
||||
if (win_pos.x < 0 || win_pos.x >= width ||
|
||||
win_pos.y < 0 || win_pos.y >= height) return; // Out of window bounds.
|
||||
|
||||
const int2 true_pos = to_screen(win_pos);
|
||||
internal::draw_global_pixel(color, true_pos);
|
||||
}
|
||||
void window_base::draw_line(const color& color, const int2& pos_a, const int2& pos_b)
|
||||
{
|
||||
// FIXME: This causes artifacts occasionally along the top and bottom of the window.
|
||||
// Why?
|
||||
|
||||
double slope = (double)(pos_b.y - pos_a.y) / (pos_b.x - pos_a.x),
|
||||
inv_slope = (double)(pos_b.x - pos_a.x) / (pos_b.y - pos_a.y); // Prevent divide by zero errors.
|
||||
|
||||
int2 a = pos_a, b = pos_b;
|
||||
if (a.x < 0) a = int2(0, -a.x * slope + a.y); // Left wall truncate for A.
|
||||
else if (a.x >= width) a = int2(width - 1, ((width - 1) - a.x) * slope + a.y); // Right wall truncate for A.
|
||||
if (a.y < 0) a = int2(-a.y * inv_slope + a.x, 0); // Bottom wall truncate for A.
|
||||
else if (a.y >= height) a = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for A.
|
||||
|
||||
if (b.x < 0) b = int2(0, -a.x * slope + a.y); // Left wall truncate for B.
|
||||
else if (b.x >= width) b = int2(width - 1, ((width - 1) - a.x) * slope + a.y); // Right wall truncate for B.
|
||||
if (b.y < 0) b = int2(-a.y * inv_slope + a.x, 0); // Bottom wall truncate for B.
|
||||
else if (b.y >= height) b = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for B.
|
||||
|
||||
const int2 true_pos_a = to_screen(a),
|
||||
true_pos_b = to_screen(b);
|
||||
internal::draw_global_line(color, true_pos_a, true_pos_b);
|
||||
}
|
||||
|
||||
@ -17,6 +17,8 @@ sharp::window_base::window_base(const string& title, const int2& pos, const int2
|
||||
|
||||
win_features = window_features::defaults;
|
||||
styles = window_styles::defaults;
|
||||
|
||||
elapsed_time = 0;
|
||||
}
|
||||
sharp::window_base::~window_base()
|
||||
{
|
||||
@ -40,6 +42,10 @@ window_features& sharp::window_base::features()
|
||||
{
|
||||
return win_features;
|
||||
}
|
||||
double sharp::window_base::get_elapsed_time() const
|
||||
{
|
||||
return elapsed_time;
|
||||
}
|
||||
const int2 sharp::window_base::get_pos() const
|
||||
{
|
||||
return int2(posX, posY);
|
||||
@ -137,3 +143,16 @@ void sharp::window_base::show()
|
||||
OFF_INTERNAL_FLAG(this, WINDOW_HEADER_VALIDATED);
|
||||
OFF_INTERNAL_FLAG(this, WINDOW_CONTENT_VALIDATED);
|
||||
}
|
||||
|
||||
const int2 sharp::window_base::to_screen(const int2& window_pos) const
|
||||
{
|
||||
int header_height = get_header_height();
|
||||
if (header_height > 0) return int2(window_pos.x + posX, window_pos.y + posY + header_height + 1);
|
||||
else return int2(window_pos.x + posX, window_pos.y + posY);
|
||||
}
|
||||
const int2 sharp::window_base::to_window(const int2& screen_pos) const
|
||||
{
|
||||
int header_height = get_header_height();
|
||||
if (header_height > 0) return int2(screen_pos.x - posX, screen_pos.y - posY - header_height - 1);
|
||||
else return int2(screen_pos.x - posY, screen_pos.y - posY);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user