]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Texture.cc
library class revamped as manager, goodbye tilemap
[chaz/yoink] / src / Moof / Texture.cc
index 5341af33d32085632d605029705fa21b4d1c3b7e..801acbae227f89d7a58970a1e97ed836a008391a 100644 (file)
 #include <cstdio>              // FILE
 #include <cstring>             // strncmp
 
 #include <cstdio>              // FILE
 #include <cstring>             // strncmp
 
+#include <boost/algorithm/string.hpp>
 #include <boost/bind.hpp>
 
 #include "Dispatch.hh"
 #include <boost/bind.hpp>
 
 #include "Dispatch.hh"
-#include "Core.hh"
 #include "Error.hh"
 #include "Error.hh"
-#include "Image.hh"
-#include "Library.hh"
+#include "Manager.hh"
 #include "Log.hh"
 #include "OpenGL.hh"
 #include "Log.hh"
 #include "OpenGL.hh"
+#include "Script.hh"
 #include "Texture.hh"
 #include "Video.hh"
 
 #include "Texture.hh"
 #include "Video.hh"
 
@@ -50,11 +50,11 @@ 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
  * 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
- * library so that multiple texture objects can share the same internal objects
+ * manager so that multiple texture objects can share the same internal objects
  * and avoid having duplicate textures loaded to GL.
  */
 
  * and avoid having duplicate textures loaded to GL.
  */
 
-class Texture::Impl : public Library<Impl>
+class Texture::Impl : public Manager<Impl>
 {
 
        /**
 {
 
        /**
@@ -103,33 +103,40 @@ class Texture::Impl : public Library<Impl>
                return value;
        }
 
                return value;
        }
 
+
+       static void bindScriptConstants(Mf::Script& script)
+       {
+               script.push(GL_CLAMP); script.set("CLAMP");
+               script.push(GL_REPEAT); script.set("REPEAT");
+               script.push(GL_LINEAR); script.set("LINEAR");
+               script.push(GL_NEAREST); script.set("NEAREST");
+               script.push(GL_LINEAR_MIPMAP_LINEAR); script.set("LINEAR_MIPMAP_LINEAR");
+               script.push(GL_LINEAR_MIPMAP_NEAREST); script.set("LINEAR_MIPMAP_NEAREST");
+               script.push(GL_NEAREST_MIPMAP_LINEAR); script.set("NEAREST_MIPMAP_LINEAR");
+               script.push(GL_NEAREST_MIPMAP_NEAREST); script.set("NEAREST_MIPMAP_NEAREST");
+       }
+
 public:
 
        /**
         * Construction is initialization.
         */
 
 public:
 
        /**
         * Construction is initialization.
         */
 
-       explicit Impl(const std::string& name) :
-               Library<Impl>(name),
-               //mContext(0),
-               mImage(Texture::getPath(getName())),
-               mWidth(0),
-               mHeight(0),
-               mMode(0),
+       Impl() :
                mMinFilter(GL_NEAREST),
                mMagFilter(GL_NEAREST),
                mWrapS(GL_CLAMP),
                mWrapT(GL_CLAMP),
                mMinFilter(GL_NEAREST),
                mMagFilter(GL_NEAREST),
                mWrapS(GL_CLAMP),
                mWrapT(GL_CLAMP),
+               mTilesS(1),
+               mTilesT(1),
                mObject(0)
        {
                // make sure we have a video context
                mObject(0)
        {
                // make sure we have a video context
-               //ASSERT(video && "cannot load textures without a current video context");
+               ASSERT(video && "cannot load textures without a current video context");
 
                // we want to know when the GL context is recreated
                mDispatchHandler = core.addHandler("video.newcontext",
                                boost::bind(&Impl::contextRecreated, this));
 
                // we want to know when the GL context is recreated
                mDispatchHandler = core.addHandler("video.newcontext",
                                boost::bind(&Impl::contextRecreated, this));
-
-               loadFromFile();
        }
 
        ~Impl()
        }
 
        ~Impl()
@@ -214,19 +221,55 @@ public:
         * @return Image data.
         */
 
         * @return Image data.
         */
 
-       void loadFromFile()
+       void init(const std::string& name)
        {
        {
-               if (!mImage.isValid())
+               std::string path = Texture::getPath(name);
+
+               mImage = Image::alloc(path);
+               if (!mImage->isValid())
+               {
+                       logWarning << "texture not found: " << path << std::endl;
+                       Error(Error::RESOURCE_NOT_FOUND, path).raise();
+               }
+
+               mImage->flip();
+
+               Mf::Script script;
+
+               importLogFunctions(script);
+               bindScriptConstants(script);
+
+               if (script.doString(mImage->getComment()) != Mf::Script::SUCCESS)
                {
                {
-                       logWarning << "texture not found: " << getName() << std::endl;
-                       throw Error(Error::RESOURCE_NOT_FOUND, getName());
+                       std::string str;
+                       script[-1].get(str);
+                       Mf::logWarning(str);
                }
                }
+               else
+               {
+                       Mf::logInfo << "loading tiles from texture " << path << std::endl;
+
+                       Mf::Script::Slot globals = script.getGlobalTable();
+                       Mf::Script::Slot top = script[-1];
 
 
-               mImage.flip();
+                       globals.pushField("tiles_s");
+                       top.get(mTilesS);
 
 
-               mWidth = mImage.getWidth();
-               mHeight = mImage.getHeight();
-               mMode = mImage.getColorMode();
+                       globals.pushField("tiles_t");
+                       top.get(mTilesT);
+
+                       globals.pushField("min_filter");
+                       top.get(mMinFilter);
+
+                       globals.pushField("mag_filter");
+                       top.get(mMagFilter);
+
+                       globals.pushField("wrap_s");
+                       top.get(mWrapS);
+
+                       globals.pushField("wrap_t");
+                       top.get(mWrapT);
+               }
        }
 
 
        }
 
 
@@ -243,8 +286,6 @@ public:
                        return;
                }
 
                        return;
                }
 
