Reimplement comets using glsl (part I)
TODO: 1) use VertexObject 2) possibly offload more computation to GPUpull/3/head
parent
702531879c
commit
5af66f9ab2
|
@ -0,0 +1,9 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform vec3 color;
|
||||||
|
varying float shade;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(color, shade);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
attribute float brightness;
|
||||||
|
|
||||||
|
uniform vec3 color;
|
||||||
|
uniform vec3 viewDir;
|
||||||
|
uniform float fadeFactor;
|
||||||
|
|
||||||
|
varying float shade;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
shade = abs(dot(viewDir.xyz, gl_Normal.xyz) * brightness * fadeFactor);
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
|
@ -5355,22 +5355,6 @@ struct CometTailVertex
|
||||||
|
|
||||||
static CometTailVertex cometTailVertices[CometTailSlices * MaxCometTailPoints];
|
static CometTailVertex cometTailVertices[CometTailSlices * MaxCometTailPoints];
|
||||||
|
|
||||||
static void ProcessCometTailVertex(const Color& cometTailColor,
|
|
||||||
const CometTailVertex& v,
|
|
||||||
const Vector3f& viewDir,
|
|
||||||
float fadeDistFromSun)
|
|
||||||
{
|
|
||||||
// If fadeDistFromSun = x/x0 >= 1.0, comet tail starts fading,
|
|
||||||
// i.e. fadeFactor quickly transits from 1 to 0.
|
|
||||||
|
|
||||||
float fadeFactor = 0.5f - 0.5f * (float) tanh(fadeDistFromSun - 1.0f / fadeDistFromSun);
|
|
||||||
float shade = abs(viewDir.dot(v.normal) * v.brightness * fadeFactor);
|
|
||||||
glColor4f(cometTailColor.red(), cometTailColor.green(),
|
|
||||||
cometTailColor.blue(), shade);
|
|
||||||
glVertex(v.point);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Compute a rough estimate of the visible length of the dust tail.
|
// Compute a rough estimate of the visible length of the dust tail.
|
||||||
// TODO: This is old code that needs to be rewritten. For one thing,
|
// TODO: This is old code that needs to be rewritten. For one thing,
|
||||||
// the length is inversely proportional to the distance from the sun,
|
// the length is inversely proportional to the distance from the sun,
|
||||||
|
@ -5389,6 +5373,10 @@ void Renderer::renderCometTail(const Body& body,
|
||||||
const Observer& observer,
|
const Observer& observer,
|
||||||
float discSizeInPixels)
|
float discSizeInPixels)
|
||||||
{
|
{
|
||||||
|
auto prog = shaderManager->getShader("comet");
|
||||||
|
if (prog == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
double now = observer.getTime();
|
double now = observer.getTime();
|
||||||
|
|
||||||
Vector3f cometPoints[MaxCometTailPoints];
|
Vector3f cometPoints[MaxCometTailPoints];
|
||||||
|
@ -5453,74 +5441,57 @@ void Renderer::renderCometTail(const Body& body,
|
||||||
Vector3f u = v.unitOrthogonal();
|
Vector3f u = v.unitOrthogonal();
|
||||||
Vector3f w = u.cross(v);
|
Vector3f w = u.cross(v);
|
||||||
|
|
||||||
glColor4f(0.0f, 1.0f, 1.0f, 0.5f);
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslate(pos);
|
|
||||||
|
|
||||||
// glActiveTexture(GL_TEXTURE0);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
||||||
|
|
||||||
for (i = 0; i < nTailPoints; i++)
|
for (i = 0; i < nTailPoints; i++)
|
||||||
{
|
{
|
||||||
float brightness = 1.0f - (float) i / (float) (nTailPoints - 1);
|
float brightness = 1.0f - (float) i / (float) (nTailPoints - 1);
|
||||||
Vector3f v0, v1;
|
Vector3f v0, v1;
|
||||||
float sectionLength;
|
float sectionLength;
|
||||||
if (i != 0 && i != nTailPoints - 1)
|
float w0, w1;
|
||||||
|
// Special case the first vertex in the comet tail
|
||||||
|
if (i == 0)
|
||||||
{
|
{
|
||||||
v0 = cometPoints[i] - cometPoints[i - 1];
|
v0 = cometPoints[1] - cometPoints[0];
|
||||||
v1 = cometPoints[i + 1] - cometPoints[i];
|
|
||||||
sectionLength = v0.norm();
|
|
||||||
v0.normalize();
|
|
||||||
v1.normalize();
|
|
||||||
q.setFromTwoVectors(v0, v1);
|
|
||||||
Matrix3f m = q.toRotationMatrix();
|
|
||||||
u = m * u;
|
|
||||||
v = m * v;
|
|
||||||
w = m * w;
|
|
||||||
}
|
|
||||||
else if (i == 0)
|
|
||||||
{
|
|
||||||
v0 = cometPoints[i + 1] - cometPoints[i];
|
|
||||||
sectionLength = v0.norm();
|
sectionLength = v0.norm();
|
||||||
v0.normalize();
|
v0.normalize();
|
||||||
v1 = v0;
|
v1 = v0;
|
||||||
|
w0 = 1.0f;
|
||||||
|
w1 = 0.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v0 = cometPoints[i] - cometPoints[i - 1];
|
v0 = cometPoints[i] - cometPoints[i - 1];
|
||||||
sectionLength = v0.norm();
|
sectionLength = v0.norm();
|
||||||
v0.normalize();
|
v0.normalize();
|
||||||
v1 = v0;
|
|
||||||
}
|
if (i == nTailPoints - 1)
|
||||||
|
{
|
||||||
float radius = (float) i / (float) nTailPoints *
|
v1 = v0;
|
||||||
dustTailRadius;
|
}
|
||||||
float dr = (dustTailRadius / (float) nTailPoints) /
|
else
|
||||||
sectionLength;
|
{
|
||||||
|
v1 = (cometPoints[i + 1] - cometPoints[i]).normalized();
|
||||||
auto w0 = (float) atan(dr);
|
q.setFromTwoVectors(v0, v1);
|
||||||
float d = std::sqrt(1.0f + w0 * w0);
|
Matrix3f m = q.toRotationMatrix();
|
||||||
float w1 = 1.0f / d;
|
u = m * u;
|
||||||
w0 = w0 / d;
|
v = m * v;
|
||||||
|
w = m * w;
|
||||||
// Special case the first vertex in the comet tail
|
}
|
||||||
if (i == 0)
|
float dr = (dustTailRadius / (float) nTailPoints) / sectionLength;
|
||||||
{
|
w0 = atan(dr);
|
||||||
w0 = 1;
|
float d = sqrt(1.0f + w0 * w0);
|
||||||
w1 = 0.0f;
|
w1 = 1.0f / d;
|
||||||
|
w0 = w0 / d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float radius = (float) i / (float) nTailPoints * dustTailRadius;
|
||||||
for (int j = 0; j < nTailSlices; j++)
|
for (int j = 0; j < nTailSlices; j++)
|
||||||
{
|
{
|
||||||
float theta = (float) (2 * PI * (float) j / nTailSlices);
|
float theta = (float) (2 * PI * (float) j / nTailSlices);
|
||||||
auto s = (float) sin(theta);
|
float s, c;
|
||||||
auto c = (float) cos(theta);
|
sincos(theta, s, c);
|
||||||
CometTailVertex& vtx = cometTailVertices[i * nTailSlices + j];
|
CometTailVertex& vtx = cometTailVertices[i * nTailSlices + j];
|
||||||
vtx.normal = u * (s * w1) + w * (c * w1) + v * w0;
|
vtx.normal = u * (s * w1) + w * (c * w1) + v * w0;
|
||||||
|
vtx.normal.normalize();
|
||||||
s *= radius;
|
s *= radius;
|
||||||
c *= radius;
|
c *= radius;
|
||||||
|
|
||||||
|
@ -5529,40 +5500,65 @@ void Renderer::renderCometTail(const Body& body,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f viewDir = pos.normalized();
|
glPushMatrix();
|
||||||
|
glTranslate(pos);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
|
||||||
|
prog->use();
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
auto brightness = prog->attribIndex("brightness");
|
||||||
|
if (brightness != -1)
|
||||||
|
glEnableVertexAttribArray(brightness);
|
||||||
|
prog->vec3Param("color") = body.getCometTailColor().toVector3();
|
||||||
|
prog->vec3Param("viewDir") = pos.normalized();
|
||||||
|
// If fadeDistFromSun = x/x0 >= 1.0, comet tail starts fading,
|
||||||
|
// i.e. fadeFactor quickly transits from 1 to 0.
|
||||||
|
float fadeFactor = 0.5f * (1.0f - tanh(fadeDistance - 1.0f / fadeDistance));
|
||||||
|
prog->floatParam("fadeFactor") = fadeFactor;
|
||||||
|
|
||||||
|
vector<unsigned short> indeces;
|
||||||
|
indeces.reserve(nTailSlices * 2 + 2);
|
||||||
|
for (int j = 0; j < nTailSlices; j++)
|
||||||
|
{
|
||||||
|
indeces.push_back(j);
|
||||||
|
indeces.push_back(j + nTailSlices);
|
||||||
|
}
|
||||||
|
indeces.push_back(0);
|
||||||
|
indeces.push_back(nTailSlices);
|
||||||
|
|
||||||
|
const size_t stride = sizeof(CometTailVertex);
|
||||||
for (i = 0; i < nTailPoints - 1; i++)
|
for (i = 0; i < nTailPoints - 1; i++)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUAD_STRIP);
|
const auto p = &cometTailVertices[i * nTailSlices];
|
||||||
int n = i * nTailSlices;
|
glVertexPointer(3, GL_FLOAT, stride, &p->point);
|
||||||
for (int j = 0; j < nTailSlices; j++)
|
glNormalPointer(GL_FLOAT, stride, &p->normal);
|
||||||
{
|
if (brightness != -1)
|
||||||
ProcessCometTailVertex(body.getCometTailColor(),
|
glVertexAttribPointer(brightness, 1, GL_FLOAT, GL_FALSE, stride, &p->brightness);
|
||||||
cometTailVertices[n + j], viewDir,
|
glDrawElements(GL_TRIANGLE_STRIP, indeces.size(), GL_UNSIGNED_SHORT, indeces.data());
|
||||||
fadeDistance);
|
|
||||||
ProcessCometTailVertex(body.getCometTailColor(),
|
|
||||||
cometTailVertices[n + j + nTailSlices],
|
|
||||||
viewDir, fadeDistance);
|
|
||||||
}
|
|
||||||
ProcessCometTailVertex(body.getCometTailColor(),
|
|
||||||
cometTailVertices[n], viewDir, fadeDistance);
|
|
||||||
ProcessCometTailVertex(body.getCometTailColor(),
|
|
||||||
cometTailVertices[n + nTailSlices],
|
|
||||||
viewDir, fadeDistance);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
if (brightness == -1)
|
||||||
|
glDisableVertexAttribArray(brightness);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
#ifdef DEBUG_COMET_TAIL
|
||||||
for (i = 0; i < nTailPoints; i++)
|
glDisable(GL_TEXTURE_2D);
|
||||||
{
|
glDisable(GL_LIGHTING);
|
||||||
glVertex(cometPoints[i]);
|
glColor4f(0.0f, 1.0f, 1.0f, 0.5f);
|
||||||
}
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnd();
|
glVertexPointer(3, GL_FLOAT, 0, cometPoints);
|
||||||
|
glDrawArrays(GL_LINE_STRIP, 0, nTailPoints);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
#endif
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue