Display object can return ndc coordinates from a pixel coordinate box
This commit is contained in:
parent
03d179eed4
commit
54cf01246b
56
src/Box.cpp
56
src/Box.cpp
|
@ -1,6 +1,6 @@
|
||||||
/* /\ +--------------------------------------------------------------+
|
/* /\ +--------------------------------------------------------------+
|
||||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
____/ \____ /| - 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] |
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
@ -10,33 +10,37 @@
|
||||||
|
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
|
|
||||||
/* Construct a Box by giving a corner coordinate (top left in SDL coordinates, bottom left in GL coordinates)
|
/* Construct a Box by giving a corner coordinate (top left if Y-axis is not inverted, bottom left otherwise) and
|
||||||
* and size (as width, height). The gl argument indicates that the Y-coordinate increases from the bottom of
|
* size (as width, height). The invert_y argument indicates that the Y-coordinate increases from the bottom of
|
||||||
* the screen to the top rather than the default case where it increases from the top to the bottom. */
|
* the screen to the top rather than the default case where it increases from the top to the bottom. */
|
||||||
Box::Box(const glm::vec2& corner, const glm::vec2& size, bool use_gl_coordinates)
|
Box::Box(const glm::vec2& corner, const glm::vec2& size, bool invert_y)
|
||||||
{
|
{
|
||||||
x = corner.x;
|
x = corner.x;
|
||||||
y = corner.y;
|
y = corner.y;
|
||||||
w = size.x;
|
w = size.x;
|
||||||
h = size.y;
|
h = size.y;
|
||||||
gl(use_gl_coordinates);
|
this->invert_y(invert_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a Box by passing an SDL_Rect struct, which is of the form {x, y, w, h} and limited to int arguments */
|
/* Construct a Box from float arguments: x, y, width, height. If invert_y is set, the Y-axis increases from bottom to
|
||||||
Box::Box(const SDL_Rect& rect, bool use_gl_coordinates) : Box({rect.x, rect.y}, {rect.w, rect.h}, use_gl_coordinates) {}
|
* top instead of top to bottom. */
|
||||||
|
Box::Box(float x, float y, float width, float height, bool invert_y) : Box({x, y}, {width, height}, invert_y) {}
|
||||||
|
|
||||||
/* Set GL mode to true, meaning the Y-coordinate increases from the bottom of the screen to the top, or false,
|
/* Construct a Box by passing an SDL_Rect struct, which is of the form {x, y, w, h} and limited to int arguments. */
|
||||||
* meaning SDL mode where the Y-coordinate increases from the top of the screen to the bottom. */
|
Box::Box(const SDL_Rect& rect, bool invert_y) : Box({rect.x, rect.y}, {rect.w, rect.h}, invert_y) {}
|
||||||
void Box::gl(bool use_gl_coordinates)
|
|
||||||
|
/* Set inverted Y mode to true, meaning the Y-coordinate increases from the bottom to the top, or false, meaning the
|
||||||
|
* Y-coordinate increases from the top to the bottom. */
|
||||||
|
void Box::invert_y(bool invert)
|
||||||
{
|
{
|
||||||
this->use_gl_coordinates = use_gl_coordinates;
|
invert_y_state = invert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if GL coordinate mode was set, meaning the Y-coordinate increases from the bottom of the screen to
|
/* Returns true if Y-axis was set to inverted, meaning the Y-coordinate increases from the bottom to the top, or false,
|
||||||
* the top, or false, meaning SDL mode where the Y-coordinate increases from the top of the screen to the bottom. */
|
* meaning Y-coordinate increases from the top to the bottom. */
|
||||||
bool Box::gl() const
|
bool Box::inverted_y() const
|
||||||
{
|
{
|
||||||
return use_gl_coordinates;
|
return invert_y_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the width */
|
/* Return the width */
|
||||||
|
@ -98,7 +102,7 @@ float Box::area() const
|
||||||
float Box::top() const
|
float Box::top() const
|
||||||
{
|
{
|
||||||
/* if Y-coordinate increases from bottom to top, use the bottom to determine this value */
|
/* if Y-coordinate increases from bottom to top, use the bottom to determine this value */
|
||||||
if (gl())
|
if (inverted_y())
|
||||||
{
|
{
|
||||||
return bottom() + height();
|
return bottom() + height();
|
||||||
}
|
}
|
||||||
|
@ -119,7 +123,7 @@ float Box::right() const
|
||||||
float Box::bottom() const
|
float Box::bottom() const
|
||||||
{
|
{
|
||||||
/* if Y-coordinate increases from bottom to top, use the stored Y-coordinate */
|
/* if Y-coordinate increases from bottom to top, use the stored Y-coordinate */
|
||||||
if (gl())
|
if (inverted_y())
|
||||||
{
|
{
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +150,7 @@ float Box::cx() const
|
||||||
float Box::cy() const
|
float Box::cy() const
|
||||||
{
|
{
|
||||||
/* if Y-coordinate increases from bottom to top, add from the bottom */
|
/* if Y-coordinate increases from bottom to top, add from the bottom */
|
||||||
if (gl())
|
if (inverted_y())
|
||||||
{
|
{
|
||||||
return bottom() + height() / 2.0f;
|
return bottom() + height() / 2.0f;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +183,7 @@ void Box::drag_top(float delta)
|
||||||
{
|
{
|
||||||
float new_location = top() + delta;
|
float new_location = top() + delta;
|
||||||
height(std::abs(bottom() - new_location));
|
height(std::abs(bottom() - new_location));
|
||||||
if ((gl() && new_location < bottom()) || (!gl() && new_location > bottom()))
|
if ((inverted_y() && new_location < bottom()) || (!inverted_y() && new_location > bottom()))
|
||||||
{
|
{
|
||||||
bottom(new_location);
|
bottom(new_location);
|
||||||
}
|
}
|
||||||
|
@ -239,7 +243,7 @@ void Box::drag_bottom(float delta)
|
||||||
{
|
{
|
||||||
float new_location = bottom() + delta;
|
float new_location = bottom() + delta;
|
||||||
height(std::abs(top() - new_location));
|
height(std::abs(top() - new_location));
|
||||||
if ((gl() && new_location > top()) || (!gl() && new_location < bottom()))
|
if ((inverted_y() && new_location > top()) || (!inverted_y() && new_location < bottom()))
|
||||||
{
|
{
|
||||||
top(new_location);
|
top(new_location);
|
||||||
}
|
}
|
||||||
|
@ -477,9 +481,9 @@ bool Box::fits(const Box& container) const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
!(
|
!(
|
||||||
((gl() && top() > container.top()) || (!gl() && top() < container.top())) ||
|
((inverted_y() && top() > container.top()) || (!inverted_y() && top() < container.top())) ||
|
||||||
right() > container.right() ||
|
right() > container.right() ||
|
||||||
((gl() && bottom() < container.bottom()) || (!gl() && bottom() > container.bottom())) ||
|
((inverted_y() && bottom() < container.bottom()) || (!inverted_y() && bottom() > container.bottom())) ||
|
||||||
left() < container.left()
|
left() < container.left()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -487,7 +491,7 @@ bool Box::fits(const Box& container) const
|
||||||
/* Removes any part of the box that is not inside the passed crop area box */
|
/* Removes any part of the box that is not inside the passed crop area box */
|
||||||
void Box::crop(const Box& area)
|
void Box::crop(const Box& area)
|
||||||
{
|
{
|
||||||
if ((gl() && top() > area.top()) || (!gl() && top() < area.top()))
|
if ((inverted_y() && top() > area.top()) || (!inverted_y() && top() < area.top()))
|
||||||
{
|
{
|
||||||
top(area.top(), true);
|
top(area.top(), true);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +499,7 @@ void Box::crop(const Box& area)
|
||||||
{
|
{
|
||||||
right(area.right(), true);
|
right(area.right(), true);
|
||||||
}
|
}
|
||||||
if ((gl() && bottom() < area.bottom()) || (!gl() && bottom() > area.bottom()))
|
if ((inverted_y() && bottom() < area.bottom()) || (!inverted_y() && bottom() > area.bottom()))
|
||||||
{
|
{
|
||||||
bottom(area.bottom(), true);
|
bottom(area.bottom(), true);
|
||||||
}
|
}
|
||||||
|
@ -509,7 +513,7 @@ void Box::crop(const Box& area)
|
||||||
* will return true. */
|
* will return true. */
|
||||||
bool Box::collide(const glm::vec2& point) const
|
bool Box::collide(const glm::vec2& point) const
|
||||||
{
|
{
|
||||||
return point.x >= left() && point.x <= right() && point.y >= (gl() ? bottom() : top()) && point.y <= (gl() ? top() : bottom());
|
return point.x >= left() && point.x <= right() && point.y >= (inverted_y() ? bottom() : top()) && point.y <= (inverted_y() ? top() : bottom());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if the line segment intersects the box, false otherwise. If intersection is passed and there is a
|
/* Returns true if the line segment intersects the box, false otherwise. If intersection is passed and there is a
|
||||||
|
@ -557,7 +561,7 @@ bool Box::collide(const Segment& segment, glm::vec2& intersection) const
|
||||||
bool Box::collide(const Box& box, Box* overlap) const
|
bool Box::collide(const Box& box, Box* overlap) const
|
||||||
{
|
{
|
||||||
float top, bottom, h;
|
float top, bottom, h;
|
||||||
if (gl())
|
if (inverted_y())
|
||||||
{
|
{
|
||||||
top = std::min(this->top(), box.top());
|
top = std::min(this->top(), box.top());
|
||||||
bottom = std::max(this->bottom(), box.bottom());
|
bottom = std::max(this->bottom(), box.bottom());
|
||||||
|
|
|
@ -28,14 +28,15 @@ class Box : public SDL_FRect
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool use_gl_coordinates;
|
bool invert_y_state = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0}, bool = false);
|
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0}, bool = false);
|
||||||
|
Box(float, float, float, float, bool = false);
|
||||||
Box(const SDL_Rect&, bool = false);
|
Box(const SDL_Rect&, bool = false);
|
||||||
void gl(bool);
|
void invert_y(bool);
|
||||||
bool gl() const;
|
bool inverted_y() const;
|
||||||
float width() const;
|
float width() const;
|
||||||
void width(float);
|
void width(float);
|
||||||
float height() const;
|
float height() const;
|
||||||
|
|
|
@ -14,11 +14,23 @@ glm::ivec2 Display::window_size() const
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the window dimensions as a Box object. If use_gl_coordinates is set, the lower left will be (0, 0).
|
/* 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). */
|
* Otherwise, the top left will be (0, 0). Setting invert will cause the values to be compatible with
|
||||||
Box Display::window_box(bool use_gl_coordinates) const
|
* glViewport. */
|
||||||
|
Box Display::window_box(bool invert_y) const
|
||||||
{
|
{
|
||||||
return Box(glm::vec2(0, 0), window_size(), use_gl_coordinates);
|
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 ndc_subsection = ndc;
|
||||||
|
Box window = window_box(subsection.inverted_y());
|
||||||
|
ndc_subsection.move({(subsection.x - window.x) / window.width() * 2.0f, (subsection.y - window.y) / window.height() * 2.0f});
|
||||||
|
ndc_subsection.size({subsection.width() / window.width() * 2.0f, subsection.height() / window.height() * 2.0f});
|
||||||
|
return ndc_subsection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the pixel format of display at specified index (defaults to index 0) */
|
/* Get the pixel format of display at specified index (defaults to index 0) */
|
||||||
|
@ -45,18 +57,22 @@ void Display::screen_pixels(unsigned char* pixels, int w, int h, int x, int y) c
|
||||||
if (get_root()->is_gl_context)
|
if (get_root()->is_gl_context)
|
||||||
{
|
{
|
||||||
GLenum format;
|
GLenum format;
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
if constexpr (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||||
|
{
|
||||||
format = GL_BGRA;
|
format = GL_BGRA;
|
||||||
#else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
format = GL_RGBA;
|
format = GL_RGBA;
|
||||||
#endif
|
}
|
||||||
glReadBuffer(GL_FRONT);
|
glReadBuffer(GL_FRONT);
|
||||||
glReadPixels(x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
|
glReadPixels(x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
|
||||||
// SDL_Log("(%i, %i, %i) (%i, %i, %i, %i)",
|
/* Debug statement showing the framebuffer status and first pixel read */
|
||||||
// glCheckFramebufferStatus(GL_FRAMEBUFFER),
|
std::ostringstream message;
|
||||||
// glCheckFramebufferStatus(GL_READ_FRAMEBUFFER),
|
message << "read framebuffer status: " << glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) <<
|
||||||
// glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER),
|
", draw framebuffer status: " << glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) <<
|
||||||
// pixels[0], pixels[1], pixels[2], pixels[3]);
|
", upper left screen pixel value read: " << pixels[0] << " " << pixels[1] << " " << pixels[2] << " " << pixels[3];
|
||||||
|
sb::Log::log(message, sb::Log::DEBUG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,11 +17,13 @@ class Display : public Node
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const static int bpp = 32;
|
const static int bpp = 32;
|
||||||
|
inline const static Box ndc {-1.0f, -1.0f, 2.0f, 2.0f, true};
|
||||||
|
|
||||||
Display(Node*);
|
Display(Node*);
|
||||||
glm::ivec2 window_size() const;
|
glm::ivec2 window_size() const;
|
||||||
Uint32 pixel_format(int = 0) const;
|
Uint32 pixel_format(int = 0) const;
|
||||||
Box window_box(bool = false) 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;
|
void screen_pixels(unsigned char*, int, int, int = 0, int = 0) const;
|
||||||
SDL_Surface* screen_surface() const;
|
SDL_Surface* screen_surface() const;
|
||||||
SDL_Surface* screen_surface_from_pixels(unsigned char*, bool) const;
|
SDL_Surface* screen_surface_from_pixels(unsigned char*, bool) const;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* /\ +--------------------------------------------------------------+
|
/* /\ +--------------------------------------------------------------+
|
||||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
____/ \____ /| - 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] |
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
|
16
src/Node.cpp
16
src/Node.cpp
|
@ -1,3 +1,13 @@
|
||||||
|
/* /\ +--------------------------------------------------------------+
|
||||||
|
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
\ / / | copy, and modify without restriction |
|
||||||
|
+--\ ^__^ /--+ | |
|
||||||
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
| SPACE ~~~~~ | /
|
||||||
|
| ~~~~~~~ BOX |/
|
||||||
|
+-------------*/
|
||||||
|
|
||||||
#include "Configuration.hpp"
|
#include "Configuration.hpp"
|
||||||
#include "Delegate.hpp"
|
#include "Delegate.hpp"
|
||||||
#include "Display.hpp"
|
#include "Display.hpp"
|
||||||
|
@ -99,9 +109,11 @@ const Game* Node::get_root() const
|
||||||
return dynamic_cast<const Game*>(r);
|
return dynamic_cast<const Game*>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Box Node::window_box(bool use_gl_coordinates)
|
/* Get the window dimensions in pixels as a box object. If invert_y is set, the bottom left will be (0, 0).
|
||||||
|
* Otherwise, it the top left will be (0, 0). */
|
||||||
|
Box Node::window_box(bool invert_y)
|
||||||
{
|
{
|
||||||
return get_display().window_box(use_gl_coordinates);
|
return get_display().window_box(invert_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::suppress_input()
|
void Node::suppress_input()
|
||||||
|
|
10
src/Node.hpp
10
src/Node.hpp
|
@ -1,3 +1,13 @@
|
||||||
|
/* /\ +--------------------------------------------------------------+
|
||||||
|
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
\ / / | copy, and modify without restriction |
|
||||||
|
+--\ ^__^ /--+ | |
|
||||||
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
| SPACE ~~~~~ | /
|
||||||
|
| ~~~~~~~ BOX |/
|
||||||
|
+-------------*/
|
||||||
|
|
||||||
#ifndef SB_NODE_H_
|
#ifndef SB_NODE_H_
|
||||||
#define SB_NODE_H_
|
#define SB_NODE_H_
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue