• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 11389946634

17 Oct 2024 05:25PM UTC coverage: 12.068% (-0.008%) from 12.076%
11389946634

push

github

10110111
Rewrite spheric mirror to make it more efficient

The old version rewrote VBO about 150×3 times per frame, which is very
inefficient, especially given that the data written never change.
This version writes these constant data once in the constructor of the
distorter and uses them on rendering.

Fixes #3535

0 of 99 new or added lines in 1 file covered. (0.0%)

4 existing lines in 1 file now uncovered.

14434 of 119607 relevant lines covered (12.07%)

15301.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/core/StelViewportEffect.cpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2010 Fabien Chereau
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
#include "StelViewportEffect.hpp"
21
#include "StelApp.hpp"
22
#include "StelCore.hpp"
23
#include "StelPainter.hpp"
24
#include "SphericMirrorCalculator.hpp"
25
#include "StelFileMgr.hpp"
26
#include "StelMovementMgr.hpp"
27
#include "StelUtils.hpp"
28

29
#include <QOpenGLFramebufferObject>
30
#include <QSettings>
31
#include <QFile>
32
#include <QDir>
33

34
namespace
35
{
36
constexpr int SPHERIC_MIRROR_COORDS_PER_VERTEX = 2;
37
constexpr int SPHERIC_MIRROR_COORDS_PER_COLOR = 4;
38
constexpr int SPHERIC_MIRROR_COORDS_PER_TEXCOORD = 2;
39
enum
40
{
41
        VERTEX_ATTRIB_INDEX,
42
        COLOR_ATTRIB_INDEX,
43
        TEXCOORD_ATTRIB_INDEX,
44
};
45
}
46

UNCOV
47
void StelViewportEffect::paintViewportBuffer(const QOpenGLFramebufferObject* buf) const
×
48
{
49
        StelPainter sPainter(StelApp::getInstance().getCore()->getProjection2d());
×
50
        sPainter.setColor(1,1,1);
×
51
        sPainter.glFuncs()->glBindTexture(GL_TEXTURE_2D, buf->texture());
×
52
        sPainter.drawRect2d(0, 0, buf->size().width(), buf->size().height());
×
53
}
×
54

55
struct VertexPoint
56
{
57
        Vec2f ver_xy;
58
        Vec4f color;
59
        double h;
60
};
61

62
StelViewportDistorterFisheyeToSphericMirror::StelViewportDistorterFisheyeToSphericMirror(int screen_w,int screen_h)
×
63
        : screen_w(screen_w)
×
64
        , screen_h(screen_h)
×
65
        , originalProjectorParams(StelApp::getInstance().getCore()->getCurrentStelProjectorParams())
×
66
        , texture_point_array(Q_NULLPTR)
×
NEW
67
        , vao(new QOpenGLVertexArrayObject)
×
NEW
68
        , verticesVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer))