-               //if (!mContext) loadFromFile();
-
                glGenTextures(1, &mObject);
                glBindTexture(GL_TEXTURE_2D, mObject);
 
                glGenTextures(1, &mObject);
                glBindTexture(GL_TEXTURE_2D, mObject);
 
@@ -253,20 +294,17 @@ public:
                (
                        GL_TEXTURE_2D,
                        0,
                (
                        GL_TEXTURE_2D,
                        0,
-                       mMode,
+                       mImage->getMode(),
                        //3,
                        //3,
-                       mWidth,
-                       mHeight,
+                       mImage->getWidth(),
+                       mImage->getHeight(),
                        0,
                        0,
-                       mMode,
+                       mImage->getMode(),
                        GL_UNSIGNED_BYTE,
                        GL_UNSIGNED_BYTE,
-                       mImage.getPixels()
+                       mImage->getPixels()
                );
 
                setProperties();
                );
 
                setProperties();
-
-               //SDL_FreeSurface(mContext);
-               //mContext = 0;
        }
 
 
        }
 
 
@@ -326,15 +364,35 @@ public:
        }
 
 
        }
 
 
-       Image                           mImage;
-       unsigned                        mWidth;                 ///< Horizontal dimension of the image.
-       unsigned                        mHeight;                ///< Vertical dimension.
+       bool getTileCoords(Texture::TileIndex index, Scalar coords[8]) const
+       {
+               // make sure the index represents a real tile
+               if (index >= mTilesS * mTilesT) return false;
+
+               Scalar w = 1.0 / Scalar(mTilesS);
+               Scalar h = 1.0 / Scalar(mTilesT);
+
+               coords[0] = Scalar(index % mTilesS) * w;
+               coords[1] = (Scalar(mTilesT - 1) -
+                               Scalar(index / mTilesS)) * h;
+               coords[2] = coords[0] + w;
+               coords[3] = coords[1];
+               coords[4] = coords[2];
+               coords[5] = coords[1] + h;
+               coords[6] = coords[0];
+               coords[7] = coords[5];
+
+               return true;
+       }
+
+       ImageP                          mImage;
 
 
-       GLuint                          mMode;                  ///< GL_RGB or GL_RGBA.
-       GLuint                          mMinFilter;             ///< Minifcation filter.
+       GLuint                          mMinFilter;             ///< Minification filter.
        GLuint                          mMagFilter;             ///< Magnification filter.
        GLuint                          mWrapS;                 ///< Wrapping behavior horizontally.
        GLuint                          mWrapT;                 ///< Wrapping behavior vertically.
        GLuint                          mMagFilter;             ///< Magnification filter.
        GLuint                          mWrapS;                 ///< Wrapping behavior horizontally.
        GLuint                          mWrapT;                 ///< Wrapping behavior vertically.
