convert ndc box to pixel coordinates box in display

This commit is contained in:
frank 2021-11-19 14:13:37 -05:00
parent 660865b2f2
commit 86ca3eabec
10 changed files with 94 additions and 55 deletions

View File

@ -1,8 +1,3 @@
#include "SDL.h"
#include "Box.hpp"
#include "Configuration.hpp"
#include "Display.hpp"
#include "Audio.hpp"
BGM::BGM(Node* parent) : Node(parent) {}

View File

@ -3,7 +3,7 @@
#include <regex>
#include <map>
#include "SDL.h"
#include "SDL_mixer.h"
#include "filesystem.hpp"
#include "Node.hpp"
@ -86,4 +86,8 @@ struct Audio : Node
};
#include "Box.hpp"
#include "Configuration.hpp"
#include "Display.hpp"
#endif

View File

@ -70,7 +70,7 @@ void Box::height(float height)
/* Return the size as a vector {width, height} */
glm::vec2 Box::size() const
{
return glm::vec2(width(), height());
return {width(), height()};
}
/* Set the size. Negative values will be clamped to zero. */
@ -307,49 +307,49 @@ glm::vec2 Box::nw() const
/* Return the coordinates of the center of the top edge */
glm::vec2 Box::north() const
{
return glm::vec2(left() + width() / 2.0f, top());
return {left() + width() / 2.0f, top()};
}
/* Return the coordinates of the top right corner */
glm::vec2 Box::ne() const
{
return glm::vec2(right(), top());
return {right(), top()};
}
/* Return the coordinates of the center of the right edge */
glm::vec2 Box::east() const
{
return glm::vec2(right(), top() + height() / 2.0f);
return {right(), top() + height() / 2.0f};
}
/* Return the coordinates of the bottom right corner */
glm::vec2 Box::se() const
{
return glm::vec2(right(), bottom());
return {right(), bottom()};
}
/* Return the coordinates of the center of the bottom edge */
glm::vec2 Box::south() const
{
return glm::vec2(left() + width() / 2, bottom());
return {left() + width() / 2, bottom()};
}
/* Return the coordinates of the bottom left edge */
glm::vec2 Box::sw() const
{
return glm::vec2(left(), bottom());
return {left(), bottom()};
}
/* Return the coordinates of the center of the left edge */
glm::vec2 Box::west() const
{
return glm::vec2(left(), top() + height() / 2.0f);
return {left(), top() + height() / 2.0f};
}
/* Return the center coordinates */
glm::vec2 Box::center() const
{
return glm::vec2(left() + width() / 2.0f, top() + height() / 2.0f);
return {cx(), cy()};
}
/* Move the box by specifying the top left corner coordinates */

View File

