Atmosphere.cpp   Atmosphere.cpp 
skipping to change at line 20 skipping to change at line 20
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QSettings>
#include "Atmosphere.hpp" #include "Atmosphere.hpp"
#include "renderer/StelRenderer.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelToneReproducer.hpp" #include "StelToneReproducer.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelPainter.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include <QDebug>
#include <QSettings>
#include <QOpenGLShaderProgram>
inline bool myisnan(double value) inline bool myisnan(double value)
{ {
return value != value; return value != value;
} }
Atmosphere::Atmosphere() Atmosphere::Atmosphere(void)
: viewport(0,0,0,0) : viewport(0,0,0,0)
, skyResolutionY(44)
, skyResolutionX(44)
, posGrid(NULL)
, posGridBuffer(QOpenGLBuffer::VertexBuffer)
, indicesBuffer(QOpenGLBuffer::IndexBuffer)
, colorGrid(NULL)
, colorGridBuffer(QOpenGLBuffer::VertexBuffer)
, averageLuminance(0.f) , averageLuminance(0.f)
, eclipseFactor(1.f) , eclipseFactor(1.f)
, lightPollutionLuminance(0) , lightPollutionLuminance(0)
, shader(NULL)
, vertexGrid(NULL)
, renderer(NULL)
{ {
setFadeDuration(1.5f); setFadeDuration(1.5f);
}
Atmosphere::~Atmosphere(void) QOpenGLShader vShader(QOpenGLShader::Vertex);
{ if (!vShader.compileSourceFile(":/shaders/xyYToRGB.glsl"))
if(NULL != shader) {delete shader;} {
if(NULL != vertexGrid) {delete vertexGrid;} qFatal("Error while compiling atmosphere vertex shader: %s",
foreach(StelIndexBuffer* buffer, rowIndices) vShader.log().toLatin1().constData());
}
if (!vShader.log().isEmpty())
{ {
delete buffer; qWarning() << "Warnings while compiling atmosphere vertex sh ader: " << vShader.log();
} }
QOpenGLShader fShader(QOpenGLShader::Fragment);
if (!fShader.compileSourceCode(
"varying mediump vec3 resultSkyColor
;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(resultSkyCo
lor, 1.);\n"
"}"))
{
qFatal("Error while compiling atmosphere fragment shader: %s
", fShader.log().toLatin1().constData());
}
if (!fShader.log().isEmpty())
{
qWarning() << "Warnings while compiling atmosphere fragment
shader: " << vShader.log();
}
atmoShaderProgram = new QOpenGLShaderProgram();
atmoShaderProgram->addShader(&vShader);
atmoShaderProgram->addShader(&fShader);
StelPainter::linkProg(atmoShaderProgram, "atmosphere");
atmoShaderProgram->bind();
shaderAttribLocations.alphaWaOverAlphaDa = atmoShaderProgram->unifor
mLocation("alphaWaOverAlphaDa");
shaderAttribLocations.oneOverGamma = atmoShaderProgram->uniformLocat
ion("oneOverGamma");
shaderAttribLocations.term2TimesOneOverMaxdLpOneOverGamma = atmoShad
erProgram->uniformLocation("term2TimesOneOverMaxdLpOneOverGamma");
shaderAttribLocations.brightnessScale = atmoShaderProgram->uniformLo
cation("brightnessScale");
shaderAttribLocations.sunPos = atmoShaderProgram->uniformLocation("s
unPos");
shaderAttribLocations.term_x = atmoShaderProgram->uniformLocation("t
erm_x");
shaderAttribLocations.Ax = atmoShaderProgram->uniformLocation("Ax");
shaderAttribLocations.Bx = atmoShaderProgram->uniformLocation("Bx");
shaderAttribLocations.Cx = atmoShaderProgram->uniformLocation("Cx");
shaderAttribLocations.Dx = atmoShaderProgram->uniformLocation("Dx");
shaderAttribLocations.Ex = atmoShaderProgram->uniformLocation("Ex");
shaderAttribLocations.term_y = atmoShaderProgram->uniformLocation("t
erm_y");
shaderAttribLocations.Ay = atmoShaderProgram->uniformLocation("Ay");
shaderAttribLocations.By = atmoShaderProgram->uniformLocation("By");
shaderAttribLocations.Cy = atmoShaderProgram->uniformLocation("Cy");
shaderAttribLocations.Dy = atmoShaderProgram->uniformLocation("Dy");
shaderAttribLocations.Ey = atmoShaderProgram->uniformLocation("Ey");
shaderAttribLocations.projectionMatrix = atmoShaderProgram->uniformL
ocation("projectionMatrix");
shaderAttribLocations.skyVertex = atmoShaderProgram->attributeLocati
on("skyVertex");
shaderAttribLocations.skyColor = atmoShaderProgram->attributeLocatio
n("skyColor");
atmoShaderProgram->release();
} }
void Atmosphere::computeColor Atmosphere::~Atmosphere(void)
(double JD, Vec3d sunPos, Vec3d moonPos, float moonPhase, StelCore*
core, float eclipseFac,
float latitude, float altitude, float temperature, float relativeHu
midity)
{ {
// We lazily initialize vertex buffer at the first draw, delete [] posGrid;
// so we can only call this after that. posGrid = NULL;
// We also need a renderer reference (again lazily from draw()) to delete[] colorGrid;
// construct index buffers as they might change at every call to com colorGrid = NULL;
puteColor(). delete atmoShaderProgram;
if(NULL == renderer) {return;} atmoShaderProgram = NULL;
}
void Atmosphere::computeColor(double JD, Vec3d _sunPos, Vec3d moonPos, floa
t moonPhase,
StelCore* core, f
loat latitude, float altitude, float temperature, float relativeHumidity)
{
const StelProjectorP prj = core->getProjection(StelCore::FrameAltAz, StelCore::RefractionOff); const StelProjectorP prj = core->getProjection(StelCore::FrameAltAz, StelCore::RefractionOff);
if (viewport != prj->getViewport()) if (viewport != prj->getViewport())
{ {
// The viewport changed: update the number of points in the // The viewport changed: update the number of point of the g
grid rid
updateGrid(prj); viewport = prj->getViewport();
delete[] colorGrid;
delete [] posGrid;
skyResolutionY = StelApp::getInstance().getSettings()->value
("landscape/atmosphereybin", 44).toInt();
skyResolutionX = (int)floor(0.5+skyResolutionY*(0.5*sqrt(3.0
))*prj->getViewportWidth()/prj->getViewportHeight());
posGrid = new Vec2f[(1+skyResolutionX)*(1+skyResolutionY)];
colorGrid = new Vec4f[(1+skyResolutionX)*(1+skyResolutionY)]
;
float stepX = (float)prj->getViewportWidth() / (skyResolutio
nX-0.5);
float stepY = (float)prj->getViewportHeight() / skyResolutio
nY;
float viewport_left = (float)prj->getViewportPosX();
float viewport_bottom = (float)prj->getViewportPosY();
for (int x=0; x<=skyResolutionX; ++x)
{
for(int y=0; y<=skyResolutionY; ++y)
{
Vec2f &v(posGrid[y*(1+skyResolutionX)+x]);
v[0] = viewport_left + ((x == 0) ? 0.f :
(x == skyResolutionX) ? (flo
at)prj->getViewportWidth() : (x-0.5*(y&1))*stepX);
v[1] = viewport_bottom+y*stepY;
}
}
posGridBuffer.destroy();
//posGridBuffer = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)
;
Q_ASSERT(posGridBuffer.type()==QOpenGLBuffer::VertexBuffer);
posGridBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
posGridBuffer.create();
posGridBuffer.bind();
posGridBuffer.allocate(posGrid, (1+skyResolutionX)*(1+skyRes
olutionY)*8);
posGridBuffer.release();
// Generate the indices used to draw the quads
unsigned short* indices = new unsigned short[(skyResolutionX
+1)*skyResolutionY*2];
int i=0;
for (int y2=0; y2<skyResolutionY; ++y2)
{
unsigned int g0 = y2*(1+skyResolutionX);
unsigned int g1 = (y2+1)*(1+skyResolutionX);
for (int x2=0; x2<=skyResolutionX; ++x2)
{
indices[i++]=g0++;
indices[i++]=g1++;
}
}
indicesBuffer.destroy();
//indicesBuffer = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
Q_ASSERT(indicesBuffer.type()==QOpenGLBuffer::IndexBuffer);
indicesBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
indicesBuffer.create();
indicesBuffer.bind();
indicesBuffer.allocate(indices, (skyResolutionX+1)*skyResolu
tionY*2*2);
indicesBuffer.release();
delete[] indices;
indices=NULL;
colorGridBuffer.destroy();
colorGridBuffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
colorGridBuffer.create();
colorGridBuffer.bind();
colorGridBuffer.allocate(colorGrid, (1+skyResolutionX)*(1+sk
yResolutionY)*4*4);
colorGridBuffer.release();
} }
eclipseFactor = eclipseFac; if (myisnan(_sunPos.length()))
if(eclipseFac < 0.0001f) _sunPos.set(0.,0.,-1.*AU);
eclipseFactor = 0.0001f; if (myisnan(moonPos.length()))
moonPos.set(0.,0.,-1.*AU);
// Update the eclipse intensity factor to apply on atmosphere model
// these are for radii
const float sun_angular_size = atan(696000.f/AU/_sunPos.length());
const float moon_angular_size = atan(1738.f/AU/moonPos.length());
const float touch_angle = sun_angular_size + moon_angular_size;
// determine luminance falloff during solar eclipses
_sunPos.normalize();
moonPos.normalize();
float separation_angle = std::acos(_sunPos.dot(moonPos)); // angle
between them
// qDebug("touch at %f\tnow at %f (%f)\n", touch_angle, separation_a
ngle, separation_angle/touch_angle);
// bright stars should be visible at total eclipse
// TODO: correct for atmospheric diffusion
// TODO: use better coverage function (non-linear)
// because of above issues, this algorithm darkens more quickly than
reality
if (separation_angle < touch_angle)
{
float dark_angle = moon_angular_size - sun_angular_size;
float min = 0.0001f; // so bright stars show up at total ec
lipse
if (dark_angle < 0.f)
{
// annular eclipse
float asun = sun_angular_size*sun_angular_size;
min = (asun - moon_angular_size*moon_angular_size)/a
sun; // minimum proportion of sun uncovered
dark_angle *= -1;
}
if (separation_angle < dark_angle)
eclipseFactor = min;
else
eclipseFactor = min + (1.f-min)*(separation_angle-da
rk_angle)/(touch_angle-dark_angle);
}
else
eclipseFactor = 1.f;
// No need to calculate if not visible // No need to calculate if not visible
if (!fader.getInterstate()) if (!fader.getInterstate())
{ {
averageLuminance = 0.001f + lightPollutionLuminance; averageLuminance = 0.001f + lightPollutionLuminance;
return; return;
} }
// Calculate the atmosphere RGB for each point of the grid // Calculate the atmosphere RGB for each point of the grid
if (myisnan(sunPos.length())) float sunPos[3];
sunPos.set(0.,0.,-1.*AU); sunPos[0] = _sunPos[0];
if (myisnan(moonPos.length())) sunPos[1] = _sunPos[1];
moonPos.set(0.,0.,-1.*AU); sunPos[2] = _sunPos[2];
sunPos.normalize();
moonPos.normalize();
float sun_pos[3];
sun_pos[0] = sunPos[0];
sun_pos[1] = sunPos[1];
sun_pos[2] = sunPos[2];
float moon_pos[3]; float moon_pos[3];
moon_pos[0] = moonPos[0]; moon_pos[0] = moonPos[0];
moon_pos[1] = moonPos[1]; moon_pos[1] = moonPos[1];
moon_pos[2] = moonPos[2]; moon_pos[2] = moonPos[2];
sky.setParamsv(sun_pos, 5.f); sky.setParamsv(sunPos, 5.f);
skyb.setLocation(latitude * M_PI/180., altitude, temperature, relati veHumidity); skyb.setLocation(latitude * M_PI/180., altitude, temperature, relati veHumidity);
skyb.setSunMoon(moon_pos[2], sun_pos[2]); skyb.setSunMoon(moon_pos[2], sunPos[2]);
// Calculate the date from the julian day. // Calculate the date from the julian day.
int year, month, day; int year, month, day;
StelUtils::getDateFromJulianDay(JD, &year, &month, &day); StelUtils::getDateFromJulianDay(JD, &year, &month, &day);
skyb.setDate(year, month, moonPhase); skyb.setDate(year, month, moonPhase);
// Variables used to compute the average sky luminance // Variables used to compute the average sky luminance
double sum_lum = 0.; float sum_lum = 0.f;
Vec3d point(1., 0., 0.); Vec3d point(1., 0., 0.);
skylightStruct2 b2;
float lumi; float lumi;
vertexGrid->unlock();
// Compute the sky color for every point above the ground // Compute the sky color for every point above the ground
for (int i=0; i<(1+skyResolutionX)*(1+skyResolutionY); ++i) for (int i=0; i<(1+skyResolutionX)*(1+skyResolutionY); ++i)
{ {
const Vec2f position = vertexGrid->getVertex(i).position; const Vec2f &v(posGrid[i]);
prj->unProject(position[0], position[1], point); prj->unProject(v[0],v[1],point);
Q_ASSERT(fabs(point.lengthSquared()-1.0) < 1e-10); Q_ASSERT(fabs(point.lengthSquared()-1.0) < 1e-10);
if (point[2]<=0) if (point[2]<=0)
{ {
point[2] = -point[2]; point[2] = -point[2];
// The sky below the ground is the symmetric of the one above : // The sky below the ground is the symmetric of the one above :
// it looks nice and gives proper values for brightn ess estimation // it looks nice and gives proper values for brightn ess estimation
} }
// Use the Skybright.cpp 's models for brightness which give s better results. // Use the Skybright.cpp 's models for brightness which give s better results.
lumi = skyb.getLuminance(moon_pos[0]*point[0]+moon_pos[1]*po lumi = skyb.getLuminance(moon_pos[0]*point[0]+moon_pos[1]*po
int[1]+moon_pos[2]*point[2], int[1]+
sun_pos[0]* moon_pos[2]*point[2], sunPos[0]*point[0]+sun
point[0]+sun_pos[1]*point[1]+sun_pos[2]*point[2], Pos[1]*point[1]+
point[2]); sunPos[2]*point[2], point[2]);
lumi *= eclipseFactor; lumi *= eclipseFactor;
// Add star background luminance // Add star background luminance
lumi += 0.0001; lumi += 0.0001f;
// Multiply by the input scale of the ToneConverter (is not done automatically by the xyYtoRGB method called later) // Multiply by the input scale of the ToneConverter (is not done automatically by the xyYtoRGB method called later)
//lumi*=eye->getInputScale(); //lumi*=eye->getInputScale();
// Add the light pollution luminance AFTER the scaling to av oid scaling it because it is the cause // Add the light pollution luminance AFTER the scaling to av oid scaling it because it is the cause
// of the scaling itself // of the scaling itself
lumi += lightPollutionLuminance; lumi += lightPollutionLuminance;
// Store for later statistics // Store for later statistics
sum_lum+=lumi; sum_lum+=lumi;
Q_ASSERT_X(NULL != vertexGrid, Q_FUNC_INFO,
"Vertex buffer not initialized when setting color
s");
// Now need to compute the xy part of the color component // Now need to compute the xy part of the color component
// This is done in a GLSL shader if possible // This is done in the openGL shader
if(NULL != shader) // Store the back projected position + luminance in the inpu
{ t color to the shader
// Store the back projected position + luminance in colorGrid[i].set(point[0], point[1], point[2], lumi);
the input color to the shader
const Vec4f color = Vec4f(point[0], point[1], point[
2], lumi);
vertexGrid->setVertex(i, Vertex(position, color));
continue;
}
// Shaderless fallback
if (lumi > 0.01)
{
// Use the Skylight model for the color
b2.pos[0] = point[0];
b2.pos[1] = point[1];
b2.pos[2] = point[2];
sky.getxyYValuev(b2);
}
else
{
// Too dark to see atmosphere color, don't bother co
mputing it
b2.color[0] = 0.25;
b2.color[1] = 0.25;
}
const Vec4f color = Vec4f(b2.color[0], b2.color[1], lumi, 1.
0f);
vertexGrid->setVertex(i, Vertex(position, color));
} }
vertexGrid->lock();
colorGridBuffer.bind();
colorGridBuffer.write(0, colorGrid, (1+skyResolutionX)*(1+skyResolut
ionY)*4*4);
colorGridBuffer.release();
// Update average luminance // Update average luminance
averageLuminance = sum_lum/((1+skyResolutionX)*(1+skyResolutionY)); averageLuminance = sum_lum/((1+skyResolutionX)*(1+skyResolutionY));
} }
void Atmosphere::draw(StelCore* core, StelRenderer* renderer) // Draw the atmosphere using the precalc values stored in tab_sky
void Atmosphere::draw(StelCore* core)
{ {
// Renderer is NULL at first draw call.
// We load the shader, initialize vertex buffer and set the renderer
.
//
// We don't actually draw anything at the first call - computeColor
// must be called to fill the vertex buffer with drawable data.
if(NULL == this->renderer)
{
Q_ASSERT_X(NULL == shader && NULL == vertexGrid && rowIndice
s.size() == 0,
Q_FUNC_INFO, "Shader and/or vertex/index buffer i
nitialized at first draw call");
if(renderer->isGLSLSupported())
{
if(!lazyLoadShader(renderer))
{
qWarning() << "Failed loading atmosphere sha
der. Falling back to CPU code path";
}
}
vertexGrid = renderer->createVertexBuffer<Vertex>(PrimitiveT
ype_TriangleStrip);
this->renderer = renderer;
return;
}
Q_ASSERT_X(NULL != vertexGrid && rowIndices.size() > 0, Q_FUNC_INFO,
"Vertex and/or index buffer not initialized at first draw
call");
Q_ASSERT_X(vertexGrid->length() == (skyResolutionY + 1) * (skyResolu
tionX + 1),
Q_FUNC_INFO, "Vertex grid size doesn't match atmosphere r
esolution");
Q_ASSERT_X(rowIndices.size() == skyResolutionY, Q_FUNC_INFO,
"Number of row index buffers doesn't match atmosphere res
olution");
if (StelApp::getInstance().getVisionModeNight()) if (StelApp::getInstance().getVisionModeNight())
{
return; return;
}
StelToneReproducer* eye = core->getToneReproducer(); StelToneReproducer* eye = core->getToneReproducer();
if (!fader.getInterstate()) if (!fader.getInterstate())
{
return; return;
}
renderer->setBlendMode(BlendMode_Add); StelPainter sPainter(core->getProjection2d());
glBlendFunc(GL_ONE, GL_ONE);
sPainter.enableTexture2d(false);
glEnable(GL_BLEND);
const float atm_intensity = fader.getInterstate(); const float atm_intensity = fader.getInterstate();
if(NULL != shader)
{
shader->bind();
float a, b, c;
eye->getShadersParams(a, b, c);
shader->setUniformValue("alphaWaOverAlphaDa"
, a);
shader->setUniformValue("oneOverGamma"
, b);
shader->setUniformValue("term2TimesOneOverMaxdLpOneOverGamma
" , c);
shader->setUniformValue("brightnessScale"
, atm_intensity);
Vec3f sunPos;
float term_x, Ax, Bx, Cx, Dx, Ex, term_y, Ay, By, Cy, Dy, Ey
;
sky.getShadersParams(sunPos, term_x, Ax, Bx, Cx, Dx, Ex, ter
m_y, Ay, By, Cy, Dy, Ey);
shader->setUniformValue("sunPos" , sunPos);
shader->setUniformValue("term_x" , term_x);
shader->setUniformValue("Ax" , Ax);
shader->setUniformValue("Bx" , Bx);
shader->setUniformValue("Cx" , Cx);
shader->setUniformValue("Dx" , Dx);
shader->setUniformValue("Ex" , Ex);
shader->setUniformValue("term_y" , term_y);
shader->setUniformValue("Ay" , Ay);
shader->setUniformValue("By" , By);
shader->setUniformValue("Cy" , Cy);
shader->setUniformValue("Dy" , Dy);
shader->setUniformValue("Ey" , Ey);
const Mat4f& projectionMatrix = core->getProjection2d()->get
ProjectionMatrix();
shader->setUniformValue("projectionMatrix", projectionMatrix
);
for(int row = 0; row < skyResolutionY; ++row)
{
renderer->drawVertexBuffer(vertexGrid, rowIndices[ro
w]);
}
shader->release();
}
else
{
// No shader is available on this graphics card, compute col
ors on the CPU.
// Adapt luminance at this point to avoid a mismatch with th
e adaptation value
vertexGrid->unlock();
for (int i = 0; i < (1 + skyResolutionX) * (1 + skyResoluti
onY); ++i)
{
Vertex vertex = vertexGrid->getVertex(i);
eye->xyYToRGB(vertex.color);
vertex.color *= atm_intensity;
vertexGrid->setVertex(i, vertex);
}
vertexGrid->lock();
for(int row = 0; row < skyResolutionY; ++row)
{
renderer->drawVertexBuffer(vertexGrid, rowIndices[ro
w]);
}
}
}
bool Atmosphere::lazyLoadShader(StelRenderer* renderer)
{
qDebug() << "Using vertex shader for atmosphere rendering.";
QFile vertexShaderFile(":/shaders/xyYToRGB.glsl");
if(!vertexShaderFile.open(QIODevice::ReadOnly))
{
qWarning() << "Error opening shader file: ':/shaders/xyYToRG
B.glsl'";
return false;
}
shader = renderer->createGLSLShader();
if(!shader->addVertexShader(QTextStream(&vertexShaderFile).readAll()
))
{
qWarning() << "Error adding atmosphere vertex shader: " << s
hader->log();
delete shader;
shader = NULL;
return false;
}
if(!shader->addFragmentShader("varying mediump vec4 resultSkyColor;\
n"
"void main()\n"
"{\n"
" gl_FragColor = resultSkyColor;\n"
"}"))
{
qWarning() << "Error adding atmosphere fragment shader: " <<
shader->log();
delete shader;
shader = NULL;
return false;
}
if(!shader->build()) atmoShaderProgram->bind();
{ float a, b, c;
qWarning() << "Error building atmosphere shader: " << shader eye->getShadersParams(a, b, c);
->log(); atmoShaderProgram->setUniformValue(shaderAttribLocations.alphaWaOver
delete shader; AlphaDa, a);
shader = NULL; atmoShaderProgram->setUniformValue(shaderAttribLocations.oneOverGamm
return false; a, b);
} atmoShaderProgram->setUniformValue(shaderAttribLocations.term2TimesO
neOverMaxdLpOneOverGamma, c);
if(!shader->log().isEmpty()) atmoShaderProgram->setUniformValue(shaderAttribLocations.brightnessS
{ cale, atm_intensity);
qDebug() << "Atmosphere shader build log: " << shader->log() Vec3f sunPos;
; float term_x, Ax, Bx, Cx, Dx, Ex, term_y, Ay, By, Cy, Dy, Ey;
} sky.getShadersParams(sunPos, term_x, Ax, Bx, Cx, Dx, Ex, term_y, Ay,
By, Cy, Dy, Ey);
return true; atmoShaderProgram->setUniformValue(shaderAttribLocations.sunPos, sun
} Pos[0], sunPos[1], sunPos[2]);
atmoShaderProgram->setUniformValue(shaderAttribLocations.term_x, ter
void Atmosphere::updateGrid(const StelProjectorP projector) m_x);
{ atmoShaderProgram->setUniformValue(shaderAttribLocations.Ax, Ax);
viewport = projector->getViewport(); atmoShaderProgram->setUniformValue(shaderAttribLocations.Bx, Bx);
const float viewportWidth = projector->getViewportWidth(); atmoShaderProgram->setUniformValue(shaderAttribLocations.Cx, Cx);
const float viewportHeight = projector->getViewportHeight(); atmoShaderProgram->setUniformValue(shaderAttribLocations.Dx, Dx);
const float aspectRatio = viewportWidth / viewportHeight; atmoShaderProgram->setUniformValue(shaderAttribLocations.Ex, Ex);
skyResolutionY = StelApp::getInstance() atmoShaderProgram->setUniformValue(shaderAttribLocations.term_y, ter
.getSettings() m_y);
->value("landscape/atmosphereybi atmoShaderProgram->setUniformValue(shaderAttribLocations.Ay, Ay);
n", 44) atmoShaderProgram->setUniformValue(shaderAttribLocations.By, By);
.toInt(); atmoShaderProgram->setUniformValue(shaderAttribLocations.Cy, Cy);
const float resolutionX = skyResolutionY * 0.5 * sqrt(3.0) * aspe atmoShaderProgram->setUniformValue(shaderAttribLocations.Dy, Dy);
ctRatio; atmoShaderProgram->setUniformValue(shaderAttribLocations.Ey, Ey);
skyResolutionX = static_cast<int>(floor(0.5 + resolution const Mat4f& m = sPainter.getProjector()->getProjectionMatrix();
X)); atmoShaderProgram->setUniformValue(shaderAttribLocations.projectionM
const float stepX = viewportWidth / (skyResolutionX - 0.5) atrix,
; QMatrix4x4(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13],
const float stepY = viewportHeight / skyResolutionY; m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]));
const float viewportLeft = projector->getViewportPosX();
const float viewportBottom = projector->getViewportPosY(); colorGridBuffer.bind();
atmoShaderProgram->setAttributeBuffer(shaderAttribLocations.skyColor
vertexGrid->unlock(); , GL_FLOAT, 0, 4, 0);
vertexGrid->clear(); colorGridBuffer.release();
atmoShaderProgram->enableAttributeArray(shaderAttribLocations.skyCol
// Construct the vertex grid. or);
for(int y = 0; y <= skyResolutionY; ++y) posGridBuffer.bind();
{ atmoShaderProgram->setAttributeBuffer(shaderAttribLocations.skyVerte
const float yPos = viewportBottom + y * stepY; x, GL_FLOAT, 0, 2, 0);
for (int x = 0; x <= skyResolutionX; ++x) posGridBuffer.release();
{ atmoShaderProgram->enableAttributeArray(shaderAttribLocations.skyVer
const float offset = (x == 0) ? 0.0f : tex);
(x == skyResolutionX) ? viewpor
tWidth // And draw everything at once
: (x - 0. indicesBuffer.bind();
5 * (y & 1)) * stepX; int shift=0;
const float xPos = viewportLeft + offset; for (int y=0;y<skyResolutionY;++y)
vertexGrid->addVertex(Vertex(Vec2f(xPos, yPos), Vec4 {
f())); glDrawElements(GL_TRIANGLE_STRIP, (skyResolutionX+1)*2, GL_U
} NSIGNED_SHORT, reinterpret_cast<void*>(shift));
} shift += (skyResolutionX+1)*2*2;
vertexGrid->lock(); }
indicesBuffer.release();
// The grid is (resolutionX + 1) * (resolutionY + 1),
// so the rows are for 0 to resolutionY-1 atmoShaderProgram->disableAttributeArray(shaderAttribLocations.skyVe
// The last row includes vertices in row resolutionY rtex);
atmoShaderProgram->disableAttributeArray(shaderAttribLocations.skyCo
// Construct an index buffer for each row in the grid. lor);
for(int row = 0; row < skyResolutionY; ++row) atmoShaderProgram->release();
{ // GZ: debug output
StelIndexBuffer* buffer; //const StelProjectorP prj = core->getProjection(StelCore::FrameEqui
// Reuse previously used row index buffer. noxEqu);
if(rowIndices.size() > row) //StelPainter painter(prj);
{ //painter.setFont(font);
buffer = rowIndices[row]; //sPainter.setColor(0.7, 0.7, 0.7);
buffer->unlock(); //sPainter.drawText(83, 120, QString("Atmosphere::getAverageLuminanc
buffer->clear(); e(): %1" ).arg(getAverageLuminance()));
} //qDebug() << atmosphere->getAverageLuminance();
// Add new row index buffer.
else
{
buffer = renderer->createIndexBuffer(IndexType_U16);
rowIndices.append(buffer);
}
uint g0 = row * (1 + skyResolutionX);
uint g1 = (row + 1) * (1 + skyResolutionX);
for (int col = 0; col <= skyResolutionX; ++col)
{
buffer->addIndex(g0++);
buffer->addIndex(g1++);
}
buffer->lock();
Q_ASSERT_X(buffer->length() == (skyResolutionX + 1) * 2, Q_F
UNC_INFO,
"Unexpected grid row index buffer size");
}
Q_ASSERT_X(rowIndices.size() >= skyResolutionY, Q_FUNC_INFO,
"Not enough row index buffers");
} }
 End of changes. 38 change blocks. 
344 lines changed or deleted 312 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/