Add LOD for planet rings

pull/3/head
Hleb Valoshka 2019-10-31 21:22:44 +03:00
parent 9e9541ce1b
commit 0af14d4ca8
4 changed files with 31 additions and 12 deletions

View File

@ -23,6 +23,7 @@
#include <GL/glew.h>
#include <string>
#include <vector>
#include <array>
#include <map>
#include <list>
@ -87,7 +88,7 @@ class RingSystem
float outerRadius;
Color color;
MultiResTexture texture;
GLuint vboId{ 0 };
std::array<GLuint, 4> vboId {{ 0, 0, 0, 0 }};
RingSystem(float inner, float outer) :
innerRadius(inner), outerRadius(outer),

View File

@ -4783,15 +4783,20 @@ void Renderer::renderObject(const Vector3f& pos,
}
}
if (obj.rings != nullptr &&
(renderFlags & ShowPlanetRings) != 0 &&
distance <= obj.rings->innerRadius)
float segmentSizeInPixels = 0.0f;
if (obj.rings != nullptr && (renderFlags & ShowPlanetRings) != 0)
{
renderRings_GLSL(*obj.rings, ri, ls,
radius, 1.0f - obj.semiAxes.y(),
textureResolution,
(renderFlags & ShowRingShadows) != 0 && lit,
this);
// calculate ring segment size in pixels, actual size is segmentSizeInPixels * tan(segmentAngle)
segmentSizeInPixels = 2.0f * obj.rings->outerRadius / (max(nearPlaneDistance, altitude) * pixelSize);
if (distance <= obj.rings->innerRadius)
{
renderRings_GLSL(*obj.rings, ri, ls,
radius, 1.0f - obj.semiAxes.y(),
textureResolution,
(renderFlags & ShowRingShadows) != 0 && lit,
segmentSizeInPixels,
this);
}
}
if (obj.atmosphere != nullptr)
@ -4958,6 +4963,7 @@ void Renderer::renderObject(const Vector3f& pos,
radius, 1.0f - obj.semiAxes.y(),
textureResolution,
(renderFlags & ShowRingShadows) != 0 && lit,
segmentSizeInPixels,
this);
}
}

View File

@ -588,7 +588,8 @@ renderAtmosphere_GLSL(const RenderInfo& ri,
static void renderRingSystem(GLuint *vboId,
float innerRadius,
float outerRadius)
float outerRadius,
unsigned int nSections = 180)
{
struct RingVertex
{
@ -597,12 +598,12 @@ static void renderRingSystem(GLuint *vboId,
};
constexpr const float angle = 2*static_cast<float>(PI);
constexpr const unsigned int nSections = 180;
if (*vboId == 0)
{
struct RingVertex vertex;
vector<struct RingVertex> ringCoord;
ringCoord.reserve(2 * nSections);
for (unsigned i = 0; i <= nSections; i++)
{
float t = (float) i / (float) nSections;
@ -669,6 +670,7 @@ void renderRings_GLSL(RingSystem& rings,
float planetOblateness,
unsigned int textureResolution,
bool renderShadow,
float segmentSizeInPixels,
const Renderer* renderer)
{
float inner = rings.innerRadius / planetRadius;
@ -773,7 +775,16 @@ void renderRings_GLSL(RingSystem& rings,
else
glDisable(GL_TEXTURE_2D);
renderRingSystem(&rings.vboId, inner, outer);
unsigned nSections = 180;
size_t i = 0;
for (i = 0; i < rings.vboId.size() - 1; i++)
{
float s = segmentSizeInPixels * tan(PI / nSections);
if (s < 30.0f) // TODO: make configurable
break;
nSections <<= 1;
}
renderRingSystem(&rings.vboId[i], inner, outer, nSections);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);

View File

@ -68,6 +68,7 @@ void renderRings_GLSL(RingSystem& rings,
float planetOblateness,
unsigned int textureResolution,
bool renderShadow,
float segmentSizeInPixels,
const Renderer* renderer);
void renderGeometry_GLSL_Unlit(Geometry* geometry,