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 #include "renderers/OpenGLGUIRenderer/openglrenderer.h"
00028 #include "renderers/OpenGLGUIRenderer/opengltexture.h"
00029 #include "CEGUIExceptions.h"
00030
00031
00032
00033 namespace CEGUI
00034 {
00035
00036
00037
00038 const int OpenGLRenderer::VERTEX_PER_QUAD = 6;
00039 const int OpenGLRenderer::VERTEX_PER_TRIANGLE = 3;
00040 const int OpenGLRenderer::VERTEXBUFFER_CAPACITY = OGLRENDERER_VBUFF_CAPACITY;
00041
00042
00043
00044
00045
00046 OpenGLRenderer::OpenGLRenderer(uint max_quads) :
00047 d_queueing(true),
00048 d_currTexture(0),
00049 d_bufferPos(0)
00050 {
00051 GLint vp[4];
00052
00053
00054 glGetIntegerv(GL_VIEWPORT, vp);
00055 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &d_maxTextureSize);
00056 d_display_area.d_left = 0;
00057 d_display_area.d_top = 0;
00058 d_display_area.d_right = (float)vp[2];
00059 d_display_area.d_bottom = (float)vp[3];
00060 }
00061
00062
00063 OpenGLRenderer::OpenGLRenderer(uint max_quads,int width, int height) :
00064 d_queueing(true),
00065 d_currTexture(0),
00066 d_bufferPos(0)
00067 {
00068 GLint vp[4];
00069
00070
00071 glGetIntegerv(GL_VIEWPORT, vp);
00072 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &d_maxTextureSize);
00073 d_display_area.d_left = 0;
00074 d_display_area.d_top = 0;
00075 d_display_area.d_right = static_cast<float>(width);
00076 d_display_area.d_bottom = static_cast<float>(height);
00077 }
00078
00079
00080
00081
00082
00083 OpenGLRenderer::~OpenGLRenderer(void)
00084 {
00085 destroyAllTextures();
00086 }
00087
00088
00089
00090
00091
00092 void OpenGLRenderer::addQuad(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
00093 {
00094
00095 if (!d_queueing)
00096 {
00097 renderQuadDirect(dest_rect, z, tex, texture_rect, colours, quad_split_mode);
00098 }
00099 else
00100 {
00101 QuadInfo quad;
00102 quad.position = dest_rect;
00103 quad.position.d_bottom = d_display_area.d_bottom - dest_rect.d_bottom;
00104 quad.position.d_top = d_display_area.d_bottom - dest_rect.d_top;
00105 quad.z = z;
00106 quad.texid = ((OpenGLTexture*)tex)->getOGLTexid();
00107 quad.texPosition = texture_rect;
00108 quad.topLeftCol = colourToOGL(colours.d_top_left);
00109 quad.topRightCol = colourToOGL(colours.d_top_right);
00110 quad.bottomLeftCol = colourToOGL(colours.d_bottom_left);
00111 quad.bottomRightCol = colourToOGL(colours.d_bottom_right);
00112
00113
00114 quad.splitMode = quad_split_mode;
00115
00116 d_quadlist.insert(quad);
00117 }
00118
00119 }
00120
00121
00122
00123
00124
00125
00126 void OpenGLRenderer::doRender(void)
00127 {
00128 d_currTexture = 0;
00129
00130 initPerFrameStates();
00131 glInterleavedArrays(GL_T2F_C4UB_V3F , 0, myBuff);
00132
00133
00134 for (QuadList::iterator i = d_quadlist.begin(); i != d_quadlist.end(); ++i)
00135 {
00136 const QuadInfo& quad = (*i);
00137
00138 if(d_currTexture != quad.texid)
00139 {
00140 renderVBuffer();
00141 glBindTexture(GL_TEXTURE_2D, quad.texid);
00142 d_currTexture = quad.texid;
00143 }
00144
00145
00146 myBuff[d_bufferPos].vertex[0] = quad.position.d_left;
00147 myBuff[d_bufferPos].vertex[1] = quad.position.d_top;
00148 myBuff[d_bufferPos].vertex[2] = quad.z;
00149 myBuff[d_bufferPos].color = quad.topLeftCol;
00150 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_left;
00151 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_top;
00152 ++d_bufferPos;
00153
00154
00155 myBuff[d_bufferPos].vertex[0] = quad.position.d_left;
00156 myBuff[d_bufferPos].vertex[1] = quad.position.d_bottom;
00157 myBuff[d_bufferPos].vertex[2] = quad.z;
00158 myBuff[d_bufferPos].color = quad.bottomLeftCol;
00159 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_left;
00160 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_bottom;
00161 ++d_bufferPos;
00162
00163
00164
00165
00166 if (quad.splitMode == TopLeftToBottomRight)
00167 {
00168 myBuff[d_bufferPos].vertex[0] = quad.position.d_right;
00169 myBuff[d_bufferPos].vertex[1] = quad.position.d_bottom;
00170 myBuff[d_bufferPos].vertex[2] = quad.z;
00171 myBuff[d_bufferPos].color = quad.bottomRightCol;
00172 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_right;
00173 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_bottom;
00174 }
00175
00176 else
00177 {
00178 myBuff[d_bufferPos].vertex[0] = quad.position.d_right;
00179 myBuff[d_bufferPos].vertex[1] = quad.position.d_top;
00180 myBuff[d_bufferPos].vertex[2] = quad.z;
00181 myBuff[d_bufferPos].color = quad.topRightCol;
00182 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_right;
00183 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_top;
00184 }
00185 ++d_bufferPos;
00186
00187
00188 myBuff[d_bufferPos].vertex[0] = quad.position.d_right;
00189 myBuff[d_bufferPos].vertex[1] = quad.position.d_top;
00190 myBuff[d_bufferPos].vertex[2] = quad.z;
00191 myBuff[d_bufferPos].color = quad.topRightCol;
00192 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_right;
00193 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_top;
00194 ++d_bufferPos;
00195
00196
00197
00198
00199 if (quad.splitMode == TopLeftToBottomRight)
00200 {
00201 myBuff[d_bufferPos].vertex[0] = quad.position.d_left;
00202 myBuff[d_bufferPos].vertex[1] = quad.position.d_top;
00203 myBuff[d_bufferPos].vertex[2] = quad.z;
00204 myBuff[d_bufferPos].color = quad.topLeftCol;
00205 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_left;
00206 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_top;
00207 }
00208
00209 else
00210 {
00211 myBuff[d_bufferPos].vertex[0] = quad.position.d_left;
00212 myBuff[d_bufferPos].vertex[1] = quad.position.d_bottom;
00213 myBuff[d_bufferPos].vertex[2] = quad.z;
00214 myBuff[d_bufferPos].color = quad.bottomLeftCol;
00215 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_left;
00216 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_bottom;
00217 }
00218 ++d_bufferPos;
00219
00220
00221 myBuff[d_bufferPos].vertex[0] = quad.position.d_right;
00222 myBuff[d_bufferPos].vertex[1] = quad.position.d_bottom;
00223 myBuff[d_bufferPos].vertex[2] = quad.z;
00224 myBuff[d_bufferPos].color = quad.bottomRightCol;
00225 myBuff[d_bufferPos].tex[0] = quad.texPosition.d_right;
00226 myBuff[d_bufferPos].tex[1] = quad.texPosition.d_bottom;
00227 ++d_bufferPos;
00228
00229 if(d_bufferPos > (VERTEXBUFFER_CAPACITY - VERTEX_PER_QUAD))
00230 {
00231 renderVBuffer();
00232 }
00233
00234 }
00235
00236
00237 renderVBuffer();
00238
00239 exitPerFrameStates();
00240 }
00241
00242
00243
00244
00245
00246 void OpenGLRenderer::clearRenderList(void)
00247 {
00248 d_quadlist.clear();
00249 }
00250
00251
00252
00253
00254
00255 Texture* OpenGLRenderer::createTexture(void)
00256 {
00257 OpenGLTexture* tex = new OpenGLTexture(this);
00258 d_texturelist.push_back(tex);
00259 return tex;
00260 }
00261
00262
00263
00264
00265
00266 Texture* OpenGLRenderer::createTexture(const String& filename, const String& resourceGroup)
00267 {
00268 OpenGLTexture* tex = (OpenGLTexture*)createTexture();
00269 tex->loadFromFile(filename, resourceGroup);
00270
00271 return tex;
00272 }
00273
00274
00275
00276
00277
00278 Texture* OpenGLRenderer::createTexture(float size)
00279 {
00280 OpenGLTexture* tex = (OpenGLTexture*)createTexture();
00281 tex->setOGLTextureSize((uint)size);
00282
00283 return tex;
00284 }
00285
00286
00287
00288
00289
00290 void OpenGLRenderer::destroyTexture(Texture* texture)
00291 {
00292 if (texture != NULL)
00293 {
00294 OpenGLTexture* tex = (OpenGLTexture*)texture;
00295 d_texturelist.remove(tex);
00296 delete tex;
00297 }
00298
00299 }
00300
00301
00302
00303
00304
00305 void OpenGLRenderer::destroyAllTextures(void)
00306 {
00307 while (!d_texturelist.empty())
00308 {
00309 destroyTexture(*(d_texturelist.begin()));
00310 }
00311 }
00312
00313
00314
00315
00316
00317 void OpenGLRenderer::initPerFrameStates(void)
00318 {
00319
00320 glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
00321 glPushAttrib(GL_ALL_ATTRIB_BITS);
00322
00323 glPolygonMode(GL_FRONT, GL_FILL);
00324 glMatrixMode(GL_PROJECTION);
00325 glPushMatrix();
00326 glLoadIdentity();
00327 gluOrtho2D(0.0, d_display_area.d_right, 0.0, d_display_area.d_bottom);
00328
00329 glMatrixMode(GL_MODELVIEW);
00330 glPushMatrix();
00331 glLoadIdentity();
00332
00333 glDisable(GL_LIGHTING);
00334 glDisable(GL_DEPTH_TEST);
00335
00336 glEnable(GL_BLEND);
00337 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00338
00339 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00340 glEnable(GL_TEXTURE_2D);
00341 }
00342
00343
00344 void OpenGLRenderer::exitPerFrameStates(void)
00345 {
00346 glDisable(GL_TEXTURE_2D);
00347
00348 glPopMatrix();
00349 glMatrixMode(GL_PROJECTION);
00350 glPopMatrix();
00351 glMatrixMode(GL_MODELVIEW);
00352
00353
00354 glPopClientAttrib();
00355 glPopAttrib();
00356 }
00357
00358
00359
00360
00361
00362 void OpenGLRenderer::renderVBuffer(void)
00363 {
00364
00365 if (d_bufferPos == 0)
00366 {
00367 return;
00368 }
00369
00370
00371 glDrawArrays(GL_TRIANGLES, 0, d_bufferPos);
00372
00373
00374 d_bufferPos = 0;
00375 }
00376
00377
00378
00379
00380
00381 void OpenGLRenderer::sortQuads(void)
00382 {
00383
00384 }
00385
00386
00387
00388
00389
00390 void OpenGLRenderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
00391 {
00392 QuadInfo quad;
00393 quad.position.d_left = dest_rect.d_left;
00394 quad.position.d_right = dest_rect.d_right;
00395 quad.position.d_bottom = d_display_area.d_bottom - dest_rect.d_bottom;
00396 quad.position.d_top = d_display_area.d_bottom - dest_rect.d_top;
00397 quad.texPosition = texture_rect;
00398
00399 quad.topLeftCol = colourToOGL(colours.d_top_left);
00400 quad.topRightCol = colourToOGL(colours.d_top_right);
00401 quad.bottomLeftCol = colourToOGL(colours.d_bottom_left);
00402 quad.bottomRightCol = colourToOGL(colours.d_bottom_right);
00403
00404 MyQuad myquad[VERTEX_PER_QUAD];
00405
00406 initPerFrameStates();
00407 glInterleavedArrays(GL_T2F_C4UB_V3F , 0, myquad);
00408 glBindTexture(GL_TEXTURE_2D, ((OpenGLTexture*)tex)->getOGLTexid());
00409
00410
00411 myquad[0].vertex[0] = quad.position.d_left;
00412 myquad[0].vertex[1] = quad.position.d_top;
00413 myquad[0].vertex[2] = z;
00414 myquad[0].color = quad.topLeftCol;
00415 myquad[0].tex[0] = quad.texPosition.d_left;
00416 myquad[0].tex[1] = quad.texPosition.d_top;
00417
00418
00419 myquad[1].vertex[0] = quad.position.d_left;
00420 myquad[1].vertex[1] = quad.position.d_bottom;
00421 myquad[1].vertex[2] = z;
00422 myquad[1].color = quad.bottomLeftCol;
00423 myquad[1].tex[0] = quad.texPosition.d_left;
00424 myquad[1].tex[1] = quad.texPosition.d_bottom;
00425
00426
00427
00428
00429 if (quad_split_mode == TopLeftToBottomRight)
00430 {
00431 myquad[2].vertex[0] = quad.position.d_right;
00432 myquad[2].vertex[1] = quad.position.d_bottom;
00433 myquad[2].vertex[2] = z;
00434 myquad[2].color = quad.bottomRightCol;
00435 myquad[2].tex[0] = quad.texPosition.d_right;
00436 myquad[2].tex[1] = quad.texPosition.d_bottom;
00437 }
00438
00439 else
00440 {
00441 myquad[2].vertex[0] = quad.position.d_right;
00442 myquad[2].vertex[1] = quad.position.d_top;
00443 myquad[2].vertex[2] = z;
00444 myquad[2].color = quad.topRightCol;
00445 myquad[2].tex[0] = quad.texPosition.d_right;
00446 myquad[2].tex[1] = quad.texPosition.d_top;
00447 }
00448
00449
00450 myquad[3].vertex[0] = quad.position.d_right;
00451 myquad[3].vertex[1] = quad.position.d_top;
00452 myquad[3].vertex[2] = z;
00453 myquad[3].color = quad.topRightCol;
00454 myquad[3].tex[0] = quad.texPosition.d_right;
00455 myquad[3].tex[1] = quad.texPosition.d_top;
00456
00457
00458
00459
00460 if (quad_split_mode == TopLeftToBottomRight)
00461 {
00462 myquad[4].vertex[0] = quad.position.d_left;
00463 myquad[4].vertex[1] = quad.position.d_top;
00464 myquad[4].vertex[2] = z;
00465 myquad[4].color = quad.topLeftCol;
00466 myquad[4].tex[0] = quad.texPosition.d_left;
00467 myquad[4].tex[1] = quad.texPosition.d_top;
00468 }
00469
00470 else
00471 {
00472 myquad[4].vertex[0] = quad.position.d_left;
00473 myquad[4].vertex[1] = quad.position.d_bottom;
00474 myquad[4].vertex[2] = z;
00475 myquad[4].color = quad.bottomLeftCol;
00476 myquad[4].tex[0] = quad.texPosition.d_left;
00477 myquad[4].tex[1] = quad.texPosition.d_bottom;
00478 }
00479
00480
00481 myquad[5].vertex[0] = quad.position.d_right;
00482 myquad[5].vertex[1] = quad.position.d_bottom;
00483 myquad[5].vertex[2] = z;
00484 myquad[5].color = quad.bottomRightCol;
00485 myquad[5].tex[0] = quad.texPosition.d_right;
00486 myquad[5].tex[1] = quad.texPosition.d_bottom;
00487
00488 glDrawArrays(GL_TRIANGLES, 0, 6);
00489
00490 exitPerFrameStates();
00491 }
00492
00493
00494
00495
00496
00497 long OpenGLRenderer::colourToOGL(const colour& col) const
00498 {
00499 ulong cval;
00500 cval = (static_cast<ulong>(255 * col.getAlpha())) << 24;
00501 cval |= (static_cast<ulong>(255 * col.getBlue())) << 16;
00502 cval |= (static_cast<ulong>(255 * col.getGreen())) << 8;
00503 cval |= (static_cast<ulong>(255 * col.getRed()));
00504
00505 return cval;
00506 }
00507
00508 }
00509