squircle and 2d collision demo; config auto refresh
|
@ -1,4 +1,6 @@
|
||||||
*.o
|
*.o
|
||||||
local/
|
local/
|
||||||
build/
|
build/
|
||||||
demo/demo
|
demo/2d_collision/2d_collision
|
||||||
|
demo/squircle/squircle
|
||||||
|
demo/cube/cube
|
||||||
|
|
162
README
|
@ -1,26 +1,37 @@
|
||||||
++~~~~~~~~~~~~~~~~~~~~~~~++
|
/\ +--------------------------------------------------------------+
|
||||||
++~~~~~~~~~~~~~~~~~~~~~~~++
|
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
:: ::
|
\ / / | copy, modify and sell without restriction |
|
||||||
:: SFW (SDL Framework) ::
|
+--\ ^__^ /--+ | |
|
||||||
:: ::
|
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
++~~~~~~~~~~~~~~~~~~~~~~~++
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
++~~~~~~~~~~~~~~~~~~~~~~~++
|
| SPACE ~~~~~ | /
|
||||||
|
| ~~~~~~~ BOX |/
|
||||||
|
+--------------+
|
||||||
|
|
||||||
|
[SPACE BOX] is a C++ framework that facilitates the creation of SDL + OpenGL projects
|
||||||
|
through the use of generic objects that can be used and extended by the programmer. It
|
||||||
|
focuses on game projects but its usefulness is not limited to games.
|
||||||
|
|
||||||
SFW is a C++ framework that facilitates the creation of SDL projects. It
|
The main intention for the project is to make running cross-platform applications easier
|
||||||
provides generic game objects that can be used, extended or overwritten. Games
|
and more immediate by providing a universal tool set that exists as a hidden, extensible
|
||||||
written using this framework can be exported to PC, Mac, Linux, Web GL,
|
layer between SDL + OpenGL and the project.
|
||||||
Raspberry Pi, and Android.
|
|
||||||
|
|
||||||
It is in an early untested state. It comes with a simple program that
|
An important quality of the framework is it should allow the programmer to start a project
|
||||||
demonstrates how to use it for a project that can switch between SDL and OpenGL
|
by extending only a single function, the Game class's update function. Additionally, the
|
||||||
contexts.
|
framework should by default create applications that can be easily exported to many
|
||||||
|
platforms (PC, OS/X, Linux, Web GL, Raspberry Pi, and Android) by using a standard
|
||||||
|
Makefile.
|
||||||
|
|
||||||
Requirements
|
It is in an early, untested state. It comes with a few simple examples that demonstrate
|
||||||
````````````
|
how in can be used to create interactive graphics programs.
|
||||||
The SFW source includes some external libraries in lib/ that the default
|
|
||||||
Makefile included with the demo shows how to compile, but there are other
|
################
|
||||||
libraries that must also be present in order to compile a project which uses the
|
# Requirements #
|
||||||
framework
|
################
|
||||||
|
|
||||||
|
The repository includes some external libraries in lib/ that the default Makefile included
|
||||||
|
with the demo shows how to compile, but there are other requirements, including external
|
||||||
|
libraries that must be linked to a project in order to compile it.
|
||||||
|
|
||||||
* libSDL2 (developed against v2.0.14)
|
* libSDL2 (developed against v2.0.14)
|
||||||
* libSDL2-image
|
* libSDL2-image
|
||||||
|
@ -29,22 +40,23 @@ framework
|
||||||
* OpenGL/GLES/GLES2
|
* OpenGL/GLES/GLES2
|
||||||
* compiler that supports C++17
|
* compiler that supports C++17
|
||||||
|
|
||||||
Installing Requirements
|
###########################
|
||||||
```````````````````````
|
# Installing Requirements #
|
||||||
libSDL2, libSDL2-image, libSDL2-ttf, and libSDL2-mixer must be available to
|
###########################
|
||||||
link with your project, so you can try your package manager's libSDL2 dev
|
|
||||||
packages or build from source. The included sdl2-config utility program can be
|
|
||||||
used to generate flags for linking to SDL2 when it is installed outside of
|
|
||||||
your platform's usual library location.
|
|
||||||
|
|
||||||
libSDL2:
|
libSDL2, libSDL2-image, libSDL2-ttf, and libSDL2-mixer must be available to link with your
|
||||||
|
project, so you can try your package manager's libSDL2 dev packages or build from source.
|
||||||
|
The included sdl2-config utility program can be used to generate flags for linking to SDL2
|
||||||
|
when it is installed outside of your platform's usual library location.
|
||||||
|
|
||||||
|
libSDL2
|
||||||
|
```````
|
||||||
- Download from http://libsdl.org/download-2.0.php
|
- Download from http://libsdl.org/download-2.0.php
|
||||||
- Run ./configure --prefix=[YOUR LIBRARIES PATH] (I'm using $HOME/local/sdl)
|
- Run ./configure --prefix=[YOUR LIBRARIES PATH] (I'm using $HOME/local/sdl)
|
||||||
- Run make && make install
|
- Run make && make install
|
||||||
|
|
||||||
libSDL2-image, libSDL2-ttf, libSDL2-mixer:
|
libSDL2-image, libSDL2-ttf, libSDL2-mixer
|
||||||
|
`````````````````````````````````````````
|
||||||
- Download from:
|
- Download from:
|
||||||
- https://www.libsdl.org/projects/SDL_image/
|
- https://www.libsdl.org/projects/SDL_image/
|
||||||
- https://www.libsdl.org/projects/SDL_ttf/
|
- https://www.libsdl.org/projects/SDL_ttf/
|
||||||
|
@ -52,48 +64,80 @@ libSDL2-image, libSDL2-ttf, libSDL2-mixer:
|
||||||
- Run ./configure --prefix=[YOUR LIB PATH] --with-sdl-prefix=[YOUR SDL PATH]
|
- Run ./configure --prefix=[YOUR LIB PATH] --with-sdl-prefix=[YOUR SDL PATH]
|
||||||
- In my case, prefix and SDL prefix are both $HOME/local/sdl
|
- In my case, prefix and SDL prefix are both $HOME/local/sdl
|
||||||
|
|
||||||
OpenGL/GLES/GLES2:
|
OpenGL/GLES/GLES2
|
||||||
|
`````````````````
|
||||||
|
- Install GL/GLES according to your platform and link to it during compilation. GLEW is
|
||||||
|
included in the lib/ folder of this framework and should find GL on your platform if it
|
||||||
|
is installed.
|
||||||
|
|
||||||
- Install GL/GLES according to your platform and link to it during compilation.
|
#########
|
||||||
GLEW is included in the lib/ folder of this framework and should find GL on
|
# Demos #
|
||||||
your platform if it is installed.
|
#########
|
||||||
|
|
||||||
Demo
|
The `demo/` folder contains programs that demonstrate and test the capabilities of the
|
||||||
|
framework. In order to compile each, you should edit the definitions in the Makefile.
|
||||||
|
|
||||||
|
cube
|
||||||
````
|
````
|
||||||
The `demo/` folder contains a simple cube demo. The main purpose of the demo is
|
Switch between GL and SDL contexts by pressing spacebar. The GL context draws a textured,
|
||||||
to demonstrate switching between 3D and 2D contexts. In order to compile the
|
rotating cube, and the SDL context draws basic geometric shapes and a moving 2D sprite.
|
||||||
demo, you will have to edit the paths in the Makefile to point to the locations
|
|
||||||
of the necessary libraries on your system.
|
|
||||||
|
|
||||||
Other libraries
|
2d_collision
|
||||||
```````````````
|
````````````
|
||||||
These are other libraries that have been used in projects that use this
|
Test collision detection between a 2D sprite and other 2D sprites and boxes. Per-pixel
|
||||||
framework but aren't required by the framework
|
collision can be tested.
|
||||||
|
|
||||||
opencv:
|
squircle
|
||||||
|
````````
|
||||||
|
Map an image from a rectangle to a circle or from a circle to a rectangle using a shader
|
||||||
|
program. Based on the elliptical grid mapping equations at:
|
||||||
|
|
||||||
|
- http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html
|
||||||
|
|
||||||
|
###################
|
||||||
|
# Other libraries #
|
||||||
|
###################
|
||||||
|
|
||||||
|
These are other libraries that have been used in projects that use this framework but
|
||||||
|
aren't required by the framework
|
||||||
|
|
||||||
|
opencv
|
||||||
|
``````
|
||||||
- Download from https://opencv.org/releases/
|
- Download from https://opencv.org/releases/
|
||||||
- configure (with custom installation path)
|
- configure (with custom installation path)
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=$HOME/local/opencv ..
|
cmake -DCMAKE_INSTALL_PREFIX=$HOME/local/opencv ..
|
||||||
- make && make install
|
- make && make install
|
||||||
|
|
||||||
zbar:
|
zbar
|
||||||
|
````
|
||||||
- Download from http://zbar.sourceforge.net/download.html
|
- Download from http://zbar.sourceforge.net/download.html
|
||||||
- configure to only use image processing features (requires imagemagick) and
|
- configure to only use image processing features (requires imagemagick) and
|
||||||
choose your installation directory
|
choose your installation directory
|
||||||
./configure --without-gtk --without-python --without-qt --disable-video --prefix=$HOME/local/zbar
|
./configure --without-gtk --without-python --without-qt --disable-video --prefix=$HOME/local/zbar
|
||||||
- make && make install
|
- make && make install
|
||||||
|
|
||||||
License
|
########
|
||||||
```````
|
# Font #
|
||||||
The original code for this framework is licensed to freely use, copy, modify and
|
########
|
||||||
sell, without restriction under the zlib license. See LICENSE.txt for details.
|
|
||||||
|
When initializing a Game object, the framework will attempt to load the font file
|
||||||
|
"BPmono.ttf" from the project root (where the compiled executable is located). If this
|
||||||
|
file isn't found, the program can still run successfully, but the framerate indicator
|
||||||
|
(mapped to CTRL+f by default) will be disabled. The repository contains "BPmono.ttf", so
|
||||||
|
you can create a symlink to the file in the project root if you want to use the framerate
|
||||||
|
indicator.
|
||||||
|
|
||||||
|
###########
|
||||||
|
# License #
|
||||||
|
###########
|
||||||
|
|
||||||
|
The original code for this framework is licensed to freely use, copy, modify and sell,
|
||||||
|
without restriction under the zlib license. See LICENSE.txt for details.
|
||||||
|
|
||||||
Included libraries are included under various permissive licenses:
|
Included libraries are included under various permissive licenses:
|
||||||
|
|
||||||
- BPmono.ttf is licensed under the Creative Commons Attribution - No Derivative
|
- BPmono.ttf is licensed under the Creative Commons Attribution - No Derivative Works 3.0
|
||||||
Works 3.0 license. See LICENSE_BPmono.txt for details.
|
license. See LICENSE_BPmono.txt for details.
|
||||||
|
|
||||||
- gif-h is unlicensed, public domain code released under the The Unlicense. See
|
- gif-h is unlicensed, public domain code released under the The Unlicense. See
|
||||||
lib/gif-h/LICENSE
|
lib/gif-h/LICENSE
|
||||||
|
@ -102,14 +146,14 @@ Included libraries are included under various permissive licenses:
|
||||||
|
|
||||||
- GLM is included under the MIT license in lib/glm/LICENSE
|
- GLM is included under the MIT license in lib/glm/LICENSE
|
||||||
|
|
||||||
- nlohmann's json library is included under the MIT license in
|
- nlohmann's json library is included under the MIT license in lib/json/LICENSE.MIT
|
||||||
lib/json/LICENSE.MIT
|
|
||||||
|
|
||||||
- SDL2 GFX is included under a permissive license in lib/sdl2-gfx/LICENSE
|
- SDL2 GFX is included under a permissive license in lib/sdl2-gfx/LICENSE
|
||||||
|
|
||||||
- superxbr.cpp is included under a permissive license at the top of
|
- superxbr.cpp is included under the permissive license at the top of lib/superxbr.cpp
|
||||||
lib/superxbr.cpp
|
|
||||||
|
|
||||||
Business
|
############
|
||||||
````````
|
# Business #
|
||||||
420@shampoo.ooo
|
############
|
||||||
|
|
||||||
|
egg@shampoo.ooo
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../BPmono.ttf
|
|
@ -0,0 +1,173 @@
|
||||||
|
#include "CollisionTest.hpp"
|
||||||
|
|
||||||
|
CollisionTest::CollisionTest() : Game()
|
||||||
|
{
|
||||||
|
get_delegate().subscribe(&CollisionTest::respond, this);
|
||||||
|
load_sdl_context();
|
||||||
|
enemy.set_color_mod({255, 128, 128, 255});
|
||||||
|
wooper.load();
|
||||||
|
enemy.load();
|
||||||
|
wooper.add_box({80, 200});
|
||||||
|
enemy.add_box({90, 100});
|
||||||
|
wooper.add_box({300, 10});
|
||||||
|
enemy.add_box({90, 200});
|
||||||
|
wooper.add_box({180, 20});
|
||||||
|
enemy.add_box({180, 50});
|
||||||
|
enemy.move({50, 50});
|
||||||
|
Pixels wooper_pixels = Pixels(wooper);
|
||||||
|
for (int x = 0; x < wooper.get_w(); x++)
|
||||||
|
{
|
||||||
|
wooper_pixels.set(Color(128, 255, 64), x, 12);
|
||||||
|
}
|
||||||
|
wooper_pixels.apply();
|
||||||
|
Box box = {{5, 10}, {20, 4}};
|
||||||
|
Pixels enemy_pixels = Pixels(enemy, box);
|
||||||
|
for (int x = -1, y = -1; x > -box.width(); x--, y--)
|
||||||
|
{
|
||||||
|
enemy_pixels.set(Color(-1.3, 68.9, 800.8), x, y);
|
||||||
|
}
|
||||||
|
enemy_pixels.apply();
|
||||||
|
canvas = SDL_CreateTexture(get_renderer(), SDL_PIXELFORMAT_RGBA4444, SDL_TEXTUREACCESS_STREAMING, 200, 100);
|
||||||
|
Pixels canvas_pixels = Pixels(get_renderer(), canvas);
|
||||||
|
for (int x = 0, y = 0; x < 288; x++, y += x)
|
||||||
|
{
|
||||||
|
canvas_pixels.set(Color(x, y, x + y), x, y);
|
||||||
|
}
|
||||||
|
canvas_pixels.apply();
|
||||||
|
Box subsection = Box({5, 10}, {60, 20});
|
||||||
|
Pixels sub_canvas_pixels = Pixels(get_renderer(), canvas, subsection);
|
||||||
|
for (int x = 0; x < subsection.width(); x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < subsection.height(); y++)
|
||||||
|
{
|
||||||
|
// *canvas_pixels.operator()<std::uint16_t*>(x, y) = 0xfb60;
|
||||||
|
*canvas_pixels.operator()<std::uint16_t*>(x, y) = Color(255, 200, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_Color color = {0, 1, 2, 3};
|
||||||
|
std::cout << std::boolalpha << (Color(255, 255, 255) == Color(255, 255, 255)) << " " <<
|
||||||
|
(Color(122.1, 853.8, -1.3) == Color(122, 86, 255)) << " " << (Color(1, 2, 3, 4) == ((SDL_Color){1, 2, 3, 4})) << " " <<
|
||||||
|
(Color(256, 257, 258, 259) != color) << std::endl;
|
||||||
|
sub_canvas_pixels.apply();
|
||||||
|
test_crop(
|
||||||
|
{
|
||||||
|
Box({-5, -2}, {10, 5}),
|
||||||
|
Box({window_box().right() - 30, 10}, {100, 1000}),
|
||||||
|
Box(window_box().se() - glm::vec2(10, 15), {789, 123}),
|
||||||
|
Box(window_box().sw() - glm::vec2(1, 1), {5, 5})
|
||||||
|
});
|
||||||
|
// std::cout << "out of bounds pixel is " << screen_subsection_pixels.get(0, 0) <<
|
||||||
|
// " out of bounds pixel is " << screen_subsection_pixels.get(-1, 0) <<
|
||||||
|
// " in bounds pixel is " << screen_subsection_pixels.get(0, -1) <<
|
||||||
|
// " out of bounds pixel is " << screen_subsection_pixels.get(-1, -1) << std::endl;
|
||||||
|
// screen_subsection_pixels.set(Color(255, 0, 0), 0, -1);
|
||||||
|
// screen_subsection_pixels.set(Color(255, 255, 255), 0, 0);
|
||||||
|
// screen_subsection_pixels.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionTest::test_crop(const std::vector<Box>& boxes)
|
||||||
|
{
|
||||||
|
for (const Box& box : boxes)
|
||||||
|
{
|
||||||
|
Pixels screen_subsection_pixels = Pixels(get_renderer(), nullptr, box);
|
||||||
|
std::cout << box << " cropped by screen to " << screen_subsection_pixels.rect << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionTest::respond(SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (get_delegate().compare(event, "up"))
|
||||||
|
{
|
||||||
|
wooper.move_weighted({0, -2});
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "left"))
|
||||||
|
{
|
||||||
|
wooper.move_weighted({-2, 0});
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "right"))
|
||||||
|
{
|
||||||
|
wooper.move_weighted({2, 0});
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "down"))
|
||||||
|
{
|
||||||
|
wooper.move_weighted({0, 2});
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "toggle-collide-all"))
|
||||||
|
{
|
||||||
|
collide_all = !collide_all;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "toggle-collide-all-other"))
|
||||||
|
{
|
||||||
|
collide_all_other = !collide_all_other;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "toggle-precise-collision"))
|
||||||
|
{
|
||||||
|
precise = !precise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionTest::update()
|
||||||
|
{
|
||||||
|
SDL_SetRenderTarget(get_renderer(), NULL);
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), 64, 128, 64, 255);
|
||||||
|
SDL_RenderClear(get_renderer());
|
||||||
|
wooper.update();
|
||||||
|
enemy.update();
|
||||||
|
SDL_Color white = {255, 255, 255, 255}, red = {255, 0, 0, 255}, color;
|
||||||
|
Box overlap;
|
||||||
|
SDL_Rect rect;
|
||||||
|
for (const Box& box : boxes)
|
||||||
|
{
|
||||||
|
color = wooper.collide(box, overlap, precise, collide_all) ? red : white;
|
||||||
|
SDL_SetRenderTarget(get_renderer(), NULL);
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
|
||||||
|
rect = box;
|
||||||
|
SDL_RenderDrawRect(get_renderer(), &rect);
|
||||||
|
rect = overlap;
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), 255, 255, 0, 255);
|
||||||
|
SDL_RenderDrawRect(get_renderer(), &rect);
|
||||||
|
}
|
||||||
|
glm::vec2 intersection;
|
||||||
|
for (const Segment& segment : segments)
|
||||||
|
{
|
||||||
|
color = wooper.collide(segment, intersection, collide_all) ? red : white;
|
||||||
|
glm::vec2 start = segment.start(), end = segment.end();
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
|
||||||
|
SDL_RenderDrawLine(get_renderer(), start.x, start.y, end.x, end.y);
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), 255, 255, 0, 255);
|
||||||
|
SDL_RenderDrawPoint(get_renderer(), intersection.x, intersection.y);
|
||||||
|
}
|
||||||
|
for (const glm::vec2& point : points)
|
||||||
|
{
|
||||||
|
color = wooper.collide(point, collide_all) ? red : white;
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
|
||||||
|
SDL_RenderDrawPoint(get_renderer(), point.x, point.y);
|
||||||
|
}
|
||||||
|
if (wooper.collide(enemy, overlap, precise, collide_all, collide_all_other))
|
||||||
|
{
|
||||||
|
SDL_SetRenderTarget(get_renderer(), nullptr);
|
||||||
|
SDL_SetRenderDrawColor(get_renderer(), 0, 255, 0, 255);
|
||||||
|
rect = overlap;
|
||||||
|
SDL_RenderDrawRect(get_renderer(), &rect);
|
||||||
|
}
|
||||||
|
Box screen_subsection_box = Box({0, 0}, {30, 60});
|
||||||
|
screen_subsection_box.sw(window_box().sw());
|
||||||
|
Pixels screen_subsection_pixels = Pixels(get_renderer(), nullptr, screen_subsection_box);
|
||||||
|
for (int x = 0; x < screen_subsection_pixels.rect.w; x++)
|
||||||
|
{
|
||||||
|
screen_subsection_pixels.set(Color(255, 0, 255), x, 5);
|
||||||
|
}
|
||||||
|
screen_subsection_pixels.apply();
|
||||||
|
SDL_SetRenderTarget(get_renderer(), nullptr);
|
||||||
|
Box canvas_box = sfw::get_texture_box(canvas);
|
||||||
|
canvas_box.nw({340, 200});
|
||||||
|
SDL_RenderCopyF(get_renderer(), canvas, nullptr, &canvas_box);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CollisionTest collision_test = CollisionTest();
|
||||||
|
collision_test.run();
|
||||||
|
collision_test.quit();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef CollisionTest_h_
|
||||||
|
#define CollisionTest_h_
|
||||||
|
|
||||||
|
#include "Game.hpp"
|
||||||
|
#include "Sprite.hpp"
|
||||||
|
#include "Pixels.hpp"
|
||||||
|
#include "Color.hpp"
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
class CollisionTest : public Game
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Sprite wooper = Sprite(this, "wooper.png");
|
||||||
|
Sprite enemy = Sprite(this, "wooper.png");
|
||||||
|
SDL_Texture* canvas;
|
||||||
|
std::vector<Box> boxes = {
|
||||||
|
{{50, 20}, {20, 10}},
|
||||||
|
{{300, 100}, {50, 60}},
|
||||||
|
{{160, 300}, {30, 10}},
|
||||||
|
};
|
||||||
|
std::vector<Segment> segments = {
|
||||||
|
{{5, 50}, {15, 90}},
|
||||||
|
{{250, 250}, {200, 240}}
|
||||||
|
};
|
||||||
|
std::vector<glm::vec2> points = {{100, 300}, {205, 20}, {450, 300}};
|
||||||
|
bool collide_all = false;
|
||||||
|
bool collide_all_other = false;
|
||||||
|
bool precise = false;
|
||||||
|
|
||||||
|
void test_crop(const std::vector<Box>&);
|
||||||
|
void respond(SDL_Event&);
|
||||||
|
void update();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CollisionTest();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,101 @@
|
||||||
|
# /\ +--------------------------------------------------------------+
|
||||||
|
# ____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
# \ / / | copy, modify and sell without restriction |
|
||||||
|
# +--\ ^__^ /--+ | |
|
||||||
|
# | ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
# | ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
# | SPACE ~~~~~ | /
|
||||||
|
# | ~~~~~~~ BOX |/
|
||||||
|
# +--------------+
|
||||||
|
#
|
||||||
|
# [ Makefile for 2D collision demo ]
|
||||||
|
#
|
||||||
|
# This should build the 2D collision demo for Linux. Compilation to other platforms
|
||||||
|
# hasn't been attempted yet.
|
||||||
|
#
|
||||||
|
# Edit the parameters as necessary and run `make linux` in the current directory.
|
||||||
|
#
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# Location parameters #
|
||||||
|
#######################
|
||||||
|
|
||||||
|
# Location of source files for the demo
|
||||||
|
SRC_DIR := ./
|
||||||
|
|
||||||
|
# Locations of [SPACE BOX] source and dependencies required to be compiled from source. These
|
||||||
|
# locations are configured to match the structure of the [SPACE BOX] repository but can be
|
||||||
|
# modified as necessary.
|
||||||
|
SB_DIR := ../../
|
||||||
|
SB_SRC_DIR := $(SB_DIR)src/
|
||||||
|
SB_LIB_DIR := $(SB_DIR)lib/
|
||||||
|
SDLGFX2_DIR := $(SB_LIB_DIR)sdl2-gfx/
|
||||||
|
GLEW_DIR := $(SB_LIB_DIR)glew/
|
||||||
|
|
||||||
|
# C and C++ compiler commands
|
||||||
|
CC := clang
|
||||||
|
CPPC := clang++
|
||||||
|
|
||||||
|
# Location of SDL config program
|
||||||
|
SDLCONFIG := ~/local/sdl/bin/sdl2-config
|
||||||
|
|
||||||
|
# Edit to point to the location of BPmono.ttf
|
||||||
|
CREATE_FONT_SYMLINK := ln -nsf $(SB_DIR)"BPmono.ttf" .
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# Based on above parameters #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
CFLAGS := -Wall -O0 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) -g $(shell $(SDLCONFIG) --cflags)
|
||||||
|
CPP_FLAGS := $(CFLAGS) --std=c++17
|
||||||
|
LFLAGS := $(shell $(SDLCONFIG) --libs) -lpthread
|
||||||
|
SB_H_FILES := $(wildcard $(addprefix $(SB_SRC_DIR),*.hpp))
|
||||||
|
SB_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o),$(SB_H_FILES:.hpp=.o))
|
||||||
|
SRC_H_FILES := $(wildcard $(addprefix $(SRC_DIR),*.hpp))
|
||||||
|
SRC_O_FILES := $(SRC_H_FILES:.hpp=.o)
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# Targets for building [SPACE BOX], dependencies and demo source #
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
$(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
||||||
|
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
||||||
|
$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \
|
||||||
|
Delegate.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp)
|
||||||
|
$(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp)
|
||||||
|
$(SB_SRC_DIR)Delegate.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Input.hpp)
|
||||||
|
$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp)
|
||||||
|
$(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp)
|
||||||
|
$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp)
|
||||||
|
$(SRC_DIR)CollisionTest.o : $(SB_H_FILES)
|
||||||
|
%.o : %.cpp %.hpp
|
||||||
|
$(CPPC) $(CPP_FLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# Target for Linux build #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
linux : $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) \
|
||||||
|
$(SB_O_FILES) CollisionTest.o
|
||||||
|
$(CREATE_FONT_SYMLINK)
|
||||||
|
$(CPPC) $(LFLAGS) -D__LINUX__ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs $^ -o 2d_collision
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Target for cleaning up object files #
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
clean :
|
||||||
|
- rm *.o
|
||||||
|
- rm $(SB_SRC_DIR)*.o
|
||||||
|
- rm $(GLEW_DIR)*.o
|
||||||
|
- rm $(SDLGFX2_DIR)*.o
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"keys":
|
||||||
|
{
|
||||||
|
"toggle-collide-all": ["CTRL", "c"],
|
||||||
|
"toggle-collide-all-other": ["CTRL", "o"],
|
||||||
|
"toggle-precise-collision": ["CTRL", "p"]
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 425 B |
120
demo/Makefile
|
@ -1,120 +0,0 @@
|
||||||
SFW_DIR = ../
|
|
||||||
SFW_SRC_DIR = $(SFW_DIR)src/
|
|
||||||
SFW_LIB_DIR = $(SFW_DIR)lib/
|
|
||||||
SDLGFX2_DIR = $(SFW_LIB_DIR)sdl2-gfx/
|
|
||||||
GLEW_DIR = $(SFW_LIB_DIR)glew/
|
|
||||||
CC_LINUX = clang-7
|
|
||||||
CPPC_LINUX = clang++-7
|
|
||||||
SDLCONFIG = /home/frank/local/sdl/bin/sdl2-config
|
|
||||||
CFLAGS = -Wall -O0 -c -I$(SFW_LIB_DIR) -I$(SFW_SRC_DIR) -g
|
|
||||||
CPP_FLAGS = $(CFLAGS) --std=c++17
|
|
||||||
SDL_FLAGS = $(shell $(SDLCONFIG) --cflags)
|
|
||||||
LFLAGS = $(shell $(SDLCONFIG) --libs) -lpthread
|
|
||||||
export ANDROID_HOME = /home/frank/ext/software/android-sdk
|
|
||||||
export ANDROID_NDK_HOME = /home/frank/ext/software/android-ndk-r8d
|
|
||||||
BUILDDIR = build
|
|
||||||
ANDROIDPROJECT = com.tarecontrol.demo
|
|
||||||
SOFTWARE_ROOT = /home/frank/ext/software
|
|
||||||
SDLHOME = $(SOFTWARE_ROOT)/SDL2-2.0.9
|
|
||||||
SDL_IMG_HOME = $(SOFTWARE_ROOT)/SDL2_image-2.0.4
|
|
||||||
SDL_TTF_HOME = $(SOFTWARE_ROOT)/SDL2_ttf-2.0.14
|
|
||||||
GLEW_WIN32_HOME = $(SOFTWARE_ROOT)/glew-2.1.0-win32
|
|
||||||
PROJECTHOME = $(shell pwd)
|
|
||||||
EMSCRIPTENHOME = /home/frank/ext/software/emsdk/emscripten/tag-1.38.12
|
|
||||||
SDLEMLIBSHOME = $(SDLHOME)/build/em/build/.libs
|
|
||||||
EMBUILDDIR = em
|
|
||||||
WINBUILDDIR = win
|
|
||||||
SDLMINGWHOME = $(SDLHOME)/i686-w64-mingw32
|
|
||||||
SDL_IMG_MINGW_HOME = $(SDL_IMG_HOME)/i686-w64-mingw32
|
|
||||||
SDL_TTF_MINGW_HOME = $(SDL_TTF_HOME)/i686-w64-mingw32
|
|
||||||
APPDIR = Main.app/Contents
|
|
||||||
SYSFWPATH = /Library/Frameworks
|
|
||||||
|
|
||||||
$(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
|
||||||
$(CC_LINUX) $(CFLAGS) $(SDL_FLAGS) $< -o $@
|
|
||||||
|
|
||||||
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
|
||||||
$(CC_LINUX) $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Box.*pp Node.*pp Animation.*pp)
|
|
||||||
$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Sprite.*pp Configuration.*pp Delegate.*pp Display.*pp \
|
|
||||||
Recorder.*pp Node.*pp Input.*pp)
|
|
||||||
$(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Configuration.*pp Delegate.*pp)
|
|
||||||
$(SFW_SRC_DIR)Animation.o: $(addprefix $(SFW_SRC_DIR),Node.*pp Timer.*pp)
|
|
||||||
$(SFW_SRC_DIR)Recorder.o: $(addprefix $(SFW_SRC_DIR),extension.*pp Node.*pp Delegate.*pp Animation.*pp Display.*pp)
|
|
||||||
$(SFW_SRC_DIR)Input.o: $(addprefix $(SFW_SRC_DIR),Delegate.*pp Node.*pp)
|
|
||||||
$(SFW_SRC_DIR)Configuration.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
|
|
||||||
$(SFW_SRC_DIR)Delegate.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
|
|
||||||
$(SFW_SRC_DIR)Display.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
|
|
||||||
$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp)
|
|
||||||
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@
|
|
||||||
|
|
||||||
Demo.o: Demo.cpp Demo.hpp $(addprefix $(SFW_SRC_DIR),Sprite.*pp Node.*pp Game.*pp Box.*pp Input.*pp \
|
|
||||||
Recorder.*pp Timer.*pp Animation.*pp extension.*pp)
|
|
||||||
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@
|
|
||||||
|
|
||||||
linux: Demo.o $(addprefix $(SFW_SRC_DIR),Sprite.o Node.o Game.o Box.o Configuration.o Input.o Delegate.o \
|
|
||||||
Display.o Recorder.o Timer.o Animation.o extension.o) \
|
|
||||||
$(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o)
|
|
||||||
$(CPPC_LINUX) $(LFLAGS) -D__LINUX__ $^ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs -o demo
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm *.o
|
|
||||||
rm $(SFW_SRC_DIR)*.o
|
|
||||||
rm $(GLEW_DIR)*.o
|
|
||||||
rm $(SDLGFX2_DIR)*.o
|
|
||||||
|
|
||||||
android :
|
|
||||||
if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi;
|
|
||||||
cd $(SDLHOME)/build-scripts/ && \
|
|
||||||
./androidbuild.sh $(ANDROIDPROJECT) $(PROJECTHOME)/main.cpp
|
|
||||||
cp -r $(SDLHOME)/build/$(ANDROIDPROJECT) $(BUILDDIR)
|
|
||||||
sed -i s/2\.3\.3/2\.2\.3/g $(BUILDDIR)/$(ANDROIDPROJECT)/build.gradle
|
|
||||||
sed -i s/26\.0\.1/23\.0\.1/g $(BUILDDIR)/$(ANDROIDPROJECT)/app/build.gradle
|
|
||||||
cd $(BUILDDIR)/$(ANDROIDPROJECT) && ./gradlew assembleDebug
|
|
||||||
|
|
||||||
emscripten :
|
|
||||||
if [ ! -d $(BUILDDIR)/$(EMBUILDDIR) ]; then mkdir -p $(BUILDDIR)/$(EMBUILDDIR); fi;
|
|
||||||
cd $(BUILDDIR)/$(EMBUILDDIR) && \
|
|
||||||
$(EMSCRIPTENHOME)/em++ -O2 $(PROJECTHOME)/main.cpp -I$(SDLHOME)/include \
|
|
||||||
-Wall -s USE_SDL=2 -o main.html
|
|
||||||
|
|
||||||
mingw :
|
|
||||||
if [ ! -d $(BUILDDIR)/$(WINBUILDDIR) ]; then mkdir -p $(BUILDDIR)/$(WINBUILDDIR); fi;
|
|
||||||
cd $(BUILDDIR)/$(WINBUILDDIR) && \
|
|
||||||
i686-w64-mingw32-g++ -std=c++17 $(PROJECTHOME)/main.cpp -I$(SDLMINGWHOME)/include/SDL2 \
|
|
||||||
-I$(SDL_IMG_MINGW_HOME)/include/SDL2 -I$(SDL_TTF_MINGW_HOME)/include/SDL2 $(INC) \
|
|
||||||
$(PROJECTHOME)/sdl2-gfx/SDL2_gfxPrimitives.c $(PROJECTHOME)/sdl2-gfx/SDL2_rotozoom.c $(PROJECTHOME)/glew/glew.c \
|
|
||||||
-L$(SDLMINGWHOME)/lib -L$(SDL_IMG_MINGW_HOME)/lib -L$(SDL_TTF_MINGW_HOME)/lib \
|
|
||||||
-lmingw32 -lSDL2_image \
|
|
||||||
-lSDL2_ttf -lstdc++fs \
|
|
||||||
-lSDL2main -lSDL2 -lopengl32 -Wall -O2 -o main.exe && \
|
|
||||||
cp $(SDLMINGWHOME)/bin/SDL2.dll $(SDL_IMG_MINGW_HOME)/bin/SDL2_image.dll \
|
|
||||||
$(SDL_TTF_MINGW_HOME)/bin/SDL2_ttf.dll .
|
|
||||||
|
|
||||||
osx :
|
|
||||||
g++ -I $(SYSFWPATH)/SDL2.framework/Headers $(INC) \
|
|
||||||
-I $(SYSFWPATH)/SDL2_image.framework/Headers -Wl,-rpath,$(SYSFWPATH) \
|
|
||||||
-framework SDL2 -framework SDL2_image -framework OpenGL main.cpp sdl2-gfx/SDL2_rotozoom.c \
|
|
||||||
-o main
|
|
||||||
|
|
||||||
osx-bundle :
|
|
||||||
if [ ! -d "$(APPDIR)" ]; then mkdir -p $(APPDIR); fi;
|
|
||||||
if [ ! -d "$(APPDIR)" ]; then mkdir $(APPDIR); fi;
|
|
||||||
if [ ! -d "$(APPDIR)/MacOS" ]; then mkdir $(APPDIR)/MacOS; fi;
|
|
||||||
if [ ! -d "$(APPDIR)/Frameworks" ]; then mkdir $(APPDIR)/Frameworks; fi;
|
|
||||||
if [ ! -d "$(APPDIR)/Resources" ]; then mkdir $(APPDIR)/Resources; fi;
|
|
||||||
touch $(APPDIR)/Info.plist
|
|
||||||
cp -r $(SYSFWPATH)/SDL2.framework $(APPDIR)/Frameworks
|
|
||||||
cp -r $(SYSFWPATH)/SDL2_image.framework $(APPDIR)/Frameworks
|
|
||||||
g++ -I $(SYSFWPATH)/SDL2.framework/Headers -I $(SYSFWPATH)/SDL2_image.framework/Headers \
|
|
||||||
-Wl,-rpath,@executable_path/../Frameworks -Wl,-rpath,$(SYSFWPATH) \
|
|
||||||
-framework SDL2 -framework SDL2_image -framework OpenGL main.cpp -o $(APPDIR)/MacOS/main
|
|
||||||
|
|
||||||
cross : linux android emscripten mingw
|
|
||||||
|
|
||||||
# main : main.o
|
|
||||||
# g++ -o main $(LFLAGS) -lGL main.o
|
|
||||||
|
|
||||||
# main.o : main.cpp
|
|
||||||
# g++ -c $(CFLAGS) -DLINUX main.cpp
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../BPmono.ttf
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "Demo.hpp"
|
#include "Cube.hpp"
|
||||||
|
|
||||||
char* file_to_buf(const char *path)
|
char* file_to_buf(const char *path)
|
||||||
{
|
{
|
||||||
|
@ -104,36 +104,6 @@ GLuint get_gl_texture_from_surface(SDL_Surface *surface, GLint mipmap_filter, bo
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface* get_framerate_indicator_surface(int frame_count)
|
|
||||||
{
|
|
||||||
TTF_Font* font = TTF_OpenFont("resource/SourceCodePro-Regular.otf", 14);
|
|
||||||
std::string padded = sfw::pad(frame_count, 2);
|
|
||||||
SDL_Surface* shaded = TTF_RenderText_Shaded(
|
|
||||||
font, padded.c_str(), {0, 0, 0}, {255, 255, 255});
|
|
||||||
SDL_Surface* converted = SDL_ConvertSurfaceFormat(
|
|
||||||
shaded, SDL_PIXELFORMAT_ARGB8888, 0);
|
|
||||||
SDL_Surface* flipped = zoomSurface(converted, 1, -1, SMOOTHING_OFF);
|
|
||||||
SDL_FreeSurface(shaded);
|
|
||||||
SDL_FreeSurface(converted);
|
|
||||||
if (not flipped)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Could not create text %s\n", SDL_GetError());
|
|
||||||
}
|
|
||||||
TTF_CloseFont(font);
|
|
||||||
return flipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_framerate_indicator(int frame_count, GLuint id)
|
|
||||||
{
|
|
||||||
SDL_Surface* message = get_framerate_indicator_surface(frame_count);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, message->w, message->h, GL_BGRA,
|
|
||||||
GL_UNSIGNED_BYTE, message->pixels);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
SDL_FreeSurface(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
|
Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
|
||||||
{
|
{
|
||||||
set_frame_length(500);
|
set_frame_length(500);
|
||||||
|
@ -142,41 +112,41 @@ Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
|
||||||
|
|
||||||
void Mushroom::update()
|
void Mushroom::update()
|
||||||
{
|
{
|
||||||
move(direction);
|
move_weighted({direction, 0});
|
||||||
int x = box.left();
|
int x = get_left();
|
||||||
glm::ivec2 resolution = get_display().window_size();
|
glm::ivec2 resolution = get_display().window_size();
|
||||||
if (x > resolution.x or x < 0)
|
if (x > resolution.x or x < 0)
|
||||||
{
|
{
|
||||||
direction = -direction;
|
direction = -direction;
|
||||||
if (x > resolution.x)
|
if (x > resolution.x)
|
||||||
{
|
{
|
||||||
move(resolution.x - x);
|
move({resolution.x - x, 0});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
move(-x);
|
move({-x, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Sprite::update();
|
Sprite::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Demo::Demo()
|
Cube::Cube()
|
||||||
{
|
{
|
||||||
Mix_Music *music = Mix_LoadMUS("resource/Field.mp3");
|
Mix_Music *music = Mix_LoadMUS("resource/Field.mp3");
|
||||||
// Mix_Music *music = Mix_LoadMUS("/home/frank/WATERMELON-clean.mp3");
|
// Mix_Music *music = Mix_LoadMUS("/home/frank/WATERMELON-clean.mp3");
|
||||||
Mix_PlayMusic(music, -1);
|
Mix_PlayMusic(music, -1);
|
||||||
load_gl_context();
|
load_gl_context();
|
||||||
delegate.subscribe(&Demo::respond, this);
|
delegate.subscribe(&Cube::respond, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Demo::load_sdl_context()
|
void Cube::load_sdl_context()
|
||||||
{
|
{
|
||||||
Game::load_sdl_context();
|
Game::load_sdl_context();
|
||||||
grass.load();
|
grass.load();
|
||||||
mushroom.load();
|
mushroom.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Demo::load_gl_context()
|
void Cube::load_gl_context()
|
||||||
{
|
{
|
||||||
Game::load_gl_context();
|
Game::load_gl_context();
|
||||||
grass.unload();
|
grass.unload();
|
||||||
|
@ -221,19 +191,12 @@ void Demo::load_gl_context()
|
||||||
};
|
};
|
||||||
GLuint background_colors_buffer;
|
GLuint background_colors_buffer;
|
||||||
glGenBuffers(1, &background_colors_buffer);
|
glGenBuffers(1, &background_colors_buffer);
|
||||||
std::array<glm::vec3, 6> framerate_indicator_vertices = {
|
|
||||||
{
|
|
||||||
{.9, 1, 0}, {1, 1, 0}, {.9, .9, 0},
|
|
||||||
{1, 1, 0}, {1, .9, 0}, {.9, .9, 0}
|
|
||||||
}};
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
std::vector<glm::vec3> vertices;
|
std::vector<glm::vec3> vertices;
|
||||||
vertices.reserve(cube.size() + background_vertices.size() + framerate_indicator_vertices.size());
|
vertices.reserve(cube.size() + background_vertices.size());
|
||||||
vertices.insert(vertices.begin(), cube.begin(), cube.end());
|
vertices.insert(vertices.begin(), cube.begin(), cube.end());
|
||||||
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
|
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
|
||||||
vertices.insert(vertices.end(), framerate_indicator_vertices.begin(),
|
|
||||||
framerate_indicator_vertices.end());
|
|
||||||
glm::ivec2 resolution = get_display().window_size();
|
glm::ivec2 resolution = get_display().window_size();
|
||||||
projection = glm::perspective(
|
projection = glm::perspective(
|
||||||
glm::radians(45.0f), resolution.x / (float) resolution.y, 0.1f,
|
glm::radians(45.0f), resolution.x / (float) resolution.y, 0.1f,
|
||||||
|
@ -253,11 +216,6 @@ void Demo::load_gl_context()
|
||||||
// face_ids.push_back(get_gl_texture_from_surface(surface, GL_LINEAR));
|
// face_ids.push_back(get_gl_texture_from_surface(surface, GL_LINEAR));
|
||||||
// SDL_FreeSurface(surface);
|
// SDL_FreeSurface(surface);
|
||||||
// }
|
// }
|
||||||
std::array<glm::vec2, 6> framerate_indicator_uv = {
|
|
||||||
{
|
|
||||||
{0, 1}, {1, 1}, {0, 0},
|
|
||||||
{1, 1}, {1, 0}, {0, 0}
|
|
||||||
}};
|
|
||||||
std::array<glm::vec2, 36> cube_uv = {
|
std::array<glm::vec2, 36> cube_uv = {
|
||||||
{
|
{
|
||||||
{1, 1}, {0, 1}, {0, 0},
|
{1, 1}, {0, 1}, {0, 0},
|
||||||
|
@ -274,10 +232,8 @@ void Demo::load_gl_context()
|
||||||
{1, 1}, {0, 1}, {0, 0}
|
{1, 1}, {0, 1}, {0, 0}
|
||||||
}};
|
}};
|
||||||
std::vector<glm::vec2> uv;
|
std::vector<glm::vec2> uv;
|
||||||
uv.reserve(cube_uv.size() + background_vertices.size() + framerate_indicator_uv.size());
|
uv.reserve(cube_uv.size() + background_vertices.size());
|
||||||
std::copy(cube_uv.begin(), cube_uv.end(), uv.begin());
|
std::copy(cube_uv.begin(), cube_uv.end(), uv.begin());
|
||||||
std::copy(framerate_indicator_uv.begin(), framerate_indicator_uv.end(),
|
|
||||||
uv.begin() + cube_uv.size() + background_vertices.size());
|
|
||||||
GLuint uvbuffer;
|
GLuint uvbuffer;
|
||||||
glGenBuffers(1, &uvbuffer);
|
glGenBuffers(1, &uvbuffer);
|
||||||
unsigned char fake_texture_color[4] = {255, 255, 255, 255};
|
unsigned char fake_texture_color[4] = {255, 255, 255, 255};
|
||||||
|
@ -330,13 +286,9 @@ void Demo::load_gl_context()
|
||||||
// glBindTexture(GL_TEXTURE_2D, space_texture_id);
|
// glBindTexture(GL_TEXTURE_2D, space_texture_id);
|
||||||
// glUniform1i(sampler_uniform_id, 0);
|
// glUniform1i(sampler_uniform_id, 0);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
frame_count_timestamp = SDL_GetTicks();
|
|
||||||
SDL_Surface* fps_surface = get_framerate_indicator_surface(frame_count);
|
|
||||||
framerate_texture_id = get_gl_texture_from_surface(fps_surface, GL_LINEAR);
|
|
||||||
SDL_FreeSurface(fps_surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Demo::respond(SDL_Event& event)
|
void Cube::respond(SDL_Event& event)
|
||||||
{
|
{
|
||||||
if (delegate.compare(event, "context"))
|
if (delegate.compare(event, "context"))
|
||||||
{
|
{
|
||||||
|
@ -367,7 +319,7 @@ void Demo::respond(SDL_Event& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Demo::update()
|
void Cube::update()
|
||||||
{
|
{
|
||||||
// while (SDL_PollEvent(&event))
|
// while (SDL_PollEvent(&event))
|
||||||
// {
|
// {
|
||||||
|
@ -440,16 +392,7 @@ void Demo::update()
|
||||||
glDisableVertexAttribArray(1);
|
glDisableVertexAttribArray(1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glDrawArrays(GL_TRIANGLES, 36, 6);
|
glDrawArrays(GL_TRIANGLES, 36, 6);
|
||||||
if (show_framerate)
|
float rotation = .0005f * get_frame_length();
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, framerate_texture_id);
|
|
||||||
glDisableVertexAttribArray(2);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttrib3f(2, 1, 1, 1);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 42, 6);
|
|
||||||
}
|
|
||||||
// printf("%s\n", glm::to_string(model).c_str());
|
|
||||||
float rotation = .0005f * frame_length;
|
|
||||||
model = glm::rotate(model, rotation, glm::vec3(0.0f, 1.0f, 0.0f));
|
model = glm::rotate(model, rotation, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
mvp = projection * view * model;
|
mvp = projection * view * model;
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
@ -482,40 +425,29 @@ void Demo::update()
|
||||||
int speed = 2;
|
int speed = 2;
|
||||||
if (up_active)
|
if (up_active)
|
||||||
{
|
{
|
||||||
grass.move(0, -speed);
|
grass.move_weighted({0, -speed});
|
||||||
}
|
}
|
||||||
if (right_active)
|
if (right_active)
|
||||||
{
|
{
|
||||||
grass.move(speed);
|
grass.move_weighted({speed, 0});
|
||||||
}
|
}
|
||||||
if (down_active)
|
if (down_active)
|
||||||
{
|
{
|
||||||
grass.move(0, speed);
|
grass.move_weighted({0, speed});
|
||||||
}
|
}
|
||||||
if (left_active)
|
if (left_active)
|
||||||
{
|
{
|
||||||
grass.move(-speed, 0);
|
grass.move_weighted({-speed, 0});
|
||||||
}
|
}
|
||||||
grass.update();
|
grass.update();
|
||||||
mushroom.update();
|
mushroom.update();
|
||||||
SDL_RenderPresent(renderer);
|
|
||||||
}
|
|
||||||
frame_count++;
|
|
||||||
if (ticks - frame_count_timestamp >= 1000)
|
|
||||||
{
|
|
||||||
frame_count_timestamp = ticks;
|
|
||||||
if (is_gl_context and show_framerate)
|
|
||||||
{
|
|
||||||
set_framerate_indicator(frame_count, framerate_texture_id);
|
|
||||||
}
|
|
||||||
frame_count = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main()
|
||||||
{
|
{
|
||||||
Demo demo = Demo();
|
Cube cube = Cube();
|
||||||
demo.run();
|
cube.run();
|
||||||
demo.quit();
|
cube.quit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -14,17 +14,6 @@
|
||||||
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
||||||
#include "sdl2-gfx/SDL2_rotozoom.h"
|
#include "sdl2-gfx/SDL2_rotozoom.h"
|
||||||
|
|
||||||
// #if defined(__LINUX__) or defined(__MINGW32__)
|
|
||||||
// #define GL_GLEXT_PROTOTYPES
|
|
||||||
// #include <GL/gl.h>
|
|
||||||
// #elif defined(__ANDROID__)
|
|
||||||
// #include <GLES/gl.h>
|
|
||||||
// #elif defined(__EMSCRIPTEN__)
|
|
||||||
// #include <GLES2/gl2.h>
|
|
||||||
// #elif defined(__APPLE__)
|
|
||||||
// #include <OpenGL/gl3.h>
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include "glm/gtx/string_cast.hpp"
|
#include "glm/gtx/string_cast.hpp"
|
||||||
#include "glm/gtx/transform.hpp"
|
#include "glm/gtx/transform.hpp"
|
||||||
|
@ -50,7 +39,7 @@ struct Mushroom : Sprite
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Demo : Game
|
struct Cube : Game
|
||||||
{
|
{
|
||||||
|
|
||||||
SDL_Texture *grass_texture;
|
SDL_Texture *grass_texture;
|
||||||
|
@ -66,7 +55,7 @@ struct Demo : Game
|
||||||
std::vector<GLuint> face_ids;
|
std::vector<GLuint> face_ids;
|
||||||
float amount_rotated;
|
float amount_rotated;
|
||||||
|
|
||||||
Demo();
|
Cube();
|
||||||
void load_sdl_context();
|
void load_sdl_context();
|
||||||
void load_gl_context();
|
void load_gl_context();
|
||||||
void respond(SDL_Event&);
|
void respond(SDL_Event&);
|
|
@ -0,0 +1,175 @@
|
||||||
|
# /\ +--------------------------------------------------------------+
|
||||||
|
# ____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
# \ / / | copy, modify and sell without restriction |
|
||||||
|
# +--\ ^__^ /--+ | |
|
||||||
|
# | ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
# | ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
# | SPACE ~~~~~ | /
|
||||||
|
# | ~~~~~~~ BOX |/
|
||||||
|
# +--------------+
|
||||||
|
#
|
||||||
|
# [ Makefile for cube demo ]
|
||||||
|
#
|
||||||
|
# This should build the cube demo for Linux. Other platforms haven't been tested in
|
||||||
|
# a while and won't work without significant editing.
|
||||||
|
#
|
||||||
|
# Edit the parameters as necessary and run `make linux` in the current directory.
|
||||||
|
#
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# Location parameters #
|
||||||
|
#######################
|
||||||
|
|
||||||
|
# Location of source files for the demo
|
||||||
|
SRC_DIR := ./
|
||||||
|
|
||||||
|
# Locations of [SPACE BOX] source and dependencies required to be compiled from source. These
|
||||||
|
# locations are configured to match the structure of the [SPACE BOX] repository but can be
|
||||||
|
# modified as necessary.
|
||||||
|
SB_DIR := ../../
|
||||||
|
SB_SRC_DIR := $(SB_DIR)src/
|
||||||
|
SB_LIB_DIR := $(SB_DIR)lib/
|
||||||
|
SDLGFX2_DIR := $(SB_LIB_DIR)sdl2-gfx/
|
||||||
|
GLEW_DIR := $(SB_LIB_DIR)glew/
|
||||||
|
|
||||||
|
# C and C++ compiler commands
|
||||||
|
CC_LINUX := clang
|
||||||
|
CPPC_LINUX := clang++
|
||||||
|
|
||||||
|
# Location of SDL config program
|
||||||
|
SDLCONFIG := ~/local/sdl/bin/sdl2-config
|
||||||
|
|
||||||
|
# Edit to point to the location of BPmono.ttf
|
||||||
|
CREATE_FONT_SYMLINK := ln -nsf $(SB_DIR)"BPmono.ttf" .
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# Based on above parameters #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
CFLAGS := -Wall -O0 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) -g $(shell $(SDLCONFIG) --cflags)
|
||||||
|
CPP_FLAGS := $(CFLAGS) --std=c++17
|
||||||
|
LFLAGS := $(shell $(SDLCONFIG) --libs) -lpthread
|
||||||
|
SFW_H_FILES := $(wildcard $(addprefix $(SB_SRC_DIR),*.hpp))
|
||||||
|
SFW_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o),$(SFW_H_FILES:.hpp=.o))
|
||||||
|
SRC_H_FILES := $(wildcard $(addprefix $(SRC_DIR),*.hpp))
|
||||||
|
SRC_O_FILES := $(SRC_H_FILES:.hpp=.o)
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# Targets for building [SPACE BOX], dependencies and demo source #
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
$(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
||||||
|
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
||||||
|
$(CC_LINUX) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \
|
||||||
|
Delegate.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp)
|
||||||
|
$(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp)
|
||||||
|
$(SB_SRC_DIR)Delegate.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Input.hpp)
|
||||||
|
$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp)
|
||||||
|
$(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp)
|
||||||
|
$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp)
|
||||||
|
$(SRC_DIR)Cube.o : $(SFW_H_FILES)
|
||||||
|
%.o : %.cpp %.hpp
|
||||||
|
$(CPPC_LINUX) $(CPP_FLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# Target for Linux build #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
linux : $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) \
|
||||||
|
$(SRC_O_FILES) $(SFW_O_FILES)
|
||||||
|
$(CREATE_FONT_SYMLINK)
|
||||||
|
$(CPPC_LINUX) $(LFLAGS) -D__LINUX__ $^ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs -o cube
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Target for cleaning up object files #
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
clean :
|
||||||
|
- rm *.o
|
||||||
|
- rm $(SB_SRC_DIR)*.o
|
||||||
|
- rm $(GLEW_DIR)*.o
|
||||||
|
- rm $(SDLGFX2_DIR)*.o
|
||||||
|
|
||||||
|
#
|
||||||
|
# These assignments are necessary for cross-compiling to Android, web (via emscripten), Windows (via mingw),
|
||||||
|
# and OS/X. Cross-compilation targets have not been tested in a while and won't compile without significant changes.
|
||||||
|
#
|
||||||
|
|
||||||
|
export ANDROID_HOME = /home/frank/ext/software/android-sdk
|
||||||
|
export ANDROID_NDK_HOME = /home/frank/ext/software/android-ndk-r8d
|
||||||
|
BUILDDIR := build
|
||||||
|
ANDROIDPROJECT := com.nuggetsselect.demo
|
||||||
|
SOFTWARE_ROOT := /home/frank/ext/software
|
||||||
|
SDLHOME := $(SOFTWARE_ROOT)/SDL2-2.0.14
|
||||||
|
SDL_IMG_HOME := $(SOFTWARE_ROOT)/SDL2_image-2.0.5
|
||||||
|
SDL_TTF_HOME := $(SOFTWARE_ROOT)/SDL2_ttf-2.0.15
|
||||||
|
GLEW_WIN32_HOME := $(SOFTWARE_ROOT)/glew-2.1.0-win32
|
||||||
|
PROJECTHOME := $(shell pwd)
|
||||||
|
EMSCRIPTENHOME := /home/frank/ext/software/emsdk/emscripten/tag-1.38.12
|
||||||
|
SDLEMLIBSHOME := $(SDLHOME)/build/em/build/.libs
|
||||||
|
EMBUILDDIR := em
|
||||||
|
WINBUILDDIR := win
|
||||||
|
SDLMINGWHOME := $(SDLHOME)/i686-w64-mingw32
|
||||||
|
SDL_IMG_MINGW_HOME := $(SDL_IMG_HOME)/i686-w64-mingw32
|
||||||
|
SDL_TTF_MINGW_HOME := $(SDL_TTF_HOME)/i686-w64-mingw32
|
||||||
|
APPDIR := Main.app/Contents
|
||||||
|
SYSFWPATH := /Library/Frameworks
|
||||||
|
|
||||||
|
android :
|
||||||
|
if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi;
|
||||||
|
cd $(SDLHOME)/build-scripts/ && \
|
||||||
|
./androidbuild.sh $(ANDROIDPROJECT) $(PROJECTHOME)/main.cpp
|
||||||
|
cp -r $(SDLHOME)/build/$(ANDROIDPROJECT) $(BUILDDIR)
|
||||||
|
sed -i s/2\.3\.3/2\.2\.3/g $(BUILDDIR)/$(ANDROIDPROJECT)/build.gradle
|
||||||
|
sed -i s/26\.0\.1/23\.0\.1/g $(BUILDDIR)/$(ANDROIDPROJECT)/app/build.gradle
|
||||||
|
cd $(BUILDDIR)/$(ANDROIDPROJECT) && ./gradlew assembleDebug
|
||||||
|
|
||||||
|
emscripten :
|
||||||
|
if [ ! -d $(BUILDDIR)/$(EMBUILDDIR) ]; then mkdir -p $(BUILDDIR)/$(EMBUILDDIR); fi;
|
||||||
|
cd $(BUILDDIR)/$(EMBUILDDIR) && \
|
||||||
|
$(EMSCRIPTENHOME)/em++ -O2 $(PROJECTHOME)/main.cpp -I$(SDLHOME)/include \
|
||||||
|
-Wall -s USE_SDL=2 -o main.html
|
||||||
|
|
||||||
|
mingw :
|
||||||
|
if [ ! -d $(BUILDDIR)/$(WINBUILDDIR) ]; then mkdir -p $(BUILDDIR)/$(WINBUILDDIR); fi;
|
||||||
|
cd $(BUILDDIR)/$(WINBUILDDIR) && \
|
||||||
|
i686-w64-mingw32-g++ -std=c++17 $(PROJECTHOME)/main.cpp -I$(SDLMINGWHOME)/include/SDL2 \
|
||||||
|
-I$(SDL_IMG_MINGW_HOME)/include/SDL2 -I$(SDL_TTF_MINGW_HOME)/include/SDL2 $(INC) \
|
||||||
|
$(PROJECTHOME)/sdl2-gfx/SDL2_gfxPrimitives.c $(PROJECTHOME)/sdl2-gfx/SDL2_rotozoom.c $(PROJECTHOME)/glew/glew.c \
|
||||||
|
-L$(SDLMINGWHOME)/lib -L$(SDL_IMG_MINGW_HOME)/lib -L$(SDL_TTF_MINGW_HOME)/lib \
|
||||||
|
-lmingw32 -lSDL2_image \
|
||||||
|
-lSDL2_ttf -lstdc++fs \
|
||||||
|
-lSDL2main -lSDL2 -lopengl32 -Wall -O2 -o main.exe && \
|
||||||
|
cp $(SDLMINGWHOME)/bin/SDL2.dll $(SDL_IMG_MINGW_HOME)/bin/SDL2_image.dll \
|
||||||
|
$(SDL_TTF_MINGW_HOME)/bin/SDL2_ttf.dll .
|
||||||
|
|
||||||
|
osx :
|
||||||
|
g++ -I $(SYSFWPATH)/SDL2.framework/Headers $(INC) \
|
||||||
|
-I $(SYSFWPATH)/SDL2_image.framework/Headers -Wl,-rpath,$(SYSFWPATH) \
|
||||||
|
-framework SDL2 -framework SDL2_image -framework OpenGL main.cpp sdl2-gfx/SDL2_rotozoom.c \
|
||||||
|
-o main
|
||||||
|
|
||||||
|
osx-bundle :
|
||||||
|
if [ ! -d "$(APPDIR)" ]; then mkdir -p $(APPDIR); fi;
|
||||||
|
if [ ! -d "$(APPDIR)" ]; then mkdir $(APPDIR); fi;
|
||||||
|
if [ ! -d "$(APPDIR)/MacOS" ]; then mkdir $(APPDIR)/MacOS; fi;
|
||||||
|
if [ ! -d "$(APPDIR)/Frameworks" ]; then mkdir $(APPDIR)/Frameworks; fi;
|
||||||
|
if [ ! -d "$(APPDIR)/Resources" ]; then mkdir $(APPDIR)/Resources; fi;
|
||||||
|
touch $(APPDIR)/Info.plist
|
||||||
|
cp -r $(SYSFWPATH)/SDL2.framework $(APPDIR)/Frameworks
|
||||||
|
cp -r $(SYSFWPATH)/SDL2_image.framework $(APPDIR)/Frameworks
|
||||||
|
g++ -I $(SYSFWPATH)/SDL2.framework/Headers -I $(SYSFWPATH)/SDL2_image.framework/Headers \
|
||||||
|
-Wl,-rpath,@executable_path/../Frameworks -Wl,-rpath,$(SYSFWPATH) \
|
||||||
|
-framework SDL2 -framework SDL2_image -framework OpenGL main.cpp -o $(APPDIR)/MacOS/main
|
||||||
|
|
||||||
|
cross : linux android emscripten mingw
|
|
@ -10,10 +10,14 @@
|
||||||
"print-video-memory-size": "v",
|
"print-video-memory-size": "v",
|
||||||
"play-sound": ""
|
"play-sound": ""
|
||||||
},
|
},
|
||||||
|
"input":
|
||||||
|
{
|
||||||
|
"suppress-any-key-on-mods": true
|
||||||
|
},
|
||||||
"recording":
|
"recording":
|
||||||
{
|
{
|
||||||
"screenshot-directory": "local/screenshots",
|
"screenshot-directory": "local/screenshots",
|
||||||
"video-directory": "local/video"
|
"video-directory": "local/video",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"write-mp4": true,
|
"write-mp4": true,
|
||||||
"video-frame-length": 16.667,
|
"video-frame-length": 16.667,
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 251 B |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 270 B |
Before Width: | Height: | Size: 703 B After Width: | Height: | Size: 703 B |
|
@ -0,0 +1 @@
|
||||||
|
../../BPmono.ttf
|
|
@ -0,0 +1,101 @@
|
||||||
|
# /\ +--------------------------------------------------------------+
|
||||||
|
# ____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
# \ / / | copy, modify and sell without restriction |
|
||||||
|
# +--\ ^__^ /--+ | |
|
||||||
|
# | ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||||
|
# | ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
# | SPACE ~~~~~ | /
|
||||||
|
# | ~~~~~~~ BOX |/
|
||||||
|
# +--------------+
|
||||||
|
#
|
||||||
|
# [ Makefile for squircle demo ]
|
||||||
|
#
|
||||||
|
# This should build the squircle for Linux. Compilation to other platforms hasn't been
|
||||||
|
# attempted yet.
|
||||||
|
#
|
||||||
|
# Edit the parameters as necessary and run `make linux` in the current directory.
|
||||||
|
#
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# Location parameters #
|
||||||
|
#######################
|
||||||
|
|
||||||
|
# Location of source files for the demo
|
||||||
|
SRC_DIR := ./
|
||||||
|
|
||||||
|
# Locations of [SPACE BOX] source and dependencies required to be compiled from source. These
|
||||||
|
# locations are configured to match the structure of the [SPACE BOX] repository but can be
|
||||||
|
# modified as necessary.
|
||||||
|
SB_DIR := ../../
|
||||||
|
SB_SRC_DIR := $(SB_DIR)src/
|
||||||
|
SB_LIB_DIR := $(SB_DIR)lib/
|
||||||
|
SDLGFX2_DIR := $(SB_LIB_DIR)sdl2-gfx/
|
||||||
|
GLEW_DIR := $(SB_LIB_DIR)glew/
|
||||||
|
|
||||||
|
# C and C++ compiler commands
|
||||||
|
CC := clang
|
||||||
|
CPPC := clang++
|
||||||
|
|
||||||
|
# Location of SDL config program
|
||||||
|
SDLCONFIG := ~/local/sdl/bin/sdl2-config
|
||||||
|
|
||||||
|
# Edit to point to the location of BPmono.ttf
|
||||||
|
CREATE_FONT_SYMLINK := ln -nsf $(SB_DIR)"BPmono.ttf" .
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# Based on above parameters #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
CFLAGS := -Wall -O0 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) $(shell $(SDLCONFIG) --cflags) -g
|
||||||
|
CPP_FLAGS := $(CFLAGS) --std=c++17
|
||||||
|
LFLAGS := $(shell $(SDLCONFIG) --libs) -lpthread
|
||||||
|
SB_H_FILES := $(wildcard $(addprefix $(SB_SRC_DIR),*.hpp))
|
||||||
|
SB_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o),$(SB_H_FILES:.hpp=.o))
|
||||||
|
SRC_H_FILES := $(wildcard $(addprefix $(SRC_DIR),*.hpp))
|
||||||
|
SRC_O_FILES := $(SRC_H_FILES:.hpp=.o)
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# Targets for building [SPACE BOX], dependencies and demo source #
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
$(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
||||||
|
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
||||||
|
$(CC) $(CFLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp)
|
||||||
|
$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \
|
||||||
|
Delegate.hpp Audio.hpp)
|
||||||
|
$(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp)
|
||||||
|
$(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp)
|
||||||
|
$(SB_SRC_DIR)Delegate.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Input.hpp)
|
||||||
|
$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp)
|
||||||
|
$(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp)
|
||||||
|
$(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp)
|
||||||
|
$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp)
|
||||||
|
$(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp)
|
||||||
|
$(SRC_DIR)Squircle.o : $(SB_H_FILES)
|
||||||
|
%.o : %.cpp %.hpp
|
||||||
|
$(CPPC) $(CPP_FLAGS) $< -c -o $@
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# Target for Linux build #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
linux : $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) \
|
||||||
|
$(SB_O_FILES) $(SRC_O_FILES)
|
||||||
|
$(CREATE_FONT_SYMLINK)
|
||||||
|
$(CPPC) $(LFLAGS) -D__LINUX__ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs $^ -o squircle
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Target for cleaning up object files #
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
clean :
|
||||||
|
- rm *.o
|
||||||
|
- rm $(SB_SRC_DIR)*.o
|
||||||
|
- rm $(GLEW_DIR)*.o
|
||||||
|
- rm $(SDLGFX2_DIR)*.o
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
/\ +--------------------------------------------------------------+
|
||||||
|
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||||
|
\ / / | copy, modify and sell without restriction |
|
||||||
|
+--\ ^__^ /--+ | |
|
||||||
|
| ~/ \~ | | - originally created at [http:nugget.fun] |
|
||||||
|
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||||
|
| SPACE ~~~~~ | /
|
||||||
|
| ~~~~~~~ BOX |/
|
||||||
|
+--------------+
|
||||||
|
|
||||||
|
Demonstrates functions from the Box class that map vertices from a square to a circle
|
||||||
|
and from a circle to a square. The functions are based on the equations described at
|
||||||
|
http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Squircle.hpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Squircle squircle = Squircle();
|
||||||
|
squircle.run();
|
||||||
|
squircle.quit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Squircle::Squircle()
|
||||||
|
{
|
||||||
|
/* subscribe to command events */
|
||||||
|
get_delegate().subscribe(&Squircle::respond, this);
|
||||||
|
/* testing graphics in GL context */
|
||||||
|
load_gl_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squircle::load_gl_context()
|
||||||
|
{
|
||||||
|
super::load_gl_context();
|
||||||
|
/* 2D vertices for any texture that is a plane spanning the screen */
|
||||||
|
std::array<glm::vec2, 6> plane_vertices = {{
|
||||||
|
{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f},
|
||||||
|
{1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f}
|
||||||
|
}};
|
||||||
|
std::vector<glm::vec2> circle_vertices = sfw::points_on_circle(get_configuration()["circle-resolution"]);
|
||||||
|
circle_vertices.insert(circle_vertices.begin(), {0.0f, 0.0f});
|
||||||
|
circle_vertices.insert(circle_vertices.end(), circle_vertices[1]);
|
||||||
|
circle_vertices_count = circle_vertices.size();
|
||||||
|
/* Generate vertex buffer object to hold both mapped and unmapped data */
|
||||||
|
GLuint vbo;
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
/* Allocate space for plane and circle and copy plane vertices in VBO */
|
||||||
|
GLsizeiptr vbo_size = (plane_vertices.size() + circle_vertices.size()) * sizeof(glm::vec2);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vbo_size, plane_vertices.data(), GL_STATIC_DRAW);
|
||||||
|
/* Allocate VAO for the plane vertices and connect attributes to the VBO */
|
||||||
|
glGenVertexArrays(1, &unmapped_vao);
|
||||||
|
glBindVertexArray(unmapped_vao);
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
/* Copy circle vertices into VBO */
|
||||||
|
GLintptr offset = plane_vertices.size() * sizeof(glm::vec2);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, offset, circle_vertices.size() * sizeof(glm::vec2), circle_vertices.data());
|
||||||
|
/* Allocate VAO for the circle vertices and connect attributes to the VBO */
|
||||||
|
glGenVertexArrays(1, &mapped_vao);
|
||||||
|
glBindVertexArray(mapped_vao);
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid*>(offset));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
/* Load flat shader program */
|
||||||
|
GLuint vertex_shader = load_shader("flat.vert", GL_VERTEX_SHADER);
|
||||||
|
GLuint fragment_shader = load_shader("flat.frag", GL_FRAGMENT_SHADER);
|
||||||
|
flat_program = glCreateProgram();
|
||||||
|
glBindAttribLocation(flat_program, 0, "position");
|
||||||
|
glAttachShader(flat_program, vertex_shader);
|
||||||
|
glAttachShader(flat_program, fragment_shader);
|
||||||
|
link_shader(flat_program);
|
||||||
|
glUseProgram(flat_program);
|
||||||
|
/* load image */
|
||||||
|
load_image_index(0);
|
||||||
|
base_texture_shader_location = glGetUniformLocation(flat_program, "base_texture");
|
||||||
|
mode_uniform_location = glGetUniformLocation(flat_program, "mode");
|
||||||
|
transformation_uniform_location = glGetUniformLocation(flat_program, "transformation");
|
||||||
|
log_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load image at path as an SDL surface, generate texture to load pixel data into, allocate storage, and bind
|
||||||
|
* and edit texture properties. Returns the ID of the generated texture. */
|
||||||
|
GLuint Squircle::load_file_into_texture(fs::path path) const
|
||||||
|
{
|
||||||
|
GLuint texture_id;
|
||||||
|
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface(IMG_Load(path.c_str()), SDL_FreeSurface);
|
||||||
|
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface);
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, flipped_surface->w, flipped_surface->h);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, flipped_surface->w, flipped_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, flipped_surface->pixels);
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "loaded image into texture id #" << texture_id << " " << flipped_surface->w << " x " << flipped_surface->h;
|
||||||
|
log(message.str());
|
||||||
|
return texture_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squircle::load_image_index(int index)
|
||||||
|
{
|
||||||
|
std::vector<fs::path> paths = sfw::glob("images/.*");
|
||||||
|
fs::path path = paths[index % paths.size()];
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "loading " << path;
|
||||||
|
log(message.str());
|
||||||
|
image_index = index;
|
||||||
|
base_texture_id = load_file_into_texture(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squircle::respond(SDL_Event& event)
|
||||||
|
{
|
||||||
|
if (get_delegate().compare(event, "next"))
|
||||||
|
{
|
||||||
|
load_image_index(image_index + 1);
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "mode"))
|
||||||
|
{
|
||||||
|
mode = mode == Mode::SQUIRCLE ? Mode::UNSQUIRCLE : Mode::SQUIRCLE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "left"))
|
||||||
|
{
|
||||||
|
spin_z = Spin::NEGATIVE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "right"))
|
||||||
|
{
|
||||||
|
spin_z = Spin::POSITIVE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, {std::string("left"), std::string("right")}, false, true))
|
||||||
|
{
|
||||||
|
spin_z = Spin::NONE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "up"))
|
||||||
|
{
|
||||||
|
spin_x = Spin::NEGATIVE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, "down"))
|
||||||
|
{
|
||||||
|
spin_x = Spin::POSITIVE;
|
||||||
|
}
|
||||||
|
else if (get_delegate().compare(event, {std::string("up"), std::string("down")}, false, true))
|
||||||
|
{
|
||||||
|
spin_x = Spin::NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squircle::update()
|
||||||
|
{
|
||||||
|
/* apply rotation to transformation matrix */
|
||||||
|
float rotation_speed = get_configuration()["rotation-speed"];
|
||||||
|
transformation = glm::rotate(transformation, spin_z * rotation_speed, {0, 0, 1});
|
||||||
|
transformation = glm::rotate(transformation, spin_x * rotation_speed, {1, 0, 0});
|
||||||
|
glUniformMatrix4fv(transformation_uniform_location, 1, false, &transformation[0][0]);
|
||||||
|
/* viewport box will be used to tell GL where to draw */
|
||||||
|
Box viewport_box = window_box();
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
/* paint the screen black */
|
||||||
|
glClearColor(0, 0, 0, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
/* set uniform and activate texture */
|
||||||
|
glUniform1i(base_texture_shader_location, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, base_texture_id);
|
||||||
|
/* set viewport to left side of screen for unmapped plane */
|
||||||
|
glViewport(viewport_box.left(), viewport_box.top(), viewport_box.width() / 2, viewport_box.height());
|
||||||
|
/* draws plane vertices and plane UV */
|
||||||
|
glBindVertexArray(unmapped_vao);
|
||||||
|
glUniform1i(mode_uniform_location, mode == Mode::UNSQUIRCLE ? 2 : 0);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
/* set viewport to right side of screen for mapped plane */
|
||||||
|
glUseProgram(flat_program);
|
||||||
|
glViewport(viewport_box.cx(), viewport_box.top(), viewport_box.width() / 2, viewport_box.height());
|
||||||
|
/* draws mapped plane vertices and plane UV */
|
||||||
|
glBindVertexArray(mapped_vao);
|
||||||
|
glUniform1i(mode_uniform_location, mode == Mode::SQUIRCLE ? 1 : 0);
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, circle_vertices_count);
|
||||||
|
SDL_GL_SwapWindow(get_window());
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef Squircle_h_
|
||||||
|
#define Squircle_h_
|
||||||
|
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "Game.hpp"
|
||||||
|
#include "filesystem.hpp"
|
||||||
|
|
||||||
|
class Squircle : public Game
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum Mode : bool
|
||||||
|
{
|
||||||
|
SQUIRCLE,
|
||||||
|
UNSQUIRCLE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Spin
|
||||||
|
{
|
||||||
|
NEGATIVE = -1,
|
||||||
|
NONE,
|
||||||
|
POSITIVE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
GLuint base_texture_shader_location = 0, base_texture_id = 0, flat_program = 0, unmapped_vao = 0, mapped_vao = 0,
|
||||||
|
mode_uniform_location = 0, transformation_uniform_location = 0;
|
||||||
|
int circle_vertices_count = 0, image_index = 0;
|
||||||
|
Mode mode = Mode::SQUIRCLE;
|
||||||
|
glm::mat4 transformation = glm::mat4(1.0f);
|
||||||
|
Spin spin_z = Spin::NONE, spin_x = Spin::NONE;
|
||||||
|
|
||||||
|
typedef Game super;
|
||||||
|
void load_gl_context();
|
||||||
|
GLuint load_file_into_texture(fs::path) const;
|
||||||
|
void load_image_index(int);
|
||||||
|
void update();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Squircle();
|
||||||
|
void respond(SDL_Event&);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"circle-resolution": 48,
|
||||||
|
"rotation-speed": 0.1,
|
||||||
|
"recording":
|
||||||
|
{
|
||||||
|
"screenshot-directory": "local/screenshots",
|
||||||
|
"video-directory": "local/video",
|
||||||
|
"enabled": true,
|
||||||
|
"write-mp4": true,
|
||||||
|
"video-frame-length": 33.333,
|
||||||
|
"max-video-memory": 2000,
|
||||||
|
"mp4-pixel-format": "yuv420p"
|
||||||
|
},
|
||||||
|
"log":
|
||||||
|
{
|
||||||
|
"debug-to-stdout": false
|
||||||
|
},
|
||||||
|
"configuration":
|
||||||
|
{
|
||||||
|
"auto-refresh": true
|
||||||
|
},
|
||||||
|
"keys":
|
||||||
|
{
|
||||||
|
"next": "space",
|
||||||
|
"mode": "enter"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec2 frag_uv;
|
||||||
|
in vec2 original_coordinates;
|
||||||
|
in vec4 clip_coordinates;
|
||||||
|
uniform sampler2D base_texture;
|
||||||
|
uniform int mode;
|
||||||
|
|
||||||
|
/* [-1, 1] normalized device coordinates to [0, 1] UV coordinates */
|
||||||
|
vec2 ndc_to_uv(vec2 coordinates)
|
||||||
|
{
|
||||||
|
return (coordinates + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* coordinates in circle with radius <= 1 to box coordinates in [-1, 1] */
|
||||||
|
vec2 circle_to_box(vec2 circle)
|
||||||
|
{
|
||||||
|
float u = circle.x;
|
||||||
|
float v = circle.y;
|
||||||
|
float u_sq = pow(u, 2);
|
||||||
|
float v_sq = pow(v, 2);
|
||||||
|
float rt_2 = sqrt(2);
|
||||||
|
float x = .5 * sqrt(2 + 2 * u * rt_2 + u_sq - v_sq) - .5 * sqrt(2 - 2 * u * rt_2 + u_sq - v_sq);
|
||||||
|
float y = .5 * sqrt(2 + 2 * v * rt_2 - u_sq + v_sq) - .5 * sqrt(2 - 2 * v * rt_2 - u_sq + v_sq);
|
||||||
|
return vec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* box coordinates in [-1, 1] to coordinates in circle with radius <= 1 */
|
||||||
|
vec2 box_to_circle(vec2 box)
|
||||||
|
{
|
||||||
|
float u = box.x * sqrt(1 - .5 * pow(box.y, 2));
|
||||||
|
float v = box.y * sqrt(1 - .5 * pow(box.x, 2));
|
||||||
|
return vec2(u, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
/* normalized device coordinates (coordinates in [-1, 1] space within viewport) */
|
||||||
|
vec2 ndc = original_coordinates;
|
||||||
|
/* map to circle if requested */
|
||||||
|
if (mode == 1)
|
||||||
|
{
|
||||||
|
ndc = circle_to_box(ndc);
|
||||||
|
}
|
||||||
|
else if (mode == 2)
|
||||||
|
{
|
||||||
|
ndc = box_to_circle(ndc);
|
||||||
|
}
|
||||||
|
/* translate ndc to uv space and get texel */
|
||||||
|
gl_FragColor = texture(base_texture, ndc_to_uv(ndc));
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec2 position;
|
||||||
|
in vec2 vertex_uv;
|
||||||
|
uniform mat4 transformation;
|
||||||
|
uniform int mode;
|
||||||
|
out vec2 original_coordinates;
|
||||||
|
out vec4 clip_coordinates;
|
||||||
|
out vec2 frag_uv;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 0, 1);
|
||||||
|
if (mode > 0)
|
||||||
|
{
|
||||||
|
gl_Position *= transformation;
|
||||||
|
}
|
||||||
|
original_coordinates = position;
|
||||||
|
clip_coordinates = gl_Position;
|
||||||
|
frag_uv = vertex_uv;
|
||||||
|
}
|
After Width: | Height: | Size: 9.7 KiB |
|
@ -52,7 +52,7 @@ bool Animation::is_playing(bool include_delay)
|
||||||
void Animation::update()
|
void Animation::update()
|
||||||
{
|
{
|
||||||
timer.update();
|
timer.update();
|
||||||
if (playing and not paused and containing_object->is_active())
|
if (playing && !paused && containing_object->is_active())
|
||||||
{
|
{
|
||||||
if (delay > 0)
|
if (delay > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -515,13 +515,6 @@ bool Box::collide(const Box& box, Box& overlap) const
|
||||||
return collide(box, &overlap);
|
return collide(box, &overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map any point in the bounds of a square with x and y between [-, radius] to a circle with specified radius. If
|
|
||||||
* center is specified, both the square and circle are centered at specified point. The default radius is 1, and the
|
|
||||||
* default center is (0, 0). Formula taken from http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html */
|
|
||||||
glm::vec2 Box::map_point_to_circle(const glm::vec2& point, float radius, const glm::vec2& center) const
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the string representation of a Box "{left, top, width, height}" */
|
/* Return the string representation of a Box "{left, top, width, height}" */
|
||||||
std::string Box::string() const
|
std::string Box::string() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,6 @@ public:
|
||||||
bool collide(const Segment&, glm::vec2&) const;
|
bool collide(const Segment&, glm::vec2&) const;
|
||||||
bool collide(const Box&, Box* = nullptr) const;
|
bool collide(const Box&, Box* = nullptr) const;
|
||||||
bool collide(const Box&, Box&) const;
|
bool collide(const Box&, Box&) const;
|
||||||
glm::vec2 map_point_to_circle(const glm::vec2&, float, const glm::vec2&) const;
|
|
||||||
virtual std::string class_name() const { return "Box"; }
|
virtual std::string class_name() const { return "Box"; }
|
||||||
std::string string() const;
|
std::string string() const;
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,20 @@
|
||||||
|
|
||||||
#include "Configuration.hpp"
|
#include "Configuration.hpp"
|
||||||
|
|
||||||
Configuration::Configuration(Node *parent) : Configuration(parent, "config.json") {}
|
/* Initialize a Configuration object. The path argument is the location where the config file is stored.
|
||||||
|
* If there is no file located at the path, it will be created if the write method is called. System level
|
||||||
|
* default assignments defined in this file can be added to and overwritten by user supplied JSON file at
|
||||||
|
* the specified path or at a path passed to the load function. */
|
||||||
Configuration::Configuration(Node *parent, fs::path path) : Node(parent)
|
Configuration::Configuration(Node *parent, fs::path path) : Node(parent)
|
||||||
{
|
{
|
||||||
config_path = path;
|
config_path = path;
|
||||||
set_defaults();
|
set_defaults();
|
||||||
load();
|
load();
|
||||||
merge();
|
auto_refresher.set_frame_length(config["configuration"]["auto-refresh-interval"].get<float>());
|
||||||
|
auto_refresh(config["configuration"]["auto-refresh"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the system level config JSON with default values set by the framework */
|
/* Fill the system level config JSON dict with default values set by the framework */
|
||||||
void Configuration::set_defaults()
|
void Configuration::set_defaults()
|
||||||
{
|
{
|
||||||
sys_config["keys"] = {
|
sys_config["keys"] = {
|
||||||
|
@ -34,14 +37,14 @@ void Configuration::set_defaults()
|
||||||
sys_config["input"] = {
|
sys_config["input"] = {
|
||||||
{"suppress-any-key-on-mods", true},
|
{"suppress-any-key-on-mods", true},
|
||||||
{"system-any-key-ignore-commands", {"fullscreen", "screenshot", "toggle-framerate", "record", "quit"}},
|
{"system-any-key-ignore-commands", {"fullscreen", "screenshot", "toggle-framerate", "record", "quit"}},
|
||||||
{"any-key-ignore-commands", {}},
|
{"any-key-ignore-commands", nlohmann::json::array()},
|
||||||
{"default-unsuppress-delay", 700},
|
{"default-unsuppress-delay", 700},
|
||||||
{"ignore-repeat-keypress", true}
|
{"ignore-repeat-keypress", true}
|
||||||
};
|
};
|
||||||
sys_config["display"] = {
|
sys_config["display"] = {
|
||||||
{"dimensions", {640, 480}},
|
{"dimensions", {640, 480}},
|
||||||
{"framerate", 60},
|
{"framerate", 60},
|
||||||
{"title", "sfw"},
|
{"title", "[SPACE BOX]"},
|
||||||
{"debug", false},
|
{"debug", false},
|
||||||
{"show-cursor", false},
|
{"show-cursor", false},
|
||||||
{"render-test-spacing", 2},
|
{"render-test-spacing", 2},
|
||||||
|
@ -83,41 +86,90 @@ void Configuration::set_defaults()
|
||||||
{"info-file-name", "log.txt"},
|
{"info-file-name", "log.txt"},
|
||||||
{"debug-file-name", "debug_log.txt"}
|
{"debug-file-name", "debug_log.txt"}
|
||||||
};
|
};
|
||||||
|
sys_config["configuration"] = {
|
||||||
|
{"auto-refresh", false},
|
||||||
|
{"auto-refresh-interval", 1000}
|
||||||
|
};
|
||||||
|
config = sys_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load the configuration file at path */
|
||||||
|
void Configuration::load(fs::path path)
|
||||||
|
{
|
||||||
|
/* read contents of path into the game level config JSON dict */
|
||||||
|
if (fs::exists(path))
|
||||||
|
{
|
||||||
|
std::ifstream contents(path);
|
||||||
|
contents >> user_config;
|
||||||
|
/* store modification time */
|
||||||
|
config_file_modification_time = fs::last_write_time(path);
|
||||||
|
/* merge into the full config JSON dict */
|
||||||
|
merge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the configuration file at Configuration::config_path */
|
||||||
void Configuration::load()
|
void Configuration::load()
|
||||||
{
|
{
|
||||||
load(config_path);
|
load(config_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::load(fs::path path)
|
/* Merge the system level config JSON dict (hard-coded in this file) with the user level config JSON
|
||||||
{
|
* dict (loaded from disk by the load function) */
|
||||||
if (fs::exists(path))
|
|
||||||
{
|
|
||||||
std::ifstream contents(path);
|
|
||||||
contents >> game_config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Configuration::merge()
|
void Configuration::merge()
|
||||||
{
|
{
|
||||||
config = sys_config;
|
if (not user_config.empty())
|
||||||
if (not game_config.empty())
|
|
||||||
{
|
{
|
||||||
for (auto& section: game_config.items())
|
/* loop over first level key/value pairs */
|
||||||
|
for (auto& item: user_config.items())
|
||||||
{
|
{
|
||||||
config[section.key()].update(game_config[section.key()]);
|
/* if the value is an object (dict), merge it into the config, overwriting keys already in the config */
|
||||||
|
if (item.value().is_object())
|
||||||
|
{
|
||||||
|
config[item.key()].update(item.value());
|
||||||
|
}
|
||||||
|
/* otherwise just assign config key to this value */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config[item.key()] = item.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set auto refresh to on or off */
|
||||||
|
void Configuration::auto_refresh(bool on)
|
||||||
|
{
|
||||||
|
on ? auto_refresher.play() : auto_refresher.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Refresh the config contents by calling the default load function */
|
||||||
|
void Configuration::refresh()
|
||||||
|
{
|
||||||
|
if (fs::exists(config_path) && fs::last_write_time(config_path) > config_file_modification_time)
|
||||||
|
{
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "config file modified, reloading " << config_path;
|
||||||
|
debug(message.str());
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write configuration to specified path in JSON format */
|
||||||
|
void Configuration::write(fs::path path)
|
||||||
|
{
|
||||||
|
std::ofstream output(path);
|
||||||
|
output << std::setw(tab_width) << user_config << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write configuration to config_path (set at initialization) */
|
||||||
void Configuration::write()
|
void Configuration::write()
|
||||||
{
|
{
|
||||||
write(config_path);
|
write(config_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::write(fs::path path)
|
/* Updates the auto refresher */
|
||||||
|
void Configuration::update()
|
||||||
{
|
{
|
||||||
std::ofstream output(path);
|
auto_refresher.update();
|
||||||
output << std::setw(tab_width) << game_config << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,41 @@
|
||||||
#define Configuration_h_
|
#define Configuration_h_
|
||||||
|
|
||||||
#include "json/json.hpp"
|
#include "json/json.hpp"
|
||||||
|
|
||||||
#include "filesystem.hpp"
|
#include "filesystem.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
|
#include "Animation.hpp"
|
||||||
|
|
||||||
struct Configuration : Node
|
class Configuration : public Node
|
||||||
{
|
{
|
||||||
nlohmann::json sys_config, game_config, config;
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
nlohmann::json sys_config, user_config;
|
||||||
fs::path config_path;
|
fs::path config_path;
|
||||||
int tab_width = 4;
|
int tab_width = 4;
|
||||||
|
Animation auto_refresher = Animation(&Configuration::refresh, this);
|
||||||
|
fs::file_time_type config_file_modification_time;
|
||||||
|
|
||||||
Configuration(Node*);
|
|
||||||
Configuration(Node*, fs::path);
|
|
||||||
void set_defaults();
|
void set_defaults();
|
||||||
void load();
|
|
||||||
void load(fs::path path);
|
|
||||||
void merge();
|
void merge();
|
||||||
void write();
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
nlohmann::json config;
|
||||||
|
|
||||||
|
Configuration(Node*, fs::path = "config.json");
|
||||||
|
void load(fs::path path);
|
||||||
|
void load();
|
||||||
|
void auto_refresh(bool);
|
||||||
|
void refresh();
|
||||||
void write(fs::path path);
|
void write(fs::path path);
|
||||||
|
void write();
|
||||||
|
void update();
|
||||||
virtual std::string class_name() const { return "Configuration"; }
|
virtual std::string class_name() const { return "Configuration"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Extend GLM so nlohmann::json can read and write glm::vec2 */
|
||||||
namespace glm
|
namespace glm
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -40,6 +53,7 @@ namespace glm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extend std::filesystem so nlohmann::json can read and write std::filesystem::path */
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
namespace std::experimental::filesystem
|
namespace std::experimental::filesystem
|
||||||
#else
|
#else
|
||||||
|
|
10
src/Game.cpp
|
@ -28,7 +28,7 @@ SDL_Surface* FramerateIndicator::get_surface()
|
||||||
|
|
||||||
void FramerateIndicator::refresh()
|
void FramerateIndicator::refresh()
|
||||||
{
|
{
|
||||||
if (!is_hidden() && get_root()->bp_mono_font != NULL)
|
if (!is_hidden() && get_root()->bp_mono_font != nullptr)
|
||||||
{
|
{
|
||||||
unload();
|
unload();
|
||||||
SDL_Surface* surface = get_surface();
|
SDL_Surface* surface = get_surface();
|
||||||
|
@ -133,7 +133,7 @@ Game::Game()
|
||||||
SDL_Log("initialized SDL ttf %d.%d.%d", SDL_TTF_MAJOR_VERSION,
|
SDL_Log("initialized SDL ttf %d.%d.%d", SDL_TTF_MAJOR_VERSION,
|
||||||
SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
|
SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
|
||||||
}
|
}
|
||||||
if ((bp_mono_font = TTF_OpenFont("BPmono.ttf", 14)) == NULL)
|
if ((bp_mono_font = TTF_OpenFont("BPmono.ttf", 14)) == nullptr)
|
||||||
{
|
{
|
||||||
print_error("Could not load BPmono.ttf");
|
print_error("Could not load BPmono.ttf");
|
||||||
}
|
}
|
||||||
|
@ -671,15 +671,13 @@ void Game::frame(float ticks)
|
||||||
// std::cout << ", last_frame_length: " << last_frame_length << " [rendering frame]";
|
// std::cout << ", last_frame_length: " << last_frame_length << " [rendering frame]";
|
||||||
if (last_frame_length < 1000)
|
if (last_frame_length < 1000)
|
||||||
{
|
{
|
||||||
// if (!is_gl_context)
|
recorder.update();
|
||||||
// {
|
|
||||||
recorder.update();
|
|
||||||
// }
|
|
||||||
delegate.dispatch();
|
delegate.dispatch();
|
||||||
audio.update();
|
audio.update();
|
||||||
input.unsuppress_animation.update();
|
input.unsuppress_animation.update();
|
||||||
update();
|
update();
|
||||||
framerate_indicator.update();
|
framerate_indicator.update();
|
||||||
|
configuration.update();
|
||||||
if (!is_gl_context)
|
if (!is_gl_context)
|
||||||
{
|
{
|
||||||
SDL_SetRenderTarget(renderer, nullptr);
|
SDL_SetRenderTarget(renderer, nullptr);
|
||||||
|
|
|
@ -57,6 +57,12 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/* two-state enum equivalent to a boolean that can improve readability depending on the context */
|
||||||
|
enum class Flip {
|
||||||
|
OFF,
|
||||||
|
ON
|
||||||
|
};
|
||||||
|
|
||||||
/* Prevent an instance of this class from being copied or moved */
|
/* Prevent an instance of this class from being copied or moved */
|
||||||
Game(const Game&) = delete;
|
Game(const Game&) = delete;
|
||||||
Game& operator=(const Game&) = delete;
|
Game& operator=(const Game&) = delete;
|
||||||
|
@ -77,7 +83,7 @@ public:
|
||||||
Input input = Input(this);
|
Input input = Input(this);
|
||||||
Audio audio = Audio(this);
|
Audio audio = Audio(this);
|
||||||
std::vector<float> frame_length_history;
|
std::vector<float> frame_length_history;
|
||||||
TTF_Font* bp_mono_font = NULL;
|
TTF_Font* bp_mono_font = nullptr;
|
||||||
FramerateIndicator framerate_indicator = FramerateIndicator(this);
|
FramerateIndicator framerate_indicator = FramerateIndicator(this);
|
||||||
|
|
||||||
Game();
|
Game();
|
||||||
|
|
|
@ -15,7 +15,7 @@ Segment::Segment(const glm::vec2& location) : Segment(location, location) {};
|
||||||
|
|
||||||
Segment::Segment(const Box& start, const Box& end) : Segment(start.center(), end.center()) {};
|
Segment::Segment(const Box& start, const Box& end) : Segment(start.center(), end.center()) {};
|
||||||
|
|
||||||
inline glm::vec2 Segment::start() const
|
glm::vec2 Segment::start() const
|
||||||
{
|
{
|
||||||
return start_;
|
return start_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
Segment(const glm::vec2&);
|
Segment(const glm::vec2&);
|
||||||
Segment(const Box&, const Box&);
|
Segment(const Box&, const Box&);
|
||||||
Segment(const Sprite&, const Sprite&);
|
Segment(const Sprite&, const Sprite&);
|
||||||
inline glm::vec2 start() const;
|
glm::vec2 start() const;
|
||||||
void start(const glm::vec2&);
|
void start(const glm::vec2&);
|
||||||
glm::vec2 end() const;
|
glm::vec2 end() const;
|
||||||
void end(const glm::vec2&);
|
void end(const glm::vec2&);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Pixels.hpp"
|
#include "Pixels.hpp"
|
||||||
#include "extension.hpp"
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
/* Edit a vector in place, giving it the specified magnitude while maintaining the direction */
|
||||||
void sfw::set_magnitude(glm::vec2& vector, float magnitude)
|
void sfw::set_magnitude(glm::vec2& vector, float magnitude)
|
||||||
{
|
{
|
||||||
vector = glm::normalize(vector) * magnitude;
|
vector = glm::normalize(vector) * magnitude;
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace sfw
|
||||||
glm::vec2 point_on_circle(float, float = 1.0f);
|
glm::vec2 point_on_circle(float, float = 1.0f);
|
||||||
void points_on_circle(std::vector<glm::vec2>&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
void points_on_circle(std::vector<glm::vec2>&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
||||||
std::vector<glm::vec2> points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
std::vector<glm::vec2> points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
||||||
glm::vec2 map_rectangle_xy_to_circle(const glm::vec2&, float = 1.0f, const glm::vec2& = {0, 0});
|
|
||||||
Box get_texture_box(SDL_Texture*);
|
Box get_texture_box(SDL_Texture*);
|
||||||
glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&);
|
glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&);
|
||||||
std::vector<std::vector<Box>> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4);
|
std::vector<std::vector<Box>> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4);
|
||||||
|
|