diff options
-rw-r--r-- | asset/texture/ERROR.png | bin | 0 -> 3581 bytes | |||
-rw-r--r-- | src/crepe/api/Texture.cpp | 2 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 24 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 6 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.cpp | 59 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.h | 30 | ||||
-rw-r--r-- | src/example/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/example/rendering_particle.cpp | 61 |
8 files changed, 151 insertions, 32 deletions
diff --git a/asset/texture/ERROR.png b/asset/texture/ERROR.png Binary files differnew file mode 100644 index 0000000..2af3548 --- /dev/null +++ b/asset/texture/ERROR.png diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp index de0d0ea..734a5bb 100644 --- a/src/crepe/api/Texture.cpp +++ b/src/crepe/api/Texture.cpp @@ -35,5 +35,5 @@ int Texture::get_width() const { } int Texture::get_height() const { if (this->texture == nullptr) return 0; - return SDLContext::get_instance().get_width(*this); + return SDLContext::get_instance().get_height(*this); } diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 83e91f8..40189f6 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -7,8 +7,8 @@ #include <cmath> #include <cstddef> #include <functional> -#include <iostream> #include <memory> +#include <stdexcept> #include <string> #include "../api/Sprite.h" @@ -31,28 +31,20 @@ SDLContext::SDLContext() { // FIXME: read window defaults from config manager if (SDL_Init(SDL_INIT_VIDEO) < 0) { - // FIXME: throw exception - std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; - return; + throw std::runtime_error("SDL could not initialize!"); } SDL_Window * tmp_window = SDL_CreateWindow("Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->viewport.w, this->viewport.h, 0); if (!tmp_window) { - // FIXME: throw exception - std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; - return; + throw std::runtime_error("Window could not be created!"); } this->game_window = {tmp_window, [](SDL_Window * window) { SDL_DestroyWindow(window); }}; SDL_Renderer * tmp_renderer = SDL_CreateRenderer(this->game_window.get(), -1, SDL_RENDERER_ACCELERATED); if (!tmp_renderer) { - // FIXME: throw exception - std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() - << std::endl; - SDL_DestroyWindow(this->game_window.get()); - return; + throw std::runtime_error("Renderer could not be created!"); } this->game_renderer @@ -60,9 +52,7 @@ SDLContext::SDLContext() { int img_flags = IMG_INIT_PNG; if (!(IMG_Init(img_flags) & img_flags)) { - // FIXME: throw exception - std::cout << "SDL_image could not initialize! SDL_image Error: " << IMG_GetError() - << std::endl; + throw std::runtime_error("SDL_image could not initialize!"); } } @@ -135,8 +125,8 @@ void SDLContext::draw(const Sprite & sprite, const Transform & transform, const void SDLContext::camera(const Camera & cam) { this->viewport.w = static_cast<int>(cam.aspect_width); this->viewport.h = static_cast<int>(cam.aspect_height); - this->viewport.x = static_cast<int>(cam.x) - (SCREEN_WIDTH / 2); - this->viewport.y = static_cast<int>(cam.y) - (SCREEN_HEIGHT / 2); + this->viewport.x = static_cast<int>(cam.x) - (this->viewport.w / 2); + this->viewport.y = static_cast<int>(cam.y) - (this->viewport.h / 2); SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g, cam.bg_color.b, cam.bg_color.a); diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 007092b..78ac56b 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -11,10 +11,6 @@ #include "../api/Transform.h" #include "api/Camera.h" -// FIXME: this needs to be removed -const int SCREEN_WIDTH = 640; -const int SCREEN_HEIGHT = 480; - namespace crepe { // TODO: SDL_Keycode is defined in a header not distributed with crepe, which means this @@ -127,6 +123,8 @@ private: */ void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); + void draw_particle(const Vector2 & pos, const Camera & camera); + //! Clears the screen, preparing for a new frame. void clear_screen(); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index fa3d0de..23ab738 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -1,3 +1,4 @@ +#include <cmath> #include <functional> #include <vector> @@ -5,8 +6,11 @@ #include "../api/Sprite.h" #include "../api/Transform.h" #include "../facade/SDLContext.h" -#include "../util/Log.h" +#include "../util/log.h" +#include "../api/ParticleEmitter.h" +#include "../api/Vector2.h" +#include "Particle.h" #include "RenderSystem.h" using namespace crepe; @@ -24,21 +28,62 @@ void RenderSystem::update_camera() { this->curr_cam = &cam; } } -void RenderSystem::render_sprites() const { - ComponentManager & mgr = this->component_manager; - std::vector<std::reference_wrapper<Sprite>> sprites = mgr.get_components_by_type<Sprite>(); +bool RenderSystem::render_particle(const Sprite & sprite, + const Transform & tm) { + ComponentManager & mgr = ComponentManager::get_instance(); SDLContext & render = SDLContext::get_instance(); + + auto emitters = mgr.get_components_by_id<ParticleEmitter>(sprite.game_object_id); + + bool rendering_particles = false; + + Transform tmp(0, Vector2{0, 0}, 0, 0); + tmp.scale = tm.scale; + for (const ParticleEmitter & em : emitters) { + if (!em.active) continue; + if (!(em.data.sprite.game_object_id == sprite.game_object_id)) continue; + + rendering_particles = true; + + for (const Particle & p : em.data.particles) { + if (!p.active) continue; + tmp.position = p.position; + tmp.rotation = p.angle; + render.draw(em.data.sprite, tmp, *curr_cam); + } + } + return rendering_particles; +} +void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) { + + ComponentManager & mgr = ComponentManager::get_instance(); + SDLContext & render = SDLContext::get_instance(); + + render.draw(sprite, tm, *curr_cam); +} + +void RenderSystem::render() { + + ComponentManager & mgr = ComponentManager::get_instance(); + + auto sprites = mgr.get_components_by_type<Sprite>(); for (const Sprite & sprite : sprites) { - auto transforms = mgr.get_components_by_id<Transform>(sprite.game_object_id); - render.draw(sprite, transforms[0], *curr_cam); + if (!sprite.active) continue; + auto transform = mgr.get_components_by_id<Transform>(sprite.game_object_id).front().get(); + + bool rendered_particles = this->render_particle(sprite, transform); + + if (rendered_particles) continue; + + this->render_normal(sprite, transform); } } void RenderSystem::update() { this->clear_screen(); this->update_camera(); - this->render_sprites(); + this->render(); this->present_screen(); } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 87ec494..ad44716 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,6 +1,8 @@ #pragma once #include "api/Camera.h" +#include "api/Sprite.h" +#include "api/Transform.h" #include "System.h" @@ -23,6 +25,12 @@ public: */ void update() override; + + RenderSystem(const RenderSystem &) = delete; + RenderSystem(RenderSystem &&) = delete; + RenderSystem & operator=(const RenderSystem &) = delete; + RenderSystem & operator=(RenderSystem &&) = delete; + private: //! Clears the screen in preparation for rendering. void clear_screen() const; @@ -33,12 +41,28 @@ private: //! Updates the active camera used for rendering. void update_camera(); - //! Renders all active sprites to the screen. - void render_sprites() const; + //! Renders the whole screen + void render(); + + /** + * \brief Renders all the particles on the screen from a given sprite. + * + * \param sprite renders the particles with given texture + * \param tm the Transform component for scale + * \return true if particles have been rendered + */ + bool render_particle(const Sprite &, const Transform & tm); + + /** + * \brief renders a sprite with a Transform component on the screen + * + * \param sprite the sprite component that holds all the data + * \param tm the Transform component that holds the position,rotation and scale + */ + void render_normal(const Sprite &, const Transform & tm); /** * \todo Include color handling for sprites. - * \todo Implement particle emitter rendering with sprites. * \todo Add text rendering using SDL_ttf for text components. * \todo Implement a text component and a button component. * \todo Ensure each sprite is checked for active status before rendering. diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 3a5b543..ec08c08 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -29,5 +29,6 @@ add_example(db) add_example(ecs) add_example(scene_manager) add_example(particles) +add_example(rendering_particle) add_example(gameloop) diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp new file mode 100644 index 0000000..33013ef --- /dev/null +++ b/src/example/rendering_particle.cpp @@ -0,0 +1,61 @@ +#include "api/Camera.h" +#include "system/ParticleSystem.h" +#include <SDL2/SDL_timer.h> +#include <crepe/ComponentManager.h> + +#include <crepe/Component.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/ParticleEmitter.h> +#include <crepe/api/Rigidbody.h> +#include <crepe/api/Texture.h> +#include <crepe/api/Transform.h> +#include <crepe/system/RenderSystem.h> +#include <crepe/util/log.h> +#include <crepe/api/Color.h> +#include <crepe/api/Sprite.h> +#include <crepe/api/Vector2.h> + +#include <chrono> + +using namespace crepe; +using namespace std; + +int main(int argc, char * argv[]) { + GameObject game_object(0, "", "", Vector2{100, 100}, 0, 0.1); + Color color(255, 255, 255, 255); + Sprite test_sprite = game_object.add_component<Sprite>( + make_shared<Texture>("../asset/texture/img.png"), color, + FlipSettings{false, false}); + game_object.add_component<ParticleEmitter>(ParticleEmitter::Data{ + .position = {0, 0}, + .max_particles = 10, + .emission_rate = 0.1, + .min_speed = 6, + .max_speed = 20, + .min_angle = -20, + .max_angle = 20, + .begin_lifespan = 0, + .end_lifespan = 60, + .force_over_time = Vector2{0, 0}, + .boundary{ + .width = 1000, + .height = 1000, + .offset = Vector2{0, 0}, + .reset_on_exit = false, + }, + .sprite = test_sprite, + }); + game_object.add_component<Camera>(Color::get_white()); + + auto & sys = crepe::RenderSystem::get_instance(); + auto sys_part = crepe::ParticleSystem(); + auto start = std::chrono::steady_clock::now(); + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { + sys_part.update(); + sys.update(); + SDL_Delay(10 ); + } + + return 0; +} + |