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