comparison ext/guichan-0.8.2/src/opengl/openglimage.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/opengl/openglimage.hpp"
49
50 #include "guichan/exception.hpp"
51
52 namespace gcn
53 {
54 OpenGLImage::OpenGLImage(const unsigned int* pixels, int width, int height,
55 bool convertToDisplayFormat)
56 {
57 mAutoFree = true;
58
59 mWidth = width;
60 mHeight = height;
61 mTextureWidth = 1, mTextureHeight = 1;
62
63 while(mTextureWidth < mWidth)
64 {
65 mTextureWidth *= 2;
66 }
67
68 while(mTextureHeight < mHeight)
69 {
70 mTextureHeight *= 2;
71 }
72
73 // Create a new pixel array and copy the pixels into it
74 mPixels = new unsigned int[mTextureWidth * mTextureHeight];
75
76 #ifdef __BIG_ENDIAN__
77 const unsigned int magicPink = 0xff00ffff;
78 #else
79 const unsigned int magicPink = 0xffff00ff;
80 #endif
81 int x, y;
82 for (y = 0; y < mTextureHeight; y++)
83 {
84 for (x = 0; x < mTextureWidth; x++)
85 {
86 if (x < mWidth && y < mHeight)
87 {
88 unsigned int c = pixels[x + y * mWidth];
89
90 // Magic pink to transparent
91 if (c == magicPink)
92 {
93 c = 0x00000000;
94 }
95
96 mPixels[x + y * mTextureWidth] = c;
97 }
98 else
99 {
100 mPixels[x + y * mTextureWidth] = 0x00000000;
101 }
102 }
103 }
104
105 if (convertToDisplayFormat)
106 {
107 OpenGLImage::convertToDisplayFormat();
108 }
109 }
110
111 OpenGLImage::OpenGLImage(GLuint textureHandle, int width, int height, bool autoFree)
112 {
113 mTextureHandle = textureHandle;
114 mAutoFree = autoFree;
115 mPixels = NULL;
116
117 mWidth = width;
118 mHeight = height;
119 mTextureWidth = 1, mTextureHeight = 1;
120
121 while(mTextureWidth < mWidth)
122 {
123 mTextureWidth *= 2;
124 }
125
126 while(mTextureHeight < mHeight)
127 {
128 mTextureHeight *= 2;
129 }
130 }
131
132 OpenGLImage::~OpenGLImage()
133 {
134 if (mAutoFree)
135 {
136 free();
137 }
138 }
139
140 GLuint OpenGLImage::getTextureHandle() const
141 {
142 return mTextureHandle;
143 }
144
145 int OpenGLImage::getTextureWidth() const
146 {
147 return mTextureWidth;
148 }
149
150 int OpenGLImage::getTextureHeight() const
151 {
152 return mTextureHeight;
153 }
154
155 void OpenGLImage::free()
156 {
157 if (mPixels == NULL)
158 {
159 glDeleteTextures(1, &mTextureHandle);
160 }
161 else
162 {
163 delete[] mPixels;
164 mPixels = NULL;
165 }
166 }
167
168 int OpenGLImage::getWidth() const
169 {
170 return mWidth;
171 }
172
173 int OpenGLImage::getHeight() const
174 {
175 return mHeight;
176 }
177
178 Color OpenGLImage::getPixel(int x, int y)
179 {
180 if (mPixels == NULL)
181 {
182 throw GCN_EXCEPTION("Image has been converted to display format");
183 }
184
185 if (x < 0 || x >= mWidth || y < 0 || y >= mHeight)
186 {
187 throw GCN_EXCEPTION("Coordinates outside of the image");
188 }
189
190 unsigned int c = mPixels[x + y * mTextureWidth];
191
192 #ifdef __BIG_ENDIAN__
193 unsigned char r = (unsigned char) ((c >> 24) & 0xff);
194 unsigned char g = (unsigned char) ((c >> 16) & 0xff);
195 unsigned char b = (unsigned char) ((c >> 8) & 0xff);
196 unsigned char a = (unsigned char) (c & 0xff);
197 #else
198 unsigned char a = (unsigned char) ((c >> 24) & 0xff);
199 unsigned char b = (unsigned char) ((c >> 16) & 0xff);
200 unsigned char g = (unsigned char) ((c >> 8) & 0xff);
201 unsigned char r = (unsigned char) (c & 0xff);
202 #endif
203
204 return Color(r, g, b, a);
205 }
206
207 void OpenGLImage::putPixel(int x, int y, const Color& color)
208 {
209 if (mPixels == NULL)
210 {
211 throw GCN_EXCEPTION("Image has been converted to display format");
212 }
213
214 if (x < 0 || x >= mWidth || y < 0 || y >= mHeight)
215 {
216 throw GCN_EXCEPTION("Coordinates outside of the image");
217 }
218
219 #ifdef __BIG_ENDIAN__
220 unsigned int c = color.a | color.b << 8 | color.g << 16 | color.r << 24;
221 #else
222 unsigned int c = color.r | color.g << 8 | color.b << 16 | color.a << 24;
223 #endif
224
225 mPixels[x + y * mTextureWidth] = c;
226 }
227
228 void OpenGLImage::convertToDisplayFormat()
229 {
230 if (mPixels == NULL)
231 {
232 throw GCN_EXCEPTION("Image has already been converted to display format");
233 }
234
235 glGenTextures(1, &mTextureHandle);
236 glBindTexture(GL_TEXTURE_2D, mTextureHandle);
237
238 glTexImage2D(GL_TEXTURE_2D,
239 0,
240 4,
241 mTextureWidth,
242 mTextureHeight,
243 0,
244 GL_RGBA,
245 GL_UNSIGNED_BYTE,
246 mPixels);
247
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
250
251 delete[] mPixels;
252 mPixels = NULL;
253
254 GLenum error = glGetError();
255 if (error)
256 {
257 std::string errmsg;
258 switch (error)
259 {
260 case GL_INVALID_ENUM:
261 errmsg = "GL_INVALID_ENUM";
262 break;
263
264 case GL_INVALID_VALUE:
265 errmsg = "GL_INVALID_VALUE";
266 break;
267
268 case GL_INVALID_OPERATION:
269 errmsg = "GL_INVALID_OPERATION";
270 break;
271
272 case GL_STACK_OVERFLOW:
273 errmsg = "GL_STACK_OVERFLOW";
274 break;
275
276 case GL_STACK_UNDERFLOW:
277 errmsg = "GL_STACK_UNDERFLOW";
278 break;
279
280 case GL_OUT_OF_MEMORY:
281 errmsg = "GL_OUT_OF_MEMORY";
282 break;
283 }
284
285 throw GCN_EXCEPTION(std::string("Unable to convert to OpenGL display format, glGetError said: ") + errmsg);
286 }
287 }
288 }