×
69
{
70
        QSettings& conf = *StelApp::getInstance().getSettings();
×
71
        StelCore* core = StelApp::getInstance().getCore();
×
72
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
73
        screen_h *= params.devicePixelsPerPixel;
×
74
        screen_w *= params.devicePixelsPerPixel;
×
75
        // initialize viewport parameters and texture size:
76

77
        // maximum FOV value of the not yet distorted image
78
        double distorter_max_fov = conf.value("spheric_mirror/distorter_max_fov",175.).toDouble();
×
79
        if (distorter_max_fov > 240.)
×
80
                distorter_max_fov = 240.;
×
81
        else if (distorter_max_fov < 120.)
×
82
                distorter_max_fov = 120.;
×
83
        if (distorter_max_fov > core->getMovementMgr()->getMaxFov())
×
84
                distorter_max_fov = core->getMovementMgr()->getMaxFov();
×
85

86
        StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
87
        core->getMovementMgr()->setMaxFov(distorter_max_fov);
×
88

89
        // width of the not yet distorted image
90
        newProjectorParams.devicePixelsPerPixel = 1;
×
91
        newProjectorParams.viewportXywh[2] = conf.value("spheric_mirror/newProjectorParams.viewportXywhWidth", originalProjectorParams.viewportXywh[2] * params.devicePixelsPerPixel).toInt();
×
92
        if (newProjectorParams.viewportXywh[2] <= 0)
×
93
        {
94
                newProjectorParams.viewportXywh[2] = qRound(originalProjectorParams.viewportXywh[2] * params.devicePixelsPerPixel);
×
95
        }
96
        else if (newProjectorParams.viewportXywh[2] > screen_w)
×
97
        {
98
                newProjectorParams.viewportXywh[2] = screen_w;
×
99
        }
100

101
        // height of the not yet distorted image
102
        newProjectorParams.viewportXywh[3] = conf.value("spheric_mirror/newProjectorParams.viewportXywhHeight", originalProjectorParams.viewportXywh[3] * params.devicePixelsPerPixel).toInt();
×
103
        if (newProjectorParams.viewportXywh[3] <= 0)
×
104
        {
105
                newProjectorParams.viewportXywh[3] = qRound(originalProjectorParams.viewportXywh[3] * params.devicePixelsPerPixel);
×
106
        }
107
        else if (newProjectorParams.viewportXywh[3] > screen_h)
×
108
        {
109
                newProjectorParams.viewportXywh[3] = screen_h;
×
110
        }
111

112
        // center of the FOV-disk in the not yet distorted image
113
        newProjectorParams.viewportCenter[0] = conf.value("spheric_mirror/viewportCenterX", 0.5*newProjectorParams.viewportXywh[2]).toDouble();
×
114
        newProjectorParams.viewportCenter[1] = conf.value("spheric_mirror/viewportCenterY", 0.5*newProjectorParams.viewportXywh[3]).toDouble();
×
115

116
        // diameter of the FOV-disk in pixels
117
        newProjectorParams.viewportFovDiameter = conf.value("spheric_mirror/viewport_fov_diameter", qMin(newProjectorParams.viewportXywh[2],newProjectorParams.viewportXywh[3])).toDouble();
×
118

119
        viewport_texture_offset[0] = (screen_w-newProjectorParams.viewportXywh[2])>>1;
×
120
        viewport_texture_offset[1] = (screen_h-newProjectorParams.viewportXywh[3])>>1;
×
121

122
        newProjectorParams.viewportXywh[0] = (screen_w-newProjectorParams.viewportXywh[2]) >> 1;
×
123
        newProjectorParams.viewportXywh[1] = (screen_h-newProjectorParams.viewportXywh[3]) >> 1;
×
124

125
        core->setCurrentStelProjectorParams(newProjectorParams);
×
126

127
        // init transformation
128
        VertexPoint *vertex_point_array = Q_NULLPTR;
×
129
        const QString custom_distortion_file = conf.value("spheric_mirror/custom_distortion_file","").toString();
×
130
        if (custom_distortion_file.isEmpty()) {
×
131
                float texture_triangle_base_length = conf.value("spheric_mirror/texture_triangle_base_length",16.f).toFloat();
×
132
                if (texture_triangle_base_length > 256.f) {
×
133
                        texture_triangle_base_length = 256.f;
×
134
                } else if (texture_triangle_base_length < 2.f) {
×
135
                        texture_triangle_base_length = 2.f;
×
136
                }
137
                max_x = static_cast<int>(StelUtils::trunc(0.5f + static_cast<float>(screen_w)/texture_triangle_base_length));
×
138
                step_x = screen_w / static_cast<float>(max_x-0.5);
×
139
                max_y = static_cast<int>(StelUtils::trunc(screen_h/(texture_triangle_base_length*0.5f*std::sqrt(3.0f))));
×
140
                step_y = screen_h/ static_cast<float>(max_y);
×
141

142
                double gamma = qMax(0.0, conf.value("spheric_mirror/projector_gamma",0.45).toDouble());
×
143

144
                const float view_scaling_factor = 0.5f * static_cast<float>(newProjectorParams.viewportFovDiameter) / prj->fovToViewScalingFactor(static_cast<float>(distorter_max_fov*(M_PI/360.0)));
×
145
                texture_point_array = new Vec2f[static_cast<size_t>((max_x+1)*(max_y+1))];
×
146
                vertex_point_array = new VertexPoint[static_cast<size_t>((max_x+1)*(max_y+1))];
×
147
                double max_h = 0;
×
148
                SphericMirrorCalculator calc(conf);
×
149
                for (int j=0;j<=max_y;j++) {
×
150
                        for (int i=0;i<=max_x;i++) {
×
151
                                VertexPoint &vertex_point(vertex_point_array[(j*(max_x+1)+i)]);
×
152
                                Vec2f &texture_point(texture_point_array[(j*(max_x+1)+i)]);
×
153
                                vertex_point.ver_xy[0] = ((i == 0) ? 0.f : (i == max_x) ? screen_w : (i-0.5f*(j&1))*step_x);
×
154
                                vertex_point.ver_xy[1] = j*step_y;
×
155
                                Vec3f v,vX,vY;
×
156
                                bool rc = calc.retransform(
×
157
                                                          (vertex_point.ver_xy[0]-0.5f*screen_w) / screen_h,
×
158
                                                          (vertex_point.ver_xy[1]-0.5f*screen_h) / screen_h, v,vX,vY);
×
159
                                rc &= prj->forward(v);
×
160
                                const float x = static_cast<float>(newProjectorParams.viewportCenter[0]) + v[0] * view_scaling_factor;
×
161
                                const float y = static_cast<float>(newProjectorParams.viewportCenter[1]) + v[1] * view_scaling_factor;
×
162
                                vertex_point.h = rc ? static_cast<double>((vX^vY).norm()) : 0.0;
×
163

164
                                // sharp image up to the border of the fisheye image, at the cost of
165
                                // accepting clamping artefacts. You can get rid of the clamping
166
                                // artefacts by specifying a viewport size a little less then
167
                                // (1<<n)*(1<<n), for instance 1022*1022. With a viewport size
168
                                // of 512*512 and viewportFovDiameter=512 you will get clamping
169
                                // artefacts in the 3 otherwise black hills on the bottom of the image.
170

171
                                //      if (x < 0.f) {x=0.f;vertex_point.h=0;}
172
                                //      else if (x > newProjectorParams.viewportXywh[2]) {x=newProjectorParams.viewportXywh[2];vertex_point.h=0;}
173
                                //      if (y < 0.f) {y=0.f;vertex_point.h=0;}
174
                                //      else if (y > newProjectorParams.viewportXywh[3]) {y=newProjectorParams.viewportXywh[3];vertex_point.h=0;}
175

176
                                texture_point[0] = (viewport_texture_offset[0]+x)/screen_w;
×
177
                                texture_point[1] = (viewport_texture_offset[1]+y)/screen_h;
×
178

179
                                if (vertex_point.h > max_h) max_h = vertex_point.h;
×
180
                        }
181
                }
182
                for (int j=0;j<=max_y;j++) {
×
183
                        for (int i=0;i<=max_x;i++) {
×
184
                                VertexPoint &vertex_point(vertex_point_array[(j*(max_x+1)+i)]);
×
185
                                vertex_point.color[0] = vertex_point.color[1] = vertex_point.color[2] =
×
186
                                        (vertex_point.h<=0.0) ? 0.0f : static_cast<float>(exp(gamma*log(vertex_point.h/max_h)));
×
187
                                vertex_point.color[3] = 1.0f;
×
188
                        }
189
                }
190
        } else {
191
                QFile file;
×
192
                QTextStream in;
×
193
                QString fName = StelFileMgr::findFile(custom_distortion_file);
×
194
                if (fName.isEmpty()) {
×
195
                        qWarning() << "WARNING: could not open custom_distortion_file:" << custom_distortion_file;
×
196
                } else {
197
                        file.setFileName(fName);
×
198
                        if(file.open(QIODevice::ReadOnly))
×
199
                                in.setDevice(&file);
×
200
                        else
201
                                qWarning() << "WARNING: could not open custom_distortion_file:" << custom_distortion_file;
×
202
                }
203
                Q_ASSERT(file.error()!=QFile::NoError);
×
204
                in >> max_x >> max_y;
×
205
                Q_ASSERT(in.status()==QTextStream::Ok && max_x>0 && max_y>0);
×
206
                step_x = screen_w / (static_cast<float>(max_x)-0.5f);
×
207
                step_y = screen_h / static_cast<float>(max_y);
×
208
                texture_point_array = new Vec2f[static_cast<size_t>((max_x+1)*(max_y+1))];
×
209
                vertex_point_array = new VertexPoint[static_cast<size_t>((max_x+1)*(max_y+1))];
×
210
                for (int j=0;j<=max_y;j++)
×
211
                {
212
                        for (int i=0;i<=max_x;i++)
×
213
                        {
214
                                VertexPoint &vertex_point(vertex_point_array[(j*(max_x+1)+i)]);
×
215
                                Vec2f &texture_point(texture_point_array[(j*(max_x+1)+i)]);
×
216
                                vertex_point.ver_xy[0] = ((i == 0) ? 0.f : (i == max_x) ? screen_w : (i-0.5f*(j&1))*step_x);
×
217
                                vertex_point.ver_xy[1] = static_cast<float>(j*step_y);
×
218
                                float x,y;
219
                                in >> x >> y >> vertex_point.color[0] >> vertex_point.color[1] >> vertex_point.color[2];
×
220
                                vertex_point.color[3] = 1.0f;
×
221
                                Q_ASSERT(in.status()!=QTextStream::Ok);
×
222
                                texture_point[0] = (viewport_texture_offset[0]+x)/screen_w;
×
223
                                texture_point[1] = (viewport_texture_offset[1]+y)/screen_h;
×
224
                        }
225
                }
226
        }
×
227

228
        // initialize the display list
229
        displayVertexList.clear();
×
230
        for (int j=0;j<max_y;j++)
×
231
        {
232
                const Vec2f *t0 = texture_point_array + j*(max_x+1);
×
233
                const Vec2f *t1 = t0;
×
234
                const VertexPoint *v0 = vertex_point_array + j*(max_x+1);
×
235
                const VertexPoint *v1 = v0;
×
236
                if (j&1)
×
237
                {
238
                        t1 += (max_x+1);
×
239
                        v1 += (max_x+1);
×
240
                }
241
                else
242
                {
243
                        t0 += (max_x+1);
×
244
                        v0 += (max_x+1);
×
245
                }
246
                for (int i=0;i<=max_x;i++,t0++,t1++,v0++,v1++)
×
247
                {
248
                        displayColorList << v0->color << v1->color;
×
249
                        displayTexCoordList << *t0 << *t1;
×
250
                        displayVertexList << v0->ver_xy << v1->ver_xy;
×
251
                }
252
        }
253
        delete[] vertex_point_array;
×
254

NEW
255
        StelApp::getInstance().ensureGLContextCurrent();
×
NEW
256
        setupBuffers();
×
NEW
257
        setupShaders();
×
NEW
258
}
×
259

