Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

openglgraphics.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __                 
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\                
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /                 
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /                  
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /                   
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /                    
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/                      
00008  *
00009  * Copyright (c) 2004, 2005 darkbits                        Js_./
00010  * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
00011  * Olof Naessén a.k.a jansem/yakslem                _asww7!uY`>  )\a//
00012  *                                                 _Qhm`] _f "'c  1!5m
00013  * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
00014  *                                               .)j(] .d_/ '-(  P .   S
00015  * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
00016  * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
00017  * binary forms, with or without                 )4d[#7r, .   '     )d`)[
00018  * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
00019  * that the following conditions are met:       j<<WP+k/);.        _W=j f
00020  * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
00021  *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
00022  *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
00023  *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
00024  * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
00025  *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
00026  *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
00027  *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
00028  *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
00029  *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
00030  * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
00031  *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
00032  *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
00033  *    from this software without specific        (js, \[QQW$QWW#?!V"".
00034  *    prior written permission.                    ]y:.<\..          .
00035  *                                                 -]n w/ '         [.
00036  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
00037  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
00038  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
00039  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
00040  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
00041  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
00042  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
00043  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
00044  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
00045  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
00046  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
00047  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00049  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00050  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00051  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00052  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00053  */
00054 
00055 /*
00056  * For comments regarding functions please see the header file. 
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         // The following code finds the real width and height of the texture.
00202         // OpenGL only supports texture sizes that are powers of two
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         // Find OpenGL texture coordinates
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         // Please dont look too closely at the next line, it is not pretty.
00221         // It uses the image data as a pointer to a GLuint
00222         glBindTexture(GL_TEXTURE_2D, *((GLuint *)(image->_getData())));
00223 
00224         glEnable(GL_TEXTURE_2D);
00225 
00226         // Check if blending already is enabled
00227         if (!mAlpha)
00228         {
00229             glEnable(GL_BLEND);
00230         }
00231         
00232         // Draw a textured quad -- the image
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         // Don't disable blending if the color has alpha
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 }

Generated on Tue May 17 21:23:26 2005 for Guichan by  doxygen 1.4.1