]>
Dogcows Code - chaz/yoink/blob - src/Moof/Texture.cc
6769d8887644a1924d2fdc67974b1afa4df4083d
2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
29 #include <cstdio> // FILE
30 #include <cstring> // strncmp
32 #include <boost/bind.hpp>
34 #include "Dispatch.hh"
48 * The texture implementation just contains all the information about the image
49 * which is worth having in memory. The image data itself is not worth keeping
50 * in memory if the texture has been loaded to GL, but the name of the resource
51 * is retained so that it can be reloaded if necessary. The implementation is a
52 * library so that multiple texture objects can share the same internal objects
53 * and avoid having duplicate textures loaded to GL.
56 class Texture::Impl
: public Library
<Impl
>
60 * Delete the texture (if it is loaded) from GL.
67 if (mObject
== gObject
)
72 glDeleteTextures(1, &mObject
);
78 * If the GL context was recreated, we need to reload the texture. This may
79 * involve reading it from disk again, but hopefully the OS was smart enough
80 * to cache it if the client has plenty of RAM.
83 void contextRecreated()
85 mObject
= gObject
= 0;
90 * This is a helper method used by some of the texture loading code. It
91 * returns the first power of two which is greater than the input value.
94 static int powerOfTwo(int input
)
108 * Construction is initialization.
111 explicit Impl(const std::string
& name
) :
114 mImage(Texture::getPath(getName())),
118 mMinFilter(GL_NEAREST
),
119 mMagFilter(GL_NEAREST
),
124 // make sure we have a video
125 VideoP video
= engine
.getVideo();
126 ASSERT(video
&& "cannot load textures without a current video context");
128 // we want to know when the GL context is recreated
129 mDispatchHandler
= engine
.addHandler("video.newcontext",
130 boost::bind(&Impl::contextRecreated
, this));
142 * Adapted from some public domain code. This stuff is common enough that
143 * it really should be included in SDL_image... We need this because images
144 * loaded with SDL_image aren't exactly GL-ready right out of the box. This
145 * method makes them ready.
149 static SDL_Surface* prepareImageForGL(SDL_Surface* surface)
151 int w = powerOfTwo(surface->w);
152 int h = powerOfTwo(surface->h);
154 // 2. OpenGL textures make more sense within the coordinate system when
155 // they are "upside down," so let's flip it.
157 flipSurface(surface);
159 // 1. OpenGL images must (generally) have dimensions of a power-of-two.
160 // If this one doesn't, we can at least be more friendly by expanding
161 // the dimensions so that they are, though there will be some empty
162 // space within the range of normal texture coordinates. It's better if
163 // textures are the right size to begin with.
165 SDL_Surface* image = SDL_CreateRGBSurface
170 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
188 Uint32 savedFlags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
189 Uint8 savedAlpha = surface->format->alpha;
190 if (savedFlags & SDL_SRCALPHA)
192 SDL_SetAlpha(surface, 0, 0);
195 SDL_Rect srcArea, destArea;
196 srcArea.x = 0; destArea.x = 0;
197 srcArea.y = 0; destArea.y = h - surface->h;
198 srcArea.w = surface->w;
199 srcArea.h = surface->h;
200 SDL_BlitSurface(surface, &srcArea, image, &destArea);
202 if (savedFlags & SDL_SRCALPHA)
204 SDL_SetAlpha(surface, savedFlags, savedAlpha);
212 * Use SDL_image to load images from file. A surface with the image data is
214 * @return Image data.
219 if (!mImage
.isValid())
221 logWarning
<< "texture not found: " << getName() << std::endl
;
222 throw Error(Error::RESOURCE_NOT_FOUND
, getName());
227 mWidth
= mImage
.getWidth();
228 mHeight
= mImage
.getHeight();
229 mMode
= mImage
.getColorMode();
234 * Upload the image to GL so that it will be accessible by a much more
235 * manageable handle and hopefully reside in video memory.
246 //if (!mContext) loadFromFile();
248 glGenTextures(1, &mObject
);
249 glBindTexture(GL_TEXTURE_2D
, mObject
);
268 //SDL_FreeSurface(mContext);
274 * Sets some texture properties such as the filters and external coordinate
280 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, mMinFilter
);
281 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, mMagFilter
);
282 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, mWrapS
);
283 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, mWrapT
);
286 inline void setMinFilter(GLuint filter
)
290 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, mMinFilter
);
293 inline void setMagFilter(GLuint filter
)
297 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, mMagFilter
);
300 inline void setWrapS(GLuint wrap
)
304 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, mWrapS
);
307 inline void setWrapT(GLuint wrap
)
311 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, mWrapT
);
321 if (mObject
!= gObject
)
323 glBindTexture(GL_TEXTURE_2D
, mObject
);
330 unsigned mWidth
; ///< Horizontal dimension of the image.
331 unsigned mHeight
; ///< Vertical dimension.
333 GLuint mMode
; ///< GL_RGB or GL_RGBA.
334 GLuint mMinFilter
; ///< Minifcation filter.
335 GLuint mMagFilter
; ///< Magnification filter.
336 GLuint mWrapS
; ///< Wrapping behavior horizontally.
337 GLuint mWrapT
; ///< Wrapping behavior vertically.
339 GLuint mObject
; ///< GL texture handle.
340 static GLuint gObject
; ///< Global GL texture handle.
342 Dispatch::Handler mDispatchHandler
;
345 GLuint
Texture::Impl::gObject
= 0;
348 Texture::Texture(const std::string
& name
) :
350 mImpl(Texture::Impl::getInstance(name
)) {}
354 * Bind the GL texture for mapping, etc.
357 void Texture::bind() const
365 * Get the texture object, for the curious.
368 GLuint
Texture::getObject() const
371 return mImpl
->mObject
;
375 void Texture::resetBind()
377 glBindTexture(GL_TEXTURE_2D
, 0);
382 unsigned Texture::getWidth() const
385 return mImpl
->mWidth
;
388 unsigned Texture::getHeight() const
391 return mImpl
->mHeight
;
395 void Texture::setMinFilter(GLuint filter
)
398 mImpl
->setMinFilter(filter
);
401 void Texture::setMagFilter(GLuint filter
)
404 mImpl
->setMagFilter(filter
);
407 void Texture::setWrapS(GLuint wrap
)
410 mImpl
->setWrapS(wrap
);
413 void Texture::setWrapT(GLuint wrap
)
416 mImpl
->setWrapT(wrap
);
420 std::string
Texture::getPath(const std::string
& name
)
422 std::string path
= Resource::getPath("textures/" + name
+ ".png");
429 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.057541 seconds and 4 git commands to generate.