NEW
260
void StelViewportDistorterFisheyeToSphericMirror::setupShaders()
×
261
{
NEW
262
        QOpenGLShader vsh(QOpenGLShader::Vertex);
×
263
        const auto vsrc =
NEW
264
                StelOpenGL::globalShaderPrefix(StelOpenGL::VERTEX_SHADER) +
×
265
                "ATTRIBUTE highp vec3 vertex;\n"
266
                "ATTRIBUTE mediump vec2 texCoord;\n"
267
                "ATTRIBUTE mediump vec4 color;\n"
268
                "uniform mediump mat4 projectionMatrix;\n"
269
                "VARYING mediump vec2 texc;\n"
270
                "VARYING mediump vec4 outColor;\n"
271
                "void main()\n"
272
                "{\n"
273
                "    gl_Position = projectionMatrix * vec4(vertex, 1.);\n"
274
                "    texc = texCoord;\n"
275
                "    outColor = color;\n"
NEW
276
                "}\n";
×
NEW
277
        vsh.compileSourceCode(vsrc);
×
NEW
278
        if (!vsh.log().isEmpty())
×
NEW
279
                qWarning().noquote() << "StelViewportDistorterFisheyeToSphericMirror: Warnings while compiling vertex shader: " << vsh.log();
×
280

NEW
281
        QOpenGLShader fsh(QOpenGLShader::Fragment);
×
282
        const auto fsrc =
NEW
283
                StelOpenGL::globalShaderPrefix(StelOpenGL::FRAGMENT_SHADER) +
×
284
                "VARYING mediump vec2 texc;\n"
285
                "VARYING mediump vec4 outColor;\n"
286
                "uniform sampler2D tex;\n"
287
                "void main()\n"
288
                "{\n"
289
                "    FRAG_COLOR = texture2D(tex, texc)*outColor;\n"
NEW
290
                "}\n";
×
NEW
291
        fsh.compileSourceCode(fsrc);
×
NEW
292
        if (!fsh.log().isEmpty())
×
NEW
293
                qWarning().noquote() << "StelViewportDistorterFisheyeToSphericMirror: Warnings while compiling fragment shader: " << fsh.log();
×
294

NEW
295
        shaderProgram.reset(new QOpenGLShaderProgram(QOpenGLContext::currentContext()));
×
NEW
296
        shaderProgram->addShader(&vsh);
×
NEW
297
        shaderProgram->addShader(&fsh);
×
NEW
298
        shaderProgram->bindAttributeLocation("vertex", VERTEX_ATTRIB_INDEX);
×
NEW
299
        shaderProgram->bindAttributeLocation("color", COLOR_ATTRIB_INDEX);
×
NEW
300
        shaderProgram->bindAttributeLocation("texCoord", TEXCOORD_ATTRIB_INDEX);
×
NEW
301
        StelPainter::linkProg(shaderProgram.get(), "spheric mirror distortion shader program");
×
NEW
302
        shaderVars.projectionMatrix = shaderProgram->uniformLocation("projectionMatrix");
×
NEW
303
        shaderVars.texture = shaderProgram->uniformLocation("tex");
×
NEW
304
}
×
305

NEW
306
void StelViewportDistorterFisheyeToSphericMirror::setupBuffers()
×
307
{
NEW
308
        verticesVBO->create();
×
NEW
309
        verticesVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
×
NEW
310
        verticesVBO->bind();
×
NEW
311
        const int colorElemSize = SPHERIC_MIRROR_COORDS_PER_COLOR * sizeof(GLfloat);
×
NEW
312
        const int vertElemSize = SPHERIC_MIRROR_COORDS_PER_VERTEX * sizeof(GLfloat);
×
NEW
313
        const int texCoordElemSize = SPHERIC_MIRROR_COORDS_PER_TEXCOORD * sizeof(GLfloat);
×
NEW
314
        const int numberOfVerticesToCopy = displayVertexList.size();
×
NEW
315
        const auto bufferSize = vertElemSize*numberOfVerticesToCopy +
×
316
                                texCoordElemSize*numberOfVerticesToCopy +
317
                                colorElemSize*numberOfVerticesToCopy;
NEW
318
        verticesVBO->allocate(bufferSize);
×
NEW
319
        vboVertexDataOffset = 0;
×
NEW
320
        const auto vertexDataSize = vertElemSize*numberOfVerticesToCopy;
×
NEW
321
        verticesVBO->write(vboVertexDataOffset, displayVertexList.constData(), vertexDataSize);
×
NEW
322
        vboTexCoordDataOffset = vertexDataSize;
×
NEW
323
        const auto texCoordDataSize = texCoordElemSize*numberOfVerticesToCopy;
×
NEW
324
        verticesVBO->write(vboTexCoordDataOffset, displayTexCoordList.constData(), texCoordDataSize);
×
NEW
325
        vboColorDataOffset = vertexDataSize + texCoordDataSize;
×
NEW
326
        const auto colorDataSize = colorElemSize*numberOfVerticesToCopy;
×
NEW
327
        verticesVBO->write(vboColorDataOffset, displayColorList.constData(), colorDataSize);
×
NEW
328
        verticesVBO->release();
×
329

NEW
330
        vao->create();
×
NEW
331
        bindVAO();
×
NEW
332
        setupCurrentVAO();
×
NEW
333
        releaseVAO();
×
NEW
334
}
×
335

