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,
FONT_PATH = 32,
FONT_SIZE = 64,
TILING = 128,
SOUND = 256,
CENTER = 512,
TEXT = 1024,
SOUND = 128,
CENTER = 256,
TEXT = 512,
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),
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());
@ -40,7 +40,7 @@ void ImageComponent::resize()
const Eigen::Vector2f textureSize((float)getTextureSize().x(), (float)getTextureSize().y());
if(mTiled)
if(mTexture->isTiled())
{
mSize = mTargetSize;
}else{
@ -74,50 +74,41 @@ void ImageComponent::resize()
mSize[0] = mTargetSize.x();
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))
mTexture.reset();
else
mTexture = TextureResource::get(path);
mTexture = TextureResource::get(path, tile);
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)
{
mTexture = texture;
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)
{
mOrigin << originX, originY;
}
void ImageComponent::setTiling(bool tile)
{
mTiled = tile;
resize();
}
void ImageComponent::setResize(float width, float height)
{
mTargetSize << width, height;
@ -157,7 +148,7 @@ void ImageComponent::render(const Eigen::Affine3f& parentTrans)
GLfloat points[12], texs[12];
GLubyte colors[6*4];
if(mTiled)
if(mTexture->isTiled())
{
float xCount = mSize.x() / getTextureSize().x();
float yCount = mSize.y() / getTextureSize().y();
@ -250,16 +241,6 @@ bool ImageComponent::hasImage()
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)
{
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"));
if(properties & PATH && elem->has("path"))
setImage(elem->get<std::string>("path"));
if(properties & TILING && elem->has("tile"))
setTiling(elem->get<bool>("tile"));
{
bool tile = (elem->has("tile") && elem->get<bool>("tile"));
setImage(elem->get<std::string>("path"), tile);
}
}

View file

@ -18,13 +18,11 @@ public:
ImageComponent(Window* window, const Eigen::Vector2f& pos = Eigen::Vector2f::Zero(), const std::string& path = "");
virtual ~ImageComponent();
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 setImage(const char* image, size_t length); //Loads image from memory.
void setImage(std::string path, bool tile = false); //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 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)
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);
inline void setResize(const Eigen::Vector2f& size) { setResize(size.x(), size.y()); }
void setMaxSize(float width, float height);
@ -49,7 +47,7 @@ private:
Eigen::Vector2f mTargetSize;
Eigen::Vector2f mOrigin;
bool mTiled, mFlipX, mFlipY, mTargetIsMax;
bool mFlipX, mFlipY, mTargetIsMax;
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

View file

@ -5,10 +5,10 @@
#include "../ImageIO.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) :
mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero())
TextureResource::TextureResource(const std::string& path, bool tile) :
mTextureID(0), mPath(path), mTextureSize(Eigen::Vector2i::Zero()), mTile(tile)
{
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
const GLint wrapMode = mTile ? GL_REPEAT : GL_CLAMP_TO_EDGE;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
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)
{
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_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_T, GL_REPEAT);
@ -122,6 +102,11 @@ Eigen::Vector2i TextureResource::getSize() const
return mTextureSize;
}
bool TextureResource::isTiled() const
{
return mTile;
}
void TextureResource::bind() const
{
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();
if(path.empty())
{
std::shared_ptr<TextureResource> tex(new TextureResource(""));
rm->addReloadable(tex); //make sure we're deinitialized even though we do nothing on reinitialization
std::shared_ptr<TextureResource> tex(new TextureResource("", tile));
rm->addReloadable(tex); //make sure we get properly deinitialized even though we do nothing on reinitialization
return tex;
}
auto foundTexture = sTextureMap.find(path);
TextureKeyType key(path, tile);
auto foundTexture = sTextureMap.find(key);
if(foundTexture != sTextureMap.end())
{
if(!foundTexture->second.expired())
{
return foundTexture->second.lock();
}
}
std::shared_ptr<TextureResource> tex = std::shared_ptr<TextureResource>(new TextureResource(path));
sTextureMap[path] = std::weak_ptr<TextureResource>(tex);
std::shared_ptr<TextureResource> tex = std::shared_ptr<TextureResource>(new TextureResource(path, tile));
sTextureMap[key] = std::weak_ptr<TextureResource>(tex);
rm->addReloadable(tex);
return tex;
}

View file

@ -10,21 +10,21 @@
class TextureResource : public IReloadable
{
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();
void unload(std::shared_ptr<ResourceManager>& rm) override;
void reload(std::shared_ptr<ResourceManager>& rm) override;
bool isTiled() const;
Eigen::Vector2i getSize() const;
void bind() const;
void initFromScreen();
void initFromMemory(const char* image, size_t length);
private:
TextureResource(const std::string& path);
TextureResource(const std::string& path, bool tile);
void initFromPath();
void initFromResource(const ResourceData data);
@ -33,6 +33,8 @@ private:
Eigen::Vector2i mTextureSize;
GLuint mTextureID;
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)
{
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);
mThemeExtras.setExtras(ThemeData::makeExtras(theme, getName(), mWindow));