mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 12:05:38 +00:00
Optimized the hell out of ImageComponent.
(been saving this one for a rainy day...) Fixed sort order assert triggered by std::sort when sorting help prompts.
This commit is contained in:
parent
9955261a1e
commit
ac0bdb47ed
|
@ -197,7 +197,7 @@ void Window::render()
|
||||||
|
|
||||||
mHelp->render(transform);
|
mHelp->render(transform);
|
||||||
|
|
||||||
if(Settings::getInstance()->getBool("DrawFramerate"))
|
if(Settings::getInstance()->getBool("DrawFramerate") && mFrameDataText)
|
||||||
{
|
{
|
||||||
Renderer::setMatrix(Eigen::Affine3f::Identity());
|
Renderer::setMatrix(Eigen::Affine3f::Identity());
|
||||||
mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get());
|
mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get());
|
||||||
|
@ -254,16 +254,18 @@ void Window::setHelpPrompts(const std::vector<HelpPrompt>& prompts)
|
||||||
};
|
};
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int aVal = 0;
|
||||||
|
int bVal = 0;
|
||||||
while(map[i] != NULL)
|
while(map[i] != NULL)
|
||||||
{
|
{
|
||||||
if(a.first == map[i])
|
if(a.first == map[i])
|
||||||
return true;
|
aVal = i;
|
||||||
else if(b.first == map[i])
|
if(b.first == map[i])
|
||||||
return false;
|
bVal = i;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return aVal > bVal;
|
||||||
});
|
});
|
||||||
|
|
||||||
mHelp->setPrompts(addPrompts);
|
mHelp->setPrompts(addPrompts);
|
||||||
|
|
|
@ -25,6 +25,7 @@ Eigen::Vector2f ImageComponent::getCenter() const
|
||||||
ImageComponent::ImageComponent(Window* window) : GuiComponent(window),
|
ImageComponent::ImageComponent(Window* window) : GuiComponent(window),
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
updateColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageComponent::~ImageComponent()
|
ImageComponent::~ImageComponent()
|
||||||
|
@ -80,6 +81,13 @@ void ImageComponent::resize()
|
||||||
{
|
{
|
||||||
svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
|
svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSizeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageComponent::onSizeChanged()
|
||||||
|
{
|
||||||
|
updateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::setImage(std::string path, bool tile)
|
void ImageComponent::setImage(std::string path, bool tile)
|
||||||
|
@ -111,6 +119,7 @@ void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture)
|
||||||
void ImageComponent::setOrigin(float originX, float originY)
|
void ImageComponent::setOrigin(float originX, float originY)
|
||||||
{
|
{
|
||||||
mOrigin << originX, originY;
|
mOrigin << originX, originY;
|
||||||
|
updateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::setResize(float width, float height)
|
void ImageComponent::setResize(float width, float height)
|
||||||
|
@ -130,54 +139,33 @@ void ImageComponent::setMaxSize(float width, float height)
|
||||||
void ImageComponent::setFlipX(bool flip)
|
void ImageComponent::setFlipX(bool flip)
|
||||||
{
|
{
|
||||||
mFlipX = flip;
|
mFlipX = flip;
|
||||||
|
updateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::setFlipY(bool flip)
|
void ImageComponent::setFlipY(bool flip)
|
||||||
{
|
{
|
||||||
mFlipY = flip;
|
mFlipY = flip;
|
||||||
|
updateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::setColorShift(unsigned int color)
|
void ImageComponent::setColorShift(unsigned int color)
|
||||||
{
|
{
|
||||||
mColorShift = color;
|
mColorShift = color;
|
||||||
|
updateColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::render(const Eigen::Affine3f& parentTrans)
|
void ImageComponent::setOpacity(unsigned char opacity)
|
||||||
{
|
{
|
||||||
Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform());
|
mOpacity = opacity;
|
||||||
Renderer::setMatrix(trans);
|
mColorShift = (mColorShift >> 8 << 8) | mOpacity;
|
||||||
|
updateColors();
|
||||||
if(mTexture && getOpacity() > 0)
|
|
||||||
{
|
|
||||||
if(mTexture->isInitialized())
|
|
||||||
{
|
|
||||||
GLfloat points[12], texs[12];
|
|
||||||
GLubyte colors[6*4];
|
|
||||||
|
|
||||||
if(mTexture->isTiled())
|
|
||||||
{
|
|
||||||
float xCount = mSize.x() / getTextureSize().x();
|
|
||||||
float yCount = mSize.y() / getTextureSize().y();
|
|
||||||
|
|
||||||
Renderer::buildGLColorArray(colors, (mColorShift >> 8 << 8)| (getOpacity()), 6);
|
|
||||||
buildImageArray(points, texs, xCount, yCount);
|
|
||||||
}else{
|
|
||||||
Renderer::buildGLColorArray(colors, (mColorShift >> 8 << 8) | (getOpacity()), 6);
|
|
||||||
buildImageArray(points, texs);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawImageArray(points, texs, colors, 6);
|
|
||||||
}else{
|
|
||||||
LOG(LogError) << "Image texture is not initialized!";
|
|
||||||
mTexture.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiComponent::renderChildren(trans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::buildImageArray(GLfloat* points, GLfloat* texs, float px, float py)
|
void ImageComponent::updateVertices()
|
||||||
{
|
{
|
||||||
|
if(!mTexture || !mTexture->isInitialized())
|
||||||
|
return;
|
||||||
|
|
||||||
// we go through this mess to make sure everything is properly rounded
|
// we go through this mess to make sure everything is properly rounded
|
||||||
// if we just round vertices at the end, edge cases occur near sizes of 0.5
|
// if we just round vertices at the end, edge cases occur near sizes of 0.5
|
||||||
Eigen::Vector2f topLeft(-mSize.x() * mOrigin.x(), -mSize.y() * mOrigin.y());
|
Eigen::Vector2f topLeft(-mSize.x() * mOrigin.x(), -mSize.y() * mOrigin.y());
|
||||||
|
@ -191,70 +179,88 @@ void ImageComponent::buildImageArray(GLfloat* points, GLfloat* texs, float px, f
|
||||||
bottomRight[0] = topLeft[0] + width;
|
bottomRight[0] = topLeft[0] + width;
|
||||||
bottomRight[1] = topLeft[1] + height;
|
bottomRight[1] = topLeft[1] + height;
|
||||||
|
|
||||||
points[0] = topLeft.x(); points[1] = topLeft.y();
|
mVertices[0].pos << topLeft.x(), topLeft.y();
|
||||||
points[2] = topLeft.x(); points[3] = bottomRight.y();
|
mVertices[1].pos << topLeft.x(), bottomRight.y();
|
||||||
points[4] = bottomRight.x(); points[5] = topLeft.y();
|
mVertices[2].pos << bottomRight.x(), topLeft.y();
|
||||||
|
|
||||||
points[6] = bottomRight.x(); points[7] = topLeft.y();
|
mVertices[3].pos << bottomRight.x(), topLeft.y();
|
||||||
points[8] = topLeft.x(); points[9] = bottomRight.y();
|
mVertices[4].pos << topLeft.x(), bottomRight.y();
|
||||||
points[10] = bottomRight.x(); points[11] = bottomRight.y();
|
mVertices[5].pos << bottomRight.x(), bottomRight.y();
|
||||||
|
|
||||||
texs[0] = 0; texs[1] = py;
|
float px, py;
|
||||||
texs[2] = 0; texs[3] = 0;
|
if(mTexture->isTiled())
|
||||||
texs[4] = px; texs[5] = py;
|
{
|
||||||
|
px = mSize.x() / getTextureSize().x();
|
||||||
|
py = mSize.y() / getTextureSize().y();
|
||||||
|
}else{
|
||||||
|
px = 1;
|
||||||
|
py = 1;
|
||||||
|
}
|
||||||
|
|
||||||
texs[6] = px; texs[7] = py;
|
mVertices[0].tex << 0, py;
|
||||||
texs[8] = 0; texs[9] = 0;
|
mVertices[1].tex << 0, 0;
|
||||||
texs[10] = px; texs[11] = 0;
|
mVertices[2].tex << px, py;
|
||||||
|
|
||||||
|
mVertices[3].tex << px, py;
|
||||||
|
mVertices[4].tex << 0, 0;
|
||||||
|
mVertices[5].tex << px, 0;
|
||||||
|
|
||||||
if(mFlipX)
|
if(mFlipX)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 11; i += 2)
|
for(int i = 0; i < 6; i++)
|
||||||
if(texs[i] == px)
|
mVertices[i].tex[0] = mVertices[i].tex[0] == px ? 0 : px;
|
||||||
texs[i] = 0;
|
|
||||||
else
|
|
||||||
texs[i] = px;
|
|
||||||
}
|
}
|
||||||
if(mFlipY)
|
if(mFlipY)
|
||||||
{
|
{
|
||||||
for(int i = 1; i < 12; i += 2)
|
for(int i = 1; i < 6; i++)
|
||||||
if(texs[i] == py)
|
mVertices[i].tex[1] = mVertices[i].tex[1] == py ? 0 : py;
|
||||||
texs[i] = 0;
|
|
||||||
else
|
|
||||||
texs[i] = py;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageComponent::drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int numArrays)
|
void ImageComponent::updateColors()
|
||||||
{
|
{
|
||||||
mTexture->bind();
|
Renderer::buildGLColorArray(mColors, (mColorShift >> 8 << 8)| (getOpacity()), 6);
|
||||||
|
}
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
void ImageComponent::render(const Eigen::Affine3f& parentTrans)
|
||||||
glEnable(GL_BLEND);
|
{
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform());
|
||||||
|
Renderer::setMatrix(trans);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
if(mTexture && mOpacity > 0)
|
||||||
|
|
||||||
if(colors != NULL)
|
|
||||||
{
|
{
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
if(mTexture->isInitialized())
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
|
{
|
||||||
|
// actually draw the image
|
||||||
|
mTexture->bind();
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex);
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, 0, mColors);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}else{
|
||||||
|
LOG(LogError) << "Image texture is not initialized!";
|
||||||
|
mTexture.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glVertexPointer(2, GL_FLOAT, 0, points);
|
GuiComponent::renderChildren(trans);
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texs);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, numArrays);
|
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
|
|
||||||
if(colors != NULL)
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageComponent::hasImage()
|
bool ImageComponent::hasImage()
|
||||||
|
|
|
@ -22,6 +22,9 @@ public:
|
||||||
//Use an already existing texture.
|
//Use an already existing texture.
|
||||||
void setImage(const std::shared_ptr<TextureResource>& texture);
|
void setImage(const std::shared_ptr<TextureResource>& texture);
|
||||||
|
|
||||||
|
void onSizeChanged() override;
|
||||||
|
void setOpacity(unsigned char opacity) override;
|
||||||
|
|
||||||
//Sets the origin as a percentage of this image (e.g. (0, 0) is top left, (0.5, 0.5) is the center)
|
//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);
|
void setOrigin(float originX, float originY);
|
||||||
inline void setOrigin(Eigen::Vector2f origin) { setOrigin(origin.x(), origin.y()); }
|
inline void setOrigin(Eigen::Vector2f origin) { setOrigin(origin.x(), origin.y()); }
|
||||||
|
@ -67,10 +70,16 @@ private:
|
||||||
// Used internally whenever the resizing parameters or texture change.
|
// Used internally whenever the resizing parameters or texture change.
|
||||||
void resize();
|
void resize();
|
||||||
|
|
||||||
// Writes 12 GLfloat points and 12 GLfloat texture coordinates to a given array at a given position.
|
struct Vertex
|
||||||
void buildImageArray(GLfloat* points, GLfloat* texs, float percentageX = 1, float percentageY = 1);
|
{
|
||||||
// Draws the given set of points and texture coordinates, number of coordinate pairs may be specified.
|
Eigen::Vector2f pos;
|
||||||
void drawImageArray(GLfloat* points, GLfloat* texs, GLubyte* colors, unsigned int count = 6);
|
Eigen::Vector2f tex;
|
||||||
|
} mVertices[6];
|
||||||
|
|
||||||
|
GLubyte mColors[6*4];
|
||||||
|
|
||||||
|
void updateVertices();
|
||||||
|
void updateColors();
|
||||||
|
|
||||||
unsigned int mColorShift;
|
unsigned int mColorShift;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue