diff --git a/05_sdl_software_renderer/renderer.cpp b/05_sdl_software_renderer/renderer.cpp index d838ee3..98b73cc 100644 --- a/05_sdl_software_renderer/renderer.cpp +++ b/05_sdl_software_renderer/renderer.cpp @@ -113,6 +113,33 @@ void Renderer::draw_sprite(const Sprite &sprite) { } } +void Renderer::draw_sprite(const Sprite *sprite) { + Texture *t = sprite->get_texture(); + + if (!t) { + return; + } + + double angle = sprite->get_angle(); + + if (Math::is_zero_approx(angle)) { + SDL_Rect sr = sprite->get_texture_clip_rect().as_rect(); + SDL_Rect dr = sprite->get_transform().as_rect(); + + SDL_RenderCopy(_renderer, t->get_texture(), &sr, &dr); + } else { + SDL_Rect sr = sprite->get_texture_clip_rect().as_rect(); + SDL_FRect dr = sprite->get_transform().as_frect(); + + SDL_FPoint p; + + p.x = sprite->get_anchor_x(); + p.y = sprite->get_anchor_y(); + + SDL_RenderCopyExF(_renderer, t->get_texture(), &sr, &dr, angle, &p, sprite->get_flip()); + } +} + int Renderer::get_dpi() const { float ddpi; float hdpi; diff --git a/05_sdl_software_renderer/renderer.h b/05_sdl_software_renderer/renderer.h index 5992903..d6c4dcb 100644 --- a/05_sdl_software_renderer/renderer.h +++ b/05_sdl_software_renderer/renderer.h @@ -33,6 +33,7 @@ public: void draw_texture(const Texture &texture, const Rect2 &src_rect, const Rect2 &dst_rect, const double angle, const float cx = 0, const float cy = 0, const SDL_RendererFlip flip = SDL_FLIP_NONE); void draw_sprite(const Sprite &sprite); + void draw_sprite(const Sprite *sprite); int get_dpi() const; int get_window_size_w() const; diff --git a/06_sdl_application/application.cpp b/06_sdl_application/application.cpp new file mode 100644 index 0000000..1eff8ef --- /dev/null +++ b/06_sdl_application/application.cpp @@ -0,0 +1,78 @@ +#include "application.h" + +#include "renderer.h" + +Application* Application::_instance = nullptr; + +#include + +void Application::event(const SDL_Event ¤t_event) { + switch (current_event.type) { + case SDL_QUIT: + running = false; + break; + //case SDL_KEYDOWN: + //input->process_event_keydown(current_event); + //break; + //case SDL_KEYUP: + //input->process_event_keyup(current_event); + //break; + } + + scene->event(current_event); +} + +void Application::update(float delta) { + scene->update(delta); +} +void Application::render() { + scene->render(); + + Renderer::get_singleton()->present(); +} + +void Application::main_loop() { + std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); + + //handle input + SDL_Event current_event; + while (SDL_PollEvent(¤t_event)) { + event(current_event); + } + + update(frame_delta); + render(); + + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed_seconds = end - start; + double t = elapsed_seconds.count(); + + double tfps = 1.0 / static_cast(target_fps); + + double remaining = tfps - t; + + if (remaining > 0) { + Uint32 fms = static_cast(remaining * 1000.0); + + frame_delta = tfps; + + SDL_Delay(fms); + } else { + frame_delta = t; + } +} + +Application::Application() { + running = true; + target_fps = 60; + + scene = nullptr; + _instance = this; +} +Application::~Application() { + _instance = nullptr; +} + +Application* Application::get_singleton() { + return _instance; +} diff --git a/06_sdl_application/application.h b/06_sdl_application/application.h new file mode 100644 index 0000000..8b6e54e --- /dev/null +++ b/06_sdl_application/application.h @@ -0,0 +1,32 @@ +#ifndef APPLICATION_H +#define APPLICATION_H + +#include + +#include "scene.h" + +class Application { +public: + bool running; + int target_fps; + + virtual void event(const SDL_Event ¤t_event); + virtual void update(float delta); + virtual void render(); + + void main_loop(); + + Application(); + virtual ~Application(); + + Scene *scene; + + static Application* get_singleton(); + + double frame_delta = 0; + +protected: + static Application* _instance; +}; + +#endif \ No newline at end of file diff --git a/06_sdl_application/compile.sh b/06_sdl_application/compile.sh index 05d9fc7..94101f3 100755 --- a/06_sdl_application/compile.sh +++ b/06_sdl_application/compile.sh @@ -23,7 +23,11 @@ g++ -Wall -g $(sdl2-config --cflags) -c image.cpp -o obj/image.o g++ -Wall -g $(sdl2-config --cflags) -c texture.cpp -o obj/texture.o g++ -Wall -g $(sdl2-config --cflags) -c sprite.cpp -o obj/sprite.o +g++ -Wall -g $(sdl2-config --cflags) -c scene.cpp -o obj/scene.o +g++ -Wall -g $(sdl2-config --cflags) -c application.cpp -o obj/application.o +g++ -Wall -g $(sdl2-config --cflags) -c main_scene.cpp -o obj/main_scene.o + g++ -Wall -g $(sdl2-config --cflags) -c main.cpp -o obj/main.o -g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/string.o obj/renderer.o obj/image.o obj/texture.o obj/sprite.o obj/main.o $(sdl2-config --libs) +g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/string.o obj/renderer.o obj/image.o obj/texture.o obj/sprite.o obj/scene.o obj/application.o obj/main_scene.o obj/main.o $(sdl2-config --libs) diff --git a/06_sdl_application/impl_application.h b/06_sdl_application/impl_application.h new file mode 100644 index 0000000..0441467 --- /dev/null +++ b/06_sdl_application/impl_application.h @@ -0,0 +1,18 @@ +#ifndef IMPL_APPLICATION_H +#define IMPL_APPLICATION_H + +#include "application.h" + +#include "main_scene.h" + +class ImplApplication : public Application { +public: + ImplApplication() : Application() { + scene = new MainScene(); + } + ~ImplApplication() { + delete scene; + } +}; + +#endif \ No newline at end of file diff --git a/06_sdl_application/main.cpp b/06_sdl_application/main.cpp index a09632a..d1d8a0c 100644 --- a/06_sdl_application/main.cpp +++ b/06_sdl_application/main.cpp @@ -1,54 +1,34 @@ -#include +#ifdef __EMSCRIPTEN__ +#include +#endif -#include "image.h" +#include "application.h" #include "renderer.h" -#include "sprite.h" -#include +#include "impl_application.h" +#define APPLICATION_CLASS ImplApplication -void main_loop_1() { - bool quit = false; - SDL_Event e; +Renderer *renderer = nullptr; +Application *application = nullptr; - while (!quit) { - while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { - quit = true; - } +void handle_frame() { + application->main_loop(); +} - if (e.type == SDL_KEYDOWN) { - printf("keydown\n"); - } +int main(int argc, char *argv[]) { + renderer = new Renderer(); + application = new APPLICATION_CLASS(); - if (e.type == SDL_KEYUP) { - printf("keyup\n"); - } - } +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(handle_frame, 0, 1); +#else + while (application->running) { + application->main_loop(); } -} +#endif -int main(int argv, char **args) { - Renderer r; + delete application; + delete renderer; - Image i("ti.bmp"); - - r.set_draw_color(0, 0, 0, 255); - r.clear(); - - Texture t(&i); - Sprite s(&t); - - s.set_x(30); - s.set_y(30); - - r.draw_sprite(s); - r.present(); - - main_loop_1(); - - t.free(); - i.free(); - r.destroy(); - - SDL_Quit(); -} + return 0; +} \ No newline at end of file diff --git a/06_sdl_application/main_scene.cpp b/06_sdl_application/main_scene.cpp new file mode 100644 index 0000000..fcb1919 --- /dev/null +++ b/06_sdl_application/main_scene.cpp @@ -0,0 +1,34 @@ +#include "main_scene.h" + +#include "renderer.h" + + +void MainScene::event(const SDL_Event &ev) { +} + +void MainScene::update(float delta) { +} + +void MainScene::render() { + Renderer::get_singleton()->clear(); + + _sprite->set_x(30); + _sprite->set_y(30); + + Renderer::get_singleton()->draw_sprite(_sprite); +} + +MainScene::MainScene() { + _image = new Image("ti.bmp"); + _texture = new Texture(_image); + _sprite = new Sprite(_texture); +} + +MainScene::~MainScene() { + _texture->free(); + _image->free(); + + delete _sprite; + delete _texture; + delete _image; +} diff --git a/06_sdl_application/main_scene.h b/06_sdl_application/main_scene.h new file mode 100644 index 0000000..ec44750 --- /dev/null +++ b/06_sdl_application/main_scene.h @@ -0,0 +1,24 @@ +#ifndef MAIN_SCENE_H +#define MAIN_SCENE_H + +#include "scene.h" + +#include "image.h" +#include "texture.h" +#include "sprite.h" + +class MainScene : public Scene { +public: + void event(const SDL_Event &ev); + void update(float delta); + void render(); + + MainScene(); + ~MainScene(); + + Image *_image; + Texture *_texture; + Sprite *_sprite; +}; + +#endif \ No newline at end of file diff --git a/06_sdl_application/renderer.cpp b/06_sdl_application/renderer.cpp index d838ee3..98b73cc 100644 --- a/06_sdl_application/renderer.cpp +++ b/06_sdl_application/renderer.cpp @@ -113,6 +113,33 @@ void Renderer::draw_sprite(const Sprite &sprite) { } } +void Renderer::draw_sprite(const Sprite *sprite) { + Texture *t = sprite->get_texture(); + + if (!t) { + return; + } + + double angle = sprite->get_angle(); + + if (Math::is_zero_approx(angle)) { + SDL_Rect sr = sprite->get_texture_clip_rect().as_rect(); + SDL_Rect dr = sprite->get_transform().as_rect(); + + SDL_RenderCopy(_renderer, t->get_texture(), &sr, &dr); + } else { + SDL_Rect sr = sprite->get_texture_clip_rect().as_rect(); + SDL_FRect dr = sprite->get_transform().as_frect(); + + SDL_FPoint p; + + p.x = sprite->get_anchor_x(); + p.y = sprite->get_anchor_y(); + + SDL_RenderCopyExF(_renderer, t->get_texture(), &sr, &dr, angle, &p, sprite->get_flip()); + } +} + int Renderer::get_dpi() const { float ddpi; float hdpi; diff --git a/06_sdl_application/renderer.h b/06_sdl_application/renderer.h index 5992903..d6c4dcb 100644 --- a/06_sdl_application/renderer.h +++ b/06_sdl_application/renderer.h @@ -33,6 +33,7 @@ public: void draw_texture(const Texture &texture, const Rect2 &src_rect, const Rect2 &dst_rect, const double angle, const float cx = 0, const float cy = 0, const SDL_RendererFlip flip = SDL_FLIP_NONE); void draw_sprite(const Sprite &sprite); + void draw_sprite(const Sprite *sprite); int get_dpi() const; int get_window_size_w() const; diff --git a/06_sdl_application/scene.cpp b/06_sdl_application/scene.cpp new file mode 100644 index 0000000..04d736d --- /dev/null +++ b/06_sdl_application/scene.cpp @@ -0,0 +1,9 @@ +#include "scene.h" + +Scene::Scene() { + +} + +Scene::~Scene() { + +} \ No newline at end of file diff --git a/06_sdl_application/scene.h b/06_sdl_application/scene.h new file mode 100644 index 0000000..b96c20d --- /dev/null +++ b/06_sdl_application/scene.h @@ -0,0 +1,16 @@ +#ifndef SCENE_H +#define SCENE_H + +#include + +class Scene { +public: + virtual void event(const SDL_Event &ev) = 0; + virtual void update(float delta) = 0; + virtual void render() = 0; + + Scene(); + virtual ~Scene(); +}; + +#endif \ No newline at end of file