From 3fa9af58bc907048a8ccadc2bef7736ec554a09d Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 5 Jun 2018 21:02:51 -0400 Subject: refactored so that the renderer is its own class --- src/renderer.cpp | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 src/renderer.cpp (limited to 'src/renderer.cpp') diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..eddd11d --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,309 @@ +#include "renderer.h" +#include "game.h" + +Renderer::Renderer() +{ + win_ = window_ptr( + SDL_CreateWindow( + "Ether", + 100, + 100, + GAME_WIDTH, + GAME_HEIGHT, + SDL_WINDOW_SHOWN)); + + if (!win_) + { + throw sdl_error(); + } + + ren_ = renderer_ptr( + SDL_CreateRenderer( + win_.get(), + -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)); + + if (!ren_) + { + throw sdl_error(); + } + + texture_ptr origFade; + { + surface_ptr pfs(IMG_Load("../res/lighting.png")); + if (!pfs) + { + throw img_error(); + } + + origFade = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get())); + } + + SDL_SetTextureBlendMode(origFade.get(), SDL_BLENDMODE_BLEND); + + playerFade_ = texture_ptr( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA4444, + SDL_TEXTUREACCESS_TARGET, + 144, + 144)); + + if (!playerFade_) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), playerFade_.get()); + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + SDL_RenderClear(ren_.get()); + SDL_RenderCopy(ren_.get(), origFade.get(), nullptr, nullptr); + + lampFade_ = texture_ptr( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA4444, + SDL_TEXTUREACCESS_TARGET, + 144, + 144)); + + if (!lampFade_) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), lampFade_.get()); + + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + SDL_RenderClear(ren_.get()); + SDL_RenderCopy(ren_.get(), origFade.get(), nullptr, nullptr); + + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_MOD); + SDL_SetRenderDrawColor(ren_.get(), 255, 204, 58, 255); + SDL_RenderFillRect(ren_.get(), nullptr); + + dustFade_ = texture_ptr( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA4444, + SDL_TEXTUREACCESS_TARGET, + 144, + 144)); + + if (!dustFade_) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), dustFade_.get()); + + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + SDL_RenderClear(ren_.get()); + SDL_RenderCopy(ren_.get(), origFade.get(), nullptr, nullptr); + + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_MOD); + SDL_SetRenderDrawColor(ren_.get(), 255, 150, 255, 255); + SDL_RenderFillRect(ren_.get(), nullptr); +} + +void Renderer::render( + const Game& game, + bool drawDark) +{ + texture_ptr canvas( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + TILE_WIDTH * game.map.getWidth(), + TILE_HEIGHT * game.map.getHeight())); + + if (!canvas) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), canvas.get()); + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren_.get(), rand() % 255, rand() % 255, rand() % 255, 255); + SDL_RenderClear(ren_.get()); + + for (int y = game.map.getTop(); y < game.map.getBottom(); y++) + { + for (int x = game.map.getLeft(); x < game.map.getRight(); x++) + { + bool draw = true; + + if ((game.player_x == x && game.player_y == y) && game.renderPlayer) + { + SDL_SetRenderDrawColor(ren_.get(), 255, 255, 0, 255); + } else if (!game.map.at(x,y).lit) + { + if (drawDark) + { + SDL_SetRenderDrawColor(ren_.get(), 40, 40, 40, 255); + } else { + draw = false; + } + } else { + int alpha = 255; + + switch (game.map.at(x,y).tile) + { + case Tile::Floor: + { + SDL_SetRenderDrawColor(ren_.get(), 210, 210, 210, alpha); + break; + } + + case Tile::Wall: + { + SDL_SetRenderDrawColor(ren_.get(), 100, 100, 100, alpha); + break; + } + + case Tile::Dust: + { + SDL_SetRenderDrawColor(ren_.get(), 128, 40, 255, alpha); + break; + } + + case Tile::Lamp: + { + SDL_SetRenderDrawColor(ren_.get(), 0, 255, 255, alpha); + break; + } + } + } + + if (draw) + { + SDL_Rect rect { + game.map.getTrueX(x) * TILE_WIDTH, + game.map.getTrueY(y) * TILE_HEIGHT, + TILE_WIDTH, + TILE_HEIGHT}; + + SDL_RenderFillRect(ren_.get(), &rect); + } + } + } + + texture_ptr mask( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + TILE_WIDTH * game.map.getWidth(), + TILE_HEIGHT * game.map.getHeight())); + + if (!mask) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), mask.get()); + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + SDL_RenderClear(ren_.get()); + + for (int y = game.map.getTop(); y < game.map.getBottom(); y++) + { + for (int x = game.map.getLeft(); x < game.map.getRight(); x++) + { + if (game.map.at(x,y).lightType != Source::None) + { + texture_ptr sourceMask( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + TILE_WIDTH * game.map.getWidth(), + TILE_HEIGHT * game.map.getHeight())); + + if (!sourceMask) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren_.get(), sourceMask.get()); + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + SDL_RenderClear(ren_.get()); + + int fadeX = game.map.getTrueX(x) - game.map.at(x,y).lightRadius; + int fadeY = game.map.getTrueY(y) - game.map.at(x,y).lightRadius; + int fadeRight = game.map.getTrueX(x) + game.map.at(x,y).lightRadius; + int fadeBottom = game.map.getTrueY(y) + game.map.at(x,y).lightRadius; + + SDL_Rect fadeRect { + fadeX * TILE_WIDTH, + fadeY * TILE_HEIGHT, + (game.map.at(x,y).lightRadius * 2 + 1) * TILE_WIDTH, + (game.map.at(x,y).lightRadius * 2 + 1) * TILE_HEIGHT}; + + if (game.map.at(x,y).lightType == Source::Lamp) + { + SDL_SetTextureBlendMode(lampFade_.get(), SDL_BLENDMODE_NONE); + SDL_RenderCopy(ren_.get(), lampFade_.get(), nullptr, &fadeRect); + } else if (game.map.at(x,y).lightType == Source::Player) { + SDL_SetTextureBlendMode(playerFade_.get(), SDL_BLENDMODE_NONE); + SDL_RenderCopy(ren_.get(), playerFade_.get(), nullptr, &fadeRect); + } else if (game.map.at(x,y).lightType == Source::Dust) { + SDL_SetTextureBlendMode(dustFade_.get(), SDL_BLENDMODE_NONE); + SDL_RenderCopy(ren_.get(), dustFade_.get(), nullptr, &fadeRect); + } + + SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); + + for (int sy = fadeY; sy < fadeBottom; sy++) + { + for (int sx = fadeX; sx < fadeRight; sx++) + { + if (!game.map.at(x,y).litTiles.count({sx, sy})) + { + SDL_Rect rect { + game.map.getTrueX(sx) * TILE_WIDTH, + game.map.getTrueY(sy) * TILE_HEIGHT, + TILE_WIDTH, + TILE_HEIGHT}; + + SDL_RenderFillRect(ren_.get(), &rect); + } + } + } + + SDL_SetRenderTarget(ren_.get(), mask.get()); + SDL_SetTextureBlendMode(sourceMask.get(), SDL_BLENDMODE_ADD); + SDL_RenderCopy(ren_.get(), sourceMask.get(), nullptr, nullptr); + } + } + } + + SDL_SetRenderTarget(ren_.get(), canvas.get()); + SDL_SetTextureBlendMode(mask.get(), SDL_BLENDMODE_MOD); + SDL_RenderCopy(ren_.get(), mask.get(), nullptr, nullptr); + + SDL_SetRenderTarget(ren_.get(), nullptr); + + if (!game.zooming) + { + SDL_RenderCopy(ren_.get(), canvas.get(), nullptr, nullptr); + } else { + // TODO: zooming back in to the player + SDL_Rect zoomRect { + ((game.maxZoom - game.curZoom) * TILE_WIDTH + game.zoomProgress) + * ZOOM_X_FACTOR / 2, + ((game.maxZoom - game.curZoom) * TILE_HEIGHT + game.zoomProgress) + * ZOOM_Y_FACTOR / 2, + (game.curZoom * TILE_WIDTH - game.zoomProgress) * ZOOM_X_FACTOR, + (game.curZoom * TILE_HEIGHT - game.zoomProgress) * ZOOM_Y_FACTOR + }; + + SDL_RenderCopy(ren_.get(), canvas.get(), &zoomRect, nullptr); + } + + SDL_RenderPresent(ren_.get()); +} -- cgit 1.4.1