StelPainter.cpp   StelPainter.cpp 
skipping to change at line 46 skipping to change at line 46
#ifndef GL_MULTISAMPLE #ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D #define GL_MULTISAMPLE 0x809D
#endif #endif
#ifndef NDEBUG #ifndef NDEBUG
QMutex* StelPainter::globalMutex = new QMutex(); QMutex* StelPainter::globalMutex = new QMutex();
#endif #endif
QPainter* StelPainter::qPainter = NULL; QPainter* StelPainter::qPainter = NULL;
QGLContext* StelPainter::glContext = NULL;
#ifdef STELPAINTER_GL2 #ifdef STELPAINTER_GL2
QGLShaderProgram* StelPainter::colorShaderProgram=NULL; QGLShaderProgram* StelPainter::colorShaderProgram=NULL;
QGLShaderProgram* StelPainter::texturesShaderProgram=NULL; QGLShaderProgram* StelPainter::texturesShaderProgram=NULL;
QGLShaderProgram* StelPainter::basicShaderProgram=NULL; QGLShaderProgram* StelPainter::basicShaderProgram=NULL;
QGLShaderProgram* StelPainter::texturesColorShaderProgram=NULL; QGLShaderProgram* StelPainter::texturesColorShaderProgram=NULL;
StelPainter::BasicShaderVars StelPainter::basicShaderVars; StelPainter::BasicShaderVars StelPainter::basicShaderVars;
StelPainter::TexturesShaderVars StelPainter::texturesShaderVars; StelPainter::TexturesShaderVars StelPainter::texturesShaderVars;
StelPainter::TexturesColorShaderVars StelPainter::texturesColorShaderVars; StelPainter::TexturesColorShaderVars StelPainter::texturesColorShaderVars;
#endif #endif
void StelPainter::setQPainter(QPainter* p) void StelPainter::setQPainter(QPainter* p)
{ {
qPainter=p; qPainter=p;
if (p==NULL)
return;
if (p->paintEngine()->type() != QPaintEngine::OpenGL && p->paintEngi
ne()->type() != QPaintEngine::OpenGL2)
{
qCritical("StelPainter::setQPainter(): StelPainter needs a Q
GLWidget to be set as viewport on the graphics view");
return;
}
QGLWidget* glwidget = dynamic_cast<QGLWidget*>(p->device());
if (glwidget && glwidget->context()!=glContext)
{
qCritical("StelPainter::setQPainter(): StelPainter needs to
paint on a GLWidget with the same GL context as the one used for initializa
tion.");
return;
}
}
void StelPainter::makeMainGLContextCurrent()
{
Q_ASSERT(glContext!=NULL);
Q_ASSERT(glContext->isValid());
glContext->makeCurrent();
}
void StelPainter::swapBuffer()
{
Q_ASSERT(glContext!=NULL);
Q_ASSERT(glContext->isValid());
glContext->swapBuffers();
} }
StelPainter::StelPainter(const StelProjectorP& proj) : prj(proj) StelPainter::StelPainter(const StelProjectorP& proj) : prj(proj)
{ {
Q_ASSERT(proj); Q_ASSERT(proj);
#ifndef NDEBUG #ifndef NDEBUG
Q_ASSERT(globalMutex); Q_ASSERT(globalMutex);
GLenum er = glGetError(); GLenum er = glGetError();
if (er!=GL_NO_ERROR) if (er!=GL_NO_ERROR)
skipping to change at line 256 skipping to change at line 285
vertices[i*2][2] = 0.0; vertices[i*2][2] = 0.0;
vertices[i*2+1][0]= prj->viewportCenter[0] + radiusHigh*sinC ache[i]; vertices[i*2+1][0]= prj->viewportCenter[0] + radiusHigh*sinC ache[i];
vertices[i*2+1][1]= prj->viewportCenter[1] + radiusHigh*cosC ache[i]; vertices[i*2+1][1]= prj->viewportCenter[1] + radiusHigh*cosC ache[i];
vertices[i*2+1][2] = 0.0; vertices[i*2+1][2] = 0.0;
} }
drawFromArray(TriangleStrip, (slices+1)*2, 0, false); drawFromArray(TriangleStrip, (slices+1)*2, 0, false);
enableClientStates(false); enableClientStates(false);
} }
#define MAX_STACKS 4096 #define MAX_STACKS 4096
static double cos_sin_rho[2*(MAX_STACKS+1)]; static float cos_sin_rho[2*(MAX_STACKS+1)];
#define MAX_SLICES 4096 #define MAX_SLICES 4096
static double cos_sin_theta[2*(MAX_SLICES+1)]; static float cos_sin_theta[2*(MAX_SLICES+1)];
static static void ComputeCosSinTheta(float phi,int segments)
void ComputeCosSinTheta(double phi,int segments) { {
double *cos_sin = cos_sin_theta; float *cos_sin = cos_sin_theta;
double *cos_sin_rev = cos_sin + 2*(segments+1); float *cos_sin_rev = cos_sin + 2*(segments+1);
const double c = cos(phi); const float c = std::cos(phi);
const double s = sin(phi); const float s = std::sin(phi);
*cos_sin++ = 1.0; *cos_sin++ = 1.f;
*cos_sin++ = 0.0; *cos_sin++ = 0.f;
*--cos_sin_rev = -cos_sin[-1];
*--cos_sin_rev = cos_sin[-2];
*cos_sin++ = c;
*cos_sin++ = s;
*--cos_sin_rev = -cos_sin[-1];
*--cos_sin_rev = cos_sin[-2];
while (cos_sin < cos_sin_rev) {
cos_sin[0] = cos_sin[-2]*c - cos_sin[-1]*s;
cos_sin[1] = cos_sin[-2]*s + cos_sin[-1]*c;
cos_sin += 2;
*--cos_sin_rev = -cos_sin[-1]; *--cos_sin_rev = -cos_sin[-1];
*--cos_sin_rev = cos_sin[-2]; *--cos_sin_rev = cos_sin[-2];
} *cos_sin++ = c;
*cos_sin++ = s;
*--cos_sin_rev = -cos_sin[-1];
*--cos_sin_rev = cos_sin[-2];
while (cos_sin < cos_sin_rev)
{
cos_sin[0] = cos_sin[-2]*c - cos_sin[-1]*s;
cos_sin[1] = cos_sin[-2]*s + cos_sin[-1]*c;
cos_sin += 2;
*--cos_sin_rev = -cos_sin[-1];
*--cos_sin_rev = cos_sin[-2];
}
} }
static static void ComputeCosSinRho(float phi, int segments)
void ComputeCosSinRho(double phi,int segments) { {
double *cos_sin = cos_sin_rho; float *cos_sin = cos_sin_rho;
double *cos_sin_rev = cos_sin + 2*(segments+1); float *cos_sin_rev = cos_sin + 2*(segments+1);
const double c = cos(phi); const float c = cos(phi);
const double s = sin(phi); const float s = sin(phi);
*cos_sin++ = 1.0; *cos_sin++ = 1.f;
*cos_sin++ = 0.0; *cos_sin++ = 0.f;
*--cos_sin_rev = cos_sin[-1]; *--cos_sin_rev = cos_sin[-1];
*--cos_sin_rev = -cos_sin[-2]; *--cos_sin_rev = -cos_sin[-2];
*cos_sin++ = c; *cos_sin++ = c;
*cos_sin++ = s; *cos_sin++ = s;
*--cos_sin_rev = cos_sin[-1];
*--cos_sin_rev = -cos_sin[-2];
while (cos_sin < cos_sin_rev) {
cos_sin[0] = cos_sin[-2]*c - cos_sin[-1]*s;
cos_sin[1] = cos_sin[-2]*s + cos_sin[-1]*c;
cos_sin += 2;
*--cos_sin_rev = cos_sin[-1]; *--cos_sin_rev = cos_sin[-1];
*--cos_sin_rev = -cos_sin[-2]; *--cos_sin_rev = -cos_sin[-2];
segments--; while (cos_sin < cos_sin_rev)
} {
cos_sin[0] = cos_sin[-2]*c - cos_sin[-1]*s;
cos_sin[1] = cos_sin[-2]*s + cos_sin[-1]*c;
cos_sin += 2;
*--cos_sin_rev = cos_sin[-1];
*--cos_sin_rev = -cos_sin[-2];
segments--;
}
} }
void StelPainter::sFanDisk(double radius, int innerFanSlices, int level) void StelPainter::computeFanDisk(float radius, int innerFanSlices, int leve l, QVector<double>& vertexArr, QVector<float>& texCoordArr)
{ {
Q_ASSERT(level<64); Q_ASSERT(level<64);
double rad[64]; float rad[64];
int i,j; int i,j;
rad[level] = radius; rad[level] = radius;
for (i=level-1;i>=0;--i) for (i=level-1;i>=0;--i)
{ {
rad[i] = rad[i+1]*(1.0-M_PI/(innerFanSlices<<(i+1)))*2.0/3.0 ; rad[i] = rad[i+1]*(1.f-M_PI/(innerFanSlices<<(i+1)))*2.f/3.f ;
} }
int slices = innerFanSlices<<level; int slices = innerFanSlices<<level;
const double dtheta = 2.0 * M_PI / slices; const float dtheta = 2.f * M_PI / slices;
Q_ASSERT(slices<=MAX_SLICES); Q_ASSERT(slices<=MAX_SLICES);
ComputeCosSinTheta(dtheta,slices); ComputeCosSinTheta(dtheta,slices);
double *cos_sin_theta_p; float* cos_sin_theta_p;
int slices_step = 2; int slices_step = 2;
static QVector<double> vertexArr; float x,y,xa,ya;
static QVector<float> texCoordArr; radius*=2.f;
double x,y; vertexArr.resize(0);
texCoordArr.resize(0);
for (i=level;i>0;--i,slices_step<<=1) for (i=level;i>0;--i,slices_step<<=1)
{ {
for (j=0,cos_sin_theta_p=cos_sin_theta; j<slices; j+=slices_ step,cos_sin_theta_p+=2*slices_step) for (j=0,cos_sin_theta_p=cos_sin_theta; j<slices-1; j+=slice s_step,cos_sin_theta_p+=2*slices_step)
{ {
vertexArr.resize(0); xa = rad[i]*cos_sin_theta_p[slices_step];
texCoordArr.resize(0); ya = rad[i]*cos_sin_theta_p[slices_step+1];
x = rad[i]*cos_sin_theta_p[slices_step]; texCoordArr << 0.5f+xa/radius << 0.5f+ya/radius;
y = rad[i]*cos_sin_theta_p[slices_step+1]; vertexArr << xa << ya << 0;
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radi
us);
vertexArr << x << y << 0;
x = rad[i]*cos_sin_theta_p[2*slices_step]; x = rad[i]*cos_sin_theta_p[2*slices_step];
y = rad[i]*cos_sin_theta_p[2*slices_step+1]; y = rad[i]*cos_sin_theta_p[2*slices_step+1];
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radi us); texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
vertexArr << x << y << 0; vertexArr << x << y << 0;
x = rad[i-1]*cos_sin_theta_p[2*slices_step]; x = rad[i-1]*cos_sin_theta_p[2*slices_step];
y = rad[i-1]*cos_sin_theta_p[2*slices_step+1]; y = rad[i-1]*cos_sin_theta_p[2*slices_step+1];
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radi texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
us); vertexArr << x << y << 0;
texCoordArr << 0.5f+xa/radius << 0.5f+ya/radius;
vertexArr << xa << ya << 0;
texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
vertexArr << x << y << 0; vertexArr << x << y << 0;
x = rad[i-1]*cos_sin_theta_p[0]; x = rad[i-1]*cos_sin_theta_p[0];
y = rad[i-1]*cos_sin_theta_p[1]; y = rad[i-1]*cos_sin_theta_p[1];
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radi texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
us); vertexArr << x << y << 0;
texCoordArr << 0.5f+xa/radius << 0.5f+ya/radius;
vertexArr << xa << ya << 0;
texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
vertexArr << x << y << 0; vertexArr << x << y << 0;
x = rad[i]*cos_sin_theta_p[0]; x = rad[i]*cos_sin_theta_p[0];
y = rad[i]*cos_sin_theta_p[1]; y = rad[i]*cos_sin_theta_p[1];
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radi us); texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
vertexArr << x << y << 0; vertexArr << x << y << 0;
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex
CoordArr.constData());
drawFromArray(TriangleFan, vertexArr.size()/3);
} }
} }
// draw the inner polygon // draw the inner polygon
slices_step>>=1; slices_step>>=1;
vertexArr.resize(0); cos_sin_theta_p=cos_sin_theta;
texCoordArr.resize(0); x = rad[0]*cos_sin_theta_p[0];
texCoordArr << 0.5 << 0.5; y = rad[0]*cos_sin_theta_p[1];
vertexArr << 0 << 0 << 0; texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
for (j=0,cos_sin_theta_p=cos_sin_theta; j<=slices; j+=slices_step,co vertexArr << x << y << 0;
s_sin_theta_p+=2*slices_step) cos_sin_theta_p+=2*slices_step;
{ x = rad[0]*cos_sin_theta_p[0];
x = rad[0]*cos_sin_theta_p[0]; y = rad[0]*cos_sin_theta_p[1];
y = rad[0]*cos_sin_theta_p[1]; texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
texCoordArr << 0.5*(1.0+x/radius) << 0.5*(1.0+y/radius); vertexArr << x << y << 0;
vertexArr << x << y << 0; cos_sin_theta_p+=2*slices_step;
} x = rad[0]*cos_sin_theta_p[0];
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)texCoordArr.constDa y = rad[0]*cos_sin_theta_p[1];
ta()); texCoordArr << 0.5f+x/radius << 0.5f+y/radius;
drawFromArray(TriangleFan, vertexArr.size()/3); vertexArr << x << y << 0;
} }
void StelPainter::sRing(double rMin, double rMax, int slices, int stacks, i nt orientInside) void StelPainter::sRing(float rMin, float rMax, int slices, int stacks, int orientInside)
{ {
double x,y; float x,y;
int j; int j;
const double nsign = (orientInside)?-1.0:1.0; static Vec3f lightPos3;
static Vec4f ambientLight;
static Vec4f diffuseLight;
float c;
const bool isLightOn = light.isEnabled();
if (isLightOn)
{
lightPos3.set(light.getPosition()[0], light.getPosition()[1]
, light.getPosition()[2]);
lightPos3 -= prj->modelViewMatrixf * Vec3f(0.f); // -posCent
erEye
lightPos3 = prj->modelViewMatrixf.transpose().multiplyWithou
tTranslation(lightPos3);
lightPos3.normalize();
ambientLight = light.getAmbient();
diffuseLight = light.getDiffuse();
}
const float nsign = orientInside?-1.f:1.f;
const double dr = (rMax-rMin) / stacks; const float dr = (rMax-rMin) / stacks;
const double dtheta = 2.0 * M_PI / slices; const float dtheta = 2.f * M_PI / slices;
if (slices < 0) slices = -slices; if (slices < 0) slices = -slices;
Q_ASSERT(slices<=MAX_SLICES); Q_ASSERT(slices<=MAX_SLICES);
ComputeCosSinTheta(dtheta,slices); ComputeCosSinTheta(dtheta,slices);
double *cos_sin_theta_p; float *cos_sin_theta_p;
static QVector<double> vertexArr; static QVector<double> vertexArr;
static QVector<float> texCoordArr; static QVector<float> texCoordArr;
static QVector<float> normalArr; static QVector<float> colorArr;
// draw intermediate stacks as quad strips // draw intermediate stacks as quad strips
for (double r = rMin; r < rMax; r+=dr) for (float r = rMin; r < rMax; r+=dr)
{ {
const double tex_r0 = (r-rMin)/(rMax-rMin); const float tex_r0 = (r-rMin)/(rMax-rMin);
const double tex_r1 = (r+dr-rMin)/(rMax-rMin); const float tex_r1 = (r+dr-rMin)/(rMax-rMin);
vertexArr.resize(0); vertexArr.resize(0);
texCoordArr.resize(0); texCoordArr.resize(0);
normalArr.resize(0); colorArr.resize(0);
for (j=0,cos_sin_theta_p=cos_sin_theta; j<=slices; ++j,cos_s in_theta_p+=2) for (j=0,cos_sin_theta_p=cos_sin_theta; j<=slices; ++j,cos_s in_theta_p+=2)
{ {
x = r*cos_sin_theta_p[0]; x = r*cos_sin_theta_p[0];
y = r*cos_sin_theta_p[1]; y = r*cos_sin_theta_p[1];
normalArr << 0 << 0 << nsign; if (isLightOn)
texCoordArr << tex_r0 << 0.5; {
vertexArr << x << y << 0; c = nsign * (lightPos3[0]*x + lightPos3[1]*y
);
if (c<0) {c=0;}
colorArr << c*diffuseLight[0] + ambientLight
[0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi
ght[2];
}
texCoordArr << tex_r0 << 0.5f;
vertexArr << x << y << 0.f;
x = (r+dr)*cos_sin_theta_p[0]; x = (r+dr)*cos_sin_theta_p[0];
y = (r+dr)*cos_sin_theta_p[1]; y = (r+dr)*cos_sin_theta_p[1];
normalArr << 0 << 0 << nsign; if (isLightOn)
texCoordArr << tex_r1 << 0.5; {
vertexArr << x << y << 0; c = nsign * (lightPos3[0]*x + lightPos3[1]*y
);
if (c<0) {c=0;}
colorArr << c*diffuseLight[0] + ambientLight
[0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi
ght[2];
}
texCoordArr << tex_r1 << 0.5f;
vertexArr << x << y << 0.f;
} }
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)texCoordArr
.constData(), NULL, (Vec3f*)normalArr.constData()); if (isLightOn)
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex
CoordArr.constData(), (Vec3f*)colorArr.constData());
else
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex
CoordArr.constData());
drawFromArray(TriangleStrip, vertexArr.size()/3); drawFromArray(TriangleStrip, vertexArr.size()/3);
} }
} }
static void sSphereMapTexCoordFast(double rho_div_fov, double costheta, dou ble sintheta, QVector<float>& out) static void sSphereMapTexCoordFast(float rho_div_fov, float costheta, float sintheta, QVector<float>& out)
{ {
if (rho_div_fov>0.5) if (rho_div_fov>0.5f)
rho_div_fov=0.5; rho_div_fov=0.5f;
out << 0.5 + rho_div_fov * costheta << 0.5 + rho_div_fov * sintheta; out << 0.5f + rho_div_fov * costheta << 0.5f + rho_div_fov * sinthet
a;
} }
void StelPainter::sSphereMap(double radius, int slices, int stacks, double textureFov, int orientInside) void StelPainter::sSphereMap(float radius, int slices, int stacks, float te xtureFov, int orientInside)
{ {
double rho,x,y,z; float rho,x,y,z;
int i, j; int i, j;
double drho = M_PI / stacks; float drho = M_PI / stacks;
Q_ASSERT(stacks<=MAX_STACKS); Q_ASSERT(stacks<=MAX_STACKS);
ComputeCosSinRho(drho,stacks); ComputeCosSinRho(drho,stacks);
double *cos_sin_rho_p; float* cos_sin_rho_p;
const double dtheta = 2.0 * M_PI / slices; const float dtheta = 2.f * M_PI / slices;
Q_ASSERT(slices<=MAX_SLICES); Q_ASSERT(slices<=MAX_SLICES);
ComputeCosSinTheta(dtheta,slices); ComputeCosSinTheta(dtheta,slices);
double *cos_sin_theta_p; float* cos_sin_theta_p;
drho/=textureFov; drho/=textureFov;
// texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y ax is // texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y ax is
// t goes from -1.0/+1.0 at z = -radius/+radius (linear along longit udes) // t goes from -1.0/+1.0 at z = -radius/+radius (linear along longit udes)
// cannot use triangle fan on texturing (s coord. at top/bottom tip varies) // cannot use triangle fan on texturing (s coord. at top/bottom tip varies)
const int imax = stacks; const int imax = stacks;
static QVector<double> vertexArr; static QVector<double> vertexArr;
static QVector<float> texCoordArr; static QVector<float> texCoordArr;
// draw intermediate stacks as quad strips // draw intermediate stacks as quad strips
if (!orientInside) // nsign==1 if (!orientInside) // nsign==1
{ {
for (i = 0,cos_sin_rho_p=cos_sin_rho,rho=0.0; i < imax; ++i, cos_sin_rho_p+=2,rho+=drho) for (i = 0,cos_sin_rho_p=cos_sin_rho,rho=0.f; i < imax; ++i, cos_sin_rho_p+=2,rho+=drho)
{ {
vertexArr.resize(0); vertexArr.resize(0);
texCoordArr.resize(0); texCoordArr.resize(0);
for (j=0,cos_sin_theta_p=cos_sin_theta;j<=slices;++j ,cos_sin_theta_p+=2) for (j=0,cos_sin_theta_p=cos_sin_theta;j<=slices;++j ,cos_sin_theta_p+=2)
{ {
x = -cos_sin_theta_p[1] * cos_sin_rho_p[1]; x = -cos_sin_theta_p[1] * cos_sin_rho_p[1];
y = cos_sin_theta_p[0] * cos_sin_rho_p[1]; y = cos_sin_theta_p[0] * cos_sin_rho_p[1];
z = cos_sin_rho_p[0]; z = cos_sin_rho_p[0];
sSphereMapTexCoordFast(rho, cos_sin_theta_p[ 0], cos_sin_theta_p[1], texCoordArr); sSphereMapTexCoordFast(rho, cos_sin_theta_p[ 0], cos_sin_theta_p[1], texCoordArr);
vertexArr << x*radius << y*radius << z*radiu s; vertexArr << x*radius << y*radius << z*radiu s;
skipping to change at line 481 skipping to change at line 551
z = cos_sin_rho_p[2]; z = cos_sin_rho_p[2];
sSphereMapTexCoordFast(rho + drho, cos_sin_t heta_p[0], cos_sin_theta_p[1], texCoordArr); sSphereMapTexCoordFast(rho + drho, cos_sin_t heta_p[0], cos_sin_theta_p[1], texCoordArr);
vertexArr << x*radius << y*radius << z*radiu s; vertexArr << x*radius << y*radius << z*radiu s;
} }
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex CoordArr.constData()); setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex CoordArr.constData());
drawFromArray(TriangleStrip, vertexArr.size()/3); drawFromArray(TriangleStrip, vertexArr.size()/3);
} }
} }
else else
{ {
for (i = 0,cos_sin_rho_p=cos_sin_rho,rho=0.0; i < imax; ++i, cos_sin_rho_p+=2,rho+=drho) for (i = 0,cos_sin_rho_p=cos_sin_rho,rho=0.f; i < imax; ++i, cos_sin_rho_p+=2,rho+=drho)
{ {
vertexArr.resize(0); vertexArr.resize(0);
texCoordArr.resize(0); texCoordArr.resize(0);
for (j=0,cos_sin_theta_p=cos_sin_theta;j<=slices;++j ,cos_sin_theta_p+=2) for (j=0,cos_sin_theta_p=cos_sin_theta;j<=slices;++j ,cos_sin_theta_p+=2)
{ {
x = -cos_sin_theta_p[1] * cos_sin_rho_p[3]; x = -cos_sin_theta_p[1] * cos_sin_rho_p[3];
y = cos_sin_theta_p[0] * cos_sin_rho_p[3]; y = cos_sin_theta_p[0] * cos_sin_rho_p[3];
z = cos_sin_rho_p[2]; z = cos_sin_rho_p[2];
sSphereMapTexCoordFast(rho + drho, cos_sin_t heta_p[0], -cos_sin_theta_p[1], texCoordArr); sSphereMapTexCoordFast(rho + drho, cos_sin_t heta_p[0], -cos_sin_theta_p[1], texCoordArr);
vertexArr << x*radius << y*radius << z*radiu s; vertexArr << x*radius << y*radius << z*radiu s;
skipping to change at line 520 skipping to change at line 590
d = std::sqrt(dx*dx + dy*dy); d = std::sqrt(dx*dx + dy*dy);
// If the text is too far away to be visible in the screen return // If the text is too far away to be visible in the screen return
if (d>qMax(prj->viewportXywh[3], prj->viewportXywh[2])*2) if (d>qMax(prj->viewportXywh[3], prj->viewportXywh[2])*2)
return; return;
theta = M_PI + std::atan2(dx, dy - 1); theta = M_PI + std::atan2(dx, dy - 1);
psi = std::atan2((float)qPainter->fontMetrics().width(ws)/ws.length( ),d + 1) * 180./M_PI; psi = std::atan2((float)qPainter->fontMetrics().width(ws)/ws.length( ),d + 1) * 180./M_PI;
if (psi>5) if (psi>5)
psi = 5; psi = 5;
qPainter->translate(x, y); if (qPainter->paintEngine()->type()==QPaintEngine::OpenGL2)
if (prj->gravityLabels) {
qPainter->translate(x, prj->viewportXywh[3]-y);
qPainter->rotate(theta*180./M_PI);
qPainter->translate(xshift, -yshift);
}
else
{
qPainter->translate(x, y);
qPainter->rotate(-theta*180./M_PI); qPainter->rotate(-theta*180./M_PI);
qPainter->translate(xshift, yshift); qPainter->translate(xshift, yshift);
qPainter->scale(1, -1); qPainter->scale(1, -1);
}
for (int i=0;i<ws.length();++i) for (int i=0;i<ws.length();++i)
{ {
qPainter->drawText(0,0,ws[i]); qPainter->drawText(0,0,ws[i]);
// with typeface need to manually advance // with typeface need to manually advance
// TODO, absolute rotation would be better than relative // TODO, absolute rotation would be better than relative
// TODO: would look better with kerning information... // TODO: would look better with kerning information...
qPainter->translate((float)qPainter->fontMetrics().width(ws. mid(i,1)) * 1.05, 0); qPainter->translate((float)qPainter->fontMetrics().width(ws. mid(i,1)) * 1.05, 0);
qPainter->rotate(-psi); qPainter->rotate(-psi);
} }
skipping to change at line 569 skipping to change at line 648
glPushMatrix(); glPushMatrix();
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glGetFloatv(GL_CURRENT_COLOR, color); glGetFloatv(GL_CURRENT_COLOR, color);
#else #else
color[0]=currentColor[0]; color[0]=currentColor[0];
color[1]=currentColor[1]; color[1]=currentColor[1];
color[2]=currentColor[2]; color[2]=currentColor[2];
color[3]=currentColor[3]; color[3]=currentColor[3];
#endif #endif
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qPainter->endNativePainting(); qPainter->endNativePainting();
qPainter->save(); qPainter->save();
qPainter->resetTransform(); qPainter->resetTransform();
qPainter->resetMatrix(); qPainter->resetMatrix();
qPainter->setRenderHints(QPainter::TextAntialiasing | QPainter::High QualityAntialiasing); // qPainter->setRenderHints(QPainter::TextAntialiasing | QPainter::High QualityAntialiasing);
const QColor qCol=QColor::fromRgbF(qMax(qMin(1.f,color[0]),0.f), qMa x(qMin(1.f,color[1]),0.f), qMax(qMin(1.f,color[2]),0.f), qMax(qMin(1.f,colo r[3]),0.f)); const QColor qCol=QColor::fromRgbF(qMax(qMin(1.f,color[0]),0.f), qMa x(qMin(1.f,color[1]),0.f), qMax(qMin(1.f,color[2]),0.f), qMax(qMin(1.f,colo r[3]),0.f));
qPainter->setPen(qCol); qPainter->setPen(qCol);
if (prj->gravityLabels && !noGravity) if (prj->gravityLabels && !noGravity)
{ {
drawTextGravity180(x, y, str, xshift, yshift); drawTextGravity180(x, y, str, xshift, yshift);
} }
else else
{ {
// There are 2 version here depending on the OpenGL engine // There are 2 version here depending on the OpenGL engine
// OpenGL 1 need to reverse the text vertically, not OpenGL 2... // OpenGL 1 need to reverse the text vertically, not OpenGL 2...
// This sounds like a Qt bug // This sounds like a Qt bug
if (qPainter->paintEngine()->type()==QPaintEngine::OpenGL2) if (qPainter->paintEngine()->type()==QPaintEngine::OpenGL2)
{ {
qPainter->translate(x+xshift, prj->viewportXywh[3]-y qPainter->translate(x, prj->viewportXywh[3]-y);
-yshift); qPainter->rotate(-angleDeg);
qPainter->translate(xshift, -yshift);
} }
else else
{ {
qPainter->translate(x+xshift, y+yshift); qPainter->translate(round(x), round(y));
qPainter->scale(1, -1); qPainter->scale(1, -1);
qPainter->rotate(-angleDeg);
qPainter->translate(round(xshift), round(-yshift));
} }
qPainter->drawText(0, 0, str); qPainter->drawText(0, 0, str);
} }
qPainter->restore(); qPainter->restore();
qPainter->beginNativePainting(); qPainter->beginNativePainting();
#ifndef STELPAINTER_GL2 #ifndef STELPAINTER_GL2
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glPopMatrix(); glPopMatrix();
skipping to change at line 636 skipping to change at line 717
vertexList.insert(iter, win2); vertexList.insert(iter, win2);
return; return;
} }
Vec3d newVertex(p1); newVertex+=p2; Vec3d newVertex(p1); newVertex+=p2;
newVertex.normalize(); newVertex.normalize();
newVertex*=radius; newVertex*=radius;
Vec3d win3(newVertex[0]+center[0], newVertex[1]+center[1], newVertex [2]+center[2]); Vec3d win3(newVertex[0]+center[0], newVertex[1]+center[1], newVertex [2]+center[2]);
const bool isValidVertex = prj->projectInPlace(win3); const bool isValidVertex = prj->projectInPlace(win3);
const double v10=win1[0]-win3[0]; const float v10=win1[0]-win3[0];
const double v11=win1[1]-win3[1]; const float v11=win1[1]-win3[1];
const double v20=win2[0]-win3[0]; const float v20=win2[0]-win3[0];
const double v21=win2[1]-win3[1]; const float v21=win2[1]-win3[1];
const double dist = std::sqrt((v10*v10+v11*v11)*(v20*v20+v21*v21)); const float dist = std::sqrt((v10*v10+v11*v11)*(v20*v20+v21*v21));
const double cosAngle = (v10*v20+v11*v21)/dist; const float cosAngle = (v10*v20+v11*v21)/dist;
if ((cosAngle>-0.999 || dist>50*50 || crossDiscontinuity) && nbI<10) if ((cosAngle>-0.999f || dist>50*50 || crossDiscontinuity) && nbI<10
)
{ {
// Use the 3rd component of the vector to store whether the vertex is valid // Use the 3rd component of the vector to store whether the vertex is valid
win3[2]= isValidVertex ? 1.0 : -1.; win3[2]= isValidVertex ? 1.0 : -1.;
fIter(prj, p1, newVertex, win1, win3, vertexList, vertexList .insert(iter, win3), radius, center, nbI+1, crossDiscontinuity || dist>50*5 0); fIter(prj, p1, newVertex, win1, win3, vertexList, vertexList .insert(iter, win3), radius, center, nbI+1, crossDiscontinuity || dist>50*5 0);
fIter(prj, newVertex, p2, win3, win2, vertexList, iter, radi us, center, nbI+1, crossDiscontinuity || dist>50*50 ); fIter(prj, newVertex, p2, win3, win2, vertexList, iter, radi us, center, nbI+1, crossDiscontinuity || dist>50*50 );
} }
} }
// Used by the method below // Used by the method below
QVector<Vec2f> StelPainter::smallCircleVertexArray; QVector<Vec2f> StelPainter::smallCircleVertexArray;
skipping to change at line 714 skipping to change at line 795
} }
else else
{ {
Vec3d tmp = (rotCenter^start)/rotCenter.length(); Vec3d tmp = (rotCenter^start)/rotCenter.length();
const double radius = fabs(tmp.length()); const double radius = fabs(tmp.length());
// Perform the tesselation of the arc in small segments in a way so that the lines look smooth // Perform the tesselation of the arc in small segments in a way so that the lines look smooth
fIter(prj, start-rotCenter, stop-rotCenter, win1, win2, tess Arc, tessArc.insert(tessArc.end(), win2), radius, rotCenter); fIter(prj, start-rotCenter, stop-rotCenter, win1, win2, tess Arc, tessArc.insert(tessArc.end(), win2), radius, rotCenter);
} }
// And draw. // And draw.
QLinkedList<Vec3d>::ConstIterator i = tessArc.begin(); QLinkedList<Vec3d>::ConstIterator i = tessArc.constBegin();
while (i+1 != tessArc.end()) while (i+1 != tessArc.constEnd())
{ {
const Vec3d& p1 = *i; const Vec3d& p1 = *i;
const Vec3d& p2 = *(++i); const Vec3d& p2 = *(++i);
const bool p1InViewport = prj->checkInViewport(p1); const bool p1InViewport = prj->checkInViewport(p1);
const bool p2InViewport = prj->checkInViewport(p2); const bool p2InViewport = prj->checkInViewport(p2);
if ((p1[2]>0 && p1InViewport) || (p2[2]>0 && p2InViewport)) if ((p1[2]>0 && p1InViewport) || (p2[2]>0 && p2InViewport))
{ {
smallCircleVertexArray.append(Vec2f(p1[0], p1[1])); smallCircleVertexArray.append(Vec2f(p1[0], p1[1]));
if (i+1==tessArc.end()) if (i+1==tessArc.constEnd())
{ {
smallCircleVertexArray.append(Vec2f(p2[0], p 2[1])); smallCircleVertexArray.append(Vec2f(p2[0], p 2[1]));
drawSmallCircleVertexArray(); drawSmallCircleVertexArray();
} }
if (viewportEdgeIntersectCallback && p1InViewport!=p 2InViewport) if (viewportEdgeIntersectCallback && p1InViewport!=p 2InViewport)
{ {
// We crossed the edge of the view port // We crossed the edge of the view port
if (p1InViewport) if (p1InViewport)
viewportEdgeIntersectCallback(prj->v iewPortIntersect(p1, p2), p2-p1, userData); viewportEdgeIntersectCallback(prj->v iewPortIntersect(p1, p2), p2-p1, userData);
else else
skipping to change at line 1114 skipping to change at line 1195
ta[1]=(texturePos[1]+texturePos[2])*0.5; ta[1]=(texturePos[1]+texturePos[2])*0.5;
ta[2]=texturePos[2]; ta[2]=texturePos[2];
} }
projectSphericalTriangle(clippingCap, va, outVertices, ta, outTextur ePos, nbI+1); projectSphericalTriangle(clippingCap, va, outVertices, ta, outTextur ePos, nbI+1);
return; return;
} }
static QVarLengthArray<Vec3f, 4096> polygonVertexArray; static QVarLengthArray<Vec3f, 4096> polygonVertexArray;
static QVarLengthArray<Vec2f, 4096> polygonTextureCoordArray; static QVarLengthArray<Vec2f, 4096> polygonTextureCoordArray;
// XXX: We should change the type to unsigned int
static QVarLengthArray<unsigned int, 4096> indexArray; static QVarLengthArray<unsigned int, 4096> indexArray;
void StelPainter::drawGreatCircleArcs(const StelVertexArray& va, const Sphe ricalCap* clippingCap, bool doSubDivise) void StelPainter::drawGreatCircleArcs(const StelVertexArray& va, const Sphe ricalCap* clippingCap)
{ {
Q_ASSERT(va.vertex.size()!=1); Q_ASSERT(va.vertex.size()!=1);
Q_ASSERT(!va.isIndexed()); // Indexed unsupported yet
switch (va.primitiveType) switch (va.primitiveType)
{ {
case StelVertexArray::Lines: case StelVertexArray::Lines:
Q_ASSERT(va.vertex.size()%2==0); Q_ASSERT(va.vertex.size()%2==0);
for (int i=0;i<va.vertex.size();i+=2) for (int i=0;i<va.vertex.size();i+=2)
drawGreatCircleArc(va.vertex.at(i), va.verte x.at(i+1), clippingCap); drawGreatCircleArc(va.vertex.at(i), va.verte x.at(i+1), clippingCap);
return; return;
case StelVertexArray::LineStrip: case StelVertexArray::LineStrip:
for (int i=0;i<va.vertex.size()-1;++i) for (int i=0;i<va.vertex.size()-1;++i)
drawGreatCircleArc(va.vertex.at(i), va.verte x.at(i+1), clippingCap); drawGreatCircleArc(va.vertex.at(i), va.verte x.at(i+1), clippingCap);
skipping to change at line 1159 skipping to change at line 1240
VertexArrayProjector(const StelVertexArray& ar, StelPainter* apainte r, const SphericalCap* aclippingCap, VertexArrayProjector(const StelVertexArray& ar, StelPainter* apainte r, const SphericalCap* aclippingCap,
QVarLengthArray<Vec3f, 4096 >* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL) QVarLengthArray<Vec3f, 4096 >* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL)
: vertexArray(ar), painter(apainter), clippingCap(aclippi ngCap), outVertices(aoutVertices), : vertexArray(ar), painter(apainter), clippingCap(aclippi ngCap), outVertices(aoutVertices),
outTexturePos(aoutTexturePos) outTexturePos(aoutTexturePos)
{ {
} }
// Project a single triangle and add it into the output arrays // Project a single triangle and add it into the output arrays
inline void operator()(const Vec3d* v0, const Vec3d* v1, const Vec3d * v2, inline void operator()(const Vec3d* v0, const Vec3d* v1, const Vec3d * v2,
const Vec2f* t0, const Ve c2f* t1, const Vec2f* t2, const Vec2f* t0, const Ve c2f* t1, const Vec2f* t2,
unsigned int i0, unsigned int i1, unsigned i2) unsigned int, unsigned in t, unsigned)
{ {
// XXX: we may optimize more by putting the declaration and the test outside of this method. // XXX: we may optimize more by putting the declaration and the test outside of this method.
const Vec3d tmpVertex[3] = {*v0, *v1, *v2}; const Vec3d tmpVertex[3] = {*v0, *v1, *v2};
if (outTexturePos) if (outTexturePos)
{ {
const Vec2f tmpTexture[3] = {*t0, *t1, *t2}; const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
painter->projectSphericalTriangle(clippingCap, tmpVe rtex, outVertices, tmpTexture, outTexturePos); painter->projectSphericalTriangle(clippingCap, tmpVe rtex, outVertices, tmpTexture, outTexturePos);
} }
else else
painter->projectSphericalTriangle(clippingCap, tmpVe rtex, outVertices, NULL, NULL); painter->projectSphericalTriangle(clippingCap, tmpVe rtex, outVertices, NULL, NULL);
skipping to change at line 1191 skipping to change at line 1272
} }
private: private:
const StelVertexArray& vertexArray; const StelVertexArray& vertexArray;
StelPainter* painter; StelPainter* painter;
const SphericalCap* clippingCap; const SphericalCap* clippingCap;
QVarLengthArray<Vec3f, 4096>* outVertices; QVarLengthArray<Vec3f, 4096>* outVertices;
QVarLengthArray<Vec2f, 4096>* outTexturePos; QVarLengthArray<Vec2f, 4096>* outTexturePos;
}; };
void StelPainter::drawStelVertexArray(const StelVertexArray& arr)
{
setVertexPointer(3, GL_DOUBLE, arr.vertex.constData());
if (arr.isTextured())
{
setTexCoordPointer(2, GL_FLOAT, arr.texCoords.constData());
enableClientStates(true, true);
}
else
{
enableClientStates(true, false);
}
if (arr.isIndexed())
drawFromArray((StelPainter::DrawingMode)arr.primitiveType, a
rr.indices.size(), 0, true, arr.indices.constData());
else
drawFromArray((StelPainter::DrawingMode)arr.primitiveType, a
rr.vertex.size());
enableClientStates(false);
}
void StelPainter::drawSphericalTriangles(const StelVertexArray& va, bool te xtured, const SphericalCap* clippingCap, bool doSubDivide) void StelPainter::drawSphericalTriangles(const StelVertexArray& va, bool te xtured, const SphericalCap* clippingCap, bool doSubDivide)
{ {
if (va.vertex.isEmpty()) if (va.vertex.isEmpty())
return; return;
// Never need to do clipping if the projection doesn't have a discon
tinuity
const bool doClip = prj->hasDiscontinuity();
Q_ASSERT(va.vertex.size()>2); Q_ASSERT(va.vertex.size()>2);
#ifndef STELPAINTER_GL2 #ifndef STELPAINTER_GL2
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif #endif
polygonVertexArray.clear(); polygonVertexArray.clear();
polygonTextureCoordArray.clear(); polygonTextureCoordArray.clear();
indexArray.clear(); indexArray.clear();
// The simplest case, we don't need to iterate through the triangles if (!doSubDivide)
at all.
if (!doClip && !doSubDivide)
{
va.draw(this);
return;
}
if (doClip && !doSubDivide)
{ {
StelVertexArray cleanVa = va.removeDiscontinuousTriangles(th if (prj->hasDiscontinuity())
is->getProjector().data()); {
cleanVa.draw(this); // We don't want to subdivise the triangles, but the
projection has discontinuities,
// so we need to make sure that no triangle is cross
ing them.
const StelVertexArray& cleanVa = va.removeDiscontinu
ousTriangles(this->getProjector().data());
drawStelVertexArray(cleanVa);
}
else
{
// The simplest case, we don't need to iterate throu
gh the triangles at all.
drawStelVertexArray(va);
}
return; return;
} }
// the last case. It is the slowest, it process the triangles one b y one. // the last case. It is the slowest, it process the triangles one b y one.
{ {
// Project all the triangles of the VertexArray into our buf fer arrays. // Project all the triangles of the VertexArray into our buf fer arrays.
VertexArrayProjector result = va.foreachTriangle(VertexArray Projector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTe xtureCoordArray : NULL)); VertexArrayProjector result = va.foreachTriangle(VertexArray Projector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTe xtureCoordArray : NULL));
result.drawResult(); result.drawResult();
return; return;
} }
} }
// Draw the given SphericalPolygon. // Draw the given SphericalPolygon.
void StelPainter::drawSphericalRegion(const SphericalRegion* poly, Spherica lPolygonDrawMode drawMode, const SphericalCap* clippingCap, bool doSubDivis e) void StelPainter::drawSphericalRegion(const SphericalRegion* poly, Spherica lPolygonDrawMode drawMode, const SphericalCap* clippingCap, bool doSubDivis e)
{ {
if (!prj->getBoundingCap().intersects(poly->getBoundingCap()))
return;
switch (drawMode) switch (drawMode)
{ {
case SphericalPolygonDrawModeBoundary: case SphericalPolygonDrawModeBoundary:
drawGreatCircleArcs(poly->getOutlineVertexArray(), c if (doSubDivise || prj->intersectViewportDiscontinui
lippingCap, doSubDivise); ty(poly->getBoundingCap()))
drawGreatCircleArcs(poly->getOutlineVertexAr
ray(), clippingCap);
else
drawStelVertexArray(poly->getOutlineVertexAr
ray());
break; break;
case SphericalPolygonDrawModeFill: case SphericalPolygonDrawModeFill:
case SphericalPolygonDrawModeTextureFill: case SphericalPolygonDrawModeTextureFill:
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
// Assumes the polygon is already tesselated as tria // The polygon is already tesselated as triangles
ngles if (doSubDivise || prj->intersectViewportDiscontinui
drawSphericalTriangles(poly->getFillVertexArray(), d ty(poly->getBoundingCap()))
rawMode==SphericalPolygonDrawModeTextureFill, clippingCap, doSubDivise); drawSphericalTriangles(poly->getFillVertexAr
ray(), drawMode==SphericalPolygonDrawModeTextureFill, clippingCap, doSubDiv
ise);
else
drawStelVertexArray(poly->getFillVertexArray
());
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
break; break;
default: default:
Q_ASSERT(0); Q_ASSERT(0);
} }
} }
/************************************************************************* /*************************************************************************
draw a simple circle, 2d viewport coordinates in pixel draw a simple circle, 2d viewport coordinates in pixel
*************************************************************************/ *************************************************************************/
void StelPainter::drawCircle(double x,double y,double r) void StelPainter::drawCircle(float x, float y, float r)
{ {
if (r <= 1.0) if (r <= 1.0)
return; return;
const Vec2d center(x,y); const Vec2f center(x,y);
const Vec2d v_center(0.5*prj->viewportXywh[2],0.5*prj->viewportXywh[ const Vec2f v_center(0.5f*prj->viewportXywh[2],0.5f*prj->viewportXyw
3]); h[3]);
const double R = v_center.length(); const float R = v_center.length();
const double d = (v_center-center).length(); const float d = (v_center-center).length();
if (d > r+R || d < r-R) if (d > r+R || d < r-R)
return; return;
const int segments = 180; const int segments = 180;
const double phi = 2.0*M_PI/segments; const float phi = 2.0*M_PI/segments;
const double cp = cos(phi); const float cp = std::cos(phi);
const double sp = sin(phi); const float sp = std::sin(phi);
double dx = r; float dx = r;
double dy = 0; float dy = 0;
static QVarLengthArray<Vec3f, 180> circleVertexArray(180); static QVarLengthArray<Vec3f, 180> circleVertexArray(180);
for (int i=0;i<segments;i++) for (int i=0;i<segments;i++)
{ {
circleVertexArray[i].set(x+dx,y+dy,0); circleVertexArray[i].set(x+dx,y+dy,0);
r = dx*cp-dy*sp; r = dx*cp-dy*sp;
dy = dx*sp+dy*cp; dy = dx*sp+dy*cp;
dx = r; dx = r;
} }
enableClientStates(true); enableClientStates(true);
setVertexPointer(3, GL_FLOAT, circleVertexArray.data()); setVertexPointer(3, GL_FLOAT, circleVertexArray.data());
drawFromArray(LineLoop, 180, 0, false); drawFromArray(LineLoop, 180, 0, false);
enableClientStates(false); enableClientStates(false);
} }
void StelPainter::drawSprite2dMode(double x, double y, float radius) void StelPainter::drawSprite2dMode(float x, float y, float radius)
{ {
static float vertexData[] = {-10.,-10.,10.,-10., 10.,10., -10.,10.}; static float vertexData[] = {-10.,-10.,10.,-10., 10.,10., -10.,10.};
static const float texCoordData[] = {0.,0., 1.,0., 0.,1., 1.,1.}; static const float texCoordData[] = {0.,0., 1.,0., 0.,1., 1.,1.};
vertexData[0]=x-radius; vertexData[1]=y-radius; vertexData[0]=x-radius; vertexData[1]=y-radius;
vertexData[2]=x+radius; vertexData[3]=y-radius; vertexData[2]=x+radius; vertexData[3]=y-radius;
vertexData[4]=x-radius; vertexData[5]=y+radius; vertexData[4]=x-radius; vertexData[5]=y+radius;
vertexData[6]=x+radius; vertexData[7]=y+radius; vertexData[6]=x+radius; vertexData[7]=y+radius;
enableClientStates(true, true); enableClientStates(true, true);
setVertexPointer(2, GL_FLOAT, vertexData); setVertexPointer(2, GL_FLOAT, vertexData);
setTexCoordPointer(2, GL_FLOAT, texCoordData); setTexCoordPointer(2, GL_FLOAT, texCoordData);
skipping to change at line 1305 skipping to change at line 1417
enableClientStates(false); enableClientStates(false);
} }
void StelPainter::drawSprite2dMode(const Vec3d& v, float radius) void StelPainter::drawSprite2dMode(const Vec3d& v, float radius)
{ {
Vec3d win; Vec3d win;
prj->project(v, win); prj->project(v, win);
drawSprite2dMode(win[0], win[1], radius); drawSprite2dMode(win[0], win[1], radius);
} }
void StelPainter::drawSprite2dMode(double x, double y, float radius, float rotation) void StelPainter::drawSprite2dMode(float x, float y, float radius, float ro tation)
{ {
static float vertexData[8]; static float vertexData[8];
static const float texCoordData[] = {0.,0., 1.,0., 0.,1., 1.,1.}; static const float texCoordData[] = {0.,0., 1.,0., 0.,1., 1.,1.};
// compute the vertex coordinates applying the translation and the r otation // compute the vertex coordinates applying the translation and the r otation
static const float vertexBase[] = {-1., -1., 1., -1., -1., 1., 1., 1 .}; static const float vertexBase[] = {-1., -1., 1., -1., -1., 1., 1., 1 .};
const float cosr = std::cos(rotation / 180 * M_PI); const float cosr = std::cos(rotation / 180 * M_PI);
const float sinr = std::sin(rotation / 180 * M_PI); const float sinr = std::sin(rotation / 180 * M_PI);
for (int i = 0; i < 8; i+=2) for (int i = 0; i < 8; i+=2)
{ {
skipping to change at line 1353 skipping to change at line 1465
enableClientStates(true); enableClientStates(true);
setVertexPointer(2, GL_FLOAT, vertexData); setVertexPointer(2, GL_FLOAT, vertexData);
} }
drawFromArray(TriangleStrip, 4, 0, false); drawFromArray(TriangleStrip, 4, 0, false);
enableClientStates(false); enableClientStates(false);
} }
/************************************************************************* /*************************************************************************
Draw a GL_POINT at the given position Draw a GL_POINT at the given position
*************************************************************************/ *************************************************************************/
void StelPainter::drawPoint2d(double x, double y) void StelPainter::drawPoint2d(float x, float y)
{ {
static float vertexData[] = {0.,0.}; static float vertexData[] = {0.,0.};
vertexData[0]=x; vertexData[0]=x;
vertexData[1]=y; vertexData[1]=y;
enableClientStates(true); enableClientStates(true);
setVertexPointer(2, GL_FLOAT, vertexData); setVertexPointer(2, GL_FLOAT, vertexData);
drawFromArray(Points, 1, 0, false); drawFromArray(Points, 1, 0, false);
enableClientStates(false); enableClientStates(false);
} }
/************************************************************************* /*************************************************************************
Draw a line between the 2 points. Draw a line between the 2 points.
*************************************************************************/ *************************************************************************/
void StelPainter::drawLine2d(double x1, double y1, double x2, double y2) void StelPainter::drawLine2d(float x1, float y1, float x2, float y2)
{ {
static float vertexData[] = {0.,0.,0.,0.}; static float vertexData[] = {0.,0.,0.,0.};
vertexData[0]=x1; vertexData[0]=x1;
vertexData[1]=y1; vertexData[1]=y1;
vertexData[2]=x2; vertexData[2]=x2;
vertexData[3]=y2; vertexData[3]=y2;
enableClientStates(true); enableClientStates(true);
setVertexPointer(2, GL_FLOAT, vertexData); setVertexPointer(2, GL_FLOAT, vertexData);
drawFromArray(Lines, 2, 0, false); drawFromArray(Lines, 2, 0, false);
enableClientStates(false); enableClientStates(false);
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Drawing methods for general (non-linear) mode // Drawing methods for general (non-linear) mode
void StelPainter::sSphere(double radius, double oneMinusOblateness, int sli ces, int stacks, int orientInside, bool flipTexture) void StelPainter::sSphere(float radius, float oneMinusOblateness, int slice s, int stacks, int orientInside, bool flipTexture)
{ {
// It is really good for performance to have Vec4f,Vec3f objects // It is really good for performance to have Vec4f,Vec3f objects
// static rather than on the stack. But why? // static rather than on the stack. But why?
// Is the constructor/destructor so expensive? // Is the constructor/destructor so expensive?
static Vec3f lightPos3; static Vec3f lightPos3;
float c;
static Vec4f ambientLight; static Vec4f ambientLight;
static Vec4f diffuseLight; static Vec4f diffuseLight;
float c;
bool isLightOn = light.isEnabled(); const bool isLightOn = light.isEnabled();
if (isLightOn) if (isLightOn)
{ {
lightPos3.set(light.getPosition()[0], light.getPosition()[1] , light.getPosition()[2]); lightPos3.set(light.getPosition()[0], light.getPosition()[1] , light.getPosition()[2]);
lightPos3 -= prj->modelViewMatrix * Vec3d(0.,0.,0.); // -pos lightPos3 -= prj->modelViewMatrixf * Vec3f(0.f);
CenterEye lightPos3 = prj->modelViewMatrixf.transpose().multiplyWithou
lightPos3 = prj->modelViewMatrix.transpose().multiplyWithout tTranslation(lightPos3);
Translation(lightPos3);
lightPos3.normalize(); lightPos3.normalize();
ambientLight = light.getAmbient(); ambientLight = light.getAmbient();
diffuseLight = light.getDiffuse(); diffuseLight = light.getDiffuse();
light.disable();
} }
GLfloat x, y, z; GLfloat x, y, z;
GLfloat s=0.f, t=0.f; GLfloat s=0.f, t=0.f;
GLint i, j; GLint i, j;
GLfloat nsign; GLfloat nsign;
if (orientInside) if (orientInside)
{ {
nsign = -1.0; nsign = -1.f;
t=0.0; // from inside texture is reversed t=0.f; // from inside texture is reversed
} }
else else
{ {
nsign = 1.0; nsign = 1.f;
t=1.0; t=1.f;
} }
const double drho = M_PI / stacks; const float drho = M_PI / stacks;
Q_ASSERT(stacks<=MAX_STACKS); Q_ASSERT(stacks<=MAX_STACKS);
ComputeCosSinRho(drho,stacks); ComputeCosSinRho(drho,stacks);
double *cos_sin_rho_p; float* cos_sin_rho_p;
const double dtheta = 2.0 * M_PI / slices; const float dtheta = 2.f * M_PI / slices;
Q_ASSERT(slices<=MAX_SLICES); Q_ASSERT(slices<=MAX_SLICES);
ComputeCosSinTheta(dtheta,slices); ComputeCosSinTheta(dtheta,slices);
const double *cos_sin_theta_p; const float *cos_sin_theta_p;
// texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y ax is // texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y ax is
// t goes from -1.0/+1.0 at z = -radius/+radius (linear along longit udes) // t goes from -1.0/+1.0 at z = -radius/+radius (linear along longit udes)
// cannot use triangle fan on texturing (s coord. at top/bottom tip varies) // cannot use triangle fan on texturing (s coord. at top/bottom tip varies)
// If the texture is flipped, we iterate the coordinates backward. // If the texture is flipped, we iterate the coordinates backward.
const GLfloat ds = ((flipTexture) ? -1 : 1) * 1.0 / slices; const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
const GLfloat dt = nsign / stacks; // from inside texture is reverse d const GLfloat dt = nsign / stacks; // from inside texture is reverse d
// draw intermediate as quad strips // draw intermediate as quad strips
static QVector<double> vertexArr; static QVector<double> vertexArr;
static QVector<float> texCoordArr; static QVector<float> texCoordArr;
static QVector<float> colorArr; static QVector<float> colorArr;
static QVector<unsigned int> indiceArr;
texCoordArr.resize(0);
vertexArr.resize(0);
colorArr.resize(0);
indiceArr.resize(0);
for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_ p+=2) for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_ p+=2)
{ {
texCoordArr.resize(0); s = !flipTexture ? 0.f : 1.f;
vertexArr.resize(0); for (j = 0,cos_sin_theta_p = cos_sin_theta; j<=slices;++j,co
colorArr.resize(0); s_sin_theta_p+=2)
s = (!flipTexture) ? 0.0 : 1.0;
for (j = 0,cos_sin_theta_p = cos_sin_theta; j <= slices;++j,
cos_sin_theta_p+=2)
{ {
x = -cos_sin_theta_p[1] * cos_sin_rho_p[1]; x = -cos_sin_theta_p[1] * cos_sin_rho_p[1];
y = cos_sin_theta_p[0] * cos_sin_rho_p[1]; y = cos_sin_theta_p[0] * cos_sin_rho_p[1];
z = nsign * cos_sin_rho_p[0]; z = nsign * cos_sin_rho_p[0];
texCoordArr << s << t; texCoordArr << s << t;
if (isLightOn) if (isLightOn)
{ {
c = nsign * (lightPos3[0]*x*oneMinusOblatene ss + lightPos3[1]*y*oneMinusOblateness + lightPos3[2]*z); c = nsign * (lightPos3[0]*x*oneMinusOblatene ss + lightPos3[1]*y*oneMinusOblateness + lightPos3[2]*z);
if (c<0) {c=0;} if (c<0) {c=0;}
colorArr << c*diffuseLight[0] + ambientLight [0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi ght[2]; colorArr << c*diffuseLight[0] + ambientLight [0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi ght[2];
skipping to change at line 1477 skipping to change at line 1587
texCoordArr << s << t - dt; texCoordArr << s << t - dt;
if (isLightOn) if (isLightOn)
{ {
c = nsign * (lightPos3[0]*x*oneMinusOblatene ss + lightPos3[1]*y*oneMinusOblateness + lightPos3[2]*z); c = nsign * (lightPos3[0]*x*oneMinusOblatene ss + lightPos3[1]*y*oneMinusOblateness + lightPos3[2]*z);
if (c<0) {c=0;} if (c<0) {c=0;}
colorArr << c*diffuseLight[0] + ambientLight [0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi ght[2]; colorArr << c*diffuseLight[0] + ambientLight [0] << c*diffuseLight[1] + ambientLight[1] << c*diffuseLight[2] + ambientLi ght[2];
} }
vertexArr << x * radius << y * radius << z * oneMinu sOblateness * radius; vertexArr << x * radius << y * radius << z * oneMinu sOblateness * radius;
s += ds; s += ds;
} }
// Draw the array now unsigned int offset = i*(slices+1)*2;
if (isLightOn) for (j = 2;j<slices*2+2;j+=2)
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex {
CoordArr.constData(), (Vec3f*)colorArr.constData()); indiceArr << offset+j-2 << offset+j-1 << offset+j;
else indiceArr << offset+j << offset+j-1 << offset+j+1;
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)tex }
CoordArr.constData());
drawFromArray(TriangleStrip, vertexArr.size()/3);
t -= dt; t -= dt;
} }
// Draw the array now
if (isLightOn) if (isLightOn)
light.enable(); setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)texCoordArr
.constData(), (Vec3f*)colorArr.constData());
else
setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)texCoordArr
.constData());
drawFromArray(Triangles, indiceArr.size(), 0, true, indiceArr.constD
ata());
} }
// Reimplementation of gluCylinder : glu is overrided for non standard proj StelVertexArray StelPainter::computeSphereNoLight(float radius, float oneMi
ection nusOblateness, int slices, int stacks, int orientInside, bool flipTexture)
void StelPainter::sCylinder(double radius, double height, int slices, int o
rientInside)
{ {
StelVertexArray result(StelVertexArray::Triangles);
GLfloat x, y, z;
GLfloat s=0.f, t=0.f;
GLint i, j;
GLfloat nsign;
if (orientInside) if (orientInside)
glCullFace(GL_FRONT); {
nsign = -1.f;
t=0.f; // from inside texture is reversed
}
else
{
nsign = 1.f;
t=1.f;
}
const float da = 2.0 * M_PI / slices; const float drho = M_PI / stacks;
Q_ASSERT(stacks<=MAX_STACKS);
ComputeCosSinRho(drho,stacks);
float* cos_sin_rho_p;
float ds = 1.0 / slices; const float dtheta = 2.f * M_PI / slices;
QVarLengthArray<Vec2f, 128> texCoordArray; Q_ASSERT(slices<=MAX_SLICES);
QVarLengthArray<Vec3d, 128> vertexArray; ComputeCosSinTheta(dtheta,slices);
float s = 0.f; const float *cos_sin_theta_p;
float x, y;
for (int i = 0; i <= slices; i++) // texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y ax
is
// t goes from -1.0/+1.0 at z = -radius/+radius (linear along longit
udes)
// cannot use triangle fan on texturing (s coord. at top/bottom tip
varies)
// If the texture is flipped, we iterate the coordinates backward.
const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
const GLfloat dt = nsign / stacks; // from inside texture is reverse
d
// draw intermediate as quad strips
for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_
p+=2)
{ {
if (i == slices) s = !flipTexture ? 0.f : 1.f;
for (j = 0,cos_sin_theta_p = cos_sin_theta; j<=slices;++j,co
s_sin_theta_p+=2)
{ {
x = 0.f; x = -cos_sin_theta_p[1] * cos_sin_rho_p[1];
y = 1.f; y = cos_sin_theta_p[0] * cos_sin_rho_p[1];
z = nsign * cos_sin_rho_p[0];
result.texCoords << Vec2f(s,t);
result.vertex << Vec3d(x*radius, y*radius, z*oneMinu
sOblateness*radius);
x = -cos_sin_theta_p[1] * cos_sin_rho_p[3];
y = cos_sin_theta_p[0] * cos_sin_rho_p[3];
z = nsign * cos_sin_rho_p[2];
result.texCoords << Vec2f(s, t-dt);
result.vertex << Vec3d(x*radius, y*radius, z*oneMinu
sOblateness*radius);
s += ds;
} }
else unsigned int offset = i*(slices+1)*2;
for (j = 2;j<slices*2+2;j+=2)
{ {
x = std::sin(da*i); result.indices << offset+j-2 << offset+j-1 << offset
y = std::cos(da*i); +j;
result.indices << offset+j << offset+j-1 << offset+j
+1;
} }
t -= dt;
}
return result;
//setArrays((Vec3d*)vertexArr.constData(), (Vec2f*)texCoordArr.const
Data());
//drawFromArray(Triangles, indiceArr.size(), 0, true, indiceArr.cons
tData());
}
// Reimplementation of gluCylinder : glu is overrided for non standard proj
ection
void StelPainter::sCylinder(float radius, float height, int slices, int ori
entInside)
{
if (orientInside)
glCullFace(GL_FRONT);
static QVarLengthArray<Vec2f, 512> texCoordArray;
static QVarLengthArray<Vec3d, 512> vertexArray;
texCoordArray.clear();
vertexArray.clear();
float s = 0.f;
float x, y;
const float ds = 1.f / slices;
const float da = 2.f * M_PI / slices;
for (int i = 0; i <= slices; ++i)
{
x = std::sin(da*i);
y = std::cos(da*i);
texCoordArray.append(Vec2f(s, 0.f)); texCoordArray.append(Vec2f(s, 0.f));
vertexArray.append(Vec3d(x*radius, y*radius, 0.)); vertexArray.append(Vec3d(x*radius, y*radius, 0.));
texCoordArray.append(Vec2f(s, 1.f)); texCoordArray.append(Vec2f(s, 1.f));
vertexArray.append(Vec3d(x*radius, y*radius, height)); vertexArray.append(Vec3d(x*radius, y*radius, height));
s += ds; s += ds;
} }
setArrays(vertexArray.constData(), texCoordArray.constData()); setArrays(vertexArray.constData(), texCoordArray.constData());
drawFromArray(TriangleStrip, vertexArray.size()); drawFromArray(TriangleStrip, vertexArray.size());
if (orientInside) if (orientInside)
glCullFace(GL_BACK); glCullFace(GL_BACK);
} }
void StelPainter::setPointSize(qreal size) void StelPainter::setPointSize(qreal size)
{ {
#ifndef STELPAINTER_GL2 #ifndef STELPAINTER_GL2
glPointSize(size); glPointSize(size);
#else #else
#warning GL ES2 to be done Q_UNUSED(size);
#endif #endif
} }
void StelPainter::setShadeModel(ShadeModel m) void StelPainter::setShadeModel(ShadeModel m)
{ {
#ifndef STELPAINTER_GL2 #ifndef STELPAINTER_GL2
glShadeModel(m); glShadeModel(m);
#else #else
#warning GL ES2 to be done Q_UNUSED(m);
#endif #endif
} }
void StelPainter::enableTexture2d(bool b) void StelPainter::enableTexture2d(bool b)
{ {
#ifndef STELPAINTER_GL2 #ifndef STELPAINTER_GL2
if (b) if (b)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
else else
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
#else #else
texture2dEnabled = b; texture2dEnabled = b;
#endif #endif
} }
void StelPainter::initSystemGLInfo() void StelPainter::initSystemGLInfo(QGLContext* ctx)
{ {
Q_ASSERT(glContext==NULL);
glContext = ctx;
#ifdef STELPAINTER_GL2 #ifdef STELPAINTER_GL2
// Basic shader: just vertex filled with plain color // Basic shader: just vertex filled with plain color
QGLShader *vshader3 = new QGLShader(QGLShader::Vertex); QGLShader *vshader3 = new QGLShader(QGLShader::Vertex);
const char *vsrc3 = const char *vsrc3 =
"attribute mediump vec3 vertex;\n" "attribute mediump vec3 vertex;\n"
"uniform mediump mat4 projectionMatrix;\n" "uniform mediump mat4 projectionMatrix;\n"
"void main(void)\n" "void main(void)\n"
"{\n" "{\n"
" gl_Position = projectionMatrix*vec4(vertex, 1.);\n" " gl_Position = projectionMatrix*vec4(vertex, 1.);\n"
"}\n"; "}\n";
skipping to change at line 1644 skipping to change at line 1820
"}\n"; "}\n";
fshader2->compileSourceCode(fsrc2); fshader2->compileSourceCode(fsrc2);
texturesShaderProgram = new QGLShaderProgram(QGLContext::currentCont ext()); texturesShaderProgram = new QGLShaderProgram(QGLContext::currentCont ext());
texturesShaderProgram->addShader(vshader2); texturesShaderProgram->addShader(vshader2);
texturesShaderProgram->addShader(fshader2); texturesShaderProgram->addShader(fshader2);
texturesShaderProgram->link(); texturesShaderProgram->link();
texturesShaderVars.projectionMatrix = texturesShaderProgram->uniform Location("projectionMatrix"); texturesShaderVars.projectionMatrix = texturesShaderProgram->uniform Location("projectionMatrix");
texturesShaderVars.texCoord = texturesShaderProgram->attributeLocati on("texCoord"); texturesShaderVars.texCoord = texturesShaderProgram->attributeLocati on("texCoord");
texturesShaderVars.vertex = texturesShaderProgram->attributeLocation ("vertex"); texturesShaderVars.vertex = texturesShaderProgram->attributeLocation ("vertex");
texturesShaderVars.texColor = texturesShaderProgram->uniformLocation ("texColor"); texturesShaderVars.texColor = texturesShaderProgram->uniformLocation ("texColor");
texturesShaderVars.texture = texturesShaderProgram->uniformLocation( "tex");
// Texture shader program + interpolated color per vertex // Texture shader program + interpolated color per vertex
QGLShader *vshader4 = new QGLShader(QGLShader::Vertex); QGLShader *vshader4 = new QGLShader(QGLShader::Vertex);
const char *vsrc4 = const char *vsrc4 =
"attribute highp vec3 vertex;\n" "attribute highp vec3 vertex;\n"
"attribute mediump vec2 texCoord;\n" "attribute mediump vec2 texCoord;\n"
"attribute mediump vec4 color;\n" "attribute mediump vec4 color;\n"
"uniform mediump mat4 projectionMatrix;\n" "uniform mediump mat4 projectionMatrix;\n"
"varying mediump vec2 texc;\n" "varying mediump vec2 texc;\n"
"varying mediump vec4 outColor;\n" "varying mediump vec4 outColor;\n"
skipping to change at line 1679 skipping to change at line 1856
"}\n"; "}\n";
fshader4->compileSourceCode(fsrc4); fshader4->compileSourceCode(fsrc4);
texturesColorShaderProgram = new QGLShaderProgram(QGLContext::curren tContext()); texturesColorShaderProgram = new QGLShaderProgram(QGLContext::curren tContext());
texturesColorShaderProgram->addShader(vshader4); texturesColorShaderProgram->addShader(vshader4);
texturesColorShaderProgram->addShader(fshader4); texturesColorShaderProgram->addShader(fshader4);
texturesColorShaderProgram->link(); texturesColorShaderProgram->link();
texturesColorShaderVars.projectionMatrix = texturesColorShaderProgra m->uniformLocation("projectionMatrix"); texturesColorShaderVars.projectionMatrix = texturesColorShaderProgra m->uniformLocation("projectionMatrix");
texturesColorShaderVars.texCoord = texturesColorShaderProgram->attri buteLocation("texCoord"); texturesColorShaderVars.texCoord = texturesColorShaderProgram->attri buteLocation("texCoord");
texturesColorShaderVars.vertex = texturesColorShaderProgram->attribu teLocation("vertex"); texturesColorShaderVars.vertex = texturesColorShaderProgram->attribu teLocation("vertex");
texturesColorShaderVars.color = texturesColorShaderProgram->attribut eLocation("color"); texturesColorShaderVars.color = texturesColorShaderProgram->attribut eLocation("color");
texturesColorShaderVars.texture = texturesColorShaderProgram->unifor mLocation("tex");
#endif #endif
} }
void StelPainter::setArrays(const Vec3d* vertice, const Vec2f* texCoords, c onst Vec3f* colorArray, const Vec3f* normalArray) void StelPainter::setArrays(const Vec3d* vertice, const Vec2f* texCoords, c onst Vec3f* colorArray, const Vec3f* normalArray)
{ {
enableClientStates(vertice, texCoords, colorArray, normalArray); enableClientStates(vertice, texCoords, colorArray, normalArray);
setVertexPointer(3, GL_DOUBLE, vertice); setVertexPointer(3, GL_DOUBLE, vertice);
setTexCoordPointer(2, GL_FLOAT, texCoords); setTexCoordPointer(2, GL_FLOAT, texCoords);
setColorPointer(3, GL_FLOAT, colorArray); setColorPointer(3, GL_FLOAT, colorArray);
setNormalPointer(GL_FLOAT, normalArray); setNormalPointer(GL_FLOAT, normalArray);
skipping to change at line 1760 skipping to change at line 1938
else if (texCoordArray.enabled && !colorArray.enabled && !normalArra y.enabled) else if (texCoordArray.enabled && !colorArray.enabled && !normalArra y.enabled)
{ {
pr = texturesShaderProgram; pr = texturesShaderProgram;
pr->bind(); pr->bind();
pr->setAttributeArray(texturesShaderVars.vertex, (const GLfl oat*)projectedVertexArray.pointer, projectedVertexArray.size); pr->setAttributeArray(texturesShaderVars.vertex, (const GLfl oat*)projectedVertexArray.pointer, projectedVertexArray.size);
pr->enableAttributeArray(texturesShaderVars.vertex); pr->enableAttributeArray(texturesShaderVars.vertex);
pr->setUniformValue(texturesShaderVars.projectionMatrix, qMa t); pr->setUniformValue(texturesShaderVars.projectionMatrix, qMa t);
pr->setUniformValue(texturesShaderVars.texColor, currentColo r[0], currentColor[1], currentColor[2], currentColor[3]); pr->setUniformValue(texturesShaderVars.texColor, currentColo r[0], currentColor[1], currentColor[2], currentColor[3]);
pr->setAttributeArray(texturesShaderVars.texCoord, (const GL float*)texCoordArray.pointer, 2); pr->setAttributeArray(texturesShaderVars.texCoord, (const GL float*)texCoordArray.pointer, 2);
pr->enableAttributeArray(texturesShaderVars.texCoord); pr->enableAttributeArray(texturesShaderVars.texCoord);
//pr->setUniformValue(texturesShaderVars.texture, 0); // use texture unit 0
} }
else if (texCoordArray.enabled && colorArray.enabled && !normalArray .enabled) else if (texCoordArray.enabled && colorArray.enabled && !normalArray .enabled)
{ {
pr = texturesColorShaderProgram; pr = texturesColorShaderProgram;
pr->bind(); pr->bind();
pr->setAttributeArray(texturesColorShaderVars.vertex, (const GLfloat*)projectedVertexArray.pointer, projectedVertexArray.size); pr->setAttributeArray(texturesColorShaderVars.vertex, (const GLfloat*)projectedVertexArray.pointer, projectedVertexArray.size);
pr->enableAttributeArray(texturesColorShaderVars.vertex); pr->enableAttributeArray(texturesColorShaderVars.vertex);
pr->setUniformValue(texturesColorShaderVars.projectionMatrix , qMat); pr->setUniformValue(texturesColorShaderVars.projectionMatrix , qMat);
pr->setAttributeArray(texturesColorShaderVars.texCoord, (con st GLfloat*)texCoordArray.pointer, 2); pr->setAttributeArray(texturesColorShaderVars.texCoord, (con st GLfloat*)texCoordArray.pointer, 2);
pr->enableAttributeArray(texturesColorShaderVars.texCoord); pr->enableAttributeArray(texturesColorShaderVars.texCoord);
pr->setAttributeArray(texturesColorShaderVars.color, (const GLfloat*)colorArray.pointer, colorArray.size); pr->setAttributeArray(texturesColorShaderVars.color, (const GLfloat*)colorArray.pointer, colorArray.size);
pr->enableAttributeArray(texturesColorShaderVars.color); pr->enableAttributeArray(texturesColorShaderVars.color);
//pr->setUniformValue(texturesShaderVars.texture, 0); // use texture unit 0
} }
else else
{ {
qDebug() << "Unhandled parameters." << texCoordArray.enabled << colorArray.enabled << normalArray.enabled; qDebug() << "Unhandled parameters." << texCoordArray.enabled << colorArray.enabled << normalArray.enabled;
qDebug() << "Light: " << light.isEnabled(); qDebug() << "Light: " << light.isEnabled();
return; return;
} }
#endif #endif
if (indices) if (indices)
glDrawElements(mode, count, GL_UNSIGNED_INT, indices + offse t); glDrawElements(mode, count, GL_UNSIGNED_INT, indices + offse t);
skipping to change at line 1857 skipping to change at line 2037
ret.pointer = polygonVertexArray.constData(); ret.pointer = polygonVertexArray.constData();
ret.enabled = array.enabled; ret.enabled = array.enabled;
return ret; return ret;
} }
// Light methods // Light methods
void StelPainterLight::setPosition(const Vec4f& v) void StelPainterLight::setPosition(const Vec4f& v)
{ {
position = v; position = v;
#ifndef STELPAINTER_GL2
glLightfv(GL_LIGHT0 + light, GL_POSITION, v);
#endif
} }
void StelPainterLight::setDiffuse(const Vec4f& v) void StelPainterLight::setDiffuse(const Vec4f& v)
{ {
diffuse = v; diffuse = v;
#ifndef STELPAINTER_GL2
glLightfv(GL_LIGHT0 + light, GL_DIFFUSE, v);
#endif
} }
void StelPainterLight::setSpecular(const Vec4f& v) void StelPainterLight::setSpecular(const Vec4f& v)
{ {
specular = v; specular = v;
#ifndef STELPAINTER_GL2
glLightfv(GL_LIGHT0 + light, GL_SPECULAR, v);
#endif
} }
void StelPainterLight::setAmbient(const Vec4f& v) void StelPainterLight::setAmbient(const Vec4f& v)
{ {
ambient = v; ambient = v;
#ifndef STELPAINTER_GL2
glLightfv(GL_LIGHT0 + light, GL_AMBIENT, v);
#endif
} }
void StelPainterLight::setEnable(bool v) void StelPainterLight::setEnable(bool v)
{ {
if (v) if (v)
enable(); enable();
else else
disable(); disable();
} }
void StelPainterLight::enable() void StelPainterLight::enable()
{ {
enabled = true; enabled = true;
#ifndef STELPAINTER_GL2
glEnable(GL_LIGHTING);
#endif
} }
void StelPainterLight::disable() void StelPainterLight::disable()
{ {
enabled = false; enabled = false;
#ifndef STELPAINTER_GL2
glDisable(GL_LIGHTING);
#endif
} }
// material functions // material functions
StelPainterMaterial::StelPainterMaterial() StelPainterMaterial::StelPainterMaterial()
: specular(0, 0, 0, 1), ambient(0.2, 0.2, 0.2, 1.0), emission(0, 0, 0, 1), shininess(0) : specular(0, 0, 0, 1), ambient(0.2, 0.2, 0.2, 1.0), emission(0, 0, 0, 1), shininess(0)
{ {
} }
void StelPainterMaterial::setSpecular(const Vec4f& v) void StelPainterMaterial::setSpecular(const Vec4f& v)
{ {
specular = v; specular = v;
#ifndef STELPAINTER_GL2
glMaterialfv(GL_FRONT, GL_SPECULAR, v);
#endif
} }
void StelPainterMaterial::setAmbient(const Vec4f& v) void StelPainterMaterial::setAmbient(const Vec4f& v)
{ {
ambient = v; ambient = v;
#ifndef STELPAINTER_GL2
glMaterialfv(GL_FRONT, GL_AMBIENT, v);
#endif
} }
void StelPainterMaterial::setEmission(const Vec4f& v) void StelPainterMaterial::setEmission(const Vec4f& v)
{ {
emission = v; emission = v;
#ifndef STELPAINTER_GL2
glMaterialfv(GL_FRONT, GL_EMISSION, v);
#endif
} }
void StelPainterMaterial::setShininess(float v) void StelPainterMaterial::setShininess(float v)
{ {
shininess = v; shininess = v;
#ifndef STELPAINTER_GL2
glMaterialfv(GL_FRONT, GL_SHININESS, &v);
#endif
} }
 End of changes. 117 change blocks. 
258 lines changed or deleted 437 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/