Use shaders to draw object as point (dumb version)
parent
a4af9e3e05
commit
539f80367f
|
@ -3524,6 +3524,51 @@ void Renderer::draw(const Observer& observer,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderPoint(const Renderer &renderer,
|
||||||
|
const Vector3f &position,
|
||||||
|
const Color &color,
|
||||||
|
float size,
|
||||||
|
bool useSprite)
|
||||||
|
{
|
||||||
|
CelestiaGLProgram *prog;
|
||||||
|
if (useSprite)
|
||||||
|
prog = renderer.getShaderManager().getShader("star");
|
||||||
|
else
|
||||||
|
prog = renderer.getShaderManager().getShader(ShaderProperties::PerVertexColor);
|
||||||
|
if (prog == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prog->use();
|
||||||
|
prog->samplerParam("starTex") = 0;
|
||||||
|
|
||||||
|
glEnable(GL_POINT_SPRITE);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, &position);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
Vector4f mainColor = color.toVector4();
|
||||||
|
glColorPointer(4, GL_FLOAT, 0, &mainColor);
|
||||||
|
glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
|
||||||
|
if (useSprite)
|
||||||
|
{
|
||||||
|
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
|
||||||
|
1, GL_FLOAT, GL_FALSE,
|
||||||
|
0, &size);
|
||||||
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDrawArrays(GL_POINTS, 0, 1);
|
||||||
|
|
||||||
|
if (useSprite)
|
||||||
|
{
|
||||||
|
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
|
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
|
||||||
|
}
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisable(GL_POINT_SPRITE);
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
// If the an object occupies a pixel or less of screen space, we don't
|
// If the an object occupies a pixel or less of screen space, we don't
|
||||||
// render its mesh at all and just display a starlike point instead.
|
// render its mesh at all and just display a starlike point instead.
|
||||||
// Switching between the particle and mesh renderings of an object is
|
// Switching between the particle and mesh renderings of an object is
|
||||||
|
@ -3610,53 +3655,11 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
|
||||||
glareAlpha *= fade;
|
glareAlpha *= fade;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix3f m = cameraOrientation.conjugate().toRotationMatrix();
|
|
||||||
Vector3f center = position;
|
|
||||||
|
|
||||||
// Offset the glare sprite so that it lies in front of the object
|
|
||||||
Vector3f direction = center.normalized();
|
|
||||||
|
|
||||||
// Position the sprite on the the line between the viewer and the
|
|
||||||
// object, and on a plane normal to the view direction.
|
|
||||||
center = center + direction * (radius / (m * Vector3f::UnitZ()).dot(direction));
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
#if !defined(NO_MAX_POINT_SIZE)
|
bool useSprites = starStyle != PointStars;
|
||||||
// TODO: OpenGL appears to limit the max point size unless we
|
if (useSprites)
|
||||||
// actually set up a shader that writes the pointsize values. To get
|
|
||||||
// around this, we'll use billboards.
|
|
||||||
Vector3f v0 = m * Vector3f(-1, -1, 0);
|
|
||||||
Vector3f v1 = m * Vector3f( 1, -1, 0);
|
|
||||||
Vector3f v2 = m * Vector3f( 1, 1, 0);
|
|
||||||
Vector3f v3 = m * Vector3f(-1, 1, 0);
|
|
||||||
float distanceAdjust = pixelSize * center.norm() * 0.5f;
|
|
||||||
|
|
||||||
if (starStyle == PointStars)
|
|
||||||
{
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glColor(color, alpha);
|
|
||||||
glVertex(center);
|
|
||||||
glEnd();
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gaussianDiscTex->bind();
|
gaussianDiscTex->bind();
|
||||||
|
renderPoint(*this, position, {color, alpha}, pointSize, useSprites);
|
||||||
pointSize *= distanceAdjust;
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glColor(color, alpha);
|
|
||||||
glTexCoord2f(0, 1);
|
|
||||||
glVertex(center + (v0 * pointSize));
|
|
||||||
glTexCoord2f(1, 1);
|
|
||||||
glVertex(center + (v1 * pointSize));
|
|
||||||
glTexCoord2f(1, 0);
|
|
||||||
glVertex(center + (v2 * pointSize));
|
|
||||||
glTexCoord2f(0, 0);
|
|
||||||
glVertex(center + (v3 * pointSize));
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the object is brighter than magnitude 1, add a halo around it to
|
// If the object is brighter than magnitude 1, add a halo around it to
|
||||||
// make it appear more brilliant. This is a hack to compensate for the
|
// make it appear more brilliant. This is a hack to compensate for the
|
||||||
|
@ -3667,52 +3670,10 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
|
||||||
if (useHalos && glareAlpha > 0.0f)
|
if (useHalos && glareAlpha > 0.0f)
|
||||||
{
|
{
|
||||||
gaussianGlareTex->bind();
|
gaussianGlareTex->bind();
|
||||||
|
renderPoint(*this, position, {color, glareAlpha}, glareSize, true);
|
||||||
glareSize *= distanceAdjust;
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glColor(color, glareAlpha);
|
|
||||||
glTexCoord2f(0, 1);
|
|
||||||
glVertex(center + (v0 * glareSize));
|
|
||||||
glTexCoord2f(1, 1);
|
|
||||||
glVertex(center + (v1 * glareSize));
|
|
||||||
glTexCoord2f(1, 0);
|
|
||||||
glVertex(center + (v2 * glareSize));
|
|
||||||
glTexCoord2f(0, 0);
|
|
||||||
glVertex(center + (v3 * glareSize));
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Disabled because of point size limits
|
|
||||||
glEnable(GL_POINT_SPRITE);
|
|
||||||
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
|
|
||||||
|
|
||||||
gaussianDiscTex->bind();
|
|
||||||
glColor(color, alpha);
|
|
||||||
glPointSize(pointSize);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glVertex(center);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
// If the object is brighter than magnitude 1, add a halo around it to
|
|
||||||
// make it appear more brilliant. This is a hack to compensate for the
|
|
||||||
// limited dynamic range of monitors.
|
|
||||||
//
|
|
||||||
// TODO: Stars look fine but planets look unrealistically bright
|
|
||||||
// with halos.
|
|
||||||
if (useHalos && glareAlpha > 0.0f)
|
|
||||||
{
|
|
||||||
gaussianGlareTex->bind();
|
|
||||||
|
|
||||||
glColor(color, glareAlpha);
|
|
||||||
glPointSize(glareSize);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glVertex(center);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_POINT_SPRITE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
#endif // NO_MAX_POINT_SIZE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue