00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifdef _WIN32
00060 #define WIN32_LEAN_AND_MEAN
00061 #include <windows.h>
00062 #endif
00063
00064 #ifdef __amigaos4__
00065 #include <mgl/gl.h>
00066 #define glVertex3i glVertex3f
00067 #else
00068 #include <GL/gl.h>
00069 #endif
00070
00071 #include <string>
00072
00073 #include "guichan/opengl/openglgraphics.hpp"
00074 #include "guichan/exception.hpp"
00075
00076
00077 namespace gcn
00078 {
00079 OpenGLGraphics::OpenGLGraphics()
00080 {
00081 setTargetPlane(640, 480);
00082 mAlpha = false;
00083 }
00084
00085 OpenGLGraphics::OpenGLGraphics(int width, int height)
00086 {
00087 setTargetPlane(width, height);
00088 }
00089
00090 OpenGLGraphics::~OpenGLGraphics()
00091 {
00092
00093 }
00094
00095 void OpenGLGraphics::_beginDraw()
00096 {
00097 glPushAttrib(
00098 GL_COLOR_BUFFER_BIT |
00099 GL_CURRENT_BIT |
00100 GL_DEPTH_BUFFER_BIT |
00101 GL_ENABLE_BIT |
00102 GL_FOG_BIT |
00103 GL_LIGHTING_BIT |
00104 GL_LINE_BIT |
00105 GL_POINT_BIT |
00106 GL_POLYGON_BIT |
00107 GL_SCISSOR_BIT |
00108 GL_STENCIL_BUFFER_BIT |
00109 GL_TEXTURE_BIT |
00110 GL_TRANSFORM_BIT
00111 );
00112
00113 glMatrixMode(GL_MODELVIEW);
00114 glPushMatrix();
00115 glLoadIdentity();
00116
00117 glMatrixMode(GL_TEXTURE);
00118 glPushMatrix();
00119 glLoadIdentity();
00120
00121 glMatrixMode(GL_PROJECTION);
00122 glPushMatrix();
00123 glLoadIdentity();
00124
00125 glOrtho(0.0, (double)mWidth, (double)mHeight, 0.0, -1.0, 1.0);
00126
00127 glDisable(GL_LIGHTING);
00128 glDisable(GL_CULL_FACE);
00129 glDisable(GL_DEPTH_TEST);
00130
00131 glEnable(GL_SCISSOR_TEST);
00132
00133 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00134
00135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00139
00140 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00141
00142 pushClipArea(Rectangle(0, 0, mWidth, mHeight));
00143 }
00144
00145 void OpenGLGraphics::_endDraw()
00146 {
00147 glMatrixMode(GL_MODELVIEW);
00148 glPopMatrix();
00149
00150 glMatrixMode(GL_TEXTURE);
00151 glPopMatrix();
00152
00153 glMatrixMode(GL_PROJECTION);
00154 glPopMatrix();
00155
00156 glPopAttrib();
00157
00158 popClipArea();
00159 }
00160
00161 bool OpenGLGraphics::pushClipArea(Rectangle area)
00162 {
00163 bool result = Graphics::pushClipArea(area);
00164
00165 glScissor(mClipStack.top().x,
00166 mHeight - mClipStack.top().y - mClipStack.top().height,
00167 mClipStack.top().width,
00168 mClipStack.top().height);
00169
00170 return result;
00171 }
00172
00173 void OpenGLGraphics::popClipArea()
00174 {
00175 Graphics::popClipArea();
00176
00177 if (mClipStack.empty())
00178 {
00179 return;
00180 }
00181
00182 glScissor(mClipStack.top().x,
00183 mHeight - mClipStack.top().y - mClipStack.top().height,
00184 mClipStack.top().width,
00185 mClipStack.top().height);
00186 }
00187
00188 void OpenGLGraphics::setTargetPlane(int width, int height)
00189 {
00190 mWidth = width;
00191 mHeight = height;
00192 }
00193
00194 void OpenGLGraphics::drawImage(const Image* image, int srcX, int srcY,
00195 int dstX, int dstY, int width,
00196 int height)
00197 {
00198 dstX += mClipStack.top().xOffset;
00199 dstY += mClipStack.top().yOffset;
00200
00201
00202
00203 int realImageWidth = 1;
00204 int realImageHeight = 1;
00205 while (realImageWidth < image->getWidth())
00206 {
00207 realImageWidth *= 2;
00208 }
00209 while (realImageHeight < image->getHeight())
00210 {
00211 realImageHeight *= 2;
00212 }
00213
00214
00215 float texX1 = srcX / (float)realImageWidth;
00216 float texY1 = srcY / (float)realImageHeight;
00217 float texX2 = (srcX+width) / (float)realImageWidth;
00218 float texY2 = (srcY+height) / (float)realImageHeight;
00219
00220
00221
00222 glBindTexture(GL_TEXTURE_2D, *((GLuint *)(image->_getData())));
00223
00224 glEnable(GL_TEXTURE_2D);
00225
00226
00227 if (!mAlpha)
00228 {
00229 glEnable(GL_BLEND);
00230 }
00231
00232
00233 glBegin(GL_QUADS);
00234 glTexCoord2f(texX1, texY1);
00235 glVertex3i(dstX, dstY, 0);
00236
00237 glTexCoord2f(texX1, texY2);
00238 glVertex3i(dstX, dstY + height, 0);
00239
00240 glTexCoord2f(texX2, texY2);
00241 glVertex3i(dstX + width, dstY + height, 0);
00242
00243 glTexCoord2f(texX2, texY1);
00244 glVertex3i(dstX + width, dstY, 0);
00245 glEnd();
00246
00247 glDisable(GL_TEXTURE_2D);
00248
00249
00250 if (!mAlpha)
00251 {
00252 glDisable(GL_BLEND);
00253 }
00254 }
00255
00256 void OpenGLGraphics::drawPoint(int x, int y)
00257 {
00258 x += mClipStack.top().xOffset;
00259 y += mClipStack.top().yOffset;
00260
00261 glBegin(GL_POINTS);
00262 glVertex3i(x, y, 0);
00263 glEnd();
00264 }
00265
00266 void OpenGLGraphics::drawLine(int x1, int y1, int x2, int y2)
00267 {
00268 x1 += mClipStack.top().xOffset;
00269 y1 += mClipStack.top().yOffset;
00270 x2 += mClipStack.top().xOffset;
00271 y2 += mClipStack.top().yOffset;
00272
00273 glBegin(GL_LINES);
00274 glVertex3f(x1+0.5f, y1+0.5f, 0);
00275 glVertex3f(x2+0.5f, y2+0.5f, 0);
00276 glEnd();
00277
00278 glBegin(GL_POINTS);
00279 glVertex3f(x2+0.5f, y2+0.5f, 0);
00280 glEnd();
00281 }
00282
00283 void OpenGLGraphics::drawRectangle(const Rectangle& rectangle)
00284 {
00285 glBegin(GL_LINE_LOOP);
00286 glVertex3f(rectangle.x + mClipStack.top().xOffset + 0.5f,
00287 rectangle.y + mClipStack.top().yOffset + 0.5f, 0);
00288 glVertex3f(rectangle.x + rectangle.width - 0.5f + mClipStack.top().xOffset,
00289 rectangle.y + mClipStack.top().yOffset + 0.5f, 0);
00290 glVertex3f(rectangle.x + rectangle.width - 0.5f + mClipStack.top().xOffset,
00291 rectangle.y + rectangle.height + mClipStack.top().yOffset - 0.5f, 0);
00292 glVertex3f(rectangle.x + mClipStack.top().xOffset + 0.5f,
00293 rectangle.y + rectangle.height + mClipStack.top().yOffset - 0.5f, 0);
00294 glEnd();
00295 }
00296
00297 void OpenGLGraphics::fillRectangle(const Rectangle& rectangle)
00298 {
00299 glBegin(GL_QUADS);
00300 glVertex3i(rectangle.x + mClipStack.top().xOffset,
00301 rectangle.y + mClipStack.top().yOffset, 0);
00302 glVertex3i(rectangle.x + rectangle.width + mClipStack.top().xOffset,
00303 rectangle.y + mClipStack.top().yOffset, 0);
00304 glVertex3i(rectangle.x + rectangle.width + mClipStack.top().xOffset,
00305 rectangle.y + rectangle.height + mClipStack.top().yOffset, 0);
00306 glVertex3i(rectangle.x + mClipStack.top().xOffset,
00307 rectangle.y + rectangle.height + mClipStack.top().yOffset, 0);
00308 glEnd();
00309 }
00310
00311 void OpenGLGraphics::setColor(const Color& color)
00312 {
00313 mColor = color;
00314 glColor4f(color.r/255.0,
00315 color.g/255.0,
00316 color.b/255.0,
00317 color.a/255.0);
00318
00319 mAlpha = color.a != 255;
00320
00321 if (mAlpha)
00322 {
00323 glEnable(GL_BLEND);
00324 }
00325 }
00326
00327 const Color& OpenGLGraphics::getColor()
00328 {
00329 return mColor;
00330 }
00331 }