NEW
336
void StelViewportDistorterFisheyeToSphericMirror::setupCurrentVAO() const
×
337
{
NEW
338
        auto& gl = *QOpenGLContext::currentContext()->functions();
×
NEW
339
        verticesVBO->bind();
×
NEW
340
        gl.glVertexAttribPointer(VERTEX_ATTRIB_INDEX, SPHERIC_MIRROR_COORDS_PER_VERTEX, GL_FLOAT,
×
NEW
341
                                 false, 0, reinterpret_cast<const void*>(vboVertexDataOffset));
×
NEW
342
        gl.glVertexAttribPointer(COLOR_ATTRIB_INDEX, SPHERIC_MIRROR_COORDS_PER_COLOR, GL_FLOAT,
×
NEW
343
                                 false, 0, reinterpret_cast<const void*>(vboColorDataOffset));
×
NEW
344
        gl.glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, SPHERIC_MIRROR_COORDS_PER_TEXCOORD, GL_FLOAT,
×
NEW
345
                                 false, 0, reinterpret_cast<const void*>(vboTexCoordDataOffset));
×
NEW
346
        verticesVBO->release();
×
NEW
347
        gl.glEnableVertexAttribArray(VERTEX_ATTRIB_INDEX);
×
NEW
348
        gl.glEnableVertexAttribArray(COLOR_ATTRIB_INDEX);
