#include "cRenderer.hpp" /*** Custom Header Files ***/ #include "cVideo.hpp" #include "../UtilityEngine/cUtility.hpp" using VideoEngine::cRenderer; using VideoEngine::cVideo; using UtilityEngine::cUtility; /*static*/ cRenderer* cRenderer::sp_inst = nullptr; /// private: cRenderer::cRenderer() : mp_renderer(nullptr), mp_rendererSoftware(nullptr) { Setup(); } cRenderer::~cRenderer() { CleanUp(); } /// public: /// Functions /*static*/ cRenderer& cRenderer::Inst() { if (sp_inst == nullptr) sp_inst = new cRenderer(); return *sp_inst; } /*static*/ void cRenderer::Delete() { delete sp_inst; sp_inst = nullptr; } const bool cRenderer::Setup() { bool rtn = false; if (cVideo::Inst().IsInit() == false) cUtility::Inst().Message("Unable to setup until SDL_Video is initialized."); else { CleanUp(); mp_renderer = cVideo::Inst().CreateRender(); SDL_Surface* surface = SDL_GetWindowSurface(cVideo::Inst().getWindow()); mp_rendererSoftware = SDL_CreateSoftwareRenderer(surface); //mp_rendererCopy = cVideo::Inst().CreateRender(); if (mp_renderer != nullptr) rtn = true; } return rtn; } void cRenderer::CleanUp() { if (mp_renderer != nullptr) SDL_DestroyRenderer(mp_renderer); if (mp_rendererSoftware != nullptr) SDL_DestroyRenderer(mp_rendererSoftware); mp_renderer = nullptr; mp_rendererSoftware = nullptr; } void cRenderer::Render( SDL_Texture* texture, SDL_Rect* srcrect, SDL_Rect* dstrect ) { cRenderer::Render(texture, srcrect, mp_renderer, dstrect); } void cRenderer::Render( SDL_Surface* surface, SDL_Rect* srcrect, SDL_Rect* dstrect ) { SDL_Texture* texture = SurfaceToTexture(surface); Render( texture, srcrect, dstrect ); SDL_DestroyTexture(texture); } void cRenderer::Render( SDL_Surface* src, const SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect ) { if (SDL_BlitSurface(src, srcrect, dst, dstrect) < 0) cUtility::Inst().Message("Unable to BlitSurface. SDL_BlitSurface():", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::Render( SDL_Texture* src, const SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect ) { src; srcrect; dst; dstrect; //??????? } void cRenderer::Render( SDL_Texture* src, const SDL_Rect* srcrect, SDL_Renderer* dst, SDL_Rect* dstrect ) { if (SDL_RenderCopy(dst, src, srcrect, dstrect) < 0) cUtility::Inst().Message("Unable to copy Texture to Renderer. SDL_RenderCopy():", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::RenderToTexture( SDL_Texture* src, SDL_Rect* srcrect, SDL_Texture* dst, SDL_Rect* dstrect ) { SetRenderTarget(dst); Render( src, srcrect, dstrect ); ResetRenderTarget(); } void cRenderer::RenderDrawColor( const SDL_Colour& colour ) { if (SDL_SetRenderDrawColor(mp_renderer, colour.r, colour.g, colour.b, colour.a) < 0) cUtility::Inst().Message("Unable to set render draw colour. SDL_SetRenderDrawColor():", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::RenderDrawRect( const SDL_Rect& rect, SDL_Texture* dst /*= nullptr */ ) { SetRenderTarget(dst); if (SDL_RenderFillRect(mp_renderer, &rect) < 0) cUtility::Inst().Message("Unable to draw rectangle. SDL_RenderFillRect():", __AT__, cUtility::eTypeSDL::SDL); ResetRenderTarget(); } void cRenderer::ScreenShot( const cString& filename, const cString& dir /*= ""*/ ) { SDL_Surface *sshot = NewSurface(); SDL_RenderReadPixels(getRenderer(), nullptr, SDL_PIXELFORMAT_RGBA32, sshot->pixels, sshot->pitch); SaveSurface(sshot, filename, dir); SDL_FreeSurface(sshot); } void cRenderer::SaveSurface( SDL_Surface* surface, const cString& fileName, const cString& dir /*= ""*/ ) { cString temp = dir + fileName; if (SDL_SaveBMP(surface, temp.c_str()) < 0) cUtility::Inst().Message("Unable to save Surface. SDL_SaveBMP()", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::SaveTexture( SDL_Texture* texture, const cString& fileName, const cString& dir /*= ""*/ ) { SDL_Surface* surface = TextureToSurface(texture); if (surface != nullptr) SaveSurface(surface, fileName, dir); else cUtility::Inst().Message("Unable to create Surface from Texture. TextureToSurface():", __AT__); SDL_FreeSurface(surface); } SDL_Texture* cRenderer::SurfaceToTexture( SDL_Surface* surface ) { SDL_Texture* rtn = SDL_CreateTextureFromSurface( mp_renderer, surface ); if ( rtn == nullptr) cUtility::Inst().Message("Unable to create Texture. SDL_CreateTextureFromSurface():", __AT__, cUtility::eTypeSDL::SDL); return rtn; } SDL_Surface* cRenderer::TextureToSurface( SDL_Texture* texture ) { SDL_Surface* rtn = nullptr; int w = 0; int h = 0; if (SDL_QueryTexture(texture, nullptr, nullptr, &w, &h) < 0) cUtility::Inst().Message("Unable to Query Texture. SDL_QueryTexture():", __AT__, cUtility::eTypeSDL::SDL); rtn = NewSurface(w, h); SDL_Rect rec = { 0, 0, w, h }; SDL_Texture* tmp_texture = NewTexture(w, h, true); // Create a new texture with Software Renderer CopyTexture(texture, tmp_texture, true); // Copy old texture to the Software Renderer Texture renderer Render(tmp_texture, nullptr, mp_rendererSoftware, &rec); // Render to the mp_rendererSoftware SDL_RenderReadPixels(mp_rendererSoftware, nullptr, SDL_PIXELFORMAT_RGBA32, rtn->pixels, rtn->pitch); return rtn; } void cRenderer::CopyTexture( SDL_Texture* src, SDL_Texture* dst, bool software /*= false*/ ) { SDL_Renderer* render = mp_renderer; if (software == true) render = mp_rendererSoftware; if (SDL_SetRenderTarget(render, dst) < 0) cUtility::Inst().Message("Unable to set render target to dst. SDL_SetRenderTarget():", __AT__, cUtility::eTypeSDL::SDL); Render(src, nullptr, render, nullptr); ResetRenderTarget(); } SDL_Surface* cRenderer::CopySurface( SDL_Surface* src ) { return SDL_ConvertSurface( src, src->format, src->flags ); } SDL_Surface* cRenderer::NewSurface( long int width /*= -1*/, long int height /*= -1*/ ) const { if (width < 0) width = cVideo::Inst().getWidth(); if (height < 0) height = cVideo::Inst().getHeight(); SDL_Surface* rtn = SDL_CreateRGBSurface(cVideo::Inst().getVideoSettings(), width, height, cVideo::Inst().getColourDepth(), cVideo::Inst().getRmask(), cVideo::Inst().getGmask(), cVideo::Inst().getBmask(), cVideo::Inst().getAmask()); if (rtn == nullptr) cUtility::Inst().Message("Unable to create surface. SDL_CreateRGBSurface():", __AT__, cUtility::eTypeSDL::SDL); return rtn; } SDL_Texture* cRenderer::NewTexture( long int width, long int height, const bool copyRenderer /*= false*/, const unsigned long int access /*= SDL_TEXTUREACCESS_TARGET*/ ) const { if (width < 0) width = cVideo::Inst().getWidth(); if (height < 0) height = cVideo::Inst().getHeight(); SDL_Renderer* renderer = nullptr; if (copyRenderer == false) renderer = mp_renderer; else renderer = mp_rendererSoftware; SDL_Texture* rtn = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, access, width, height); if (rtn == nullptr) cUtility::Inst().Message("Unable to create texture. SDL_CreateTexture:", __AT__, cUtility::eTypeSDL::SDL); return rtn; } const bool cRenderer::AreEqual( SDL_Surface& one, SDL_Surface& two ) { bool rtn = false; int x = 0; int y = 0; if (SDL_MUSTLOCK(&one) > 0) SDL_LockSurface(&one); if (SDL_MUSTLOCK(&two) > 0) SDL_LockSurface(&two); if ((one.pitch == two.pitch) && (one.h == two.h)) { unsigned char *one_pixels = (unsigned char *)one.pixels; unsigned char *two_pixels = (unsigned char *)two.pixels; rtn = true; // we are equal so far.... for (x = 0; x < one.pitch; x++) { for (y = 0; y < one.h; y++) { if (one_pixels[y + x] != two_pixels[y + x]) { rtn = false; x = one.pitch + two.pitch + 1; // break out of the top for loop y = one.h + two.h + 1; break; // we found a pixel that is not equal no need to continue } } } } if (SDL_MUSTLOCK(&one) > 0) SDL_UnlockSurface(&one); if (SDL_MUSTLOCK(&two) > 0) SDL_UnlockSurface(&two); return rtn; } void cRenderer::SetRenderTarget( SDL_Renderer* renderer, SDL_Texture* target /*= nullptr*/ ) { if (SDL_SetRenderTarget(renderer, target) < 0) cUtility::Inst().Message("Unable to set render target to dst. SDL_SetRenderTarget():", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::SetRenderTarget( SDL_Texture* target /*= nullptr*/ ) { if (SDL_SetRenderTarget(mp_renderer, target) < 0) cUtility::Inst().Message("Unable to set render target to dst. SDL_SetRenderTarget():", __AT__, cUtility::eTypeSDL::SDL); } void cRenderer::ResetRenderTarget() { if (SDL_SetRenderTarget(mp_renderer, nullptr) < 0) cUtility::Inst().Message("Unable to set render target to mp_rend. SDL_SetRenderTarget():", __AT__, cUtility::eTypeSDL::SDL); } SDL_Renderer* cRenderer::getRenderer() { return mp_renderer; } SDL_Renderer* cRenderer::getRendererCopy() { return mp_rendererSoftware; }