00001 #include "gui_gl_manager.hpp"
00002 #include "gui_gl_material.hpp"
00003 #include "gui_gl_rendertarget.hpp"
00004 #include "gui_gl_font.hpp"
00005 #include <gui_sprite.hpp>
00006 #include <gui_out.hpp>
00007 #include <utils_string.hpp>
00008
00009 #include <GL/glew.h>
00010 #include <GL/gl.h>
00011 #include <cstring>
00012
00013 namespace gui {
00014 namespace gl
00015 {
00016 manager::manager(bool bInitGLEW) :
00017 bUpdateViewMatrix_(true)
00018 {
00019 if (bInitGLEW)
00020 glewInit();
00021
00022 render_target::check_availability();
00023 material::check_availability();
00024 }
00025
00026 manager::~manager()
00027 {
00028 }
00029
00030 void manager::begin(utils::refptr<gui::render_target> pTarget) const
00031 {
00032 if (pTarget)
00033 {
00034 pCurrentTarget_ = utils::refptr<gl::render_target>::cast(pTarget);
00035 pCurrentTarget_->begin();
00036 }
00037 else
00038 {
00039 if (bUpdateViewMatrix_)
00040 update_view_matrix_();
00041
00042 glViewport(0.0f, 0.0f, pParent_->get_screen_width(), pParent_->get_screen_height());
00043 glDisable(GL_DEPTH_TEST);
00044 glEnable(GL_BLEND);
00045 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00046 glDisable(GL_LIGHTING);
00047 glDisable(GL_ALPHA_TEST);
00048 glDisable(GL_CULL_FACE);
00049
00050 glMatrixMode(GL_PROJECTION);
00051 glLoadMatrixf(reinterpret_cast<float*>(&mViewMatrix_));
00052
00053 glMatrixMode(GL_MODELVIEW);
00054 glLoadIdentity();
00055 }
00056 }
00057
00058 void manager::update_view_matrix_() const
00059 {
00060 float fWidth = pParent_->get_screen_width();
00061 float fHeight = pParent_->get_screen_height();
00062
00063 mViewMatrix_ = {
00064 2.0f/fWidth, 0.0f, -1.0f, -1.0f,
00065 0.0f, -2.0f/fHeight, 1.0f, 1.0f,
00066 0.0f, 0.0f, 1.0f, 0.0f,
00067 0.0f, 0.0f, 0.0f, 1.0f
00068 };
00069
00070 bUpdateViewMatrix_ = false;
00071 }
00072
00073 void manager::end() const
00074 {
00075 if (pCurrentTarget_)
00076 {
00077 pCurrentTarget_->end();
00078 pCurrentTarget_ = nullptr;
00079 }
00080 }
00081
00082 void manager::render_quad(const quad& mQuad) const
00083 {
00084 static const std::array<uint, 6> ids = {{0, 1, 2, 2, 3, 0}};
00085
00086 glColor4ub(255, 255, 255, 255);
00087
00088 utils::refptr<gl::material> pMat = utils::refptr<gl::material>::cast(mQuad.mat);
00089 if (pMat->get_type() == gl::material::TYPE_TEXTURE)
00090 {
00091 pMat->bind();
00092
00093 glEnable(GL_TEXTURE_2D);
00094 glBegin(GL_TRIANGLES);
00095 for (uint i = 0; i < 6; ++i)
00096 {
00097 uint j = ids[i];
00098 float a = mQuad.v[j].col.a;
00099 glColor4f(mQuad.v[j].col.r*a, mQuad.v[j].col.g*a, mQuad.v[j].col.b*a, a);
00100 glTexCoord2f(mQuad.v[j].uvs.x, mQuad.v[j].uvs.y);
00101 glVertex2f(mQuad.v[j].pos.x, mQuad.v[j].pos.y);
00102 }
00103 glEnd();
00104 }
00105 else
00106 {
00107 glDisable(GL_TEXTURE_2D);
00108 glBegin(GL_TRIANGLES);
00109 for (uint i = 0; i < 6; ++i)
00110 {
00111 uint j = ids[i];
00112 color c = mQuad.v[j].col*pMat->get_color();
00113 c.r *= c.a; c.g *= c.a; c.b *= c.a;
00114 glColor4f(c.r, c.g, c.b, c.a);
00115 glVertex2f(mQuad.v[j].pos.x, mQuad.v[j].pos.y);
00116 }
00117 glEnd();
00118 }
00119 }
00120
00121 void manager::render_quads(const quad& mQuad, const std::vector<std::array<vertex,4>>& lQuadList) const
00122 {
00123 static const std::array<uint, 6> ids = {{0, 1, 2, 2, 3, 0}};
00124
00125 glColor4ub(255, 255, 255, 255);
00126
00127 utils::refptr<gl::material> pMat = utils::refptr<gl::material>::cast(mQuad.mat);
00128 if (pMat->get_type() == gl::material::TYPE_TEXTURE)
00129 {
00130 pMat->bind();
00131
00132 glEnable(GL_TEXTURE_2D);
00133 glBegin(GL_TRIANGLES);
00134 std::vector<std::array<vertex,4>>::const_iterator iter;
00135 foreach (iter, lQuadList)
00136 {
00137 const std::array<vertex,4>& v = *iter;
00138 for (uint i = 0; i < 6; ++i)
00139 {
00140 uint j = ids[i];
00141 float a = v[j].col.a;
00142 glColor4f(v[j].col.r*a, v[j].col.g*a, v[j].col.b*a, a);
00143 glTexCoord2f(v[j].uvs.x, v[j].uvs.y);
00144 glVertex2f(v[j].pos.x, v[j].pos.y);
00145 }
00146 }
00147 glEnd();
00148 }
00149 else
00150 {
00151 glDisable(GL_TEXTURE_2D);
00152 glBegin(GL_TRIANGLES);
00153 std::vector<std::array<vertex,4>>::const_iterator iter;
00154 foreach (iter, lQuadList)
00155 {
00156 const std::array<vertex,4>& v = *iter;
00157 for (uint i = 0; i < 6; ++i)
00158 {
00159 uint j = ids[i];
00160 color c = v[j].col*pMat->get_color();
00161 c.r *= c.a; c.g *= c.a; c.b *= c.a;
00162 glColor4f(c.r, c.g, c.b, c.a);
00163 glVertex2f(v[j].pos.x, v[j].pos.y);
00164 }
00165 }
00166 glEnd();
00167 }
00168 }
00169
00170 utils::refptr<gui::material> manager::create_material(const std::string& sFileName) const
00171 {
00172 std::map<std::string, utils::wptr<gui::material>>::iterator iter = lTextureList_.find(sFileName);
00173 if (iter != lTextureList_.end())
00174 {
00175 if (utils::refptr<gui::material> pLock = iter->second.lock())
00176 return pLock;
00177 else
00178 lTextureList_.erase(iter);
00179 }
00180
00181 if (utils::ends_with(sFileName, ".png"))
00182 return create_material_png(sFileName);
00183 else
00184 {
00185 gui::out << gui::warning << "gui::gl::manager : Unsupported texture format '"
00186 << sFileName << "'." << std::endl;
00187 return nullptr;
00188 }
00189 }
00190
00191 utils::refptr<gui::material> manager::create_material(const color& mColor) const
00192 {
00193 return utils::refptr<material>(new material(mColor));
00194 }
00195
00196 utils::refptr<gui::material> manager::create_material(utils::refptr<gui::render_target> pRenderTarget) const
00197 {
00198 return utils::refptr<gl::render_target>::cast(pRenderTarget)->get_material().lock();
00199 }
00200
00201 utils::refptr<gui::render_target> manager::create_render_target(uint uiWidth, uint uiHeight) const
00202 {
00203 return utils::refptr<gui::render_target>(new gl::render_target(uiWidth, uiHeight));
00204 }
00205
00206 utils::refptr<gui::font> manager::create_font(const std::string& sFontFile, uint uiSize) const
00207 {
00208 std::string sFontName = sFontFile + "|" + utils::to_string(uiSize);
00209 std::map<std::string, utils::wptr<gui::font>>::iterator iter = lFontList_.find(sFontName);
00210 if (iter != lFontList_.end())
00211 {
00212 if (utils::refptr<gui::font> pLock = iter->second.lock())
00213 return pLock;
00214 else
00215 lFontList_.erase(iter);
00216 }
00217
00218 utils::refptr<gui::font> pFont(new gl::font(sFontFile, uiSize));
00219 lFontList_[sFontName] = pFont;
00220 return pFont;
00221 }
00222
00223 bool manager::is_gl_extension_supported(const std::string& sExtension)
00224 {
00225
00226
00227
00228 const unsigned char *pszExtensions = NULL;
00229 const unsigned char *pszStart;
00230 unsigned char *pszWhere, *pszTerminator;
00231
00232
00233 pszWhere = (unsigned char*)strchr(sExtension.c_str(), ' ');
00234 if (pszWhere || sExtension.empty())
00235 return false;
00236
00237
00238 pszExtensions = glGetString(GL_EXTENSIONS);
00239
00240
00241 pszStart = pszExtensions;
00242
00243 for (;;)
00244 {
00245 pszWhere = (unsigned char*)strstr((const char*)pszStart, sExtension.c_str());
00246 if (!pszWhere)
00247 break;
00248
00249 pszTerminator = pszWhere + sExtension.size();
00250
00251 if ((pszWhere == pszStart || *(pszWhere - 1) == ' ') &&
00252 (*pszTerminator == ' ' || *pszTerminator == '\0'))
00253 return true;
00254
00255 pszStart = pszTerminator;
00256 }
00257
00258 return false;
00259 }
00260 }
00261 }