+       unsigned                        mTilesS;
+       unsigned                        mTilesT;
 
        GLuint                          mObject;                ///< GL texture handle.
        static GLuint           gObject;                ///< Global GL texture handle.
 
        GLuint                          mObject;                ///< GL texture handle.
        static GLuint           gObject;                ///< Global GL texture handle.
@@ -346,6 +404,7 @@ GLuint Texture::Impl::gObject = 0;
 
 
 Texture::Texture(const std::string& name) :
 
 
 Texture::Texture(const std::string& name) :
+       Image(Texture::getPath(name)),
        // pass through
        mImpl(Texture::Impl::getInstance(name)) {}
 
        // pass through
        mImpl(Texture::Impl::getInstance(name)) {}
 
@@ -379,19 +438,6 @@ void Texture::resetBind()
 }
 
 
 }
 
 
-unsigned Texture::getWidth() const
-{
-       // pass through
-       return mImpl->mWidth;
-}
-
-unsigned Texture::getHeight() const
-{
-       // pass through
-       return mImpl->mHeight;
-}
-
-
 void Texture::setMinFilter(GLuint filter)
 {
        // pass through
 void Texture::setMinFilter(GLuint filter)
 {
        // pass through
@@ -417,10 +463,54 @@ void Texture::setWrapT(GLuint wrap)
 }
 
 
 }
 
 
+bool Texture::getTileCoords(TileIndex index, Scalar coords[8]) const
+{
+       // pass through
+       return mImpl->getTileCoords(index, coords);
+}
+
+bool Texture::getTileCoords(TileIndex index, Scalar coords[8],
+               Orientation orientation) const
+{
+       if (getTileCoords(index, coords))
+       {
+               if (orientation & FLIP)
+               {
+                       // this looks kinda weird, but it's just swapping in a way that
+                       // doesn't require an intermediate variable
+                       coords[1] = coords[5];
+                       coords[5] = coords[3];
+                       coords[3] = coords[7];
+                       coords[7] = coords[5];
+               }
+               if (orientation & REVERSE)
+               {
+                       coords[0] = coords[2];
+                       coords[2] = coords[6];
+                       coords[4] = coords[6];
+                       coords[6] = coords[0];
+               }
+
+               return true;
+       }
+
+       return false;
+}
+
+
 std::string Texture::getPath(const std::string& name)
 {
 std::string Texture::getPath(const std::string& name)
 {
-       std::string path = Resource::getPath("textures/" + name + ".png");
-       return path;
+       if (boost::find_last(name, ".png"))
+       {
+               return Resource::getPath(name);
+       }
+       else
+       {
+               std::string path("textures/");
+               path += name;
+               path += ".png";
+               return Resource::getPath(path);
+       }
 }
 
 
 }
 
 
This page took 0.024496 seconds and 4 git commands to generate.