opengl_gui_graphics.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 
00024 // This needs to be here, before guichan includes gl.h
00025 #include "video/opengl/fife_opengl.h"
00026 
00027 // 3rd party library includes
00028 #include <guichan/opengl.hpp>
00029 #include <guichan/font.hpp>
00030 
00031 
00032 // FIFE includes
00033 // These includes are split up in two parts, separated by one empty line
00034 // First block: files included from the FIFE root src dir
00035 #include "util/log/logger.h"
00036 #include "util/base/exception.h"
00037 #include "gui/guichan/base/gui_image.h"
00038 #include "util/structures/rect.h"
00039 #include "video/image.h"
00040 #include "video/imagemanager.h"
00041 #include "video/opengl/renderbackendopengl.h"
00042 
00043 #include "opengl_gui_graphics.h"
00044 
00045 namespace FIFE {
00046     static Logger _log(LM_GUI);
00047 
00048     OpenGLGuiGraphics::OpenGLGuiGraphics() {
00049         SDL_Surface* target = SDL_GetVideoSurface();
00050         assert(target);
00051         setTargetPlane(target->w, target->h);
00052         mColor = gcn::Color(255, 255, 255, 255);
00053         m_renderbackend = static_cast<RenderBackendOpenGL*>(RenderBackend::instance());
00054     }
00055 
00056     void OpenGLGuiGraphics::drawImage(const gcn::Image* image, int32_t srcX, int32_t srcY, int32_t dstX, int32_t dstY, int32_t width, int32_t height) {
00057         const GuiImage* g_img = dynamic_cast<const GuiImage*>(image);
00058         assert(g_img);
00059 
00060         ImagePtr fifeimg = g_img->getFIFEImage();
00061         const gcn::ClipRectangle& clip = mClipStack.top();
00062         fifeimg->render(Rect(dstX + clip.xOffset, dstY + clip.yOffset,
00063             width, height));
00064     }
00065 
00066     void OpenGLGuiGraphics::drawText(const std::string& text, int32_t x, int32_t y,
00067             uint32_t alignment) {
00068         if (mFont == NULL)
00069         {
00070             throw GuiException("OpenGLGuiGraphics::drawText() - No font set!");
00071         }
00072 
00073         switch (alignment)
00074         {
00075             case LEFT:
00076                 mFont->drawString(this, text, x, y);
00077                 break;
00078             case CENTER:
00079                 mFont->drawString(this, text, x - mFont->getWidth(text) / 2, y);
00080                 break;
00081             case RIGHT:
00082                 mFont->drawString(this, text, x - mFont->getWidth(text), y);
00083                 break;
00084             default:
00085                 FL_WARN(_log, LMsg("OpenGLGuiGraphics::drawText() - ") << "Unknown alignment: " << alignment);
00086                 mFont->drawString(this, text, x, y);
00087         }
00088     }
00089 
00090     void OpenGLGuiGraphics::drawPoint(int32_t x, int32_t y) {
00091         const gcn::ClipRectangle& top = mClipStack.top();
00092         m_renderbackend->putPixel(x + top.xOffset, y + top.yOffset, 
00093             mColor.r, mColor.g, mColor.b, mColor.a);
00094     }
00095 
00096     void OpenGLGuiGraphics::drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2) {
00097         const gcn::ClipRectangle& top = mClipStack.top();
00098         x1 += top.xOffset;
00099         x2 += top.xOffset;
00100         y1 += top.yOffset;
00101         y2 += top.yOffset;
00102 
00103         Point pbegin(static_cast<int32_t>(ceil(x1 + 0.375f)), static_cast<int32_t>(ceil(y1 + 0.375f)));
00104         Point pend(static_cast<int32_t>(ceil(x2 + 0.625f)), static_cast<int32_t>(ceil(y2 + 0.625f)));
00105 
00106         m_renderbackend->drawLine(pbegin, pend,
00107             mColor.r, mColor.g, mColor.b, mColor.a);
00108         m_renderbackend->putPixel(pbegin.x, pbegin.y,
00109             mColor.r, mColor.g, mColor.b, mColor.a);
00110         m_renderbackend->putPixel(pend.x, pend.y,
00111             mColor.r, mColor.g, mColor.b, mColor.a);
00112     }
00113 
00114     void OpenGLGuiGraphics::drawRectangle(const gcn::Rectangle& rectangle) {
00115         const gcn::ClipRectangle& top = mClipStack.top();
00116         m_renderbackend->drawRectangle(
00117             Point(rectangle.x + top.xOffset, rectangle.y + top.yOffset),
00118             rectangle.width, rectangle.height,
00119             mColor.r, mColor.g, mColor.b, mColor.a);
00120     }
00121 
00122     void OpenGLGuiGraphics::fillRectangle(const gcn::Rectangle& rectangle) {
00123         const gcn::ClipRectangle& top = mClipStack.top();
00124         m_renderbackend->fillRectangle(
00125             Point(rectangle.x + top.xOffset, rectangle.y + top.yOffset),
00126             rectangle.width, rectangle.height,
00127             mColor.r, mColor.g, mColor.b, mColor.a);
00128     }
00129 
00130     void OpenGLGuiGraphics::_beginDraw() {
00131         gcn::Rectangle area(0, 0, mWidth, mHeight);
00132         gcn::Graphics::pushClipArea(area);
00133         m_renderbackend->pushClipArea(Rect(0, 0, mWidth, mHeight), false);
00134     }
00135 
00136     void OpenGLGuiGraphics::_endDraw() {
00137         m_renderbackend->renderVertexArrays();
00138 
00139         // Cleanup
00140         gcn::Graphics::popClipArea();
00141         m_renderbackend->popClipArea();
00142     }
00143 
00144     bool OpenGLGuiGraphics::pushClipArea(gcn::Rectangle area) {
00145         // Render what we gathered so far
00146         m_renderbackend->renderVertexArrays();
00147         gcn::Graphics::pushClipArea(area);
00148 
00149         // Due to some odd conception in guiChan some of area
00150         // has xOffset and yOffset > 0. And if it happens we 
00151         // need to offset our clip area. Or we can use guichan stack.
00152         const gcn::ClipRectangle& top = mClipStack.top();
00153 
00154         m_renderbackend->pushClipArea(
00155             Rect(top.x, top.y, top.width, top.height), false);
00156 
00157         return true;
00158     }
00159 
00160     void OpenGLGuiGraphics::popClipArea() {
00161         // Render what we gathered so far
00162         m_renderbackend->renderVertexArrays();
00163         gcn::Graphics::popClipArea();
00164         m_renderbackend->popClipArea();
00165     }
00166 
00167     void OpenGLGuiGraphics::setColor(const gcn::Color& color) {
00168         mColor = color;
00169     }
00170 }