*******************************************************************************/
-#include <cstring> // memcpy
+#include <cstdio> // FILE
+#include <cstring> // strncmp
#include <boost/bind.hpp>
-#include <SDL/SDL.h>
-#include <SDL/SDL_image.h>
-
-#include "Dispatcher.hh"
+#include "Dispatch.hh"
+#include "Engine.hh"
+#include "Exception.hh"
+#include "Image.hh"
+#include "Library.hh"
#include "Log.hh"
-#include "Mippleton.hh"
#include "OpenGL.hh"
#include "Texture.hh"
* which is worth having in memory. The image data itself is not worth keeping
* in memory if the texture has been loaded to GL, but the name of the resource
* is retained so that it can be reloaded if necessary. The implementation is a
- * mippleton so that multiple texture objects can share the same internal
- * objects and avoid having duplicate textures loaded to GL.
+ * library so that multiple texture objects can share the same internal objects
+ * and avoid having duplicate textures loaded to GL.
*/
-class Texture::Impl : public Mippleton<Impl>
+class Texture::Impl : public Library<Impl>
{
/**
{
if (mObject)
{
- if (mObject == globalObject_)
+ if (mObject == gObject)
{
- globalObject_ = 0;
+ gObject = 0;
}
glDeleteTextures(1, &mObject);
* to cache it if the client has plenty of RAM.
*/
- void contextRecreated(const Notification* note)
+ void contextRecreated()
{
- mObject = globalObject_ = 0;
+ mObject = gObject = 0;
uploadToGL();
}
return value;
}
-
- static void flipSurface(SDL_Surface* image)
- {
- unsigned char* pixels = (Uint8*)(image->pixels);
-
- unsigned pitch = image->pitch;
- unsigned char line[pitch];
-
- int yBegin = 0;
- int yEnd = image->h - 1;
-
- if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
- while (yBegin < yEnd)
- {
- memcpy(line, pixels + pitch * yBegin, pitch);
- memcpy(pixels + pitch * yBegin, pixels + pitch * yEnd, pitch);
- memcpy(pixels + pitch * yEnd, line, pitch);
- yBegin++;
- yEnd--;
- }
- if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
- }
-
public:
/**
*/
explicit Impl(const std::string& name) :
- Mippleton<Impl>(name),
- mContext(0),
+ Library<Impl>(name),
+ //mContext(0),
+ mImage(Texture::getPath(getName())),
mWidth(0),
mHeight(0),
mMode(0),
mWrapT(GL_CLAMP),
mObject(0)
{
- loadFromFile();
+ // make sure the engine is initialized
+ Engine& engine = Engine::getInstance();
+ VideoP video = engine.getVideo();
+ ASSERT(video && "cannot load textures without a current video context");
// we want to know when the GL context is recreated
- Dispatcher::getInstance().addHandler("video.context_recreated",
- boost::bind(&Impl::contextRecreated, this, _1), this);
+ mDispatchHandler = engine.addHandler("video.newcontext",
+ boost::bind(&Impl::contextRecreated, this));
+
+ loadFromFile();
}
~Impl()
{
- if (mContext)
- {
- SDL_FreeSurface(mContext);
- }
-
unloadFromGL();
-
- Dispatcher::getInstance().removeHandler(this);
}
* method makes them ready.
*/
+ /*
static SDL_Surface* prepareImageForGL(SDL_Surface* surface)
{
int w = powerOfTwo(surface->w);
return image;
}
+ */
/**
* Use SDL_image to load images from file. A surface with the image data is
void loadFromFile()
{
- SDL_Surface* surface;
-
- surface = IMG_Load(Texture::getPath(getName()).c_str());
-
- if (!surface)
+ if (!mImage.isValid())
{
- logWarning("texture not found: %s", getName().c_str());
- throw Exception(Exception::FILE_NOT_FOUND);
+ logWarning << "texture not found: " << getName() << std::endl;
+ throw Exception(ErrorCode::RESOURCE_NOT_FOUND, getName());
}
- SDL_Surface* temp = prepareImageForGL(surface);
- SDL_FreeSurface(surface);
-
- if (!temp)
- {
- throw Exception(Exception::OPENGL_ERROR);
- }
+ mImage.flip();
- if (temp->format->BytesPerPixel == 3)
- {
- mMode = GL_RGB;
- }
- else if (temp->format->BytesPerPixel == 4)
- {
- mMode = GL_RGBA;
- }
- else
- {
- SDL_FreeSurface(temp);
- throw Exception(Exception::BAD_IMAGE_FORMAT);
- }
-
- mWidth = temp->w;
- mHeight = temp->h;
-
- mContext = temp;
+ mWidth = mImage.getWidth();
+ mHeight = mImage.getHeight();
+ mMode = mImage.getColorMode();
}
return;
}
- if (!mContext) loadFromFile();
+ //if (!mContext) loadFromFile();
glGenTextures(1, &mObject);
glBindTexture(GL_TEXTURE_2D, mObject);
glTexImage2D
+ //gluBuild2DMipmaps
(
GL_TEXTURE_2D,
0,
mMode,
- mContext->w,
- mContext->h,
+ //3,
+ mWidth,
+ mHeight,
0,
mMode,
GL_UNSIGNED_BYTE,
- mContext->pixels
+ mImage.getPixels()
);
setProperties();
- SDL_FreeSurface(mContext);
- mContext = 0;
+ //SDL_FreeSurface(mContext);
+ //mContext = 0;
}
{
uploadToGL();
}
- if (mObject != globalObject_)
+ if (mObject != gObject)
{
glBindTexture(GL_TEXTURE_2D, mObject);
- globalObject_ = mObject;
+ gObject = mObject;
}
}
- SDL_Surface* mContext;
- unsigned mWidth; ///< Horizontal dimension of the image.
- unsigned mHeight; ///< Vertical dimension.
+ Image mImage;
+ unsigned mWidth; ///< Horizontal dimension of the image.
+ unsigned mHeight; ///< Vertical dimension.
+
+ GLuint mMode; ///< GL_RGB or GL_RGBA.
+ GLuint mMinFilter; ///< Minifcation filter.
+ GLuint mMagFilter; ///< Magnification filter.
+ GLuint mWrapS; ///< Wrapping behavior horizontally.
+ GLuint mWrapT; ///< Wrapping behavior vertically.
- GLuint mMode; ///< Depth of the image, GL_RGB or GL_RGBA.
- GLuint mMinFilter; ///< Minifcation filter.
- GLuint mMagFilter; ///< Magnification filter.
- GLuint mWrapS; ///< Wrapping behavior horizontally.
- GLuint mWrapT; ///< Wrapping behavior vertically.
+ GLuint mObject; ///< GL texture handle.
+ static GLuint gObject; ///< Global GL texture handle.
- GLuint mObject; ///< GL texture handle.
- static GLuint globalObject_; ///< Global GL texture handle.
+ Dispatch::Handler mDispatchHandler;
};
-GLuint Texture::Impl::globalObject_ = 0;
+GLuint Texture::Impl::gObject = 0;
Texture::Texture(const std::string& name) :
void Texture::resetBind()
{
glBindTexture(GL_TEXTURE_2D, 0);
- Impl::globalObject_ = 0;
+ Impl::gObject = 0;
}