20 #ifndef _STELQGLRENDERER_HPP_
21 #define _STELQGLRENDERER_HPP_
26 #include <QGLFunctions>
27 #include <QGraphicsView>
31 #include "GenericVertexTypes.hpp"
32 #include "StelApp.hpp"
33 #include "StelGuiBase.hpp"
34 #include "StelUtils.hpp"
36 #include "StelRenderer.hpp"
37 #include "StelQGLArrayVertexBufferBackend.hpp"
38 #include "StelQGLIndexBuffer.hpp"
39 #include "StelQGLTextureBackend.hpp"
40 #include "StelQGLViewport.hpp"
41 #include "StelTextureCache.hpp"
42 #include "StelVertexBuffer.hpp"
45 #define STELQGLRENDERER_MAX_TEXTURE_UNITS 64
52 enum QGLRendererStatistics
54 ESTIMATED_TEXTURE_MEMORY = 0,
68 BATCH_PROJECTIONS_NONE_TOTAL = 14,
69 BATCH_PROJECTIONS_NONE = 15,
70 BATCH_PROJECTIONS_CPU_TOTAL = 16,
71 BATCH_PROJECTIONS_CPU = 17,
72 BATCH_PROJECTIONS_GPU_TOTAL = 18,
73 BATCH_PROJECTIONS_GPU = 19,
74 VERTEX_BUFFERS_CREATED = 20,
75 INDEX_BUFFERS_CREATED = 21,
76 TEXTURES_CREATED = 22,
93 , glContext(new QGLContext(QGLFormat(QGL::StencilBuffer |
97 , pvrSupported(pvrSupported)
101 , textTextureCache(16777216)
103 , plainRectBuffer(NULL)
104 , texturedRectBuffer(NULL)
105 , previousFrameEndTime(-1.0)
106 , globalColor(Qt::white)
107 , depthTest(DepthTest_Disabled)
108 , stencilTest(StencilTest_Disabled)
109 , blendMode(BlendMode_None)
110 , culledFaces(CullFace_None)
111 , placeholderTexture(NULL)
112 , currentFontSet(false)
113 , textureUnitCount(-1)
116 loaderThread =
new QThread();
117 loaderThread->start(QThread::LowestPriority);
118 for(
int t = 0; t < STELQGLRENDERER_MAX_TEXTURE_UNITS; ++t)
120 currentlyBoundTextures[t] = NULL;
127 loaderThread->quit();
129 if(NULL != placeholderTexture)
131 delete placeholderTexture;
132 placeholderTexture = NULL;
134 textTextureCache.clear();
135 if(NULL != textBuffer)
140 if(NULL != texturedRectBuffer)
142 delete texturedRectBuffer;
143 texturedRectBuffer = NULL;
145 if(NULL != plainRectBuffer)
147 delete plainRectBuffer;
148 plainRectBuffer = NULL;
158 loaderThread->wait();
166 glContext->makeCurrent();
168 glVendorString = QString(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
170 glRendererString = QString(reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
172 viewport.
init(
gl.hasOpenGLFeature(QGLFunctions::NPOTTextures),
211 currentFontSet =
true;
223 for(
int t = 0; t < STELQGLRENDERER_MAX_TEXTURE_UNITS; ++t)
225 if(currentlyBoundTextures[t] == textureBackend)
227 currentlyBoundTextures[t] = NULL;
228 gl.glActiveTexture(GL_TEXTURE0 + t);
229 glBindTexture(GL_TEXTURE_2D, 0);
243 culledFaces = cullFace;
263 glDepthMask(GL_TRUE);
264 glClear(GL_DEPTH_BUFFER_BIT);
265 glDepthMask(GL_FALSE);
276 glClear(GL_STENCIL_BUFFER_BIT);
282 glContext->swapBuffers();
286 virtual void drawRect(
const float x,
const float y,
287 const float width,
const float height,
288 const float angle = 0.0f);
291 const float width,
const float height,
292 const float angle = 0.0f);
303 if(Q_UNLIKELY(QGLContext::currentContext() != glContext))
307 glContext->makeCurrent();
358 (
const QString& filename,
const TextureParams& params,
const TextureLoadingMode loadingMode);
364 (
const void* data,
const QSize size,
const TextureDataFormat format,
382 Q_ASSERT_X(NULL != glContext, Q_FUNC_INFO,
383 "An attempt to use a destroyed StelQGLRenderer.");
384 Q_ASSERT_X(glContext->isValid(), Q_FUNC_INFO,
"The GL context is invalid");
405 glStencilMask(0x11111111);
414 glBlendFunc(GL_ONE, GL_ONE);
417 case BlendMode_Alpha:
418 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
421 case BlendMode_Multiply:
422 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
426 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown blend mode");
431 case DepthTest_Disabled:
432 glDisable(GL_DEPTH_TEST);
434 case DepthTest_ReadOnly:
435 glEnable(GL_DEPTH_TEST);
436 glDepthMask(GL_FALSE);
438 case DepthTest_ReadWrite:
439 glEnable(GL_DEPTH_TEST);
440 glDepthMask(GL_TRUE);
443 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown depth test mode");
448 case StencilTest_Disabled:
449 glDisable(GL_STENCIL_TEST);
451 case StencilTest_Write_1:
452 glStencilFunc(GL_ALWAYS, 0x1, 0x1);
453 glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE);
454 glEnable(GL_STENCIL_TEST);
456 case StencilTest_DrawIf_1:
457 glEnable(GL_STENCIL_TEST);
458 glStencilFunc(GL_EQUAL, 0x1, 0x1);
459 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
462 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown stencil test mode");
468 glDisable(GL_CULL_FACE);
471 glEnable(GL_CULL_FACE);
472 glCullFace(GL_FRONT);
475 glEnable(GL_CULL_FACE);
478 default: Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown cull face type");
490 glDisable(GL_CULL_FACE);
491 glDisable(GL_DEPTH_TEST);
492 glDisable(GL_STENCIL_TEST);
497 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
505 template<
class VBufferBackend>
513 (NULL == indexBuffer ? vertexBuffer->
length() : indexBuffer->
length());
517 switch(vertexBuffer->getPrimitiveType())
519 case PrimitiveType_Points:
521 case PrimitiveType_Triangles:
522 triangles = vertices / 3;
524 case PrimitiveType_TriangleStrip:
525 case PrimitiveType_TriangleFan:
526 triangles = vertices >= 3 ? vertices - 2 : 0;
528 case PrimitiveType_Lines:
529 lines = vertices / 2;
531 case PrimitiveType_LineStrip:
532 lines = vertices >= 2 ? vertices - 1 : 0;
534 case PrimitiveType_LineLoop:
538 Q_ASSERT_X(
false, Q_FUNC_INFO,
"Unknown graphics primitive type");
553 struct FrameTimeQueue
560 memset(frames,
'\0', FRAME_CAPACITY *
sizeof(
long double));
569 nextFrame = nextFrame % FRAME_CAPACITY;
575 const long double newest = frames[(nextFrame - 1 + 256) % FRAME_CAPACITY];
576 long double oldest = frames[nextFrame];
577 Q_ASSERT_X(newest >= oldest, Q_FUNC_INFO,
578 "Oldest frame time is more recent than newest");
581 while(newest - oldest > 1.0 && tooOldCount < FRAME_CAPACITY - 1)
584 oldest = frames[(nextFrame + tooOldCount) % FRAME_CAPACITY];
586 return (FRAME_CAPACITY - tooOldCount) / (newest - oldest);
594 static const int FRAME_CAPACITY = 128;
597 long double frames[FRAME_CAPACITY];
601 QGLContext* glContext;
610 QThread* loaderThread;
621 QCache<QByteArray, StelQGLTextureBackend> textTextureCache;
624 struct TexturedVertex
628 TexturedVertex(
const Vec2f& position,
const Vec2f& texCoord)
629 : position(position), texCoord(texCoord){}
646 double previousFrameEndTime;
661 StencilTest stencilTest;
667 CullFace culledFaces;
685 int textureUnitCount;
688 FrameTimeQueue recentFrames;
694 void initStatistics()
731 void clearFrameStatistics()
747 void drawTextGravityHelper
753 if(NULL != placeholderTexture) {
return placeholderTexture;}
759 const int placeholderSize = 512;
760 const int cellSize = 16;
761 QImage image(placeholderSize, placeholderSize, QImage::Format_RGB888);
762 for(
int y = 0; y < placeholderSize; ++y)
764 for (
int x = 0; x < placeholderSize; x++)
766 image.setPixel(x, y, (x / cellSize) % 2 == (y / cellSize) % 2 ? 0 : color);
772 return placeholderTexture;
789 void drawRectInternal(
const bool textured,
const float x,
const float y,
790 const float width,
const float height,
const float angle);
798 #endif // _STELQGLRENDERER_HPP_