Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // textureWrapper.hpp
- // ProjectViolet
- //
- // Created by Keegan Bilodeau on 7/27/20.
- // Copyright © 2020 Keegan Bilodeau. All rights reserved.
- //
- #ifndef textureWrapper_hpp
- #define textureWrapper_hpp
- #include <memory>
- #include <SDL.h>
- #include <SDL_ttf.h>
- #include <stdio.h>
- #include <string>
- #include <variant>
- struct RenderPoint
- {
- int x, y;
- bool isFixed = false;
- double angle = 0.0f;
- };
- struct ImageInfo
- {
- std::string path;
- bool isColorKeyed;
- double xScale, yScale;
- };
- struct TextInfo
- {
- std::string text;
- std::shared_ptr<TTF_Font> &textFont;
- SDL_Color color;
- };
- struct RectangleInfo
- {
- SDL_Rect rectangle;
- SDL_Color color;
- };
- typedef std::variant<ImageInfo, TextInfo, RectangleInfo> TextureInfo;
- class TextureWrapper
- {
- public:
- // Initializes the wrapper's fields with default values
- TextureWrapper();
- // Calls for the attached texture to be freed
- ~TextureWrapper();
- // Creates a texture from a file and attaches it to the wrapper
- bool initFromFile(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer, SDL_Color colorKey = {0xFF, 0x00, 0xDC});
- // Creates a texture from a string and attaches it to the wrapper
- bool initFromString(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer);
- // Creates a texture from a SDL rectangle and attaches it to the wrapper
- bool initFromRectangle(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer);
- // Uses the SDL renderer to render the texture to the screen
- void render(RenderPoint renderPoint, SDL_Rect camera = {0, 0, 0, 0}, std::unique_ptr<SDL_Rect> clipRect = nullptr, std::unique_ptr<SDL_Point> center = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
- // Allows one to enable the alpha channel
- void setBlendMode(SDL_BlendMode blendMode);
- // Modifies the texture's color values based off the passed color
- void modifyTextureColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
- // Changes the texture's scale factor
- void setTextureScale(double xScaleFactor, double yScaleFactor);
- // Returns the texture's orignal width (unscaled)
- int getUnscaledWidth() const;
- // Returns the texture's original height (unscaled)
- int getUnscaledHeight() const;
- // Returns the texture's scaled width
- int getScaledWidth() const;
- // Returns the texture's scaled height
- int getScaledHeight() const;
- private:
- // Frees the attached texture to allow new textures to be attached
- void freeTexture();
- // Pointer to the renderer so that it doesn't have to be repeatedly passed to the texture
- std::shared_ptr<SDL_Renderer> mRenderer;
- // The SDL texure being wrapped
- std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)> mWrappedTexture;
- // Texture's dimensions, has to be stored because they're lost when the SDL surface is converted to a texture
- int mWidth, mHeight;
- // Texture's x and y scale factor
- double mXScaleFactor, mYScaleFactor;
- };
- #endif /* textureWrapper_hpp */
- //
- // textureWrapper.cpp
- // ProjectViolet
- //
- // Created by Keegan Bilodeau on 7/27/20.
- // Copyright © 2020 Keegan Bilodeau. All rights reserved.
- //
- #include "debug.hpp"
- #include "textureWrapper.hpp"
- #include <SDL_image.h>
- using namespace Debug;
- TextureWrapper::TextureWrapper() : mRenderer(nullptr), mWrappedTexture(nullptr, nullptr), mWidth(0), mHeight(0), mXScaleFactor(0.0f), mYScaleFactor(0.0f)
- {
- }
- TextureWrapper::~TextureWrapper()
- {
- freeTexture();
- }
- void TextureWrapper::freeTexture()
- {
- mRenderer = nullptr;
- mWrappedTexture = nullptr;
- mWidth = 0;
- mHeight = 0;
- mXScaleFactor = 0.0f;
- mYScaleFactor = 0.0f;
- }
- bool TextureWrapper::initFromFile(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer, SDL_Color colorKey)
- {
- // Loading success flag
- bool success = false;
- assert(textureInfo.index() == 0);
- ImageInfo& imageInfo = std::get<ImageInfo>(textureInfo);
- // Releases any attached textures
- if (mWrappedTexture != nullptr)
- freeTexture();
- // Pass the application's renderer to the texture
- mRenderer = renderer;
- // Loads the image as a SDL surface
- std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> loadedSurface(IMG_Load(imageInfo.path.c_str()), &SDL_FreeSurface);
- // Check if it loads successfully
- if (!loadedSurface)
- {
- logMessage("Failed to load image from " + imageInfo.path + "!", SevereError, __LINE__, __FILE_NAME__);
- logMessage(IMG_GetError(), SDLImageError, __LINE__, __FILE_NAME__);
- success = false;
- }
- else
- {
- // Color keys the image if enabled
- if (imageInfo.isColorKeyed)
- SDL_SetColorKey(loadedSurface.get(), SDL_TRUE, SDL_MapRGB(loadedSurface->format, colorKey.r, colorKey.g, colorKey.b));
- // Attaches the
- mWrappedTexture = std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(SDL_CreateTextureFromSurface(mRenderer.get(), loadedSurface.get()), &SDL_DestroyTexture);
- // Check if its loaded successfully
- if (!mWrappedTexture)
- {
- logMessage("Failed to convert " + imageInfo.path + " into a texture!", SevereError, __LINE__, __FILE_NAME__);
- logMessage(SDL_GetError(), SDLError, __LINE__, __FILE_NAME__);
- success = false;
- }
- else
- {
- // Preserve the texture's dimensions
- mWidth = loadedSurface->w;
- mHeight = loadedSurface->h;
- // Store the texture scale resizing the render quad in TextureWrapper::render(...)
- mXScaleFactor = imageInfo.xScale;
- mYScaleFactor = imageInfo.yScale;
- }
- }
- return success;
- }
- bool TextureWrapper::initFromString(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer)
- {
- // Loading success flag
- bool success = true;
- assert(textureInfo.index() == 1);
- TextInfo &textInfo = std::get<TextInfo>(textureInfo);
- // Release any texture previously attached to the wrapper
- if (!mWrappedTexture)
- freeTexture();
- // Attach the renderer to the texture
- mRenderer = renderer;
- // Create a surface containing text using TTF
- std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> loadedSurface(TTF_RenderText_Blended_Wrapped(textInfo.textFont.get(), textInfo.text.c_str(), textInfo.color, 300 * 1.776), &SDL_FreeSurface);
- // Check if it was loaded successfully
- if (!loadedSurface)
- {
- logMessage("Unable to render text to a surface!", SevereError, __LINE__, __FILE_NAME__);
- logMessage(TTF_GetError(), SDLFontError, __LINE__, __FILE_NAME__);
- success = false;
- }
- else
- {
- // Convert the surface to a texture
- mWrappedTexture = std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(SDL_CreateTextureFromSurface(mRenderer.get(), loadedSurface.get()), &SDL_DestroyTexture);
- // Check if the conversion was successful
- if (!mWrappedTexture)
- {
- logMessage("Unable to convert the rendered text to a texture!", SevereError, __LINE__, __FILE_NAME__);
- logMessage(SDL_GetError(), SDLError, __LINE__, __FILE_NAME__);
- success = false;
- }
- else
- {
- mWidth = loadedSurface->w;
- mHeight = loadedSurface->h;
- mXScaleFactor = 1;
- mYScaleFactor = 1;
- }
- }
- return success;
- }
- bool TextureWrapper::initFromRectangle(TextureInfo textureInfo, std::shared_ptr<SDL_Renderer> &renderer)
- {
- // Loading success flag
- bool success = true;
- assert(textureInfo.index() == 2);
- RectangleInfo &rectInfo = std::get<RectangleInfo>(textureInfo);
- // Release any previously attached textures
- if (!mWrappedTexture)
- freeTexture();
- // Attach the renderer to the texture
- mRenderer = renderer;
- // Create a targetable texture
- mWrappedTexture = std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(SDL_CreateTexture(mRenderer.get(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, rectInfo.rectangle.w, rectInfo.rectangle.h), &SDL_DestroyTexture);
- // Check if it was created successfully
- if (!mWrappedTexture)
- {
- logMessage("Failed to create a targetable texture!", SevereError, __LINE__, __FILE_NAME__);
- logMessage(SDL_GetError(), SDLError, __LINE__, __FILE_NAME__);
- success = false;
- }
- else
- {
- // Set the dimensions
- mWidth = rectInfo.rectangle.w;
- mHeight = rectInfo.rectangle.h;
- // Set the scale
- mXScaleFactor = 1;
- mYScaleFactor = 1;
- // Make the texture the color of the rectangle:
- // 1) Target the texture
- SDL_SetRenderTarget(mRenderer.get(), mWrappedTexture.get());
- // 2) Set the render draw color to the color of the rectanlge
- SDL_SetRenderDrawColor(mRenderer.get(), rectInfo.color.r, rectInfo.color.g, rectInfo.color.b, rectInfo.color.a);
- // 3) Paint the screen by "clearing" it
- SDL_RenderClear(mRenderer.get());
- // 4) Reset the draw color
- SDL_SetRenderDrawColor(mRenderer.get(), 0xFF, 0xFF, 0xFF, 0xFF);
- // 5) Reset the texture target
- SDL_SetRenderTarget(mRenderer.get(), nullptr);
- }
- return success;
- }
- void TextureWrapper::render(RenderPoint renderPoint, SDL_Rect camera, std::unique_ptr<SDL_Rect> clipRect, std::unique_ptr<SDL_Point> center, SDL_RendererFlip flip)
- {
- SDL_Rect renderQuad {renderPoint.x, renderPoint.y, mWidth, mHeight};
- // Adjust the texture based off a camera variable if true
- if (!renderPoint.isFixed)
- {
- renderQuad.x -= camera.x;
- renderQuad.y -= camera.y;
- }
- // Applies the clip dimensions if a clip rectangle is passed
- if (clipRect)
- {
- renderQuad.w = clipRect->w;
- renderQuad.h = clipRect->h;
- }
- renderQuad.x *= mXScaleFactor;
- renderQuad.y *= mYScaleFactor;
- SDL_RenderCopyEx(mRenderer.get(), mWrappedTexture.get(), clipRect.get(), &renderQuad, renderPoint.angle, center.get(), flip);
- }
- void TextureWrapper::setBlendMode(SDL_BlendMode blendMode)
- {
- SDL_SetTextureBlendMode(mWrappedTexture.get(), blendMode);
- }
- void TextureWrapper::modifyTextureColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
- {
- SDL_SetTextureColorMod(mWrappedTexture.get(), r, g, b);
- SDL_SetTextureAlphaMod(mWrappedTexture.get(), a);
- }
- void TextureWrapper::setTextureScale(double xScaleFactor, double yScaleFactor)
- {
- mXScaleFactor = xScaleFactor;
- mYScaleFactor = yScaleFactor;
- }
- int TextureWrapper::getUnscaledWidth() const
- {
- return mWidth;
- }
- int TextureWrapper::getUnscaledHeight() const
- {
- return mHeight;
- }
- int TextureWrapper::getScaledWidth() const
- {
- return mWidth * mXScaleFactor;
- }
- int TextureWrapper::getScaledHeight() const
- {
- return mHeight * mYScaleFactor;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement