From 8c9d046123f0978ea3f770838a2321d85ffda977 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 29 May 2018 15:28:52 -0400 Subject: started implementing color tinting on lighting --- src/main.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 171 insertions(+), 20 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 2840439..c02fdd5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -15,6 +16,14 @@ public: } }; +class img_error : public std::logic_error { +public: + + img_error() : std::logic_error(IMG_GetError()) + { + } +}; + class window_deleter { public: @@ -37,6 +46,28 @@ public: using renderer_ptr = std::unique_ptr; +class surface_deleter { +public: + + void operator()(SDL_Surface* ptr) + { + SDL_FreeSurface(ptr); + } +}; + +using surface_ptr = std::unique_ptr; + +class texture_deleter { +public: + + void operator()(SDL_Texture* ptr) + { + SDL_DestroyTexture(ptr); + } +}; + +using texture_ptr = std::unique_ptr; + enum class Tile { Floor, Wall, @@ -44,6 +75,13 @@ enum class Tile { Lamp }; +enum class Source { + None, + Dust, + Lamp, + Player +}; + const int GAME_WIDTH = 640*2; const int GAME_HEIGHT = 480*2; const int TILE_WIDTH = 8*2; @@ -65,7 +103,8 @@ public: Map() : tiles(VIEW_WIDTH*VIEW_HEIGHT, Tile::Floor), lighting(VIEW_WIDTH*VIEW_HEIGHT, false), - lightStrength(VIEW_WIDTH*VIEW_HEIGHT, 0.0) + lightStrength(VIEW_WIDTH*VIEW_HEIGHT, 0.0), + lightSource(VIEW_WIDTH*VIEW_HEIGHT, Source::None) { } @@ -73,6 +112,7 @@ public: std::vector lighting; std::vector oldLighting; std::vector lightStrength; + std::vector lightSource; int lightedSpots = 0; }; @@ -84,7 +124,53 @@ void render( const Map& map, bool drawDark = true) { - SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); + texture_ptr playerFade; + { + surface_ptr pfs(IMG_Load("../res/lighting.png")); + if (!pfs) + { + throw img_error(); + } + + playerFade = texture_ptr(SDL_CreateTextureFromSurface(ren, pfs.get())); + } + + texture_ptr lampFade( + SDL_CreateTexture( + ren, + SDL_PIXELFORMAT_RGBA4444, + SDL_TEXTUREACCESS_TARGET, + 144, + 144)); + + { + SDL_SetRenderTarget(ren, lampFade.get()); + + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren, 255, 255, 255, 0); + SDL_RenderFillRect(ren, nullptr); + + SDL_RenderCopy(ren, playerFade.get(), nullptr, nullptr); + + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD); + SDL_SetRenderDrawColor(ren, 255, 180, 0, 255); + SDL_RenderFillRect(ren, nullptr); + + SDL_SetRenderTarget(ren, nullptr); + } + + int darkR = 40; + int darkG = 40; + int darkB = 40; + + if (!drawDark) + { + darkR = rand() % 255; + darkG = rand() % 255; + darkB = rand() % 255; + } + + SDL_SetRenderDrawColor(ren, darkR, darkG, darkB, 255); SDL_RenderClear(ren); for (int y = 0; y < VIEW_HEIGHT; y++) @@ -98,36 +184,40 @@ void render( SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); } else if (!map.lighting.at(x+VIEW_WIDTH*y)) { - if (drawDark) + /*if (drawDark) { SDL_SetRenderDrawColor(ren, 40, 40, 40, 255); } else { draw = false; - } + }*/ + draw = false; } else { + int alpha = map.lightStrength.at(x+y*VIEW_WIDTH) * 255; + alpha = 255; + switch (map.tiles.at(x+y*VIEW_WIDTH)) { case Tile::Floor: { - SDL_SetRenderDrawColor(ren, 210, 210, 210, 255); + SDL_SetRenderDrawColor(ren, 210, 210, 210, alpha); break; } case Tile::Wall: { - SDL_SetRenderDrawColor(ren, 100, 100, 100, 255); + SDL_SetRenderDrawColor(ren, 100, 100, 100, alpha); break; } case Tile::Dust: { - SDL_SetRenderDrawColor(ren, 128, 40, 255, 255); + SDL_SetRenderDrawColor(ren, 128, 40, 255, alpha); break; } case Tile::Lamp: { - SDL_SetRenderDrawColor(ren, 0, 255, 255, 255); + SDL_SetRenderDrawColor(ren, 0, 255, 255, alpha); break; } } @@ -136,10 +226,53 @@ void render( if (draw) { SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; + + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); SDL_RenderFillRect(ren, &rect); - int alpha = (1.0 - map.lightStrength.at(x+y*VIEW_WIDTH)) * 255; - SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha); + + } + } + } + + for (int y = 0; y < VIEW_HEIGHT; y++) + { + for (int x = 0; x < VIEW_WIDTH; x++) + { + if (map.lightSource.at(x+VIEW_WIDTH*y) != Source::None) + { + SDL_Rect fadeRect{x*TILE_WIDTH + (TILE_WIDTH/2) - (144/2), y*TILE_HEIGHT + (TILE_HEIGHT/2) - (144/2), 144, 144}; + if (map.lightSource.at(x+VIEW_WIDTH*y) == Source::Lamp) + { + //SDL_SetTextureBlendMode(lampFade.get(), SDL_BLENDMODE_MOD); + SDL_RenderCopy(ren, lampFade.get(), nullptr, &fadeRect); + //SDL_SetRenderDrawColor(ren, 255, 180, 0, 50); + //SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); + //SDL_RenderFillRect(ren, &rect); + } else if (map.lightSource.at(x+VIEW_WIDTH*y) == Source::Player) + { + //SDL_SetTextureBlendMode(playerFade.get(), SDL_BLENDMODE_MOD); + SDL_RenderCopy(ren, playerFade.get(), nullptr, &fadeRect); + } + + /*SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha); + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); + SDL_RenderFillRect(ren, &rect);*/ + } + } + } + + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren, darkR, darkG, darkB, 255); + + for (int y = 0; y < VIEW_HEIGHT; y++) + { + for (int x = 0; x < VIEW_WIDTH; x++) + { + if (!map.lighting.at(x+VIEW_WIDTH*y)) + { + SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; + SDL_RenderFillRect(ren, &rect); } } @@ -227,6 +360,7 @@ void recalculateLighting(Map& map, fov_settings_type* fov) map.lighting = std::vector(VIEW_WIDTH*VIEW_HEIGHT, false); map.lightStrength = std::vector(VIEW_WIDTH*VIEW_HEIGHT, 0.0); map.lightedSpots = 0; + map.lightSource = std::vector(VIEW_WIDTH*VIEW_HEIGHT, Source::None); fov_settings_set_opacity_test_function( fov, @@ -241,7 +375,7 @@ void recalculateLighting(Map& map, fov_settings_type* fov) fov_settings_set_apply_lighting_function( fov, - [] (void* map, int x, int y, int dx, int dy, void*) { + [] (void* map, int x, int y, int dx, int dy, void* source) { if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT)) { Map& m = *static_cast(map); @@ -259,6 +393,12 @@ void recalculateLighting(Map& map, fov_settings_type* fov) 0.0, 1.0 - std::sqrt(dx * dx + dy * dy) / static_cast(RADIUS)), 1.0/3.0)); + + Source ls = *static_cast(source); + if (static_cast(ls) > static_cast(m.lightSource[x+VIEW_WIDTH*y])) + { + //m.lightSource[x+VIEW_WIDTH*y] = ls; + } } }); @@ -266,22 +406,29 @@ void recalculateLighting(Map& map, fov_settings_type* fov) { for (int x = 0; x < VIEW_WIDTH; x++) { - if ((player_x == x && player_y == y) || map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) + Source ls = Source::None; + + if (player_x == x && player_y == y) + { + ls = Source::Player; + } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Dust) { - fov_circle(fov, static_cast(&map), nullptr, x, y, RADIUS); + ls = Source::Dust; + } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) + { + ls = Source::Lamp; } - if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp || - map.tiles[x+VIEW_WIDTH*y] == Tile::Dust) + if (ls != Source::None) { + fov_circle(fov, static_cast(&map), static_cast(&ls), x, y, RADIUS); + map.lighting[x+VIEW_WIDTH*y] = true; map.lightStrength[x+VIEW_WIDTH*y] = 1.0; + map.lightSource[x+VIEW_WIDTH*y] = ls; } } } - - map.lighting[player_x+VIEW_WIDTH*player_y] = true; - map.lightStrength[player_x+VIEW_WIDTH*player_y] = 1.0; } void processKeys(Map& map, const Input& keystate) @@ -325,6 +472,11 @@ int main(int, char**) throw sdl_error(); } + if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) + { + throw img_error(); + } + try { window_ptr win( @@ -346,8 +498,6 @@ int main(int, char**) throw sdl_error(); } - SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); - Map map; std::unique_ptr fov(new fov_settings_type()); @@ -527,6 +677,7 @@ int main(int, char**) std::cout << "SDL error (" << ex.what() << ")" << std::endl; } + IMG_Quit(); SDL_Quit(); return 0; -- cgit 1.4.1