summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2013-05-11 23:05:20 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2013-05-11 23:12:13 +0200
commitcec406ea31c3ccb22ab676ce3fd52d4cd0dfcb0d (patch)
tree61c5c3a101e2ae5a1b4c0fe352d290462675aac5 /src
parentdcf4c8941f3d0d287f0068ef64949890edeefa95 (diff)
downloadcolobot-cec406ea31c3ccb22ab676ce3fd52d4cd0dfcb0d.tar.gz
colobot-cec406ea31c3ccb22ab676ce3fd52d4cd0dfcb0d.tar.bz2
colobot-cec406ea31c3ccb22ab676ce3fd52d4cd0dfcb0d.zip
Non-power-of-2 padding for background images
* added padding options * removed old hardcoded image sizes
Diffstat (limited to 'src')
-rw-r--r--src/common/image.cpp29
-rw-r--r--src/common/image.h3
-rw-r--r--src/graphics/core/texture.h5
-rw-r--r--src/graphics/engine/engine.cpp29
-rw-r--r--src/graphics/engine/engine.h5
-rw-r--r--src/graphics/opengl/gldevice.cpp17
-rw-r--r--src/object/auto/autobase.cpp3
-rw-r--r--src/ui/maindialog.cpp20
8 files changed, 81 insertions, 30 deletions
diff --git a/src/common/image.cpp b/src/common/image.cpp
index db14797..fd55217 100644
--- a/src/common/image.cpp
+++ b/src/common/image.cpp
@@ -17,6 +17,8 @@
#include "common/image.h"
+#include "math/func.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -200,6 +202,33 @@ void CImage::Fill(Gfx::IntColor color)
}
/**
+ * Image must be valid.
+ *
+ * The dimensions are increased to nearest even power of two values.
+ * If image is already in power-of-two format, nothing is done.
+ */
+void CImage::PadToNearestPowerOfTwo()
+{
+ assert(m_data != nullptr);
+
+ if (Math::IsPowerOfTwo(m_data->surface->w) && Math::IsPowerOfTwo(m_data->surface->h))
+ return;
+
+ int w = Math::NextPowerOfTwo(m_data->surface->w);
+ int h = Math::NextPowerOfTwo(m_data->surface->h);
+
+ m_data->surface->flags &= (~SDL_SRCALPHA);
+ SDL_Surface* resizedSurface = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00,
+ 0x000000ff, 0xff000000);
+ assert(resizedSurface != NULL);
+ SDL_BlitSurface(m_data->surface, NULL, resizedSurface, NULL);
+
+ SDL_FreeSurface(m_data->surface);
+
+ m_data->surface = resizedSurface;
+}
+
+/**
* Image must be valid and pixel coords in valid range.
*
* \param pixel pixel coords (range x: 0..width-1 y: 0..height-1)
diff --git a/src/common/image.h b/src/common/image.h
index d9da75b..f0b50a3 100644
--- a/src/common/image.h
+++ b/src/common/image.h
@@ -94,6 +94,9 @@ public:
//! Returns the precise color at given pixel
Gfx::IntColor GetPixelInt(Math::IntPoint pixel);
+ //! Pads the image to nearest power of 2 dimensions
+ void PadToNearestPowerOfTwo();
+
//! Loads an image from the specified file
bool Load(const std::string &fileName);
diff --git a/src/graphics/core/texture.h b/src/graphics/core/texture.h
index 49b29f8..31e3774 100644
--- a/src/graphics/core/texture.h
+++ b/src/graphics/core/texture.h
@@ -136,6 +136,8 @@ struct TextureCreateParams
TexMinFilter minFilter;
//! Magnification filter
TexMagFilter magFilter;
+ //! Pad the image to nearest power of 2 dimensions
+ bool padToNearestPowerOfTwo;
//! Constructor; calls LoadDefault()
TextureCreateParams()
@@ -146,6 +148,7 @@ struct TextureCreateParams
{
format = TEX_IMG_RGB;
mipmap = false;
+ padToNearestPowerOfTwo = false;
minFilter = TEX_MIN_FILTER_NEAREST;
magFilter = TEX_MAG_FILTER_NEAREST;
@@ -212,6 +215,8 @@ struct Texture
unsigned int id;
//! Size of texture
Math::IntPoint size;
+ //! Original size of texture (as loaded from image)
+ Math::IntPoint originalSize;
//! Whether the texture has alpha channel
bool alpha;
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 5d77e29..806cb5f 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -94,7 +94,6 @@ CEngine::CEngine(CApplication *app)
m_backgroundCloudUp = Color();
m_backgroundCloudDown = Color();
m_backgroundFull = false;
- m_backgroundScale = Math::Point(1.0f, 1.0f);
m_overFront = true;
m_overColor = Color();
m_overMode = ENG_RSTATE_TCOLOR_BLACK;
@@ -2188,7 +2187,11 @@ bool CEngine::LoadAllTextures()
LoadTexture("map.png");
if (! m_backgroundName.empty())
- m_backgroundTex = LoadTexture(m_backgroundName);
+ {
+ TextureCreateParams params = m_defaultTexParams;
+ params.padToNearestPowerOfTwo = true;
+ m_backgroundTex = LoadTexture(m_backgroundName, params);
+ }
else
m_backgroundTex.SetInvalid();
@@ -2609,8 +2612,7 @@ float CEngine::GetFogStart(int rank)
}
void CEngine::SetBackground(const std::string& name, Color up, Color down,
- Color cloudUp, Color cloudDown,
- bool full, Math::Point scale)
+ Color cloudUp, Color cloudDown, bool full)
{
if (m_backgroundTex.Valid())
{
@@ -2624,15 +2626,17 @@ void CEngine::SetBackground(const std::string& name, Color up, Color down,
m_backgroundCloudUp = cloudUp;
m_backgroundCloudDown = cloudDown;
m_backgroundFull = full;
- m_backgroundScale = scale;
if (! m_backgroundName.empty())
- m_backgroundTex = LoadTexture(m_backgroundName);
+ {
+ TextureCreateParams params = m_defaultTexParams;
+ params.padToNearestPowerOfTwo = true;
+ m_backgroundTex = LoadTexture(m_backgroundName, params);
+ }
}
void CEngine::GetBackground(std::string& name, Color& up, Color& down,
- Color& cloudUp, Color& cloudDown,
- bool &full, Math::Point& scale)
+ Color& cloudUp, Color& cloudDown, bool &full)
{
name = m_backgroundName;
up = m_backgroundColorUp;
@@ -2640,7 +2644,6 @@ void CEngine::GetBackground(std::string& name, Color& up, Color& down,
cloudUp = m_backgroundCloudUp;
cloudDown = m_backgroundCloudDown;
full = m_backgroundFull;
- scale = m_backgroundScale;
}
void CEngine::SetForegroundName(const std::string& name)
@@ -3900,8 +3903,12 @@ void CEngine::DrawBackgroundImage()
v2 = v1+h;
}
- u2 *= m_backgroundScale.x;
- v2 *= m_backgroundScale.y;
+ Math::Point backgroundScale;
+ backgroundScale.x = static_cast<float>(m_backgroundTex.originalSize.x) / static_cast<float>(m_backgroundTex.size.x);
+ backgroundScale.y = static_cast<float>(m_backgroundTex.originalSize.y) / static_cast<float>(m_backgroundTex.size.y);
+
+ u2 *= backgroundScale.x;
+ v2 *= backgroundScale.y;
SetTexture(m_backgroundTex);
SetState(ENG_RSTATE_OPAQUE_TEXTURE | ENG_RSTATE_WRAP);
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index 671924f..16fb4e6 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -1050,10 +1050,10 @@ public:
//! Management of the background image to use
void SetBackground(const std::string& name, Color up = Color(), Color down = Color(),
Color cloudUp = Color(), Color cloudDown = Color(),
- bool full = false, Math::Point scale = Math::Point(1.0f, 1.0f));
+ bool full = false);
void GetBackground(std::string& name, Color& up, Color& down,
Color& cloudUp, Color& cloudDown,
- bool& full, Math::Point& scale);
+ bool& full);
//@}
//! Specifies the name of foreground texture
@@ -1346,7 +1346,6 @@ protected:
bool m_firstGroundSpot;
int m_secondTexNum;
bool m_backgroundFull;
- Math::Point m_backgroundScale;
std::string m_backgroundName;
Texture m_backgroundTex;
Color m_backgroundColorUp;
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 86f92b2..f351f22 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -423,11 +423,15 @@ Texture CGLDevice::CreateTexture(CImage *image, const TextureCreateParams &param
return Texture(); // invalid texture
}
- Math::IntPoint size = image->GetSize();
- if (!Math::IsPowerOfTwo(size.x) || !Math::IsPowerOfTwo(size.y))
- GetLogger()->Warn("Creating non-power-of-2 texture (%dx%d)!\n", size.x, size.y);
+ Math::IntPoint originalSize = image->GetSize();
- return CreateTexture(data, params);
+ if (params.padToNearestPowerOfTwo)
+ image->PadToNearestPowerOfTwo();
+
+ Texture tex = CreateTexture(data, params);
+ tex.originalSize = originalSize;
+
+ return tex;
}
Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &params)
@@ -437,6 +441,11 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par
result.size.x = data->surface->w;
result.size.y = data->surface->h;
+ if (!Math::IsPowerOfTwo(result.size.x) || !Math::IsPowerOfTwo(result.size.y))
+ GetLogger()->Warn("Creating non-power-of-2 texture (%dx%d)!\n", result.size.x, result.size.y);
+
+ result.originalSize = result.size;
+
// Use & enable 1st texture stage
if (m_multitextureAvailable)
glActiveTexture(GL_TEXTURE0);
diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp
index cb7f04c..d0bd87b 100644
--- a/src/object/auto/autobase.cpp
+++ b/src/object/auto/autobase.cpp
@@ -1412,9 +1412,8 @@ void CAutoBase::BeginTransit()
m_engine->SetDeepView(2000.0f); // we see very far
m_engine->ApplyChange();
- Math::Point scale;
bool full;
- m_engine->GetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, full, scale);
+ m_engine->GetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, full);
m_engine->DeleteTexture(m_bgName);
m_engine->SetBackground(m_bgBack, Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index 2dede28..985e00e 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -389,7 +389,7 @@ pb->SetState(STATE_SHADOW);
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
@@ -509,7 +509,7 @@ pb->SetState(STATE_SHADOW);
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
@@ -978,7 +978,7 @@ pb->SetState(STATE_SHADOW);
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
@@ -1177,7 +1177,7 @@ pb->SetState(STATE_SHADOW);
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
}
@@ -1702,7 +1702,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
}
@@ -1752,7 +1752,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
m_loadingCounter = 1; // enough time to display!
@@ -1774,7 +1774,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(861.0f / 1024.0f, 646.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}
if ( m_phase == PHASE_WELCOME2 )
@@ -1793,7 +1793,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(640.0f / 1024.0f, 480.0f / 512.0f));
+ true);
m_engine->SetBackForce(true);
}
if ( m_phase == PHASE_WELCOME3 )
@@ -1812,7 +1812,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(640.0f / 1024.0f, 480.0f / 512.0f));
+ true);
m_engine->SetBackForce(true);
}
@@ -1948,7 +1948,7 @@ pos.y -= 0.048f;
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
- true, Math::Point(1.0f, 768.0f / 1024.0f));
+ true);
m_engine->SetBackForce(true);
}