Mercurial > fife-parpg
comparison ext/guichan-0.8.1/src/opengl/openglgraphics.cpp @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4a0efb7baf70 |
---|---|
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/openglgraphics.hpp" | |
49 | |
50 #if defined (_WIN32) | |
51 #define WIN32_LEAN_AND_MEAN | |
52 #include <windows.h> | |
53 #endif | |
54 | |
55 #if defined (__amigaos4__) | |
56 #include <mgl/gl.h> | |
57 #define glVertex3i glVertex3f | |
58 #elif defined(__APPLE__) | |
59 #include <OpenGL/gl.h> | |
60 #else | |
61 #include <GL/gl.h> | |
62 #endif | |
63 | |
64 #include "guichan/exception.hpp" | |
65 #include "guichan/image.hpp" | |
66 #include "guichan/opengl/openglimage.hpp" | |
67 | |
68 namespace gcn | |
69 { | |
70 OpenGLGraphics::OpenGLGraphics() | |
71 { | |
72 setTargetPlane(640, 480); | |
73 mAlpha = false; | |
74 } | |
75 | |
76 OpenGLGraphics::OpenGLGraphics(int width, int height) | |
77 { | |
78 setTargetPlane(width, height); | |
79 } | |
80 | |
81 OpenGLGraphics::~OpenGLGraphics() | |
82 { | |
83 | |
84 } | |
85 | |
86 void OpenGLGraphics::_beginDraw() | |
87 { | |
88 glPushAttrib( | |
89 GL_COLOR_BUFFER_BIT | | |
90 GL_CURRENT_BIT | | |
91 GL_DEPTH_BUFFER_BIT | | |
92 GL_ENABLE_BIT | | |
93 GL_FOG_BIT | | |
94 GL_LIGHTING_BIT | | |
95 GL_LINE_BIT | | |
96 GL_POINT_BIT | | |
97 GL_POLYGON_BIT | | |
98 GL_SCISSOR_BIT | | |
99 GL_STENCIL_BUFFER_BIT | | |
100 GL_TEXTURE_BIT | | |
101 GL_TRANSFORM_BIT | | |
102 GL_POINT_BIT | | |
103 GL_LINE_BIT | |
104 ); | |
105 | |
106 glMatrixMode(GL_MODELVIEW); | |
107 glPushMatrix(); | |
108 glLoadIdentity(); | |
109 | |
110 glMatrixMode(GL_TEXTURE); | |
111 glPushMatrix(); | |
112 glLoadIdentity(); | |
113 | |
114 glMatrixMode(GL_PROJECTION); | |
115 glPushMatrix(); | |
116 glLoadIdentity(); | |
117 | |
118 glOrtho(0.0, | |
119 (double)mWidth, | |
120 (double)mHeight, | |
121 0.0, | |
122 -1.0, | |
123 1.0); | |
124 | |
125 glDisable(GL_LIGHTING); | |
126 glDisable(GL_CULL_FACE); | |
127 glDisable(GL_DEPTH_TEST); | |
128 glDisable(GL_TEXTURE_2D); | |
129 | |
130 glEnable(GL_SCISSOR_TEST); | |
131 glPointSize(1.0); | |
132 glLineWidth(1.0); | |
133 | |
134 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
135 | |
136 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
137 | |
138 pushClipArea(Rectangle(0, 0, mWidth, mHeight)); | |
139 } | |
140 | |
141 void OpenGLGraphics::_endDraw() | |
142 { | |
143 glMatrixMode(GL_MODELVIEW); | |
144 glPopMatrix(); | |
145 | |
146 glMatrixMode(GL_TEXTURE); | |
147 glPopMatrix(); | |
148 | |
149 glMatrixMode(GL_PROJECTION); | |
150 glPopMatrix(); | |
151 | |
152 glPopAttrib(); | |
153 | |
154 popClipArea(); | |
155 } | |
156 | |
157 bool OpenGLGraphics::pushClipArea(Rectangle area) | |
158 { | |
159 bool result = Graphics::pushClipArea(area); | |
160 | |
161 glScissor(mClipStack.top().x, | |
162 mHeight - mClipStack.top().y - mClipStack.top().height, | |
163 mClipStack.top().width, | |
164 mClipStack.top().height); | |
165 | |
166 return result; | |
167 } | |
168 | |
169 void OpenGLGraphics::popClipArea() | |
170 { | |
171 Graphics::popClipArea(); | |
172 | |
173 if (mClipStack.empty()) | |
174 { | |
175 return; | |
176 } | |
177 | |
178 glScissor(mClipStack.top().x, | |
179 mHeight - mClipStack.top().y - mClipStack.top().height, | |
180 mClipStack.top().width, | |
181 mClipStack.top().height); | |
182 } | |
183 | |
184 void OpenGLGraphics::setTargetPlane(int width, int height) | |
185 { | |
186 mWidth = width; | |
187 mHeight = height; | |
188 } | |
189 | |
190 void OpenGLGraphics::drawImage(const Image* image, | |
191 int srcX, | |
192 int srcY, | |
193 int dstX, | |
194 int dstY, | |
195 int width, | |
196 int height) | |
197 { | |
198 const OpenGLImage* srcImage = dynamic_cast<const OpenGLImage*>(image); | |
199 | |
200 if (srcImage == NULL) | |
201 { | |
202 throw GCN_EXCEPTION("Trying to draw an image of unknown format, must be an OpenGLImage."); | |
203 } | |
204 | |
205 if (mClipStack.empty()) | |
206 { | |
207 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?"); | |
208 } | |
209 | |
210 const ClipRectangle& top = mClipStack.top(); | |
211 | |
212 dstX += top.xOffset; | |
213 dstY += top.yOffset; | |
214 | |
215 // Find OpenGL texture coordinates | |
216 float texX1 = srcX / (float)srcImage->getTextureWidth(); | |
217 float texY1 = srcY / (float)srcImage->getTextureHeight(); | |
218 float texX2 = (srcX+width) / (float)srcImage->getTextureWidth(); | |
219 float texY2 = (srcY+height) / (float)srcImage->getTextureHeight(); | |
220 | |
221 glBindTexture(GL_TEXTURE_2D, srcImage->getTextureHandle()); | |
222 | |
223 glEnable(GL_TEXTURE_2D); | |
224 | |
225 // Check if blending already is enabled | |
226 if (!mAlpha) | |
227 { | |
228 glEnable(GL_BLEND); | |
229 } | |
230 | |
231 // Draw a textured quad -- the image | |
232 glBegin(GL_QUADS); | |
233 glTexCoord2f(texX1, texY1); | |
234 glVertex3i(dstX, dstY, 0); | |
235 | |
236 glTexCoord2f(texX1, texY2); | |
237 glVertex3i(dstX, dstY + height, 0); | |
238 | |
239 glTexCoord2f(texX2, texY2); | |
240 glVertex3i(dstX + width, dstY + height, 0); | |
241 | |
242 glTexCoord2f(texX2, texY1); | |
243 glVertex3i(dstX + width, dstY, 0); | |
244 glEnd(); | |
245 glDisable(GL_TEXTURE_2D); | |
246 | |
247 // Don't disable blending if the color has alpha | |
248 if (!mAlpha) | |
249 { | |
250 glDisable(GL_BLEND); | |
251 } | |
252 } | |
253 | |
254 void OpenGLGraphics::drawPoint(int x, int y) | |
255 { | |
256 if (mClipStack.empty()) | |
257 { | |
258 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?"); | |
259 } | |
260 | |
261 const ClipRectangle& top = mClipStack.top(); | |
262 | |
263 x += top.xOffset; | |
264 y += top.yOffset; | |
265 | |
266 glBegin(GL_POINTS); | |
267 glVertex2i(x, y); | |
268 glEnd(); | |
269 } | |
270 | |
271 void OpenGLGraphics::drawLine(int x1, int y1, int x2, int y2) | |
272 { | |
273 if (mClipStack.empty()) | |
274 { | |
275 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?"); | |
276 } | |
277 | |
278 const ClipRectangle& top = mClipStack.top(); | |
279 | |
280 x1 += top.xOffset; | |
281 y1 += top.yOffset; | |
282 x2 += top.xOffset; | |
283 y2 += top.yOffset; | |
284 | |
285 glBegin(GL_LINES); | |
286 glVertex2f(x1 + 0.375f, | |
287 y1 + 0.375f); | |
288 glVertex2f(x2 + 1.0f - 0.375f, | |
289 y2 + 1.0f - 0.375f); | |
290 glEnd(); | |
291 | |
292 glBegin(GL_POINTS); | |
293 glVertex2f(x2 + 1.0f - 0.375f, | |
294 y2 + 1.0f - 0.375f); | |
295 glEnd(); | |
296 | |
297 glBegin(GL_POINTS); | |
298 glVertex2f(x1 + 0.375f, | |
299 y1 + 0.375f); | |
300 glEnd(); | |
301 | |
302 | |
303 } | |
304 | |
305 void OpenGLGraphics::drawRectangle(const Rectangle& rectangle) | |
306 { | |
307 if (mClipStack.empty()) | |
308 { | |
309 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?"); | |
310 } | |
311 | |
312 const ClipRectangle& top = mClipStack.top(); | |
313 | |
314 glBegin(GL_LINE_LOOP); | |
315 glVertex2f(rectangle.x + top.xOffset, | |
316 rectangle.y + top.yOffset); | |
317 glVertex2f(rectangle.x + rectangle.width + top.xOffset - 1.0f, | |
318 rectangle.y + top.yOffset + 0.375f); | |
319 glVertex2f(rectangle.x + rectangle.width + top.xOffset - 1.0f, | |
320 rectangle.y + rectangle.height + top.yOffset); | |
321 glVertex2f(rectangle.x + top.xOffset, | |
322 rectangle.y + rectangle.height + top.yOffset); | |
323 glEnd(); | |
324 } | |
325 | |
326 void OpenGLGraphics::fillRectangle(const Rectangle& rectangle) | |
327 { | |
328 if (mClipStack.empty()) | |
329 { | |
330 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion outside of _beginDraw() and _endDraw()?"); | |
331 } | |
332 | |
333 const ClipRectangle& top = mClipStack.top(); | |
334 | |
335 glBegin(GL_QUADS); | |
336 glVertex2i(rectangle.x + top.xOffset, | |
337 rectangle.y + top.yOffset); | |
338 glVertex2i(rectangle.x + rectangle.width + top.xOffset, | |
339 rectangle.y + top.yOffset); | |
340 glVertex2i(rectangle.x + rectangle.width + top.xOffset, | |
341 rectangle.y + rectangle.height + top.yOffset); | |
342 glVertex2i(rectangle.x + top.xOffset, | |
343 rectangle.y + rectangle.height + top.yOffset); | |
344 glEnd(); | |
345 } | |
346 | |
347 void OpenGLGraphics::setColor(const Color& color) | |
348 { | |
349 mColor = color; | |
350 glColor4ub(color.r, color.g, color.b, color.a); | |
351 | |
352 mAlpha = color.a != 255; | |
353 | |
354 if (mAlpha) | |
355 { | |
356 glEnable(GL_BLEND); | |
357 } | |
358 } | |
359 | |
360 const Color& OpenGLGraphics::getColor() const | |
361 { | |
362 return mColor; | |
363 } | |
364 } |