×
NEW
349
        gl.glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
×
UNCOV
350
}
×
351

NEW
352
void StelViewportDistorterFisheyeToSphericMirror::bindVAO() const
×
353
{
NEW
354
        if(vao->isCreated())
×
NEW
355
                vao->bind();
×
356
        else
NEW
357
                setupCurrentVAO();
×
NEW
358
}
×
359

NEW
360
void StelViewportDistorterFisheyeToSphericMirror::releaseVAO() const
×
361
{
NEW
362
        if(vao->isCreated())
×
363
        {
NEW
364
                vao->release();
×
365
        }
366
        else
367
        {
NEW
368
                auto& gl = *QOpenGLContext::currentContext()->functions();
×
NEW
369
                gl.glDisableVertexAttribArray(VERTEX_ATTRIB_INDEX);
×
NEW
370
                gl.glDisableVertexAttribArray(COLOR_ATTRIB_INDEX);
×
NEW
371
                gl.glDisableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
×
372
        }
NEW
373
}
×
374

375

376
StelViewportDistorterFisheyeToSphericMirror::~StelViewportDistorterFisheyeToSphericMirror(void)
×
377
{
NEW
378
        StelApp::getInstance().ensureGLContextCurrent(); // Make sure that VBO & VAO will be properly deleted
×
379

380
        if (texture_point_array)
×
381
                delete[] texture_point_array;
×
382
        StelApp::getInstance().getCore()->setCurrentStelProjectorParams(originalProjectorParams);
×
383
}
×
384

385

