Reimplement galaxies using shaders
parent
02bcf41173
commit
39eb715f98
|
@ -0,0 +1,11 @@
|
|||
#version 120
|
||||
|
||||
varying vec4 color;
|
||||
varying vec2 texCoord;
|
||||
|
||||
uniform sampler2D galaxyTex;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = texture2D(galaxyTex, texCoord) * color;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#version 120
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
|
||||
varying vec4 color;
|
||||
varying vec2 texCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// we pass color index as short int
|
||||
// reusing gl_MultiTexCoord0.z
|
||||
// we use 255 only because we have 256 color indices
|
||||
float t = gl_MultiTexCoord0.z / 255.0f; // [0, 255] -> [0, 1]
|
||||
// we pass alpha values as as short int
|
||||
// reusing gl_MultiTexCoord0.w
|
||||
// we use 65535 for better precision
|
||||
float a = gl_MultiTexCoord0.w / 65535.0f; // [0, 65535] -> [0, 1]
|
||||
color = vec4(texture2D(colorTex, vec2(t, 0.0f)).rgb, a);
|
||||
texCoord = gl_MultiTexCoord0.st;
|
||||
gl_Position = ftransform();
|
||||
}
|
|
@ -31,7 +31,6 @@ using namespace std;
|
|||
using namespace celmath;
|
||||
|
||||
static int width = 128, height = 128;
|
||||
static Vector3f colorTable[256];
|
||||
static const unsigned int GALAXY_POINTS = 3500;
|
||||
|
||||
static bool formsInitialized = false;
|
||||
|
@ -41,6 +40,7 @@ static GalacticForm** ellipticalForms = nullptr;
|
|||
static GalacticForm* irregularForm = nullptr;
|
||||
|
||||
static Texture* galaxyTex = nullptr;
|
||||
static Texture* colorTex = nullptr;
|
||||
|
||||
static void InitializeForms();
|
||||
static GalacticForm* buildGalacticForms(const fs::path& filename);
|
||||
|
@ -106,6 +106,21 @@ static void GalaxyTextureEval(float u, float v, float /*w*/, unsigned char *pixe
|
|||
pixel[3] = pixVal;
|
||||
}
|
||||
|
||||
static void ColorTextureEval(float u, float v, float /*w*/, unsigned char *pixel)
|
||||
{
|
||||
unsigned int i = (u*0.5f + 0.5f)*255.99f; // [-1, 1] -> [0, 255]
|
||||
|
||||
// generic Hue profile as deduced from true-color imaging for spirals
|
||||
// Hue in degrees
|
||||
float hue = 25 * tanh(0.0615f * (27 - i));
|
||||
if (i >= 28) hue += 220;
|
||||
//convert Hue to RGB
|
||||
float r, g, b;
|
||||
DeepSkyObject::hsv2rgb(&r, &g, &b, hue, 0.20f, 1.0f);
|
||||
pixel[0] = (unsigned char) (r * 255.99f);
|
||||
pixel[1] = (unsigned char) (g * 255.99f);
|
||||
pixel[2] = (unsigned char) (b * 255.99f);
|
||||
}
|
||||
|
||||
float Galaxy::getDetail() const
|
||||
{
|
||||
|
@ -257,7 +272,7 @@ void Galaxy::render(const Vector3f& offset,
|
|||
const Quaternionf& viewerOrientation,
|
||||
float brightness,
|
||||
float pixelSize,
|
||||
const Renderer* /* unused */)
|
||||
const Renderer* renderer)
|
||||
{
|
||||
if (form == nullptr)
|
||||
{
|
||||
|
@ -265,20 +280,30 @@ void Galaxy::render(const Vector3f& offset,
|
|||
}
|
||||
else
|
||||
{
|
||||
renderGalaxyPointSprites(offset, viewerOrientation, brightness, pixelSize);
|
||||
renderGalaxyPointSprites(offset, viewerOrientation, brightness, pixelSize, renderer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void glVertex4(const Vector4f& v)
|
||||
struct GalaxyVertex
|
||||
{
|
||||
glVertex3fv(v.data());
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
|
||||
|
||||
Vector4f position;
|
||||
Matrix<GLshort, 4, 1> texCoord; // texCoord.x = x, texCoord.y = y, texCoord.z = color index, texCoord.w = alpha
|
||||
};
|
||||
|
||||
static void draw(const GalaxyVertex *v, size_t count, void *indices)
|
||||
{
|
||||
glVertexPointer(4, GL_FLOAT, sizeof(GalaxyVertex), &v->position);
|
||||
glTexCoordPointer(4, GL_SHORT, sizeof(GalaxyVertex), &v->texCoord);
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
|
||||
}
|
||||
|
||||
void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
||||
const Quaternionf& viewerOrientation,
|
||||
float brightness,
|
||||
float pixelSize)
|
||||
float pixelSize,
|
||||
const Renderer* renderer)
|
||||
{
|
||||
if (form == nullptr)
|
||||
return;
|
||||
|
@ -297,16 +322,28 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
|||
if (size < minimumFeatureSize)
|
||||
return;
|
||||
|
||||
auto *prog = renderer->getShaderManager().getShader("galaxy");
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
if (galaxyTex == nullptr)
|
||||
{
|
||||
galaxyTex = CreateProceduralTexture(width, height, GL_RGBA,
|
||||
GalaxyTextureEval);
|
||||
}
|
||||
assert(galaxyTex != nullptr);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
galaxyTex->bind();
|
||||
|
||||
if (colorTex == nullptr)
|
||||
{
|
||||
colorTex = CreateProceduralTexture(256, 1, GL_RGBA,
|
||||
ColorTextureEval);
|
||||
}
|
||||
assert(colorTex != nullptr);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
colorTex->bind();
|
||||
|
||||
Matrix3f viewMat = viewerOrientation.conjugate().toRotationMatrix();
|
||||
Vector4f v0(Vector4f::Zero());
|
||||
Vector4f v1(Vector4f::Zero());
|
||||
|
@ -317,12 +354,7 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
|||
v2.head(3) = viewMat * Vector3f( 1, 1, 0) * size;
|
||||
v3.head(3) = viewMat * Vector3f(-1, 1, 0) * size;
|
||||
|
||||
//Mat4f m = (getOrientation().toMatrix4() *
|
||||
// Mat4f::scaling(form->scale) *
|
||||
// Mat4f::scaling(getRadius()));
|
||||
|
||||
Quaternionf orientation = getOrientation().conjugate();
|
||||
|
||||
Matrix3f mScale = form->scale.asDiagonal() * size;
|
||||
Matrix3f mLinear = orientation.toRotationMatrix() * mScale;
|
||||
|
||||
|
@ -330,7 +362,7 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
|||
m.topLeftCorner(3,3) = mLinear;
|
||||
m.block<3,1>(0, 3) = offset;
|
||||
|
||||
int pow2 = 1;
|
||||
int pow2 = 1;
|
||||
|
||||
BlobVector* points = form->blobs;
|
||||
unsigned int nPoints = (unsigned int) (points->size() * clamp(getDetail()));
|
||||
|
@ -357,10 +389,22 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
|||
glPushMatrix();
|
||||
glTranslatef(-offset.x(), -offset.y(), -offset.z());
|
||||
|
||||
float btot = ((type > SBc) && (type < Irr))? 2.5f: 5.0f;
|
||||
const float btot = ((type > SBc) && (type < Irr)) ? 2.5f : 5.0f;
|
||||
const float spriteScaleFactor = 1.0f / 1.55f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
vector<GalaxyVertex, aligned_allocator<GalaxyVertex>> vertices;
|
||||
vertices.reserve(4096 / sizeof(GalaxyVertex));
|
||||
vector<short> indices;
|
||||
indices.reserve(4096 / sizeof(GalaxyVertex) / 4 * 6); // 6 indices per 4 vertices
|
||||
unsigned short j = 0;
|
||||
|
||||
prog->use();
|
||||
prog->samplerParam("galaxyTex") = 0;
|
||||
prog->samplerParam("colorTex") = 1;
|
||||
|
||||
for (unsigned int i = 0; i < nPoints; ++i)
|
||||
{
|
||||
if ((i & pow2) != 0)
|
||||
|
@ -379,22 +423,52 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
|
|||
Vector4f p = m * b.position;
|
||||
float br = b.brightness / 255.0f;
|
||||
|
||||
Vector3f c = colorTable[b.colorIndex]; // lookup static color table
|
||||
|
||||
float screenFrac = size / p.norm();
|
||||
if (screenFrac < 0.1f)
|
||||
{
|
||||
float a = btot * (0.1f - screenFrac) * brightness_corr * brightness * br;
|
||||
glColor4f(c.x(), c.y(), c.z(), (4.0f * lightGain + 1.0f) * a);
|
||||
glTexCoord2f(0, 0); glVertex4(p + v0);
|
||||
glTexCoord2f(1, 0); glVertex4(p + v1);
|
||||
glTexCoord2f(1, 1); glVertex4(p + v2);
|
||||
glTexCoord2f(0, 1); glVertex4(p + v3);
|
||||
float a = (4.0f * lightGain + 1.0f) * btot * (0.1f - screenFrac) * brightness_corr * brightness * br;
|
||||
short alpha = (short) (a * 65535.99f);
|
||||
short color = (short)b.colorIndex;
|
||||
GalaxyVertex vtx;
|
||||
vtx.position = p + v0;
|
||||
vtx.texCoord = { 0, 0, color, alpha };
|
||||
vertices.push_back(vtx);
|
||||
vtx.position = p + v1;
|
||||
vtx.texCoord = { 1, 0, color, alpha };
|
||||
vertices.push_back(vtx);
|
||||
vtx.position = p + v2;
|
||||
vtx.texCoord = { 1, 1, color, alpha };
|
||||
vertices.push_back(vtx);
|
||||
vtx.position = p + v3;
|
||||
vtx.texCoord = { 0, 1, color, alpha };
|
||||
vertices.push_back(vtx);
|
||||
|
||||
indices.push_back(j+0);
|
||||
indices.push_back(j+1);
|
||||
indices.push_back(j+2);
|
||||
indices.push_back(j+0);
|
||||
indices.push_back(j+2);
|
||||
indices.push_back(j+3);
|
||||
j += 4;
|
||||
|
||||
if ((vertices.size() + 4) * sizeof(GalaxyVertex) > 4096)
|
||||
{
|
||||
draw(&vertices[0], indices.size(), indices.data());
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
if (indices.size() > 0)
|
||||
draw(&vertices[0], indices.size(), indices.data());
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glUseProgram(0);
|
||||
glPopMatrix();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -495,12 +569,7 @@ float Galaxy::getLightGain()
|
|||
|
||||
void Galaxy::setLightGain(float lg)
|
||||
{
|
||||
if (lg < 0.0f)
|
||||
lightGain = 0.0f;
|
||||
else if (lg > 1.0f)
|
||||
lightGain = 1.0f;
|
||||
else
|
||||
lightGain = lg;
|
||||
lightGain = clamp(lg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -601,23 +670,6 @@ GalacticForm* buildGalacticForms(const fs::path& filename)
|
|||
|
||||
void InitializeForms()
|
||||
{
|
||||
// build color table:
|
||||
|
||||
for (unsigned int i = 0; i < 256; i++)
|
||||
{
|
||||
float rr, gg, bb;
|
||||
//
|
||||
// generic Hue profile as deduced from true-color imaging for spirals
|
||||
// Hue in degrees
|
||||
|
||||
float hue = (i < 28)? 25 * tanh(0.0615f * (27 - i)): 25 * tanh(0.0615f * (27 - i)) + 220;
|
||||
|
||||
//convert Hue to RGB
|
||||
|
||||
DeepSkyObject::hsv2rgb(&rr, &gg, &bb, hue, 0.20f, 1.0f);
|
||||
Color c(rr, gg, bb);
|
||||
colorTable[i] = Vector3f(c.red(), c.green(), c.blue());
|
||||
}
|
||||
// Spiral Galaxies, 7 classical Hubble types
|
||||
|
||||
spiralForms = new GalacticForm*[7];
|
||||
|
|
|
@ -47,7 +47,7 @@ class Galaxy : public DeepSkyObject
|
|||
const Eigen::Quaternionf& viewerOrientation,
|
||||
float brightness,
|
||||
float pixelSize,
|
||||
const Renderer* r = nullptr) override;
|
||||
const Renderer* r) override;
|
||||
|
||||
GalacticForm* getForm() const;
|
||||
|
||||
|
@ -85,7 +85,8 @@ class Galaxy : public DeepSkyObject
|
|||
void renderGalaxyPointSprites(const Eigen::Vector3f& offset,
|
||||
const Eigen::Quaternionf& viewerOrientation,
|
||||
float brightness,
|
||||
float pixelSize);
|
||||
float pixelSize,
|
||||
const Renderer* r);
|
||||
#if 0
|
||||
void renderGalaxyEllipsoid(const Eigen::Vector3f& offset,
|
||||
const Eigen::Quaternionf& viewerOrientation,
|
||||
|
|
Loading…
Reference in New Issue