X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FTexture.cc;h=6769d8887644a1924d2fdc67974b1afa4df4083d;hp=341b5598f13f9b8c7d42f93643f26ca3f4727568;hb=a295f8def17036c8071b56e181364f99a377cae7;hpb=8a1acac01b444dccf8b57cedf08392ada2e473c1 diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index 341b559..6769d88 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -26,15 +26,15 @@ *******************************************************************************/ -#include // memcpy +#include // FILE +#include // strncmp #include -#include -#include - -#include "Dispatcher.hh" -#include "Exception.hh" +#include "Dispatch.hh" +#include "Engine.hh" +#include "Error.hh" +#include "Image.hh" #include "Library.hh" #include "Log.hh" #include "OpenGL.hh" @@ -49,8 +49,8 @@ namespace Mf { * 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 Library @@ -64,9 +64,9 @@ class Texture::Impl : public Library { if (mObject) { - if (mObject == globalObject_) + if (mObject == gObject) { - globalObject_ = 0; + gObject = 0; } glDeleteTextures(1, &mObject); @@ -80,9 +80,9 @@ class Texture::Impl : public Library * to cache it if the client has plenty of RAM. */ - void contextRecreated(const Notification* note) + void contextRecreated() { - mObject = globalObject_ = 0; + mObject = gObject = 0; uploadToGL(); } @@ -102,29 +102,6 @@ class Texture::Impl : public Library 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: /** @@ -133,7 +110,8 @@ public: explicit Impl(const std::string& name) : Library(name), - mContext(0), + //mContext(0), + mImage(Texture::getPath(getName())), mWidth(0), mHeight(0), mMode(0), @@ -143,23 +121,20 @@ public: mWrapT(GL_CLAMP), mObject(0) { - loadFromFile(); + // make sure we have a video + 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); } @@ -170,6 +145,7 @@ public: * method makes them ready. */ + /* static SDL_Surface* prepareImageForGL(SDL_Surface* surface) { int w = powerOfTwo(surface->w); @@ -230,6 +206,7 @@ public: return image; } + */ /** * Use SDL_image to load images from file. A surface with the image data is @@ -239,42 +216,17 @@ public: 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(ErrorCode::FILE_NOT_FOUND, getName().c_str()); + logWarning << "texture not found: " << getName() << std::endl; + throw Error(Error::RESOURCE_NOT_FOUND, getName()); } - SDL_Surface* temp = prepareImageForGL(surface); - SDL_FreeSurface(surface); - - if (!temp) - { - throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT); - } + 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(ErrorCode::UNKNOWN_IMAGE_FORMAT); - } - - mWidth = temp->w; - mHeight = temp->h; - - mContext = temp; + mWidth = mImage.getWidth(); + mHeight = mImage.getHeight(); + mMode = mImage.getColorMode(); } @@ -291,7 +243,7 @@ public: return; } - if (!mContext) loadFromFile(); + //if (!mContext) loadFromFile(); glGenTextures(1, &mObject); glBindTexture(GL_TEXTURE_2D, mObject); @@ -303,18 +255,18 @@ public: 0, mMode, //3, - mContext->w, - mContext->h, + mWidth, + mHeight, 0, mMode, GL_UNSIGNED_BYTE, - mContext->pixels + mImage.getPixels() ); setProperties(); - SDL_FreeSurface(mContext); - mContext = 0; + //SDL_FreeSurface(mContext); + //mContext = 0; } @@ -366,29 +318,31 @@ public: { 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) : @@ -421,7 +375,7 @@ GLuint Texture::getObject() const void Texture::resetBind() { glBindTexture(GL_TEXTURE_2D, 0); - Impl::globalObject_ = 0; + Impl::gObject = 0; }