Stellarium 0.12.4
StelQGL1Renderer.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2012 Ferdinand Majerech
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  */
19 
20 #ifndef _STELQGL1RENDERER_HPP_
21 #define _STELQGL1RENDERER_HPP_
22 
23 
24 #include <QVector>
25 
26 #include "StelApp.hpp"
27 #include "StelCore.hpp"
28 #include "StelQGLRenderer.hpp"
29 #include "StelProjector.hpp"
30 #include "StelProjectorClasses.hpp"
31 #include "StelQGL1InterleavedArrayVertexBufferBackend.hpp"
32 
33 
50 {
51 public:
55  StelQGL1Renderer(QGraphicsView* parent)
56  : StelQGLRenderer(parent, false)
57  , initialized(false)
58  {
59  }
60 
61  virtual ~StelQGL1Renderer()
62  {
63  // Can't check the invariant here, as the renderer will be destroyed even
64  // if it's initialization has failed.
65 
66  initialized = false;
67  }
68 
69  virtual bool init()
70  {
71  Q_ASSERT_X(!initialized, Q_FUNC_INFO,
72  "StelQGL1Renderer is already initialized");
73 
74  // Using this instead of makeGLContextCurrent() to avoid invariant
75  // as we're not in valid state (getGLContext() isn't public - it doesn't call invariant)
76  getGLContext()->makeCurrent();
77 
79  {
80  qWarning() << "StelQGL1Renderer::init : parent init failed";
81  return false;
82  }
83 
84  initialized = true;
85  invariant();
86  return true;
87  }
88 
89  virtual bool areFloatTexturesSupported() const {return false;}
90 
91  virtual bool areNonPowerOfTwoTexturesSupported() const {return false;}
92 
94  {
95  // GL1 doesn't support shaders.
96  return NULL;
97  }
98 
99  virtual bool isGLSLSupported() const {return false;}
100 
101 protected:
103  (const PrimitiveType primitiveType, const QVector<StelVertexAttribute>& attributes)
104  {
105  invariant();
106  statistics[VERTEX_BUFFERS_CREATED] += 1.0;
107  return new StelQGL1InterleavedArrayVertexBufferBackend(primitiveType, attributes);
108  }
109 
111  StelIndexBuffer* indexBuffer = NULL,
112  StelProjector* projector = NULL,
113  bool dontProject = false)
114  {
115  invariant();
116 
118  dynamic_cast<StelQGL1InterleavedArrayVertexBufferBackend*>(vertexBuffer);
119  Q_ASSERT_X(backend != NULL, Q_FUNC_INFO,
120  "StelQGL1Renderer: Vertex buffer created by different renderer backend "
121  "or uninitialized");
122 
123  StelQGLIndexBuffer* glIndexBuffer = NULL;
124  if(indexBuffer != NULL)
125  {
126  glIndexBuffer = dynamic_cast<StelQGLIndexBuffer*>(indexBuffer);
127  Q_ASSERT_X(glIndexBuffer != NULL, Q_FUNC_INFO,
128  "StelQGL1Renderer: Index buffer created by different renderer "
129  "backend or uninitialized");
130  if(indexBuffer->length() == 0)
131  {
132  statistics[EMPTY_BATCHES] += 1.0;
133  return;
134  }
135  }
136  else if(backend->length() == 0)
137  {
138  statistics[EMPTY_BATCHES] += 1.0;
139  return;
140  }
141 
142  // Save openGL projection state
143  glMatrixMode(GL_TEXTURE);
144  glPushMatrix();
145  glMatrixMode(GL_PROJECTION);
146  glPushMatrix();
147  glMatrixMode(GL_MODELVIEW);
148  glPushMatrix();
149  glLoadIdentity();
150 
151  glDisable(GL_LIGHTING);
152  glDisable(GL_MULTISAMPLE);
153  glDisable(GL_DITHER);
154  glDisable(GL_ALPHA_TEST);
155  glEnable(GL_LINE_SMOOTH);
156 
157  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
158  glShadeModel(GL_SMOOTH);
159 
160  // We need a shared pointer when we're getting the projector ourselves (the 2D case),
161  // to prevent destructor of returned shared pointer from destroying it
162  // before we can use it.
163  StelProjectorP projector2DDummy =
164  (NULL != projector ? StelProjectorP(NULL)
165  : StelApp::getInstance().getCore()->getProjection2d());
166 
167  projector = (NULL != projector ? projector : &(*(projector2DDummy)));
168  // XXX: we should use a more generic way to test whether or not to do the projection.
169  if(!dontProject && (NULL == dynamic_cast<StelProjector2d*>(projector)))
170  {
171  backend->projectVertices(projector, glIndexBuffer);
172  statistics[BATCH_PROJECTIONS_CPU_TOTAL] += 1.0;
173  statistics[BATCH_PROJECTIONS_CPU] += 1.0;
174  }
175  else
176  {
177  statistics[BATCH_PROJECTIONS_NONE_TOTAL] += 1.0;
178  statistics[BATCH_PROJECTIONS_NONE] += 1.0;
179  }
180 
181  // Instead of setting GL state when functions such as setDepthTest() or setCulledFaces()
182  // are called, we only set it before drawing and reset after drawing to avoid
183  setupGLState(projector);
184 
185 
186  // Set up viewport for the projector.
187  const Vec4i viewXywh = projector->getViewportXywh();
188  glViewport(viewXywh[0], viewXywh[1], viewXywh[2], viewXywh[3]);
189  updateDrawStatistics(backend, glIndexBuffer);
190  backend->draw(*this, projector->getProjectionMatrix(), glIndexBuffer);
191 
192  // Restore default state to avoid interfering with Qt OpenGL drawing.
193  restoreGLState(projector);
194 
195  // Restore openGL projection state for Qt drawings
196  glMatrixMode(GL_TEXTURE);
197  glPopMatrix();
198  glMatrixMode(GL_PROJECTION);
199  glPopMatrix();
200  glMatrixMode(GL_MODELVIEW);
201  glPopMatrix();
202 
203  invariant();
204  }
205 
207  {
208  // Called at initialization, so can't call invariant
209  if(!gl.hasOpenGLFeature(QGLFunctions::Multitexture))
210  {
211  return 1;
212  }
213  int textureUnitCount;
214  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &textureUnitCount);
215  return std::max(textureUnitCount, STELQGLRENDERER_MAX_TEXTURE_UNITS);
216  }
217 
218 #ifndef NDEBUG
219  virtual void invariant() const
220  {
221  Q_ASSERT_X(initialized, Q_FUNC_INFO, "uninitialized StelQGL1Renderer");
223  }
224 #endif
225 
226 private:
228  bool initialized;
229 };
230 
231 #endif // _STELQGL1RENDERER_HPP_
232