summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-03-24 19:20:49 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-03-26 07:30:39 +0000
commit4091bd9568e5aff4a1f24416d26da567a2c076ad (patch)
tree32285c49c19821d5d287fab29cf264a647735ded
parent4604ee1caf00fe1a8c095119c1046e7f625e1f0b (diff)
downloadMana-4091bd9568e5aff4a1f24416d26da567a2c076ad.tar.gz
Mana-4091bd9568e5aff4a1f24416d26da567a2c076ad.tar.bz2
Mana-4091bd9568e5aff4a1f24416d26da567a2c076ad.tar.xz
Mana-4091bd9568e5aff4a1f24416d26da567a2c076ad.zip
Added functions to draw images at sub-pixel positions
This can be used for smoother mouse cursor movement when rendering our own mouse cursor (already changed in this commit) and is also necessary for implementing support for HiDPI font rendering. Also dropped some almost duplicated OpenGL code.
-rw-r--r--src/graphics.cpp29
-rw-r--r--src/graphics.h29
-rw-r--r--src/gui/gui.cpp2
-rw-r--r--src/openglgraphics.cpp126
-rw-r--r--src/openglgraphics.h13
-rw-r--r--src/sdlgraphics.cpp31
-rw-r--r--src/sdlgraphics.h9
7 files changed, 126 insertions, 113 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 19f87e0c..13089b0c 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -47,6 +47,26 @@ bool Graphics::drawImage(Image *image, int x, int y)
return drawImage(image, 0, 0, x, y, image->getWidth(), image->getHeight());
}
+bool Graphics::drawImageF(Image *image, float x, float y)
+{
+ if (!image)
+ return false;
+
+ return drawImageF(image, 0, 0, x, y, image->getWidth(), image->getHeight());
+}
+
+bool Graphics::drawRescaledImageF(Image *image, int srcX, int srcY, float dstX, float dstY, int width, int height, float desiredWidth, float desiredHeight, bool useColor)
+{
+ return drawRescaledImage(image,
+ srcX, srcY,
+ static_cast<int>(dstX),
+ static_cast<int>(dstY),
+ width, height,
+ static_cast<int>(desiredWidth),
+ static_cast<int>(desiredHeight),
+ useColor);
+}
+
bool Graphics::drawImage(Image *image,
int srcX, int srcY,
int dstX, int dstY,
@@ -60,6 +80,15 @@ bool Graphics::drawImage(Image *image,
width, height, useColor);
}
+bool Graphics::drawImageF(Image *image, int srcX, int srcY, float dstX, float dstY, int width, int height, bool useColor)
+{
+ return drawRescaledImageF(image,
+ srcX, srcY,
+ dstX, dstY,
+ width, height,
+ width, height, useColor);
+}
+
void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
{
if (!image)
diff --git a/src/graphics.h b/src/graphics.h
index 91bb01cf..79513e2c 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -96,6 +96,14 @@ class Graphics : public gcn::Graphics
bool drawImage(Image *image, int x, int y);
/**
+ * Blits an image onto the screen.
+ *
+ * @return <code>true</code> if the image was blitted properly
+ * <code>false</code> otherwise.
+ */
+ bool drawImageF(Image *image, float x, float y);
+
+ /**
* Draws a rescaled version of the image.
*/
virtual bool drawRescaledImage(Image *image, int srcX, int srcY,
@@ -105,6 +113,15 @@ class Graphics : public gcn::Graphics
bool useColor = false) = 0;
/**
+ * Draws a rescaled version of the image.
+ */
+ virtual bool drawRescaledImageF(Image *image, int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ float desiredWidth, float desiredHeight,
+ bool useColor = false);
+
+ /**
* Blits an image onto the screen.
*
* @return <code>true</code> if the image was blitted properly
@@ -116,6 +133,18 @@ class Graphics : public gcn::Graphics
int width, int height,
bool useColor = false);
+ /**
+ * Blits an image onto the screen.
+ *
+ * @return <code>true</code> if the image was blitted properly
+ * <code>false</code> otherwise.
+ */
+ virtual bool drawImageF(Image *image,
+ int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ bool useColor = false);
+
virtual void drawImagePattern(Image *image,
int x, int y,
int w, int h);
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 62350f99..68f43cc3 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -213,7 +213,7 @@ void Gui::draw()
Image *mouseCursor = mMouseCursors->get(static_cast<size_t>(mCursorType));
mouseCursor->setAlpha(mMouseCursorAlpha);
- static_cast<Graphics*>(mGraphics)->drawImage(
+ static_cast<Graphics*>(mGraphics)->drawImageF(
mouseCursor,
logicalX - 15,
logicalY - 17);
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index ea37bdaa..9e77e5f7 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -153,71 +153,11 @@ void OpenGLGraphics::updateSize(int windowWidth, int windowHeight, float scale)
glOrtho(0.0, (double)mWidth, (double)mHeight, 0.0, -1.0, 1.0);
}
-static inline void drawQuad(Image *image,
- int srcX, int srcY, int dstX, int dstY,
- int width, int height)
-{
- if (Image::getTextureType() == GL_TEXTURE_2D)
- {
- // Find OpenGL normalized texture coordinates.
- const float texX1 = static_cast<float>(srcX) /
- static_cast<float>(image->getTextureWidth());
- const float texY1 = static_cast<float>(srcY) /
- static_cast<float>(image->getTextureHeight());
- const float texX2 = static_cast<float>(srcX + width) /
- static_cast<float>(image->getTextureWidth());
- const float texY2 = static_cast<float>(srcY + height) /
- static_cast<float>(image->getTextureHeight());
-
- GLfloat tex[] =
- {
- texX1, texY1,
- texX2, texY1,
- texX2, texY2,
- texX1, texY2
- };
-
- GLint vert[] =
- {
- dstX, dstY,
- dstX + width, dstY,
- dstX + width, dstY + height,
- dstX, dstY + height
- };
-
- glVertexPointer(2, GL_INT, 0, &vert);
- glTexCoordPointer(2, GL_FLOAT, 0, &tex);
-
- glDrawArrays(GL_QUADS, 0, 4);
- }
- else
- {
- GLint tex[] =
- {
- srcX, srcY,
- srcX + width, srcY,
- srcX + width, srcY + height,
- srcX, srcY + height
- };
- GLint vert[] =
- {
- dstX, dstY,
- dstX + width, dstY,
- dstX + width, dstY + height,
- dstX, dstY + height
- };
-
- glVertexPointer(2, GL_INT, 0, &vert);
- glTexCoordPointer(2, GL_INT, 0, &tex);
-
- glDrawArrays(GL_QUADS, 0, 4);
- }
-}
-
static inline void drawRescaledQuad(Image *image,
- int srcX, int srcY, int dstX, int dstY,
+ int srcX, int srcY,
+ float dstX, float dstY,
int width, int height,
- int desiredWidth, int desiredHeight)
+ float desiredWidth, float desiredHeight)
{
if (Image::getTextureType() == GL_TEXTURE_2D)
{
@@ -231,7 +171,7 @@ static inline void drawRescaledQuad(Image *image,
const float texY2 = static_cast<float>(srcY + height) /
static_cast<float>(image->getTextureHeight());
- GLfloat tex[] =
+ const GLfloat tex[] =
{
texX1, texY1,
texX2, texY1,
@@ -239,7 +179,7 @@ static inline void drawRescaledQuad(Image *image,
texX1, texY2
};
- GLint vert[] =
+ const GLfloat vert[] =
{
dstX, dstY,
dstX + desiredWidth, dstY,
@@ -247,21 +187,21 @@ static inline void drawRescaledQuad(Image *image,
dstX, dstY + desiredHeight
};
- glVertexPointer(2, GL_INT, 0, &vert);
+ glVertexPointer(2, GL_FLOAT, 0, &vert);
glTexCoordPointer(2, GL_FLOAT, 0, &tex);
glDrawArrays(GL_QUADS, 0, 4);
}
else
{
- GLint tex[] =
+ const GLint tex[] =
{
srcX, srcY,
srcX + width, srcY,
srcX + width, srcY + height,
srcX, srcY + height
};
- GLint vert[] =
+ const GLfloat vert[] =
{
dstX, dstY,
dstX + desiredWidth, dstY,
@@ -269,7 +209,7 @@ static inline void drawRescaledQuad(Image *image,
dstX, dstY + desiredHeight
};
- glVertexPointer(2, GL_INT, 0, &vert);
+ glVertexPointer(2, GL_FLOAT, 0, &vert);
glTexCoordPointer(2, GL_INT, 0, &tex);
glDrawArrays(GL_QUADS, 0, 4);
@@ -277,52 +217,26 @@ static inline void drawRescaledQuad(Image *image,
}
-bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY,
- int dstX, int dstY,
- int width, int height, bool useColor)
-{
- if (!image)
- return false;
-
- srcX += image->mBounds.x;
- srcY += image->mBounds.y;
-
- if (!useColor)
- glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
-
- bindTexture(Image::mTextureType, image->mGLImage);
-
- setTexturingAndBlending(true);
-
- drawQuad(image, srcX, srcY, dstX, dstY, width, height);
-
- if (!useColor)
- {
- glColor4ub(static_cast<GLubyte>(mColor.r),
- static_cast<GLubyte>(mColor.g),
- static_cast<GLubyte>(mColor.b),
- static_cast<GLubyte>(mColor.a));
- }
-
- return true;
-}
-
bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
int dstX, int dstY,
int width, int height,
int desiredWidth, int desiredHeight,
bool useColor)
{
+ return drawRescaledImageF(image, srcX, srcY, dstX, dstY,
+ width, height, desiredWidth, desiredHeight,
+ useColor);
+}
+
+bool OpenGLGraphics::drawRescaledImageF(Image *image, int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ float desiredWidth, float desiredHeight,
+ bool useColor)
+{
if (!image)
return false;
- // Just draw the image normally when no resizing is necessary,
- if (width == desiredWidth && height == desiredHeight)
- {
- return drawImage(image, srcX, srcY, dstX, dstY,
- width, height, useColor);
- }
-
srcX += image->mBounds.x;
srcY += image->mBounds.y;
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index ab08d075..dbeab80a 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -57,12 +57,6 @@ class OpenGLGraphics final : public Graphics
void updateSize(int windowWidth, int windowHeight, float scale) override;
- bool drawImage(Image *image,
- int srcX, int srcY,
- int dstX, int dstY,
- int width, int height,
- bool useColor) override;
-
/**
* Draws a rescaled version of the image
*/
@@ -72,6 +66,13 @@ class OpenGLGraphics final : public Graphics
int desiredWidth, int desiredHeight,
bool useColor) override;
+ bool drawRescaledImageF(Image *image,
+ int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ float desiredWidth, float desiredHeight,
+ bool useColor) override;
+
void drawImagePattern(Image *image,
int x, int y,
int w, int h) override;
diff --git a/src/sdlgraphics.cpp b/src/sdlgraphics.cpp
index 8e77a64f..dc56496e 100644
--- a/src/sdlgraphics.cpp
+++ b/src/sdlgraphics.cpp
@@ -134,6 +134,37 @@ bool SDLGraphics::drawRescaledImage(Image *image,
return !(SDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect) < 0);
}
+#if SDL_VERSION_ATLEAST(2, 0, 10)
+bool SDLGraphics::drawRescaledImageF(Image *image,
+ int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ float desiredWidth, float desiredHeight,
+ bool useColor)
+{
+ // Check that preconditions for blitting are met.
+ if (!image || !image->mTexture)
+ return false;
+
+ dstX += mClipStack.top().xOffset;
+ dstY += mClipStack.top().yOffset;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ SDL_FRect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = dstX; dstRect.y = dstY;
+ srcRect.x = srcX; srcRect.y = srcY;
+ srcRect.w = width;
+ srcRect.h = height;
+ dstRect.w = desiredWidth;
+ dstRect.h = desiredHeight;
+
+ return !(SDL_RenderCopyF(mRenderer, image->mTexture, &srcRect, &dstRect) < 0);
+}
+#endif
+
void SDLGraphics::drawRescaledImagePattern(Image *image,
int x, int y,
int w, int h,
diff --git a/src/sdlgraphics.h b/src/sdlgraphics.h
index ab6407f0..3ed31ca3 100644
--- a/src/sdlgraphics.h
+++ b/src/sdlgraphics.h
@@ -48,6 +48,15 @@ public:
int desiredWidth, int desiredHeight,
bool useColor) override;
+#if SDL_VERSION_ATLEAST(2, 0, 10)
+ bool drawRescaledImageF(Image *image,
+ int srcX, int srcY,
+ float dstX, float dstY,
+ int width, int height,
+ float desiredWidth, float desiredHeight,
+ bool useColor) override;
+#endif
+
void drawRescaledImagePattern(Image *image,
int x, int y,
int w, int h,