Changed texture wrap mode to be determined as part of texture creation.

Should hopefully fix some of the weird artifacts at certain resolutions.
This commit is contained in:
Aloshi 2014-01-19 12:23:01 -06:00
parent 5b5e99c366
commit 3f1fcf2400
6 changed files with 51 additions and 87 deletions

View file

@ -32,10 +32,9 @@ namespace ThemeFlags
COLOR = 16, COLOR = 16,
FONT_PATH = 32, FONT_PATH = 32,
FONT_SIZE = 64, FONT_SIZE = 64,
TILING = 128, SOUND = 128,
SOUND = 256, CENTER = 256,
CENTER = 512, TEXT = 512,
TEXT = 1024,
ALL = 0xFFFFFFFF ALL = 0xFFFFFFFF
}; };

View file

@ -21,7 +21,7 @@ Eigen::Vector2f ImageComponent::getCenter() const
} }
ImageComponent::ImageComponent(Window* window, const Eigen::Vector2f& pos, const std::string& path) : GuiComponent(window), ImageComponent::ImageComponent(Window* window, const Eigen::Vector2f& pos, const std::string& path) : GuiComponent(window),
mTiled(false), mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF) mTargetIsMax(false), mFlipX(false), mFlipY(false), mOrigin(0.0, 0.0), mTargetSize(0, 0), mColorShift(0xFFFFFFFF)
{ {
setPosition(pos.x(), pos.y()); setPosition(pos.x(), pos.y());
@ -40,7 +40,7 @@ void ImageComponent::resize()
const Eigen::Vector2f textureSize((float)getTextureSize().x(), (float)getTextureSize().y()); const Eigen::Vector2f textureSize((float)getTextureSize().x(), (float)getTextureSize().y());
if(mTiled) if(mTexture->isTiled())
{ {
mSize = mTargetSize; mSize = mTargetSize;
}else{ }else{
@ -74,50 +74,41 @@ void ImageComponent::resize()
mSize[0] = mTargetSize.x(); mSize[0] = mTargetSize.x();
mSize[1] = (mTargetSize.x() / textureSize.x()) * textureSize.y(); mSize[1] = (mTargetSize.x() / textureSize.x()) * textureSize.y();
} }
LOG(LogInfo) << "resized to: " << mSize.x() << ", " << mSize.y();
} }
} }
} }
void ImageComponent::setImage(std::string path) void ImageComponent::setImage(std::string path, bool tile)
{ {
if(path.empty() || !ResourceManager::getInstance()->fileExists(path)) if(path.empty() || !ResourceManager::getInstance()->fileExists(path))
mTexture.reset(); mTexture.reset();
else else
mTexture = TextureResource::get(path); mTexture = TextureResource::get(path, tile);
resize(); resize();
} }
void ImageComponent::setImage(const char* path, size_t length, bool tile)
{
mTexture.reset();
mTexture = TextureResource::get("", tile);
mTexture->initFromMemory(path, length);
resize();
}
void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture) void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture)
{ {
mTexture = texture; mTexture = texture;
resize(); resize();
} }
void ImageComponent::setImage(const char* path, size_t length)
{
mTexture.reset();
mTexture = TextureResource::get("");
mTexture->initFromMemory(path, length);
resize();
}
void ImageComponent::setOrigin(float originX, float originY) void ImageComponent::setOrigin(float originX, float originY)
{ {
mOrigin << originX, originY; mOrigin << originX, originY;
} }
void ImageComponent::setTiling(bool tile)
{
mTiled = tile;
resize();
}
void ImageComponent::setResize(float width, float height) void ImageComponent::setResize(float width, float height)
{ {
mTargetSize << width, height; mTargetSize << width, height;
@ -157,7 +148,7 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans)
GLfloat points[12], texs[12]; GLfloat points[12], texs[12];
GLubyte colors[6*4]; GLubyte colors[6*4];
if(mTiled) if(mTexture->isTiled())
{ {
float xCount = mSize.x() / getTextureSize().x(); float xCount = mSize.x() / getTextureSize().x();
float yCount = mSize.y() / getTextureSize().y(); float yCount = mSize.y() / getTextureSize().y();
@ -250,16 +241,6 @@ bool ImageComponent::hasImage()
return (bool)mTexture; return (bool)mTexture;
} }
void ImageComponent::copyScreen()
{
mTexture.reset();
mTexture = TextureResource::get("");
mTexture->initFromScreen();
resize();
}
void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
{ {
LOG(LogInfo) << " req image [" << view << "." << element << "] (flags: " << properties << ")"; LOG(LogInfo) << " req image [" << view << "." << element << "] (flags: " << properties << ")";
@ -294,8 +275,8 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const s
setOrigin(elem->get<Eigen::Vector2f>("origin")); setOrigin(elem->get<Eigen::Vector2f>("origin"));
if(properties & PATH && elem->has("path")) if(properties & PATH && elem->has("path"))
setImage(elem->get<std::string>("path")); {
bool tile = (elem->has("tile") && elem->get<bool>("tile"));
if(properties & TILING && elem->has("tile")) setImage(elem->get<std::string>("path"), tile);
setTiling(elem->get<bool>("tile")); }
} }

View file

@ -18,13 +18,11 @@ public:
ImageComponent(Window* window, const Eigen::Vector2f& pos = Eigen::Vector2f::Zero(), const std::string& path = ""); ImageComponent(Window* window, const Eigen::Vector2f& pos = Eigen::Vector2f::Zero(), const std::string& path = "");
virtual ~ImageComponent(); virtual ~ImageComponent();
void copyScreen(); //Copy the entire screen into a texture for us to use. void setImage(std::string path, bool tile = false); //Loads the image at the given filepath.
void setImage(std::string path); //Loads the image at the given filepath. void setImage(const char* image, size_t length, bool tile = false); //Loads image from memory.
void setImage(const char* image, size_t length); //Loads image from memory.
void setImage(const std::shared_ptr<TextureResource>& texture); //Use an already existing texture. void setImage(const std::shared_ptr<TextureResource>& texture); //Use an already existing texture.
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 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)
inline void setOrigin(Eigen::Vector2f origin) { setOrigin(origin.x(), origin.y()); } inline void setOrigin(Eigen::Vector2f origin) { setOrigin(origin.x(), origin.y()); }
void setTiling(bool tile); //Enables or disables tiling. Must be called before loading an image or resizing will be weird.
void setResize(float width, float height); void setResize(float width, float height);
inline void setResize(const Eigen::Vector2f& size) { setResize(size.x(), size.y()); } inline void setResize(const Eigen::Vector2f& size) { setResize(size.x(), size.y()); }
void setMaxSize(float width, float height); void setMaxSize(float width, float height);
@ -49,7 +47,7 @@ private:
Eigen::Vector2f mTargetSize; Eigen::Vector2f mTargetSize;
Eigen::Vector2f mOrigin; Eigen::Vector2f mOrigin;
bool mTiled, mFlipX, mFlipY, mTargetIsMax; bool mFlipX, mFlipY, mTargetIsMax;
void resize(); 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 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

View file

@ -5,10 +5,10 @@
#include "../ImageIO.h" #include "../ImageIO.h"
#include "../Renderer.h" #include "../Renderer.h"
std::map< std::string, std::weak_ptr<TextureResource> > TextureResource::sTextureMap; std::map< TextureResource::TextureKeyType, std::weak_ptr<TextureResource> > TextureResource::sTextureMap;
TextureResource::TextureResource(const std::string& path) : TextureResource::TextureResource(const std::string& path, bool tile) :
mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()) mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()), mTile(tile)
{ {
reload(ResourceManager::getInstance()); reload(ResourceManager::getInstance());
} }
@ -52,34 +52,13 @@ void TextureResource::initFromResource(const ResourceData data)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
mTextureSize << width, height; mTextureSize << width, height;
} }
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[0] = height;
mTextureSize[1] = height;
}
void TextureResource::initFromMemory(const char* data, size_t length) void TextureResource::initFromMemory(const char* data, size_t length)
{ {
deinit(); deinit();
@ -102,6 +81,7 @@ void TextureResource::initFromMemory(const char* data, size_t length)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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_MAG_FILTER, GL_NEAREST);
const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@ -122,6 +102,11 @@ Eigen::Vector2i TextureResource::getSize() const
return mTextureSize; return mTextureSize;
} }
bool TextureResource::isTiled() const
{
return mTile;
}
void TextureResource::bind() const void TextureResource::bind() const
{ {
if(mTextureID != 0) if(mTextureID != 0)
@ -131,28 +116,27 @@ void TextureResource::bind() const
} }
std::shared_ptr<TextureResource> TextureResource::get(const std::string& path) std::shared_ptr<TextureResource> TextureResource::get(const std::string& path, bool tile)
{ {
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance(); std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
if(path.empty()) if(path.empty())
{ {
std::shared_ptr<TextureResource> tex(new TextureResource("")); std::shared_ptr<TextureResource> tex(new TextureResource("", tile));
rm->addReloadable(tex); //make sure we're deinitialized even though we do nothing on reinitialization rm->addReloadable(tex); //make sure we get properly deinitialized even though we do nothing on reinitialization
return tex; return tex;
} }
auto foundTexture = sTextureMap.find(path); TextureKeyType key(path, tile);
auto foundTexture = sTextureMap.find(key);
if(foundTexture != sTextureMap.end()) if(foundTexture != sTextureMap.end())
{ {
if(!foundTexture->second.expired()) if(!foundTexture->second.expired())
{
return foundTexture->second.lock(); return foundTexture->second.lock();
}
} }
std::shared_ptr<TextureResource> tex = std::shared_ptr<TextureResource>(new TextureResource(path)); std::shared_ptr<TextureResource> tex = std::shared_ptr<TextureResource>(new TextureResource(path, tile));
sTextureMap[path] = std::weak_ptr<TextureResource>(tex); sTextureMap[key] = std::weak_ptr<TextureResource>(tex);
rm->addReloadable(tex); rm->addReloadable(tex);
return tex; return tex;
} }

