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 }