mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Created the ResourceManager, Resource, and TextureResource classes.
The ResourceManager provides a unified interface for accessing resource data, embedded or from the filesystem, with initialization/deinitialization handled automatically behind the scenes. It also keeps from creating duplicate resources (e.g. when two ImageComponents use the same image file). Audio still needs to be moved over to it.
This commit is contained in:
parent
ae50cc82ad
commit
90af5d47ab
|
@ -149,6 +149,9 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Resource.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/Resources.h
|
||||
)
|
||||
set(ES_SOURCES
|
||||
|
@ -187,6 +190,9 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiMenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/GuiSettingsMenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Resource.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/logo/ES_logo_16.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data/logo/ES_logo_32.cpp
|
||||
)
|
||||
|
|
|
@ -53,8 +53,9 @@ void Window::render()
|
|||
|
||||
void Window::init()
|
||||
{
|
||||
mInputManager->init();
|
||||
mInputManager->init(); //shouldn't this go AFTER renderer initialization?
|
||||
Renderer::init(0, 0);
|
||||
mResourceManager.init();
|
||||
|
||||
for(unsigned int i = 0; i < mGuiStack.size(); i++)
|
||||
{
|
||||
|
@ -70,6 +71,7 @@ void Window::deinit()
|
|||
}
|
||||
|
||||
mInputManager->deinit();
|
||||
mResourceManager.deinit();
|
||||
Renderer::deinit();
|
||||
}
|
||||
|
||||
|
@ -97,3 +99,8 @@ InputManager* Window::getInputManager()
|
|||
{
|
||||
return mInputManager;
|
||||
}
|
||||
|
||||
ResourceManager* Window::getResourceManager()
|
||||
{
|
||||
return &mResourceManager;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "GuiComponent.h"
|
||||
#include "InputManager.h"
|
||||
#include "resources/ResourceManager.h"
|
||||
#include <vector>
|
||||
|
||||
class Window
|
||||
|
@ -23,9 +24,11 @@ public:
|
|||
void deinit();
|
||||
|
||||
InputManager* getInputManager();
|
||||
ResourceManager* getResourceManager();
|
||||
|
||||
private:
|
||||
InputManager* mInputManager;
|
||||
ResourceManager mResourceManager;
|
||||
std::vector<GuiComponent*> mGuiStack;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
#include <math.h>
|
||||
#include "../Log.h"
|
||||
#include "../Renderer.h"
|
||||
#include "../Window.h"
|
||||
|
||||
Vector2u ImageComponent::getTextureSize() { return mTextureSize; }
|
||||
Vector2u ImageComponent::getTextureSize()
|
||||
{
|
||||
if(mTexture)
|
||||
return mTexture->getSize();
|
||||
else
|
||||
return Vector2u(0, 0);
|
||||
}
|
||||
|
||||
ImageComponent::ImageComponent(Window* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool allowUpscale) : GuiComponent(window)
|
||||
{
|
||||
mTextureID = 0;
|
||||
|
||||
setOffset(Vector2i(offsetX, offsetY));
|
||||
|
||||
//default origin is the center of image
|
||||
|
@ -35,120 +40,15 @@ ImageComponent::ImageComponent(Window* window, int offsetX, int offsetY, std::st
|
|||
|
||||
ImageComponent::~ImageComponent()
|
||||
{
|
||||
unloadImage();
|
||||
}
|
||||
|
||||
void ImageComponent::loadImage(std::string path)
|
||||
{
|
||||
//make sure the file *exists*
|
||||
if(!boost::filesystem::exists(path))
|
||||
{
|
||||
LOG(LogError) << "Image \"" << path << "\" not found!";
|
||||
return;
|
||||
}
|
||||
|
||||
//make sure we don't already have an image
|
||||
unloadImage();
|
||||
|
||||
|
||||
FREE_IMAGE_FORMAT format = FIF_UNKNOWN;
|
||||
FIBITMAP* image = NULL;
|
||||
BYTE* imageData = NULL;
|
||||
unsigned int width, height;
|
||||
|
||||
//detect the filetype
|
||||
format = FreeImage_GetFileType(path.c_str(), 0);
|
||||
if(format == FIF_UNKNOWN)
|
||||
format = FreeImage_GetFIFFromFilename(path.c_str());
|
||||
if(format == FIF_UNKNOWN)
|
||||
{
|
||||
LOG(LogError) << "Error - could not detect filetype for image \"" << path << "\"!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//make sure we can read this filetype first, then load it
|
||||
if(FreeImage_FIFSupportsReading(format))
|
||||
{
|
||||
image = FreeImage_Load(format, path.c_str());
|
||||
}else{
|
||||
LOG(LogError) << "Error - file format reading not supported for image \"" << path << "\"!";
|
||||
return;
|
||||
}
|
||||
|
||||
//make sure it loaded properly
|
||||
if(!image)
|
||||
{
|
||||
LOG(LogError) << "Error loading image \"" << path << "\"!";
|
||||
return;
|
||||
}
|
||||
|
||||
//convert to 32bit
|
||||
FIBITMAP* imgConv = FreeImage_ConvertTo32Bits(image);
|
||||
FreeImage_Unload(image);
|
||||
image = imgConv;
|
||||
|
||||
//get a pointer to the image data as BGRA
|
||||
imageData = FreeImage_GetBits(image);
|
||||
if(!imageData)
|
||||
{
|
||||
LOG(LogError) << "Error retriving bits from image \"" << path << "\"!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
width = FreeImage_GetWidth(image);
|
||||
height = FreeImage_GetHeight(image);
|
||||
|
||||
//if width or height are zero then something is clearly wrong
|
||||
if(!width || !height)
|
||||
{
|
||||
LOG(LogError) << "Width or height are zero for image \"" << path << "\"!";
|
||||
FreeImage_Unload(image);
|
||||
return;
|
||||
}
|
||||
|
||||
//convert from BGRA to RGBA
|
||||
GLubyte* imageRGBA = new GLubyte[4*width*height];
|
||||
for(unsigned int i = 0; i < width*height; i++)
|
||||
{
|
||||
imageRGBA[i*4+0] = imageData[i*4+2];
|
||||
imageRGBA[i*4+1] = imageData[i*4+1];
|
||||
imageRGBA[i*4+2] = imageData[i*4+0];
|
||||
imageRGBA[i*4+3] = imageData[i*4+3];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//now for the openGL texture stuff
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageRGBA);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mTextureSize.x = width;
|
||||
mTextureSize.y = height;
|
||||
|
||||
//free the image data
|
||||
FreeImage_Unload(image);
|
||||
|
||||
//free the memory from that pointer
|
||||
delete[] imageRGBA;
|
||||
|
||||
resize();
|
||||
}
|
||||
|
||||
void ImageComponent::resize()
|
||||
{
|
||||
mSize.x = mTextureSize.x;
|
||||
mSize.y = mTextureSize.y;
|
||||
if(!mTexture)
|
||||
return;
|
||||
|
||||
mSize.x = getTextureSize().x;
|
||||
mSize.y = getTextureSize().y;
|
||||
|
||||
//(we don't resize tiled images)
|
||||
if(!mTiled && (mTargetSize.x || mTargetSize.y))
|
||||
|
@ -176,19 +76,7 @@ void ImageComponent::resize()
|
|||
}
|
||||
|
||||
if(mTiled)
|
||||
{
|
||||
mSize = mTargetSize;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::unloadImage()
|
||||
{
|
||||
if(mTextureID)
|
||||
{
|
||||
glDeleteTextures(1, &mTextureID);
|
||||
|
||||
mTextureID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::setImage(std::string path)
|
||||
|
@ -198,10 +86,8 @@ void ImageComponent::setImage(std::string path)
|
|||
|
||||
mPath = path;
|
||||
|
||||
unloadImage();
|
||||
if(!path.empty())
|
||||
loadImage(path);
|
||||
|
||||
mTexture = mWindow->getResourceManager()->getTexture(path);
|
||||
resize();
|
||||
}
|
||||
|
||||
void ImageComponent::setOrigin(float originX, float originY)
|
||||
|
@ -240,15 +126,15 @@ void ImageComponent::setFlipY(bool flip)
|
|||
|
||||
void ImageComponent::onRender()
|
||||
{
|
||||
if(mTextureID && getOpacity() > 0)
|
||||
if(mTexture && getOpacity() > 0)
|
||||
{
|
||||
GLfloat points[12], texs[12];
|
||||
GLubyte colors[6*4];
|
||||
|
||||
if(mTiled)
|
||||
{
|
||||
float xCount = (float)mSize.x / mTextureSize.x;
|
||||
float yCount = (float)mSize.y / mTextureSize.y;
|
||||
float xCount = (float)mSize.x / getTextureSize().x;
|
||||
float yCount = (float)mSize.y / getTextureSize().y;
|
||||
|
||||
Renderer::buildGLColorArray(colors, 0xFFFFFF00 | (getOpacity()), 6);
|
||||
buildImageArray(0, 0, points, texs, xCount, yCount);
|
||||
|
@ -303,7 +189,8 @@ void ImageComponent::buildImageArray(int posX, int posY, GLfloat* points, GLfloa
|
|||
|
||||
void ImageComponent::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int numArrays)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
mTexture->bind();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -332,21 +219,6 @@ void ImageComponent::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* col
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void ImageComponent::init()
|
||||
{
|
||||
if(!mPath.empty())
|
||||
loadImage(mPath);
|
||||
|
||||
GuiComponent::init();
|
||||
}
|
||||
|
||||
void ImageComponent::deinit()
|
||||
{
|
||||
unloadImage();
|
||||
|
||||
GuiComponent::deinit();
|
||||
}
|
||||
|
||||
bool ImageComponent::hasImage()
|
||||
{
|
||||
return !mPath.empty();
|
||||
|
@ -357,32 +229,10 @@ void ImageComponent::setOpacity(unsigned char opacity) { mOpacity = opacity; }
|
|||
|
||||
void ImageComponent::copyScreen()
|
||||
{
|
||||
unloadImage();
|
||||
|
||||
int width = Renderer::getScreenWidth();
|
||||
int height = Renderer::getScreenHeight();
|
||||
mTexture.reset();
|
||||
|
||||
//glReadBuffer(GL_FRONT);
|
||||
|
||||
/*char* data = new char[width*height*3];
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);*/
|
||||
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
//delete[] data;
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mTextureSize.x = height;
|
||||
mTextureSize.y = height;
|
||||
mTexture = std::make_shared<TextureResource>();
|
||||
mTexture->initFromScreen();
|
||||
|
||||
resize();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "../GuiComponent.h"
|
||||
#include <string>
|
||||
#include <FreeImage.h>
|
||||
|
||||
#include <memory>
|
||||
#include "../resources/TextureResource.h"
|
||||
|
||||
class ImageComponent : public GuiComponent
|
||||
{
|
||||
|
@ -18,8 +18,7 @@ public:
|
|||
ImageComponent(Window* window, int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool allowUpscale = false);
|
||||
virtual ~ImageComponent();
|
||||
|
||||
//Copy the entire screen into a texture for us to use.
|
||||
void copyScreen();
|
||||
void copyScreen(); //Copy the entire screen into a texture for us to use.
|
||||
void setImage(std::string path); //Loads the image at the given filepath.
|
||||
void setOrigin(float originX, float originY); //Sets the origin as a percentage of this image (e.g. (0, 0) is top left, (0.5, 0.5) is the center)
|
||||
void setTiling(bool tile); //Enables or disables tiling. Must be called before loading an image or resizing will be weird.
|
||||
|
@ -31,13 +30,8 @@ public:
|
|||
//You can get the rendered size of the ImageComponent with getSize().
|
||||
Vector2u getTextureSize();
|
||||
|
||||
|
||||
bool hasImage();
|
||||
|
||||
//Image textures will be deleted on renderer deinitialization, and recreated on reinitialization (if mPath is not empty).
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
unsigned char getOpacity();
|
||||
void setOpacity(unsigned char opacity);
|
||||
|
||||
|
@ -46,22 +40,19 @@ protected:
|
|||
|
||||
private:
|
||||
Vector2u mTargetSize;
|
||||
Vector2u mTextureSize;
|
||||
Vector2f mOrigin;
|
||||
|
||||
bool mAllowUpscale, mTiled, mFlipX, mFlipY;
|
||||
|
||||
unsigned char mOpacity;
|
||||
|
||||
void loadImage(std::string path);
|
||||
void resize();
|
||||
void buildImageArray(int x, int y, GLfloat* points, GLfloat* texs, float percentageX = 1, float percentageY = 1); //writes 12 GLfloat points and 12 GLfloat texture coordinates to a given array at a given position
|
||||
void drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int count = 6); //draws the given set of points and texture coordinates, number of coordinate pairs may be specified (default 6)
|
||||
void unloadImage();
|
||||
|
||||
std::string mPath;
|
||||
|
||||
GLuint mTextureID;
|
||||
std::shared_ptr<TextureResource> mTexture;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
0
src/resources/Resource.cpp
Normal file
0
src/resources/Resource.cpp
Normal file
14
src/resources/Resource.h
Normal file
14
src/resources/Resource.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
struct ResourceData
|
||||
{
|
||||
const unsigned char* ptr;
|
||||
const size_t length;
|
||||
};
|
||||
|
||||
class Resource
|
||||
{
|
||||
public:
|
||||
virtual void init(ResourceData data) = 0;
|
||||
virtual void deinit() = 0;
|
||||
};
|
95
src/resources/ResourceManager.cpp
Normal file
95
src/resources/ResourceManager.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include "ResourceManager.h"
|
||||
#include "../Log.h"
|
||||
#include <fstream>
|
||||
|
||||
//from ES_logo_16.cpp
|
||||
extern const size_t es_logo_16_data_len;
|
||||
extern const unsigned char es_logo_16_data[];
|
||||
|
||||
//from ES_logo_32.cpp
|
||||
extern const size_t es_logo_32_data_len;
|
||||
extern const unsigned char es_logo_32_data[];
|
||||
|
||||
struct EmbeddedResource
|
||||
{
|
||||
const char* internal_path;
|
||||
ResourceData resourceData;
|
||||
};
|
||||
|
||||
static const int embedded_resource_count = 2;
|
||||
static const EmbeddedResource embedded_resources[embedded_resource_count] = {
|
||||
{ "internal://es_logo_16.png", {es_logo_16_data, es_logo_16_data_len} },
|
||||
{ "internal://es_logo_32.png", {es_logo_32_data, es_logo_32_data_len} }
|
||||
};
|
||||
|
||||
std::shared_ptr<TextureResource> ResourceManager::getTexture(const std::string& path)
|
||||
{
|
||||
if(path.empty())
|
||||
return std::shared_ptr<TextureResource>(); //NULL pointer
|
||||
|
||||
if(mTextureMap[path].expired())
|
||||
{
|
||||
std::shared_ptr<TextureResource> ret(new TextureResource());
|
||||
mTextureMap[path] = std::weak_ptr<TextureResource>(ret);
|
||||
|
||||
initializeResource(path, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return mTextureMap[path].lock();
|
||||
}
|
||||
|
||||
void ResourceManager::init()
|
||||
{
|
||||
for(auto iter = mTextureMap.begin(); iter != mTextureMap.end(); iter++)
|
||||
{
|
||||
if(!iter->second.expired())
|
||||
{
|
||||
initializeResource(iter->first, iter->second.lock());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceManager::deinit()
|
||||
{
|
||||
for(auto iter = mTextureMap.begin(); iter != mTextureMap.end(); iter++)
|
||||
{
|
||||
if(!iter->second.expired())
|
||||
iter->second.lock()->deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceManager::initializeResource(const std::string& path, std::shared_ptr<Resource> resource)
|
||||
{
|
||||
for(int i = 0; i < embedded_resource_count; i++)
|
||||
{
|
||||
if(strcmp(embedded_resources[i].internal_path, path.c_str()) == 0)
|
||||
{
|
||||
//this embedded resource matches the filepath; use it
|
||||
resource->init(embedded_resources[i].resourceData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//it's not embedded; load the file, initialize with it, then free the file
|
||||
ResourceData data = loadFile(path);
|
||||
resource->init(data);
|
||||
delete[] data.ptr;
|
||||
}
|
||||
|
||||
ResourceData ResourceManager::loadFile(const std::string& path)
|
||||
{
|
||||
std::ifstream stream(path, std::ios::binary);
|
||||
|
||||
stream.seekg(0, stream.end);
|
||||
size_t size = (size_t)stream.tellg();
|
||||
stream.seekg(0, stream.beg);
|
||||
|
||||
unsigned char* data = new unsigned char[size];
|
||||
stream.read((char*)data, size);
|
||||
stream.close();
|
||||
|
||||
ResourceData ret = {data, size};
|
||||
return ret;
|
||||
}
|
34
src/resources/ResourceManager.h
Normal file
34
src/resources/ResourceManager.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "Resource.h"
|
||||
#include "TextureResource.h"
|
||||
|
||||
|
||||
//The ResourceManager exists to:
|
||||
//1. Automatically deal with initializing/deinitializing various resources (OpenGL textures, SDL audio)
|
||||
//2. Allow loading resources embedded into the executable like an actual file.
|
||||
// a. Allow embedded resources to be optionally remapped to actual files for further customization.
|
||||
//3. Keep from creating duplicate resources.
|
||||
|
||||
//The ResourceManager returns resources as std::shared_ptrs.
|
||||
//When the resource no longer has any references, it will be automatically freed.
|
||||
//If ES launches a game, all resources will have deinit() called on them and SDL will deinitialize.
|
||||
//Once the game exits and ES returns, resources will have init() called on them.
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TextureResource> getTexture(const std::string& path);
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
private:
|
||||
void initializeResource(const std::string& path, std::shared_ptr<Resource> resource);
|
||||
ResourceData loadFile(const std::string& path);
|
||||
|
||||
std::map< std::string, std::weak_ptr<TextureResource> > mTextureMap;
|
||||
};
|
86
src/resources/TextureResource.cpp
Normal file
86
src/resources/TextureResource.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include "TextureResource.h"
|
||||
#include "../Log.h"
|
||||
#include "../platform.h"
|
||||
#include GLHEADER
|
||||
#include "../ImageIO.h"
|
||||
#include "../Renderer.h"
|
||||
|
||||
TextureResource::TextureResource() : mTextureID(0)
|
||||
{
|
||||
}
|
||||
|
||||
TextureResource::~TextureResource()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
|
||||
void TextureResource::init(ResourceData data)
|
||||
{
|
||||
//make sure we aren't going to leak an old texture
|
||||
deinit();
|
||||
|
||||
size_t width, height;
|
||||
std::vector<unsigned char> imageRGBA = ImageIO::loadFromMemoryRGBA32(data.ptr, data.length, width, height);
|
||||
|
||||
if(imageRGBA.size() == 0)
|
||||
{
|
||||
LOG(LogError) << "Could not initialize texture!";
|
||||
return;
|
||||
}
|
||||
|
||||
//now for the openGL texture stuff
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageRGBA.data());
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mTextureSize.x = width;
|
||||
mTextureSize.y = height;
|
||||
}
|
||||
|
||||
void TextureResource::deinit()
|
||||
{
|
||||
if(mTextureID != 0)
|
||||
{
|
||||
glDeleteTextures(1, &mTextureID);
|
||||
mTextureID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2u TextureResource::getSize()
|
||||
{
|
||||
return mTextureSize;
|
||||
}
|
||||
|
||||
void TextureResource::bind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
}
|
||||
|
||||
void TextureResource::initFromScreen()
|
||||
{
|
||||
deinit();
|
||||
|
||||
int width = Renderer::getScreenWidth();
|
||||
int height = Renderer::getScreenHeight();
|
||||
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
mTextureSize.x = height;
|
||||
mTextureSize.y = height;
|
||||
}
|
27
src/resources/TextureResource.h
Normal file
27
src/resources/TextureResource.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
|
||||
#include <string>
|
||||
#include "../Vector2.h"
|
||||
#include "../platform.h"
|
||||
#include GLHEADER
|
||||
|
||||
class TextureResource : public Resource
|
||||
{
|
||||
public:
|
||||
TextureResource();
|
||||
~TextureResource();
|
||||
|
||||
void init(ResourceData data) override;
|
||||
void deinit() override;
|
||||
|
||||
Vector2u getSize();
|
||||
void bind();
|
||||
|
||||
void initFromScreen();
|
||||
|
||||
private:
|
||||
Vector2u mTextureSize;
|
||||
GLuint mTextureID;
|
||||
};
|
Loading…
Reference in a new issue