]>
Dogcows Code - chaz/yoink/blob - src/texture.cc
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 *******************************************************************************/
31 #include <boost/bind.hpp>
34 #include <SDL/SDL_image.h>
36 #include "dispatcher.hh"
51 glDeleteTextures(1, &object
);
56 void contextRecreated(const notification
& note
)
63 texture_impl(texture
* outside
, bool keepInMemory
)
64 : interface(outside
), keepData(keepInMemory
), object(0), imageData(0)
66 dispatcher::instance().addHandler("video.context_recreated",
67 boost::bind(&texture_impl::contextRecreated
, this, _1
),
73 dispatcher::instance().removeHandler(this);
77 SDL_FreeSurface(imageData
);
83 static int powerOfTwo(int input
)
94 static SDL_Surface
* prepareImageForGL(SDL_Surface
* surface
)
96 // Adapted from some public domain code. This stuff is common enough
97 // that it really should be included in SDL_image... We need this
98 // because images loaded with SDL_image aren't exactly OpenGL-ready
99 // right out of the box.
101 int w
= powerOfTwo(surface
->w
);
102 int h
= powerOfTwo(surface
->h
);
104 // 1. OpenGL images must (generally) have dimensions of a power-of-two.
106 SDL_Surface
* image
= SDL_CreateRGBSurface
111 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
129 Uint32 savedFlags
= surface
->flags
&(SDL_SRCALPHA
|SDL_RLEACCELOK
);
130 Uint8 savedAlpha
= surface
->format
->alpha
;
131 if (savedFlags
& SDL_SRCALPHA
)
133 SDL_SetAlpha(surface
, 0, 0);
136 SDL_Rect srcArea
, destArea
;
137 srcArea
.x
= 0; destArea
.x
= 0;
138 srcArea
.y
= 0; destArea
.y
= h
- surface
->h
;
139 srcArea
.w
= surface
->w
;
140 srcArea
.h
= surface
->h
;
141 SDL_BlitSurface(surface
, &srcArea
, image
, &destArea
);
143 if (savedFlags
& SDL_SRCALPHA
)
145 SDL_SetAlpha(surface
, savedFlags
, savedAlpha
);
148 // 2. OpenGL textures make more sense when they are "upside down."
150 Uint8 line
[image
->pitch
];
152 Uint8
*pixels
= static_cast<Uint8
*>(image
->pixels
);
153 Uint16 pitch
= image
->pitch
;
155 int yend
= image
->h
- 1;
157 if (SDL_MUSTLOCK(image
)) SDL_LockSurface(image
);
158 while (ybegin
< yend
)
160 memcpy(line
, pixels
+ pitch
* ybegin
, pitch
);
161 memcpy(pixels
+ pitch
* ybegin
, pixels
+ pitch
* yend
, pitch
);
162 memcpy(pixels
+ pitch
* yend
, line
, pitch
);
166 if (SDL_MUSTLOCK(image
)) SDL_UnlockSurface(image
);
174 SDL_Surface
* surface
;
176 surface
= IMG_Load(interface
->getPathToFile().c_str());
180 throw texture::exception("loading failed");
183 imageData
= prepareImageForGL(surface
);
184 SDL_FreeSurface(surface
);
188 throw texture::exception("");
191 if (imageData
->format
->BytesPerPixel
== 3)
195 else if (imageData
->format
->BytesPerPixel
== 4)
201 SDL_FreeSurface(imageData
);
202 throw texture::exception("image is not the required 24 or 32 bpp");
205 width
= imageData
->w
;
206 height
= imageData
->h
;
223 glGenTextures(1, &object
);
225 glBindTexture(GL_TEXTURE_2D
, object
);
240 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
241 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
245 SDL_FreeSurface(imageData
);
257 SDL_Surface
* imageData
;
263 texture::texture(const std::string
& name
, bool keepInMemory
)
264 : resource(name
), impl(new texture_impl(this, keepInMemory
)) {}
269 glBindTexture(GL_TEXTURE_2D
, getObject());
272 GLuint
texture::getObject()
283 unsigned texture::getWidth()
293 unsigned texture::getHeight()
This page took 0.050206 seconds and 5 git commands to generate.