@ -1,6 +1,6 @@
/* /\ +--------------------------------------------------------------+
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
\ / / | copy, modify and sell without restriction |
\ / / | copy, and modify without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - originally created at [http://nugget.fun] |
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+

View File

@ -1,13 +1,23 @@
/* /\ +--------------------------------------------------------------+
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
\ / / | copy, and modify without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - originally created at [http://nugget.fun] |
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+-------------*/
#include "Display.hpp"
/* Create a Display instance and subscribe to commands */
Display::Display(Node* parent) : Node(parent)
sb::Display::Display(Node* parent) : Node(parent)
{
get_delegate().subscribe(&Display::respond, this);
}
/* Return the (x, y) size in pixels of the window as an integer vector */
glm::ivec2 Display::window_size() const
glm::ivec2 sb::Display::window_size() const
{
glm::ivec2 size;
SDL_GetWindowSize(const_cast<SDL_Window*>(get_window()), &size.x, &size.y);
@ -17,14 +27,14 @@ glm::ivec2 Display::window_size() const
/* Return the window dimensions in pixels as a Box object. If invert_y is set, the lower left will be (0, 0).
* Otherwise, the top left will be (0, 0). Setting invert will cause the values to be compatible with
* glViewport. */
Box Display::window_box(bool invert_y) const
Box sb::Display::window_box(bool invert_y) const
{
return Box(glm::vec2(0, 0), window_size(), invert_y);
}
/* Return a box object with NDC coordinates of the window subsection. The subsection should be specified in
* pixel coordinates. */
Box Display::ndc_subsection(const Box& subsection) const
Box sb::Display::ndc_subsection(const Box& subsection) const
{
Box ndc_subsection = ndc;
Box window = window_box(subsection.inverted_y());
@ -33,8 +43,20 @@ Box Display::ndc_subsection(const Box& subsection) const
return ndc_subsection;
}
/* Convert a NDC area of the screen to a box object containing measurements in pixels that are based on the
* screen resolution. */
Box sb::Display::ndc_to_pixel(const Box& ndc) const
{
Box pixel_subsection = window_box();
/* The NDC size is double the ratio of the pixel size */
pixel_subsection.size(0.5f * ndc.size() * window_box().size(), true);
/* The NDC center is offset by double the ratio of the size of window in pixels, with the Y-axis inverted */
pixel_subsection.move(glm::vec2({0.5f, -0.5f}) * ndc.center() * window_box().size());
return pixel_subsection;
}
/* Get the pixel format of display at specified index (defaults to index 0) */
Uint32 Display::pixel_format(int display_index) const
Uint32 sb::Display::pixel_format(int display_index) const
{
SDL_DisplayMode display_mode;
if (SDL_GetCurrentDisplayMode(display_index, &display_mode) != 0)
@ -52,7 +74,7 @@ Uint32 Display::pixel_format(int display_index) const
/* Fill the supplied, pre-allocated buffer with 32-bit pixels (8 bits per component) from the GL
* read buffer if in GL context or from the SDL renderer if in SDL context */
void Display::screen_pixels(unsigned char* pixels, int w, int h, int x, int y) const
void sb::Display::screen_pixels(unsigned char* pixels, int w, int h, int x, int y) const
{
if (get_root()->is_gl_context)
{
@ -83,7 +105,7 @@ void Display::screen_pixels(unsigned char* pixels, int w, int h, int x, int y) c
}
}
SDL_Surface* Display::screen_surface() const
SDL_Surface* sb::Display::screen_surface() const
{
glm::ivec2 size = window_size();
unsigned char* pixels = new unsigned char[bpp / 8 * size.x * size.y];
@ -93,7 +115,7 @@ SDL_Surface* Display::screen_surface() const
return surface;
}
SDL_Surface* Display::screen_surface_from_pixels(unsigned char* pixels, bool flip) const
SDL_Surface* sb::Display::screen_surface_from_pixels(unsigned char* pixels, bool flip) const
{
glm::ivec2 size = window_size();
SDL_Surface* surface;
@ -125,7 +147,7 @@ SDL_Surface* Display::screen_surface_from_pixels(unsigned char* pixels, bool fli
}
/* Handle fullscreen request */
void Display::respond(SDL_Event& event)
void sb::Display::respond(SDL_Event& event)
{
if (get_delegate().compare(event, "fullscreen"))
{
@ -135,7 +157,7 @@ void Display::respond(SDL_Event& event)
/* Use SDL window flags to determine if fullscreen is on or off and use SDL fullscreen
* function to toggle the fullscreen state */
void Display::toggle_fullscreen() const
void sb::Display::toggle_fullscreen() const
{
SDL_Window* window = const_cast<SDL_Window*>(get_window());
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)

View File

@ -1,5 +1,15 @@
#ifndef Display_h_
#define Display_h_
/* /\ +--------------------------------------------------------------+
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
\ / / | copy, and modify without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - originally created at [http://nugget.fun] |
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+-------------*/
#ifndef SB_DISPLAY_H_
#define SB_DISPLAY_H_
#include <sstream>
#include "glm/vec2.hpp"
@ -11,26 +21,30 @@
#include "Box.hpp"
#include "Log.hpp"
class Display : public Node
namespace sb
{
class Display : public Node
{
public:
public:
const static int bpp = 32;
inline const static Box ndc {-1.0f, -1.0f, 2.0f, 2.0f, true};
const static int bpp = 32;
inline const static Box ndc {-1.0f, -1.0f, 2.0f, 2.0f, true};
Display(Node*);
glm::ivec2 window_size() const;
Uint32 pixel_format(int = 0) const;
Box window_box(bool = false) const;
Box ndc_subsection(const Box&) const;
void screen_pixels(unsigned char*, int, int, int = 0, int = 0) const;
SDL_Surface* screen_surface() const;
SDL_Surface* screen_surface_from_pixels(unsigned char*, bool) const;
void respond(SDL_Event&);
void toggle_fullscreen() const;
Display(Node*);
glm::ivec2 window_size() const;
Uint32 pixel_format(int = 0) const;
Box window_box(bool = false) const;
Box ndc_subsection(const Box&) const;
Box ndc_to_pixel(const Box&) const;
void screen_pixels(unsigned char*, int, int, int = 0, int = 0) const;
SDL_Surface* screen_surface() const;
SDL_Surface* screen_surface_from_pixels(unsigned char*, bool) const;
void respond(SDL_Event&);
void toggle_fullscreen() const;
};
};
}
#include "Game.hpp"

View File

@ -78,15 +78,15 @@ public:
int frame_count_this_second = 0, last_frame_length;
float frame_time_overflow = 0, last_frame_timestamp, last_frame_count_timestamp;
bool done = false, show_framerate = true, is_gl_context = true;
Configuration configuration = Configuration(this);
Delegate delegate = Delegate(this);
Display display = Display(this);
Recorder recorder = Recorder(this);
Input input = Input(this);
Audio audio = Audio(this);
Configuration configuration {this};
Delegate delegate {this};
sb::Display display {this};
Recorder recorder {this};
Input input {this};
Audio audio {this};
std::vector<float> frame_length_history;
TTF_Font* bp_mono_font = nullptr;
FramerateIndicator framerate_indicator = FramerateIndicator(this);
FramerateIndicator framerate_indicator {this};
Game();
virtual void reset() { activate(); }

View File

@ -59,7 +59,7 @@ Delegate& Node::get_delegate()
return get_root()->delegate;
}
const Display& Node::get_display() const
const sb::Display& Node::get_display() const
{
return get_root()->display;
}

View File

@ -21,11 +21,15 @@
class Game;
class Delegate;
class Display;
class Input;
class Box;
struct Audio;
namespace sb
{
class Display;
}
class Node
{
@ -43,7 +47,7 @@ public:
const nlohmann::json& get_configuration() const;
nlohmann::json& get_configuration();
Delegate& get_delegate();
const Display& get_display() const;
const sb::Display& get_display() const;
const SDL_Renderer* get_renderer() const;
SDL_Renderer* get_renderer();
const SDL_Window* get_window() const;

View File

@ -152,7 +152,7 @@ void Recorder::open_audio_file()
void Recorder::add_frame()
{
glm::ivec2 size = get_display().window_size();
int bytes = Display::bpp / 8 * size.x * size.y;
int bytes = sb::Display::bpp / 8 * size.x * size.y;
unsigned char* pixels = new unsigned char[bytes];
get_display().screen_pixels(pixels, size.x, size.y);
int max_length = get_configuration()["recording"]["max-stash-length"];
@ -204,7 +204,7 @@ void Recorder::add_frame()
int Recorder::get_memory_size()
{
glm::ivec2 window = get_display().window_size();
int bytes_per_frame = Display::bpp / 8 * window.x * window.y,
int bytes_per_frame = sb::Display::bpp / 8 * window.x * window.y,
size_in_bytes = 0;
for (Stash& stash : in_game_stashes)
{