1 /*************************************************************************** 2 * Copyright (C) 2005-2019 by the FIFE team * 3 * http://www.fifengine.net * 4 * This file is part of FIFE. * 5 * * 6 * FIFE is free software; you can redistribute it and/or * 7 * modify it under the terms of the GNU Lesser General Public * 8 * License as published by the Free Software Foundation; either * 9 * version 2.1 of the License, or (at your option) any later version. * 10 * * 11 * This library is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * 20 ***************************************************************************/ 21 22 // Standard C++ library includes 23 24 // This needs to be here, before Fifechan includes gl.h 25 #include "video/opengl/fife_opengl.h" 26 27 // 3rd party library includes 28 #include <fifechan/opengl.hpp> 29 #include <fifechan/font.hpp> 30 31 32 // FIFE includes 33 // These includes are split up in two parts, separated by one empty line 34 // First block: files included from the FIFE root src dir 35 #include "util/log/logger.h" 36 #include "util/base/exception.h" 37 #include "gui/fifechan/base/gui_image.h" 38 #include "util/structures/rect.h" 39 #include "video/image.h" 40 #include "video/imagemanager.h" 41 #include "video/opengl/renderbackendopengl.h" 42 43 #include "opengl_gui_graphics.h" 44 45 namespace FIFE { 46 static Logger _log(LM_GUI); 47 OpenGLGuiGraphics()48 OpenGLGuiGraphics::OpenGLGuiGraphics() { 49 mColor = fcn::Color(255, 255, 255, 255); 50 m_renderbackend = static_cast<RenderBackendOpenGL*>(RenderBackend::instance()); 51 setTargetPlane(m_renderbackend->getWidth(), m_renderbackend->getHeight()); 52 } 53 updateTarget()54 void OpenGLGuiGraphics::updateTarget() { 55 setTargetPlane(m_renderbackend->getWidth(), m_renderbackend->getHeight()); 56 } 57 drawImage(const fcn::Image * image,int32_t srcX,int32_t srcY,int32_t dstX,int32_t dstY,int32_t width,int32_t height)58 void OpenGLGuiGraphics::drawImage(const fcn::Image* image, int32_t srcX, int32_t srcY, int32_t dstX, int32_t dstY, int32_t width, int32_t height) { 59 const GuiImage* g_img = dynamic_cast<const GuiImage*>(image); 60 assert(g_img); 61 62 ImagePtr fifeimg = g_img->getFIFEImage(); 63 const fcn::ClipRectangle& clip = mClipStack.top(); 64 fifeimg->render(Rect(dstX + clip.xOffset, dstY + clip.yOffset, 65 width, height)); 66 } 67 drawText(const std::string & text,int32_t x,int32_t y,uint32_t alignment)68 void OpenGLGuiGraphics::drawText(const std::string& text, int32_t x, int32_t y, 69 uint32_t alignment) { 70 if (mFont == NULL) 71 { 72 throw GuiException("OpenGLGuiGraphics::drawText() - No font set!"); 73 } 74 75 switch (alignment) 76 { 77 case Left: 78 mFont->drawString(this, text, x, y); 79 break; 80 case Center: 81 mFont->drawString(this, text, x - mFont->getWidth(text) / 2, y); 82 break; 83 case Right: 84 mFont->drawString(this, text, x - mFont->getWidth(text), y); 85 break; 86 default: 87 FL_WARN(_log, LMsg("OpenGLGuiGraphics::drawText() - ") << "Unknown alignment: " << alignment); 88 mFont->drawString(this, text, x, y); 89 } 90 } 91 drawPoint(int32_t x,int32_t y)92 void OpenGLGuiGraphics::drawPoint(int32_t x, int32_t y) { 93 const fcn::ClipRectangle& top = mClipStack.top(); 94 m_renderbackend->putPixel(x + top.xOffset, y + top.yOffset, 95 mColor.r, mColor.g, mColor.b, mColor.a); 96 } 97 drawLine(int32_t x1,int32_t y1,int32_t x2,int32_t y2)98 void OpenGLGuiGraphics::drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2) { 99 const fcn::ClipRectangle& top = mClipStack.top(); 100 x1 += top.xOffset; 101 x2 += top.xOffset; 102 y1 += top.yOffset; 103 y2 += top.yOffset; 104 105 /*Point pbegin(static_cast<int32_t>(ceil(x1 + 0.375f)), static_cast<int32_t>(ceil(y1 + 0.375f))); 106 Point pend(static_cast<int32_t>(ceil(x2 + 0.625f)), static_cast<int32_t>(ceil(y2 + 0.625f)));*/ 107 /*if (x1 == x2) { 108 y2 += 1; 109 } else if (y1 == y2) { 110 x2 += 1; 111 }*/ 112 Point pbegin(x1, y1); 113 Point pend(x2, y2); 114 115 m_renderbackend->drawLine(pbegin, pend, 116 mColor.r, mColor.g, mColor.b, mColor.a); 117 //m_renderbackend->putPixel(pbegin.x, pbegin.y, 118 // mColor.r, mColor.g, mColor.b, mColor.a); 119 m_renderbackend->putPixel(pend.x, pend.y, 120 mColor.r, mColor.g, mColor.b, mColor.a); 121 } 122 drawLine(int32_t x1,int32_t y1,int32_t x2,int32_t y2,uint32_t width)123 void OpenGLGuiGraphics::drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t width) { 124 const fcn::ClipRectangle& top = mClipStack.top(); 125 m_renderbackend->drawThickLine(Point(x1+top.xOffset, y1+top.yOffset), Point(x2+top.xOffset, y2+top.yOffset), width, mColor.r, mColor.g, mColor.b, mColor.a); 126 } 127 drawPolyLine(const fcn::PointVector & points,uint32_t width)128 void OpenGLGuiGraphics::drawPolyLine(const fcn::PointVector& points, uint32_t width) { 129 const fcn::ClipRectangle& top = mClipStack.top(); 130 std::vector<Point> npoints; 131 fcn::PointVector::const_iterator it = points.begin(); 132 for (; it != points.end(); ++it) { 133 npoints.push_back(Point((*it).x+top.xOffset, (*it).y+top.yOffset)); 134 } 135 m_renderbackend->drawPolyLine(npoints, width, mColor.r, mColor.g, mColor.b, mColor.a); 136 } 137 drawBezier(const fcn::PointVector & points,int32_t steps,uint32_t width)138 void OpenGLGuiGraphics::drawBezier(const fcn::PointVector& points, int32_t steps, uint32_t width) { 139 const fcn::ClipRectangle& top = mClipStack.top(); 140 std::vector<Point> npoints; 141 fcn::PointVector::const_iterator it = points.begin(); 142 for (; it != points.end(); ++it) { 143 npoints.push_back(Point((*it).x+top.xOffset, (*it).y+top.yOffset)); 144 } 145 m_renderbackend->drawBezier(npoints, steps, width, mColor.r, mColor.g, mColor.b, mColor.a); 146 } 147 drawRectangle(const fcn::Rectangle & rectangle)148 void OpenGLGuiGraphics::drawRectangle(const fcn::Rectangle& rectangle) { 149 const fcn::ClipRectangle& top = mClipStack.top(); 150 m_renderbackend->drawRectangle( 151 Point(rectangle.x + top.xOffset, rectangle.y + top.yOffset), 152 rectangle.width, rectangle.height, 153 mColor.r, mColor.g, mColor.b, mColor.a); 154 } 155 fillRectangle(const fcn::Rectangle & rectangle)156 void OpenGLGuiGraphics::fillRectangle(const fcn::Rectangle& rectangle) { 157 const fcn::ClipRectangle& top = mClipStack.top(); 158 m_renderbackend->fillRectangle( 159 Point(rectangle.x + top.xOffset, rectangle.y + top.yOffset), 160 rectangle.width, rectangle.height, 161 mColor.r, mColor.g, mColor.b, mColor.a); 162 } 163 drawCircle(const fcn::Point & p,uint32_t radius)164 void OpenGLGuiGraphics::drawCircle(const fcn::Point& p, uint32_t radius) { 165 const fcn::ClipRectangle& top = mClipStack.top(); 166 m_renderbackend->drawCircle(Point(p.x+top.xOffset, p.y+top.yOffset), radius, mColor.r, mColor.g, mColor.b, mColor.a); 167 } 168 drawFillCircle(const fcn::Point & p,uint32_t radius)169 void OpenGLGuiGraphics::drawFillCircle(const fcn::Point& p, uint32_t radius) { 170 const fcn::ClipRectangle& top = mClipStack.top(); 171 m_renderbackend->drawFillCircle(Point(p.x+top.xOffset, p.y+top.yOffset), radius, mColor.r, mColor.g, mColor.b, mColor.a); 172 } 173 drawCircleSegment(const fcn::Point & p,uint32_t radius,int32_t sangle,int32_t eangle)174 void OpenGLGuiGraphics::drawCircleSegment(const fcn::Point& p, uint32_t radius, int32_t sangle, int32_t eangle) { 175 const fcn::ClipRectangle& top = mClipStack.top(); 176 m_renderbackend->drawCircleSegment(Point(p.x+top.xOffset, p.y+top.yOffset), radius, sangle, eangle, mColor.r, mColor.g, mColor.b, mColor.a); 177 } 178 drawFillCircleSegment(const fcn::Point & p,uint32_t radius,int32_t sangle,int32_t eangle)179 void OpenGLGuiGraphics::drawFillCircleSegment(const fcn::Point& p, uint32_t radius, int32_t sangle, int32_t eangle) { 180 const fcn::ClipRectangle& top = mClipStack.top(); 181 m_renderbackend->drawFillCircleSegment(Point(p.x+top.xOffset, p.y+top.yOffset), radius, sangle, eangle, mColor.r, mColor.g, mColor.b, mColor.a); 182 } 183 _beginDraw()184 void OpenGLGuiGraphics::_beginDraw() { 185 fcn::Rectangle area(0, 0, mWidth, mHeight); 186 fcn::Graphics::pushClipArea(area); 187 m_renderbackend->pushClipArea(Rect(0, 0, mWidth, mHeight), false); 188 } 189 _endDraw()190 void OpenGLGuiGraphics::_endDraw() { 191 m_renderbackend->renderVertexArrays(); 192 193 // Cleanup 194 fcn::Graphics::popClipArea(); 195 m_renderbackend->popClipArea(); 196 } 197 pushClipArea(fcn::Rectangle area)198 bool OpenGLGuiGraphics::pushClipArea(fcn::Rectangle area) { 199 // Render what we gathered so far 200 m_renderbackend->renderVertexArrays(); 201 fcn::Graphics::pushClipArea(area); 202 203 // Due to some odd conception in guiChan some of area 204 // has xOffset and yOffset > 0. And if it happens we 205 // need to offset our clip area. Or we can use Fifechan stack. 206 const fcn::ClipRectangle& top = mClipStack.top(); 207 208 m_renderbackend->pushClipArea( 209 Rect(top.x, top.y, top.width, top.height), false); 210 211 return true; 212 } 213 popClipArea()214 void OpenGLGuiGraphics::popClipArea() { 215 // Render what we gathered so far 216 m_renderbackend->renderVertexArrays(); 217 fcn::Graphics::popClipArea(); 218 m_renderbackend->popClipArea(); 219 } 220 setColor(const fcn::Color & color)221 void OpenGLGuiGraphics::setColor(const fcn::Color& color) { 222 mColor = color; 223 } 224 } 225