386
void StelViewportDistorterFisheyeToSphericMirror::distortXY(qreal &x, qreal &y) const
×
387
{
388
        float texture_x,texture_y;
389

390
        // Input positions are not scaled, so we do it here
391
        // Since the effect fbo uses pixel coordinates.
392
        x *= originalProjectorParams.devicePixelsPerPixel;
×
393
        y *= originalProjectorParams.devicePixelsPerPixel;
×
394

395
        // find the triangle and interpolate accordingly:
396
        float dy = static_cast<float>(y) / step_y;
×
397
        const int j = static_cast<int>(floorf(dy));
×
398
        dy -= j;
×
399
        if (j&1)
×
400
        {
401
                float dx = static_cast<float>(x) / step_x + 0.5f*(1.f-dy);
×
402
                const int i = static_cast<int>(floorf(dx));
×
403
                dx -= i;
×
404
                const Vec2f *const t = texture_point_array + (j*(max_x+1)+i);
×
405
                if (dx + dy <= 1.f)
×
406
                {
407
                        if (i == 0)
×
408
                        {
409
                                dx -= 0.5f*(1.f-dy);
×
410
                                dx *= 2.f;
×
411
                        }
412
                        texture_x = t[0][0] + dx * (t[1][0]-t[0][0]) + dy * (t[max_x+1][0]-t[0][0]);
×
413
                        texture_y = t[0][1] + dx * (t[1][1]-t[0][1]) + dy * (t[max_x+1][1]-t[0][1]);
×
414
                }
415
                else
416
                {
417
                        if (i == max_x-1)
×
418
                        {
419
                                dx -= 0.5f*(1.f-dy);
×
420
                                dx *= 2.f;
×
421
                        }
422
                        texture_x = t[max_x+2][0] + (1.f-dy) * (t[1][0]-t[max_x+2][0]) + (1.f-dx) * (t[max_x+1][0]-t[max_x+2][0]);
×
423
                        texture_y = t[max_x+2][1] + (1.f-dy) * (t[1][1]-t[max_x+2][1]) + (1.f-dx) * (t[max_x+1][1]-t[max_x+2][1]);
×
424
                }
425
        }
426
        else
427
        {
428
                float dx = static_cast<float>(x) / step_x + 0.5f*dy;
×
429
                const int i = static_cast<int>(floorf(dx));
×
430
                dx -= i;
×
431
                const Vec2f *const t = texture_point_array + (j*(max_x+1)+i);
×
432
                if (dx >= dy)
×
433
                {
434
                        if (i == max_x-1)
×
435
                        {
436
                                dx -= 0.5f*dy;
×
437
                                dx *= 2.f;
×
438
                        }
439
                        texture_x = t[1][0] + (1.f-dx) * (t[0][0]-t[1][0]) + dy * (t[max_x+2][0]-t[1][0]);
×
440
                        texture_y = t[1][1] + (1.f-dx) * (t[0][1]-t[1][1]) + dy * (t[max_x+2][1]-t[1][1]);
×
441
                }
442
                else
443
                {
444
                        if (i == 0)
×
445
                        {
446
                                dx -= 0.5f*dy;
×
447
                                dx *= 2.f;
×
448
                        }
449
                        texture_x = t[max_x+1][0] + (1.f-dy) * (t[0][0]-t[max_x+1][0]) + dx * (t[max_x+2][0]-t[max_x+1][0]);
×
450
                        texture_y = t[max_x+1][1] + (1.f-dy) * (t[0][1]-t[max_x+1][1]) + dx * (t[max_x+2][1]-t[max_x+1][1]);
×
451
                }
452
        }
453

454
        x = static_cast<double>(screen_w*texture_x) - viewport_texture_offset[0] + newProjectorParams.viewportXywh[0];
×
455
        y = static_cast<double>(screen_h*texture_y) - viewport_texture_offset[1] + newProjectorParams.viewportXywh[1];
×
456
}
×
457

458

459
void StelViewportDistorterFisheyeToSphericMirror::paintViewportBuffer(const QOpenGLFramebufferObject* buf) const
×
460
{
NEW
461
        const auto prj = StelApp::getInstance().getCore()->getProjection2d();
×
NEW
462
        auto& gl = *QOpenGLContext::currentContext()->functions();
×
NEW
463
        const int texUnit = 0;
×
NEW
464
        GL(gl.glActiveTexture(GL_TEXTURE0 + texUnit));
×
NEW
465
        GL(gl.glBindTexture(GL_TEXTURE_2D, buf->texture()));
×
NEW
466
        GL(gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
×
NEW
467
        GL(gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
×
468

NEW
469
        shaderProgram->bind();
×
NEW
470
        const Mat4f& m = prj->getProjectionMatrix();
×
NEW
471
        const QMatrix4x4 qMat(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]);
×
NEW
472
        shaderProgram->setUniformValue(shaderVars.projectionMatrix, qMat);
×
NEW
473
        shaderProgram->setUniformValue(shaderVars.texture, texUnit);
×
474

NEW
475
        bindVAO();
×
UNCOV
476
        for (int j=0;j<max_y;j++)
×
477
        {
NEW
478
                GL(gl.glDrawArrays(GL_TRIANGLE_STRIP, j*(max_x+1)*2, (max_x+1)*2));
×
479
        }
NEW
480
        releaseVAO();
×
481

NEW
482
        shaderProgram->release();
×
483

NEW
484
        GL(gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
×
NEW
485
        GL(gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
×
UNCOV
486
}
×
487

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc