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;
|
double magnitude() const;
|
||||||
|
|
||||||
operator float2() 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
|
struct float2
|
||||||
{
|
{
|
||||||
@ -40,6 +45,11 @@ namespace sharp
|
|||||||
double magnitude() const;
|
double magnitude() const;
|
||||||
|
|
||||||
operator int2() 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
|
struct int_rect
|
||||||
|
|||||||
@ -36,4 +36,7 @@ namespace sharp
|
|||||||
void start();
|
void start();
|
||||||
void end();
|
void end();
|
||||||
bool is_started();
|
bool is_started();
|
||||||
|
|
||||||
|
double get_delta_time();
|
||||||
|
double get_elapsed_time();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace sharp
|
|||||||
void render_iter();
|
void render_iter();
|
||||||
void render_loop();
|
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_line(const color& color, const int2& start, const int2& end);
|
||||||
void draw_global_rectangle(const color& color, const int_rect& rect);
|
void draw_global_rectangle(const color& color, const int_rect& rect);
|
||||||
void fill_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_ACTIVE = 0x01,
|
||||||
WINDOW_VISIBLE = 0x02,
|
WINDOW_VISIBLE = 0x02,
|
||||||
WINDOW_HEADER_VALIDATED = 0x04,
|
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
|
struct window_features
|
||||||
{
|
{
|
||||||
static const window_features defaults;
|
static const window_features defaults;
|
||||||
@ -49,6 +54,8 @@ namespace sharp
|
|||||||
window_features win_features;
|
window_features win_features;
|
||||||
window_styles styles;
|
window_styles styles;
|
||||||
|
|
||||||
|
double elapsed_time;
|
||||||
|
|
||||||
void paint_header() const;
|
void paint_header() const;
|
||||||
void paint_content_back() const;
|
void paint_content_back() const;
|
||||||
|
|
||||||
@ -61,6 +68,12 @@ namespace sharp
|
|||||||
virtual void paint() = 0;
|
virtual void paint() = 0;
|
||||||
virtual void tick() = 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:
|
public:
|
||||||
const window_styles& style() const;
|
const window_styles& style() const;
|
||||||
window_styles& style();
|
window_styles& style();
|
||||||
@ -68,6 +81,7 @@ namespace sharp
|
|||||||
const window_features& features() const;
|
const window_features& features() const;
|
||||||
window_features& features();
|
window_features& features();
|
||||||
|
|
||||||
|
double get_elapsed_time() const;
|
||||||
const int2 get_pos() const;
|
const int2 get_pos() const;
|
||||||
const int2 get_size() const;
|
const int2 get_size() const;
|
||||||
const int_rect get_content_rect() 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_window_rect(const int_rect& new_rect);
|
||||||
void set_title(const std::string& new_title);
|
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 invalidate();
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
|
|||||||
29
src/main.cpp
29
src/main.cpp
@ -1,3 +1,4 @@
|
|||||||
|
#include <numbers>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sharpsoft/all.hpp"
|
#include "sharpsoft/all.hpp"
|
||||||
#include "sharpsoft/basic_types.hpp"
|
#include "sharpsoft/basic_types.hpp"
|
||||||
@ -6,12 +7,36 @@
|
|||||||
// This library is intended to be referenced by the prefix `sharp::`
|
// This library is intended to be referenced by the prefix `sharp::`
|
||||||
// Including `using namespace sharp;` is not recommended.
|
// Including `using namespace sharp;` is not recommended.
|
||||||
|
|
||||||
|
using std::numbers::pi;
|
||||||
|
|
||||||
class test_window : public sharp::window_base
|
class test_window : public sharp::window_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void paint() override
|
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
|
void tick() override
|
||||||
{
|
{
|
||||||
|
|||||||
@ -67,6 +67,22 @@ sharp::int2::operator float2() const
|
|||||||
{
|
{
|
||||||
return float2(x, y);
|
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()
|
sharp::float2::float2()
|
||||||
{
|
{
|
||||||
@ -86,6 +102,22 @@ sharp::float2::operator int2() const
|
|||||||
{
|
{
|
||||||
return int2(x, y);
|
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()
|
sharp::int_rect::int_rect()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,6 +22,9 @@ color back_col;
|
|||||||
int render_wait_ms;
|
int render_wait_ms;
|
||||||
thread* render_thread = nullptr;
|
thread* render_thread = nullptr;
|
||||||
|
|
||||||
|
double delta_time;
|
||||||
|
double elapsed_time;
|
||||||
|
|
||||||
vector<window_base*> windows;
|
vector<window_base*> windows;
|
||||||
|
|
||||||
void sharp::initialize()
|
void sharp::initialize()
|
||||||
@ -34,6 +37,8 @@ void sharp::initialize(const global_properties& props)
|
|||||||
|
|
||||||
back_col = props.background_color;
|
back_col = props.background_color;
|
||||||
render_wait_ms = 1000 / props.refresh_rate;
|
render_wait_ms = 1000 / props.refresh_rate;
|
||||||
|
delta_time = 0;
|
||||||
|
elapsed_time = 0;
|
||||||
|
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
@ -49,6 +54,8 @@ void sharp::uninitialize()
|
|||||||
delete windows.at(i);
|
delete windows.at(i);
|
||||||
}
|
}
|
||||||
windows.clear();
|
windows.clear();
|
||||||
|
delta_time = 0;
|
||||||
|
elapsed_time = 0;
|
||||||
|
|
||||||
init = false;
|
init = false;
|
||||||
}
|
}
|
||||||
@ -103,15 +110,20 @@ void sharp::internal::render_iter()
|
|||||||
if (!HAS_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED) ||
|
if (!HAS_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED) ||
|
||||||
(!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED) && win->win_features.update_header))
|
(!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED) && win->win_features.update_header))
|
||||||
{
|
{
|
||||||
|
ON_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||||
win->paint_header();
|
win->paint_header();
|
||||||
|
OFF_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||||
ON_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED);
|
ON_INTERNAL_FLAG(win, WINDOW_HEADER_VALIDATED);
|
||||||
}
|
}
|
||||||
if (!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED))
|
if (!HAS_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED))
|
||||||
{
|
{
|
||||||
|
ON_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||||
win->paint_content_back();
|
win->paint_content_back();
|
||||||
win->paint();
|
win->paint();
|
||||||
|
OFF_INTERNAL_FLAG(win, WINDOW_IS_IN_PAINT_MODE);
|
||||||
ON_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED);
|
ON_INTERNAL_FLAG(win, WINDOW_CONTENT_VALIDATED);
|
||||||
}
|
}
|
||||||
|
win->elapsed_time += delta_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void sharp::internal::render_loop()
|
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.
|
thread::delay(50); // Wait a sec for the screen to be ready.
|
||||||
while (true)
|
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();
|
render_iter();
|
||||||
thread::delay(render_wait_ms);
|
thread::delay(render_wait_ms);
|
||||||
}
|
}
|
||||||
@ -151,6 +166,8 @@ void sharp::start()
|
|||||||
|
|
||||||
render_thread = new thread(internal::render_loop);
|
render_thread = new thread(internal::render_loop);
|
||||||
render_thread->start();
|
render_thread->start();
|
||||||
|
delta_time = 0;
|
||||||
|
elapsed_time = 0;
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
@ -160,6 +177,8 @@ void sharp::end()
|
|||||||
|
|
||||||
render_thread->stop();
|
render_thread->stop();
|
||||||
delete render_thread;
|
delete render_thread;
|
||||||
|
delta_time = 0;
|
||||||
|
elapsed_time = 0;
|
||||||
|
|
||||||
started = false;
|
started = false;
|
||||||
}
|
}
|
||||||
@ -168,3 +187,12 @@ bool sharp::is_started()
|
|||||||
{
|
{
|
||||||
return 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;
|
using namespace sharp;
|
||||||
|
|
||||||
#ifdef SH_PROS_ACTIVE
|
#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::set_pen(color.get_value());
|
||||||
pros::screen::draw_line(start.x, start.y, end.x, end.y);
|
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());
|
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;
|
win_features = window_features::defaults;
|
||||||
styles = window_styles::defaults;
|
styles = window_styles::defaults;
|
||||||
|
|
||||||
|
elapsed_time = 0;
|
||||||
}
|
}
|
||||||
sharp::window_base::~window_base()
|
sharp::window_base::~window_base()
|
||||||
{
|
{
|
||||||
@ -40,6 +42,10 @@ window_features& sharp::window_base::features()
|
|||||||
{
|
{
|
||||||
return win_features;
|
return win_features;
|
||||||
}
|
}
|
||||||
|
double sharp::window_base::get_elapsed_time() const
|
||||||
|
{
|
||||||
|
return elapsed_time;
|
||||||
|
}
|
||||||
const int2 sharp::window_base::get_pos() const
|
const int2 sharp::window_base::get_pos() const
|
||||||
{
|
{
|
||||||
return int2(posX, posY);
|
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_HEADER_VALIDATED);
|
||||||
OFF_INTERNAL_FLAG(this, WINDOW_CONTENT_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