View file

@ -10,21 +10,21 @@
class TextureResource : public IReloadable class TextureResource : public IReloadable
{ {
public: public:
static std::shared_ptr<TextureResource> get(const std::string& path); static std::shared_ptr<TextureResource> get(const std::string& path, bool tile = false);
virtual ~TextureResource(); virtual ~TextureResource();
void unload(std::shared_ptr<ResourceManager>& rm) override; void unload(std::shared_ptr<ResourceManager>& rm) override;
void reload(std::shared_ptr<ResourceManager>& rm) override; void reload(std::shared_ptr<ResourceManager>& rm) override;
bool isTiled() const;
Eigen::Vector2i getSize() const; Eigen::Vector2i getSize() const;
void bind() const; void bind() const;
void initFromScreen();
void initFromMemory(const char* image, size_t length); void initFromMemory(const char* image, size_t length);
private: private:
TextureResource(const std::string& path); TextureResource(const std::string& path, bool tile);
void initFromPath(); void initFromPath();
void initFromResource(const ResourceData data); void initFromResource(const ResourceData data);
@ -33,6 +33,8 @@ private:
Eigen::Vector2i mTextureSize; Eigen::Vector2i mTextureSize;
GLuint mTextureID; GLuint mTextureID;
const std::string mPath; const std::string mPath;
const bool mTile;
static std::map< std::string, std::weak_ptr<TextureResource> > sTextureMap; typedef std::pair<std::string, bool> TextureKeyType;
static std::map< TextureKeyType, std::weak_ptr<TextureResource> > sTextureMap;
}; };

View file

@ -26,7 +26,7 @@ ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGame
void ISimpleGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme) void ISimpleGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
{ {
using namespace ThemeFlags; using namespace ThemeFlags;
mBackground.applyTheme(theme, getName(), "background", PATH | TILING); mBackground.applyTheme(theme, getName(), "background", PATH);
mHeaderImage.applyTheme(theme, getName(), "header", POSITION | ThemeFlags::SIZE | PATH); mHeaderImage.applyTheme(theme, getName(), "header", POSITION | ThemeFlags::SIZE | PATH);
mThemeExtras.setExtras(ThemeData::makeExtras(theme, getName(), mWindow)); mThemeExtras.setExtras(ThemeData::makeExtras(theme, getName(), mWindow));