From 704500a9dfe46e1d50bf4238f6ec86e74c887bf3 Mon Sep 17 00:00:00 2001 From: Bilal Kahraman Date: Mon, 5 Aug 2024 01:58:19 +0300 Subject: [PATCH] Create texture struct and store w, h values of texture, decrease view distance and render solid black there --- app/main.cpp | 2 +- assets/textures/solid_black.png | Bin 0 -> 619 bytes src/Graphics/include/Graphics/renderer.h | 5 ++ src/Graphics/src/renderer.cpp | 73 +++++++++++------- .../include/TextureManager/texture_manager.h | 11 ++- src/TextureManager/src/texture_manager.cpp | 9 ++- 6 files changed, 69 insertions(+), 31 deletions(-) create mode 100644 assets/textures/solid_black.png diff --git a/app/main.cpp b/app/main.cpp index a503eee..c9986fb 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -13,7 +13,7 @@ int main() { using namespace wolfenstein; - GeneralConfig config(1280, 768, 0, 50, 120, 15.0, ToRadians(60.0)); + GeneralConfig config(1280, 768, 0, 50, 120, 10.0, ToRadians(60.0)); Game game(config); game.Run(); diff --git a/assets/textures/solid_black.png b/assets/textures/solid_black.png new file mode 100644 index 0000000000000000000000000000000000000000..5f77ef3cc0ad9bf311a8de4ab78ced8f8f720aad GIT binary patch literal 619 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)K$^Ea{HEjtmSN`?>!lvNA9*DS5g$ zhE&A8z0e4hWH`LwXR!Q})_}wV4UEieJQ4;8ql}Rq2p& map_ptr, const std::shared_ptr& camera_ptr, RenderQueue& render_queue); + void RenderIfRayHit(const int horizontal_slice, const Ray& ray, + const std::shared_ptr& camera_ptr, + RenderQueue& render_queue); + void RenderIfRayHitNot(const int horizontal_slice, + RenderQueue& render_queue); void RenderObjects(const std::vector>& objects, const std::shared_ptr& camera_ptr, RenderQueue& render_queue); diff --git a/src/Graphics/src/renderer.cpp b/src/Graphics/src/renderer.cpp index d067d97..39df0a2 100644 --- a/src/Graphics/src/renderer.cpp +++ b/src/Graphics/src/renderer.cpp @@ -57,9 +57,9 @@ void Renderer::RenderScene(const std::shared_ptr& scene_ptr, void Renderer::RenderBackground() { // Render sky auto sky_texture = TextureManager::GetInstance().GetTexture(0); - SDL_Rect src_rect = {0, 0, config_.width, config_.height / 2}; + SDL_Rect src_rect = {0, 0, sky_texture.width, sky_texture.height}; SDL_Rect dest_rect = {0, 0, config_.width, config_.height / 2}; - SDL_RenderCopy(renderer_, sky_texture, &src_rect, &dest_rect); + SDL_RenderCopy(renderer_, sky_texture.texture, &src_rect, &dest_rect); // Render ground black SDL_SetRenderDrawColor(renderer_, 50, 50, 50, 255); SDL_Rect ground_rect = {0, config_.height / 2, config_.width, @@ -71,33 +71,55 @@ void Renderer::RenderWalls(const std::shared_ptr& map_ptr, const std::shared_ptr& camera_ptr, RenderQueue& render_queue) { camera_ptr->Update(map_ptr); - const auto map = map_ptr->GetMap(); const auto rays = camera_ptr->GetRays(); - const auto camera_position = camera_ptr->GetPosition(); - const auto texture_size = 1024; - int start_x = 0; + + int horizontal_slice = 0; for (const auto& ray : *rays) { if (!ray.is_hit) { - continue; + RenderIfRayHitNot(horizontal_slice, render_queue); + } + else { + RenderIfRayHit(horizontal_slice, ray, camera_ptr, render_queue); } - auto distance = ray.perpendicular_distance * - std::cos(camera_position.theta - ray.theta); - auto line_height = static_cast(config_.height / distance); - int draw_start = -line_height / 2 + config_.height / 2; - int draw_end = line_height / 2 + config_.height / 2; - - auto hit_point = - ray.is_hit_vertical ? ray.hit_point.y : ray.hit_point.x; - hit_point = std::fmod(hit_point, 1.0); - int texture_point = static_cast(hit_point * texture_size); - - SDL_Rect src_rect = {texture_point, 0, 2, texture_size}; - SDL_Rect dest_rect = {start_x, draw_start, 2, draw_end - draw_start}; - render_queue.push({ray.wall_id, src_rect, dest_rect, distance}); - start_x += 2; + horizontal_slice += 2; }; } +void Renderer::RenderIfRayHit(const int horizontal_slice, const Ray& ray, + const std::shared_ptr& camera_ptr, + RenderQueue& render_queue) { + auto distance = ray.perpendicular_distance * + std::cos(camera_ptr->GetPosition().theta - ray.theta); + auto line_height = static_cast(config_.height / distance); + int draw_start = -line_height / 2 + config_.height / 2; + int draw_end = line_height / 2 + config_.height / 2; + + auto hit_point = ray.is_hit_vertical ? ray.hit_point.y : ray.hit_point.x; + hit_point = std::fmod(hit_point, 1.0); + const auto texture_height = + TextureManager::GetInstance().GetTexture(ray.wall_id).height; + int texture_point = static_cast(hit_point * texture_height); + + SDL_Rect src_rect = {texture_point, 0, 2, texture_height}; + SDL_Rect dest_rect = {horizontal_slice, draw_start, 2, + draw_end - draw_start}; + render_queue.push({ray.wall_id, src_rect, dest_rect, distance}); +} + +void Renderer::RenderIfRayHitNot(const int horizontal_slice, + RenderQueue& render_queue) { + auto line_height = + static_cast(config_.height / (config_.view_distance + 0.5)); + int draw_start = -line_height / 2 + config_.height / 2; + int draw_end = line_height / 2 + config_.height / 2; + + SDL_Rect src_rect = {0, 0, 2, + TextureManager::GetInstance().GetTexture(7).height}; + SDL_Rect dest_rect = {horizontal_slice, draw_start, 2, + draw_end - draw_start}; + render_queue.push({7, src_rect, dest_rect, config_.view_distance}); +} + void Renderer::RenderObjects( const std::vector>& objects, const std::shared_ptr& camera_ptr, RenderQueue& render_queue) { @@ -139,10 +161,9 @@ void Renderer::RenderTextures(RenderQueue& render_queue) { while (!render_queue.empty()) { auto renderable_texture = render_queue.top(); render_queue.pop(); - SDL_RenderCopy(renderer_, - TextureManager::GetInstance().GetTexture( - renderable_texture.texture_id), - &renderable_texture.src_rect, + const auto texture = TextureManager::GetInstance().GetTexture( + renderable_texture.texture_id); + SDL_RenderCopy(renderer_, texture.texture, &renderable_texture.src_rect, &renderable_texture.dest_rect); } } diff --git a/src/TextureManager/include/TextureManager/texture_manager.h b/src/TextureManager/include/TextureManager/texture_manager.h index 1d36d12..a25671e 100644 --- a/src/TextureManager/include/TextureManager/texture_manager.h +++ b/src/TextureManager/include/TextureManager/texture_manager.h @@ -19,6 +19,13 @@ namespace wolfenstein { +struct Texture +{ + SDL_Texture* texture; + int width; + int height; +}; + class TextureManager { @@ -32,13 +39,13 @@ class TextureManager void InitManager(SDL_Renderer* renderer); void LoadTexture(uint16_t texture_id, const std::string& texture_path); - SDL_Texture* GetTexture(uint16_t texture_id); + Texture GetTexture(uint16_t texture_id); private: TextureManager() = default; static TextureManager* instance_; - std::unordered_map textures_; + std::unordered_map textures_; SDL_Renderer* renderer_; }; diff --git a/src/TextureManager/src/texture_manager.cpp b/src/TextureManager/src/texture_manager.cpp index 4da510d..baff6d2 100644 --- a/src/TextureManager/src/texture_manager.cpp +++ b/src/TextureManager/src/texture_manager.cpp @@ -23,14 +23,19 @@ void TextureManager::InitManager(SDL_Renderer* renderer) { LoadTexture(4, texture_path + "4.png"); LoadTexture(5, texture_path + "5.png"); LoadTexture(6, texture_path + "candlebra.png"); + LoadTexture(7, texture_path + "solid_black.png"); } void TextureManager::LoadTexture(uint16_t texture_id, const std::string& texture_path) { - textures_[texture_id] = IMG_LoadTexture(renderer_, texture_path.c_str()); + Texture texture; + texture.texture = IMG_LoadTexture(renderer_, texture_path.c_str()); + SDL_QueryTexture(texture.texture, nullptr, nullptr, &texture.width, + &texture.height); + textures_[texture_id] = texture; } -SDL_Texture* TextureManager::GetTexture(uint16_t texture_id) { +Texture TextureManager::GetTexture(uint16_t texture_id) { return textures_[texture_id]; }