X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Ftexture.cc;fp=src%2Fmoof%2Ftexture.cc;h=0000000000000000000000000000000000000000;hp=94d792dfc9d8ea295a152508d9c309700b1a5c93;hb=382626aad0a683ed8642a6a807eea743db45f7f8;hpb=1da520638918096276158ecdfaeebc14a3d70be7 diff --git a/src/moof/texture.cc b/src/moof/texture.cc deleted file mode 100644 index 94d792d..0000000 --- a/src/moof/texture.cc +++ /dev/null @@ -1,399 +0,0 @@ - -/*] Copyright (c) 2009-2010, Charles McGarvey [************************** -**] All rights reserved. -* -* vi:ts=4 sw=4 tw=75 -* -* Distributable under the terms and conditions of the 2-clause BSD license; -* see the file COPYING for a complete text of the license. -* -**************************************************************************/ - -#include // FILE -#include // strncmp -#include - -#include -#include - -#include "dispatcher.hh" -#include "manager.hh" -#include "log.hh" -#include "opengl.hh" -#include "script.hh" -#include "texture.hh" -#include "video.hh" - - -namespace moof { - - -/** - * The texture implementation just contains all the information about the - * image 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 manager so that multiple texture - * objects can share the same internal objects and avoid having duplicate - * textures loaded to GL. - */ - -class texture::impl : public manager -{ - - /** - * Delete the texture (if it is loaded) from GL. - */ - - void unload_from_gl() - { - if (mObject) - { - if (mObject == gObject) - { - gObject = 0; - } - - glDeleteTextures(1, &mObject); - mObject = 0; - } - } - - /** - * If the GL context was recreated, we need to reload the texture. - * This may involve reading it from disk again, but hopefully the OS - * was smart enough to cache it if the client has plenty of RAM. - */ - - void context_recreated() - { - mObject = gObject = 0; - upload_to_gl(); - } - - /** - * This is a helper method used by some of the texture loading code. - * It returns the first power of two which is greater than the input - * value. - */ - - static int power_of_two(int input) - { - int value = 1; - - while (value < input) - { - value <<= 1; - } - return value; - } - - - static void bind_script_constants(script& script) - { - script::slot g = script.globals(); - - g.set_field("CLAMP", GL_CLAMP); - g.set_field("REPEAT", GL_REPEAT); - g.set_field("LINEAR", GL_LINEAR); - g.set_field("NEAREST", GL_NEAREST); - g.set_field("LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR); - g.set_field("LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST); - g.set_field("NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR); - g.set_field("NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST); - } - -public: - - /* - * Construction is initialization. - */ - impl() : - 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 - video* video = video::current(); - ASSERT(video && "should have a video context set"); - - // we want to know when the GL context is recreated - dispatcher& dispatcher = dispatcher::global(); - mNewContextDispatch = dispatcher.add_target("video.newcontext", - boost::bind(&impl::context_recreated, this)); - } - - ~impl() - { - unload_from_gl(); - } - - - void init(const std::string& name) - { - std::string path(name); - - resource::find(path); - - mImage = image::alloc(path); - if (!mImage->is_valid()) - { - throw std::runtime_error("texture not found: " + name); - } - - mImage->flip(); - - script script; - - bind_script_constants(script); - log::import(script); - - if (script.do_string(mImage->comment()) != script::success) - { - std::string str; - script[-1].get(str); - log_warning(str); - } - else - { - log_info("loading tiles from texture", path); - - script::slot globals = script.globals(); - globals.get(mTilesS, "tiles_s"); - globals.get(mTilesT, "tiles_t"); - globals.get(mMinFilter, "min_filter"); - globals.get(mMagFilter, "mag_filter"); - globals.get(mWrapS, "wrap_s"); - globals.get(mWrapT, "wrap_t"); - } - } - - - /* - * Upload the image to GL so that it will be accessible by a much more - * manageable handle and hopefully reside in video memory. - */ - void upload_to_gl() - { - if (mObject) - { - // already loaded - return; - } - - glGenTextures(1, &mObject); - glBindTexture(GL_TEXTURE_2D, mObject); - - glTexImage2D - //gluBuild2DMipmaps - ( - GL_TEXTURE_2D, - 0, - mImage->mode(), - //3, - mImage->width(), - mImage->height(), - 0, - mImage->mode(), - GL_UNSIGNED_BYTE, - mImage->pixels() - ); - - set_properties(); - } - - - /* - * Sets some texture properties such as the filters and external - * coordinate behavior. - */ - void set_properties() - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mMinFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mMagFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mWrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mWrapT); - } - - void min_filter(GLuint filter) - { - bind(); - mMinFilter = filter; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mMinFilter); - } - - void mag_filter(GLuint filter) - { - bind(); - mMagFilter = filter; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mMagFilter); - } - - void wrap_s(GLuint wrap) - { - bind(); - mWrapS = wrap; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mWrapS); - } - - void wrap_t(GLuint wrap) - { - bind(); - mWrapT = wrap; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mWrapT); - } - - - void bind() - { - if (mObject == 0) - { - upload_to_gl(); - } - if (mObject != gObject) - { - glBindTexture(GL_TEXTURE_2D, mObject); - gObject = mObject; - } - } - - - bool tile_coordinates(int index, scalar coords[8]) const - { - // make sure the index represents a real tile - if (index < 0 && 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; - } - - image_ptr mImage; - - GLuint mMinFilter; ///< Minification filter. - GLuint mMagFilter; ///< Magnification filter. - GLuint mWrapS; ///< Wrapping behavior horizontally. - GLuint mWrapT; ///< Wrapping behavior vertically. - int mTilesS; - int mTilesT; - - GLuint mObject; ///< GL texture handle. - static GLuint gObject; ///< Global GL texture handle. - - dispatcher::handle mNewContextDispatch; -}; - -GLuint texture::impl::gObject = 0; - - -texture::texture(const std::string& name) : // FIXME: this is really weird - image(name), - // pass through - impl_(texture::impl::instance(name)) {} - - -/** - * Bind the GL texture for mapping, etc. - */ - -void texture::bind() const -{ - // pass through - impl_->bind(); -} - - -/** - * Get the texture object, for the curious. - */ - -GLuint texture::object() const -{ - // pass through - return impl_->mObject; -} - - -void texture::reset_binding() -{ - glBindTexture(GL_TEXTURE_2D, 0); - impl::gObject = 0; -} - - -void texture::min_filter(GLuint filter) -{ - // pass through - impl_->min_filter(filter); -} - -void texture::mag_filter(GLuint filter) -{ - // pass through - impl_->mag_filter(filter); -} - -void texture::wrap_s(GLuint wrap) -{ - // pass through - impl_->wrap_s(wrap); -} - -void texture::wrap_t(GLuint wrap) -{ - // pass through - impl_->wrap_t(wrap); -} - - -bool texture::tile_coordinates(int index, scalar coords[8]) const -{ - // pass through - return impl_->tile_coordinates(index, coords); -} - -bool texture::tile_coordinates(int index, scalar coords[8], - orientation orientation) const -{ - if (tile_coordinates(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; -} - - -} // namespace moof -