Planet.cpp   Planet.cpp 
skipping to change at line 21 skipping to change at line 21
* 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 <iomanip> #include <iomanip>
#include <QTextStream> #include <QTextStream>
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <QVarLengthArray> #include <QVarLengthArray>
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelTexture.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "SolarSystem.hpp" #include "SolarSystem.hpp"
#include "StelTexture.hpp"
#include "Planet.hpp" #include "Planet.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "sideral_time.h" #include "sideral_time.h"
#include "StelTextureMgr.hpp" #include "StelTextureMgr.hpp"
#include "StelModuleMgr.hpp" #include "StelModuleMgr.hpp"
#include "StarMgr.hpp" #include "StarMgr.hpp"
#include "StelMovementMgr.hpp" #include "StelMovementMgr.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include "StelTranslator.hpp" #include "StelTranslator.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
Vec3f Planet::labelColor = Vec3f(0.4,0.4,0.8); Vec3f Planet::labelColor = Vec3f(0.4,0.4,0.8);
Vec3f Planet::orbitColor = Vec3f(1,0.6,1); Vec3f Planet::orbitColor = Vec3f(1,0.6,1);
StelTextureSP Planet::hintCircleTex; StelTextureSP Planet::hintCircleTex;
StelTextureSP Planet::texEarthShadow; StelTextureSP Planet::texEarthShadow;
Planet::Planet(const QString& englishName, Planet::Planet(const QString& englishName,
int flagLighting, int flagLighting,
double radius, double radius,
double oblateness, double oblateness,
Vec3f color, Vec3f color,
float albedo, float albedo,
const QString& atexMapName, const QString& atexMapName,
posFuncType coordFunc, posFuncType coordFunc,
void* auserDataPtr, void* auserDataPtr,
OsculatingFunctType *osculatingFunc, OsculatingFunctType *osculatingFunc,
skipping to change at line 133 skipping to change at line 131
oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b> )").arg(QString::number(getVMagnitude(core, false), 'f', 2), oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b> )").arg(QString::number(getVMagnitude(core, false), 'f', 2),
QString::number(getVMagnitude(core, true), 'f', 2)) << "<br>"; QString::number(getVMagnitude(core, true), 'f', 2)) << "<br>";
else else
oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core , false), 0, 'f', 2) << "<br>"; oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core , false), 0, 'f', 2) << "<br>";
} }
if (flags&AbsoluteMagnitude) if (flags&AbsoluteMagnitude)
oss << q_("Absolute Magnitude: %1").arg(getVMagnitude(core, false)-5.*(std::log10(getJ2000EquatorialPos(core).length()*AU/PARSEC)-1.), 0, 'f', 2) << "<br>"; oss << q_("Absolute Magnitude: %1").arg(getVMagnitude(core, false)-5.*(std::log10(getJ2000EquatorialPos(core).length()*AU/PARSEC)-1.), 0, 'f', 2) << "<br>";
oss << getPositionInfoString(core, flags); oss << getPositionInfoString(core, flags);
if ((flags&Extra2) && (core->getCurrentLocation().planetName=="Earth ")) if ((flags&Extra1) && (core->getCurrentLocation().planetName=="Earth "))
{ {
//static SolarSystem *ssystem=GETSTELMODULE(SolarSystem); //static SolarSystem *ssystem=GETSTELMODULE(SolarSystem);
//double ecl= -(ssystem->getEarth()->getRotObliquity()); // BUG DETECTED! Earth's obliquity is apparently reported constant. //double ecl= -(ssystem->getEarth()->getRotObliquity()); // BUG DETECTED! Earth's obliquity is apparently reported constant.
double ra_equ, dec_equ, lambda, beta; double ra_equ, dec_equ, lambda, beta;
double ecl= get_mean_ecliptical_obliquity(core->getJDay()) * M_PI/180.0; double ecl= get_mean_ecliptical_obliquity(core->getJDay()) * M_PI/180.0;
StelUtils::rectToSphe(&ra_equ,&dec_equ,getEquinoxEquatorialP os(core)); StelUtils::rectToSphe(&ra_equ,&dec_equ,getEquinoxEquatorialP os(core));
StelUtils::ctRadec2Ecl(ra_equ, dec_equ, ecl, &lambda, &beta) ; StelUtils::ctRadec2Ecl(ra_equ, dec_equ, ecl, &lambda, &beta) ;
if (lambda<0) lambda+=2.0*M_PI; if (lambda<0) lambda+=2.0*M_PI;
oss << q_("Ecliptic Geocentric (of date): %1/%2").arg(StelUt ils::radToDmsStr(lambda, true), StelUtils::radToDmsStr(beta, true)) << "<br >"; oss << q_("Ecliptic Geocentric (of date): %1/%2").arg(StelUt ils::radToDmsStr(lambda, true), StelUtils::radToDmsStr(beta, true)) << "<br >";
oss << q_("Obliquity (of date): %1").arg(StelUtils::radToDms Str(ecl, true)) << "<br>"; oss << q_("Obliquity (of date): %1").arg(StelUtils::radToDms Str(ecl, true)) << "<br>";
skipping to change at line 166 skipping to change at line 164
} }
else else
{ {
// xgettext:no-c-format // xgettext:no-c-format
oss << q_("Distance: %1AU").arg(distanceAu, 0, 'f', 8); oss << q_("Distance: %1AU").arg(distanceAu, 0, 'f', 8);
} }
oss << "<br>"; oss << "<br>";
} }
if (flags&Size) if (flags&Size)
oss << q_("Apparent diameter: %1").arg(StelUtils::radToDmsSt {
r(2.*getAngularSize(core)*M_PI/180., true)); double angularSize = 2.*getAngularSize(core)*M_PI/180.;
if (rings)
{
double withoutRings = 2.*getSpheroidAngularSize(core
)*M_PI/180.;
oss << q_("Apparent diameter: %1, with rings: %2")
.arg(StelUtils::radToDmsStr(withoutRings, tru
e),
StelUtils::radToDmsStr(angularSize, true
));
}
else
{
oss << q_("Apparent diameter: %1").arg(StelUtils::ra
dToDmsStr(angularSize, true));
}
oss << "<br>";
}
if ((flags&Extra2) && (englishName.compare("Sun")!=0))
{
const Vec3d& observerHelioPos = core->getObserverHeliocentri
cEclipticPos();
const double observerRq = observerHelioPos.lengthSquared();
const Vec3d& planetHelioPos = getHeliocentricEclipticPos();
const double planetRq = planetHelioPos.lengthSquared();
const double observerPlanetRq = (observerHelioPos - planetHe
lioPos).lengthSquared();
const double cos_chi = (observerPlanetRq + planetRq - observ
erRq)/(2.0*sqrt(observerPlanetRq*planetRq));
float planetPhase = 0.5f * std::abs(1.f + cos_chi);
oss << QString(q_("Phase Angle: %1")).arg(StelUtils::radToDm
sStr(getPhase(core->getObserverHeliocentricEclipticPos()))) << "<br>";
oss << QString(q_("Elongation: %1")).arg(StelUtils::radToDms
Str(getElongation(core->getObserverHeliocentricEclipticPos()))) << "<br>";
oss << QString(q_("Phase: %1")).arg(planetPhase, 0, 'f', 2)
<< "<br>";
oss << QString(q_("Illuminated: %1%")).arg(planetPhase * 100
, 0, 'f', 1) << "<br>";
}
postProcessInfoString(str, flags); postProcessInfoString(str, flags);
return str; return str;
} }
//! Get sky label (sky translation) //! Get sky label (sky translation)
QString Planet::getSkyLabel(const StelCore*) const QString Planet::getSkyLabel(const StelCore*) const
{ {
QString str; QString str;
skipping to change at line 301 skipping to change at line 328
// date increments between points wi ll not be completely constant though // date increments between points wi ll not be completely constant though
computeTransMatrix(calc_date); computeTransMatrix(calc_date);
if (osculatingFunc) if (osculatingFunc)
{ {
(*osculatingFunc)(date,calc_ date,eclipticPos); (*osculatingFunc)(date,calc_ date,eclipticPos);
} }
else else
{ {
coordFunc(calc_date, eclipti cPos, userDataPtr); coordFunc(calc_date, eclipti cPos, userDataPtr);
} }
orbitP[d] = eclipticPos;
orbit[d] = getHeliocentricEclipticPo s(); orbit[d] = getHeliocentricEclipticPo s();
} }
else else
{ {
orbit[d] = orbit[d+delta_points]; orbitP[d] = orbitP[d+delta_points];
orbit[d] = getHeliocentricPos(orbitP
[d]);
} }
} }
lastOrbitJD = new_date; lastOrbitJD = new_date;
} }
else if( delta_points < 0 && abs(delta_points) < ORBIT_SEGME NTS && orbitCached) else if( delta_points < 0 && abs(delta_points) < ORBIT_SEGME NTS && orbitCached)
{ {
for( int d=ORBIT_SEGMENTS-1; d>=0; d-- ) for( int d=ORBIT_SEGMENTS-1; d>=0; d-- )
{ {
skipping to change at line 329 skipping to change at line 358
calc_date = new_date + (d-ORBIT_SEGM ENTS/2)*date_increment; calc_date = new_date + (d-ORBIT_SEGM ENTS/2)*date_increment;
computeTransMatrix(calc_date); computeTransMatrix(calc_date);
if (osculatingFunc) { if (osculatingFunc) {
(*osculatingFunc)(date,calc_ date,eclipticPos); (*osculatingFunc)(date,calc_ date,eclipticPos);
} }
else else
{ {
coordFunc(calc_date, eclipti cPos, userDataPtr); coordFunc(calc_date, eclipti cPos, userDataPtr);
} }
orbitP[d] = eclipticPos;
orbit[d] = getHeliocentricEclipticPo s(); orbit[d] = getHeliocentricEclipticPo s();
} }
else else
{ {
orbit[d] = orbit[d+delta_points]; orbitP[d] = orbitP[d+delta_points];
orbit[d] = getHeliocentricPos(orbitP
[d]);
} }
} }
lastOrbitJD = new_date; lastOrbitJD = new_date;
} }
else if( delta_points || !orbitCached) else if( delta_points || !orbitCached)
{ {
// update all points (less efficient) // update all points (less efficient)
skipping to change at line 356 skipping to change at line 387
calc_date = date + (d-ORBIT_SEGMENTS/2)*date _increment; calc_date = date + (d-ORBIT_SEGMENTS/2)*date _increment;
computeTransMatrix(calc_date); computeTransMatrix(calc_date);
if (osculatingFunc) if (osculatingFunc)
{ {
(*osculatingFunc)(date,calc_date,ecl ipticPos); (*osculatingFunc)(date,calc_date,ecl ipticPos);
} }
else else
{ {
coordFunc(calc_date, eclipticPos, us erDataPtr); coordFunc(calc_date, eclipticPos, us erDataPtr);
} }
orbitP[d] = eclipticPos;
orbit[d] = getHeliocentricEclipticPos(); orbit[d] = getHeliocentricEclipticPos();
} }
lastOrbitJD = date; lastOrbitJD = date;
if (!osculatingFunc) orbitCached = 1; if (!osculatingFunc) orbitCached = 1;
} }
// calculate actual Planet position // calculate actual Planet position
coordFunc(date, eclipticPos, userDataPtr); coordFunc(date, eclipticPos, userDataPtr);
lastJD = date; lastJD = date;
} }
else if (fabs(lastJD-date)>deltaJD) else if (fabs(lastJD-date)>deltaJD)
{ {
// calculate actual Planet position // calculate actual Planet position
coordFunc(date, eclipticPos, userDataPtr); coordFunc(date, eclipticPos, userDataPtr);
for( int d=0; d<ORBIT_SEGMENTS; d++ )
orbit[d]=getHeliocentricPos(orbitP[d]);
lastJD = date; lastJD = date;
} }
} }
// Compute the transformation matrix from the local Planet coordinate to th e parent Planet coordinate // Compute the transformation matrix from the local Planet coordinate to th e parent Planet coordinate
void Planet::computeTransMatrix(double jd) void Planet::computeTransMatrix(double jd)
{ {
axisRotation = getSiderealTime(jd); axisRotation = getSiderealTime(jd);
skipping to change at line 451 skipping to change at line 485
{ {
while (pp->parent) while (pp->parent)
{ {
pos += pp->eclipticPos; pos += pp->eclipticPos;
pp = pp->parent; pp = pp->parent;
} }
} }
return pos; return pos;
} }
// Return heliocentric coordinate of p
Vec3d Planet::getHeliocentricPos(Vec3d p) const
{
Vec3d pos = p;
PlanetP pp = parent;
if (pp)
{
while (pp->parent)
{
pos += pp->eclipticPos;
pp = pp->parent;
}
}
return pos;
}
void Planet::setHeliocentricEclipticPos(const Vec3d &pos) void Planet::setHeliocentricEclipticPos(const Vec3d &pos)
{ {
eclipticPos = pos; eclipticPos = pos;
PlanetP p = parent; PlanetP p = parent;
if (p) if (p)
{ {
while (p->parent) while (p->parent)
{ {
eclipticPos -= p->eclipticPos; eclipticPos -= p->eclipticPos;
p = p->parent; p = p->parent;
skipping to change at line 472 skipping to change at line 522
} }
} }
// Compute the distance to the given position in heliocentric coordinate (i n AU) // Compute the distance to the given position in heliocentric coordinate (i n AU)
double Planet::computeDistance(const Vec3d& obsHelioPos) double Planet::computeDistance(const Vec3d& obsHelioPos)
{ {
distance = (obsHelioPos-getHeliocentricEclipticPos()).length(); distance = (obsHelioPos-getHeliocentricEclipticPos()).length();
return distance; return distance;
} }
// Get the phase angle for an observer at pos obsPos in the heliocentric co ordinate (dist in AU) // Get the phase angle (radians) for an observer at pos obsPos in heliocent ric coordinates (dist in AU)
double Planet::getPhase(const Vec3d& obsPos) const double Planet::getPhase(const Vec3d& obsPos) const
{ {
const double observerRq = obsPos.lengthSquared(); const double observerRq = obsPos.lengthSquared();
const Vec3d& planetHelioPos = getHeliocentricEclipticPos(); const Vec3d& planetHelioPos = getHeliocentricEclipticPos();
const double planetRq = planetHelioPos.lengthSquared(); const double planetRq = planetHelioPos.lengthSquared();
const double observerPlanetRq = (obsPos - planetHelioPos).lengthSqua red(); const double observerPlanetRq = (obsPos - planetHelioPos).lengthSqua red();
return std::acos(observerPlanetRq + planetRq - observerRq)/(2.0*sqrt //return std::acos(observerPlanetRq + planetRq - observerRq)/(2.0*sq
(observerPlanetRq*planetRq)); rt(observerPlanetRq*planetRq));
return std::acos((observerPlanetRq + planetRq - observerRq)/(2.0*sqr
t(observerPlanetRq*planetRq)));
}
// Get the elongation angle (radians) for an observer at pos obsPos in heli
ocentric coordinates (dist in AU)
double Planet::getElongation(const Vec3d& obsPos) const
{
const double observerRq = obsPos.lengthSquared();
const Vec3d& planetHelioPos = getHeliocentricEclipticPos();
const double planetRq = planetHelioPos.lengthSquared();
const double observerPlanetRq = (obsPos - planetHelioPos).lengthSqua
red();
return std::acos((observerPlanetRq + observerRq - planetRq)/(2.0*sq
rt(observerPlanetRq*observerRq)));
} }
// Computation of the visual magnitude (V band) of the planet. // Computation of the visual magnitude (V band) of the planet.
float Planet::getVMagnitude(const StelCore* core, bool withExtinction) cons t float Planet::getVMagnitude(const StelCore* core, bool withExtinction) cons t
{ {
float extinctionMag=0.0; // track magnitude loss float extinctionMag=0.0; // track magnitude loss
if (withExtinction && core->getSkyDrawer()->getFlagHasAtmosphere()) if (withExtinction && core->getSkyDrawer()->getFlagHasAtmosphere())
{ {
Vec3d altAz=getAltAzPosApparent(core); Vec3d altAz=getAltAzPosApparent(core);
altAz.normalize(); altAz.normalize();
skipping to change at line 827 skipping to change at line 888
} }
// Draw the halo // Draw the halo
// Prepare openGL lighting parameters according to luminance // Prepare openGL lighting parameters according to luminance
float surfArcMin2 = getSpheroidAngularSize(core)*60; float surfArcMin2 = getSpheroidAngularSize(core)*60;
surfArcMin2 = surfArcMin2*surfArcMin2*M_PI; // the total illuminated area in arcmin^2 surfArcMin2 = surfArcMin2*surfArcMin2*M_PI; // the total illuminated area in arcmin^2
StelPainter sPainter(core->getProjection(StelCore::FrameJ2000)); StelPainter sPainter(core->getProjection(StelCore::FrameJ2000));
Vec3d tmp = getJ2000EquatorialPos(core); Vec3d tmp = getJ2000EquatorialPos(core);
core->getSkyDrawer()->postDrawSky3dModel(&sPainter, Vec3f(tmp[0], tm p[1], tmp[2]), surfArcMin2, getVMagnitude(core, true), color); core->getSkyDrawer()->postDrawSky3dModel(&sPainter, tmp, surfArcMin2 , getVMagnitude(core, true), color);
} }
void Planet::drawSphere(StelPainter* painter, float screenSz) void Planet::drawSphere(StelPainter* painter, float screenSz)
{ {
if (texMap) if (texMap)
{ {
// For lazy loading, return if texture not yet loaded // For lazy loading, return if texture not yet loaded
if (!texMap->bind()) if (!texMap->bind())
{
return; return;
}
} }
painter->enableTexture2d(true); painter->enableTexture2d(true);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
// Draw the spheroid itself // Draw the spheroid itself
// Adapt the number of facets according with the size of the sphere for optimization // Adapt the number of facets according with the size of the sphere for optimization
int nb_facet = (int)(screenSz * 40/50); // 40 facets for 1024 pixels diameter on screen int nb_facet = (int)(screenSz * 40/50); // 40 facets for 1024 pixels diameter on screen
if (nb_facet<10) nb_facet = 10; if (nb_facet<10) nb_facet = 10;
if (nb_facet>40) nb_facet = 40; if (nb_facet>40) nb_facet = 40;
painter->setShadeModel(StelPainter::ShadeModelSmooth); painter->setShadeModel(StelPainter::ShadeModelSmooth);
// Rotate and add an extra quarter rotation so that the planet textu re map // Rotate and add an extra quarter rotation so that the planet textu re map
// fits to the observers position. No idea why this is necessary, // fits to the observers position. No idea why this is necessary,
// perhaps some openGl strangeness, or confusing sin/cos. // perhaps some openGl strangeness, or confusing sin/cos.
painter->sSphere(radius*sphereScale, oneMinusOblateness, nb_facet, n b_facet); painter->sSphere(radius*sphereScale, oneMinusOblateness, nb_facet, n b_facet);
painter->setShadeModel(StelPainter::ShadeModelFlat); painter->setShadeModel(StelPainter::ShadeModelFlat);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
} }
// draws earth shadow overlapping the moon using stencil buffer // draws earth shadow overlapping the moon using stencil buffer
// umbra and penumbra are sized separately for accuracy // umbra and penumbra are sized separately for accuracy
void Planet::drawEarthShadow(StelCore* core, StelPainter* sPainter) void Planet::drawEarthShadow(StelCore* core, StelPainter* sPainter)
{ {
SolarSystem* ssm = GETSTELMODULE(SolarSystem); SolarSystem* ssm = GETSTELMODULE(SolarSystem);
skipping to change at line 889 skipping to change at line 952
rpt.normalize(); rpt.normalize();
Vec3d upt = rpt*r_umbra*mscale*1.02; // point on umbra edge Vec3d upt = rpt*r_umbra*mscale*1.02; // point on umbra edge
rpt *= r_penumbra*mscale; // point on penumbra edge rpt *= r_penumbra*mscale; // point on penumbra edge
// modify shadow location for scaled moon // modify shadow location for scaled moon
Vec3d mdist = shadow - mh; Vec3d mdist = shadow - mh;
if (mdist.length() > r_penumbra + 2000./AU) if (mdist.length() > r_penumbra + 2000./AU)
return; // not visible so don't bother drawing return; // not visible so don't bother drawing
shadow = mh + mdist*mscale; shadow = mh + mdist*mscale;
r_penumbra *= mscale;
StelProjectorP saveProj = sPainter->getProjector(); StelProjectorP saveProj = sPainter->getProjector();
sPainter->setProjector(core->getProjection(StelCore::FrameHeliocentr icEcliptic)); sPainter->setProjector(core->getProjection(StelCore::FrameHeliocentr icEcliptic));
sPainter->enableTexture2d(true); sPainter->enableTexture2d(true);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
sPainter->setColor(1,1,1); sPainter->setColor(1,1,1);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
skipping to change at line 1045 skipping to change at line 1107
Vec3d onscreen; Vec3d onscreen;
// special case - use current Planet position as center vertex so th at draws // special case - use current Planet position as center vertex so th at draws
// on it's orbit all the time (since segmented rather than smooth cu rve) // on it's orbit all the time (since segmented rather than smooth cu rve)
Vec3d savePos = orbit[ORBIT_SEGMENTS/2]; Vec3d savePos = orbit[ORBIT_SEGMENTS/2];
orbit[ORBIT_SEGMENTS/2]=getHeliocentricEclipticPos(); orbit[ORBIT_SEGMENTS/2]=getHeliocentricEclipticPos();
orbit[ORBIT_SEGMENTS]=orbit[0]; orbit[ORBIT_SEGMENTS]=orbit[0];
int nbIter = closeOrbit ? ORBIT_SEGMENTS : ORBIT_SEGMENTS-1; int nbIter = closeOrbit ? ORBIT_SEGMENTS : ORBIT_SEGMENTS-1;
QVarLengthArray<float, 1024> vertexArray; QVarLengthArray<float, 1024> vertexArray;
sPainter.enableClientStates(true, false, false); sPainter.enableClientStates(true, false, false);
for (int n=0; n<=nbIter; ++n) for (int n=0; n<=nbIter; ++n)
{ {
if (prj->project(orbit[n],onscreen) && (vertexArray.size()== 0 || !prj->intersectViewportDiscontinuity(orbit[n-1], orbit[n]))) if (prj->project(orbit[n],onscreen) && (vertexArray.size()== 0 || !prj->intersectViewportDiscontinuity(orbit[n-1], orbit[n])))
{ {
vertexArray.append(onscreen[0]); vertexArray.append(onscreen[0]);
vertexArray.append(onscreen[1]); vertexArray.append(onscreen[1]);
} }
else if (!vertexArray.isEmpty()) else if (!vertexArray.isEmpty())
{ {
sPainter.setVertexPointer(2, GL_FLOAT, vertexArray.c onstData()); sPainter.setVertexPointer(2, GL_FLOAT, vertexArray.c onstData());
 End of changes. 22 change blocks. 
14 lines changed or deleted 93 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/