Support more than one light source when rendering objects.
parent
0846de52ba
commit
2f7d0089fc
|
@ -75,7 +75,8 @@ struct DirectionalLight
|
|||
{
|
||||
Color color;
|
||||
float intensity;
|
||||
Vec3f direction;
|
||||
Vec3f direction_eye;
|
||||
Vec3f direction_obj;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2875,6 +2875,8 @@ static void renderSphereDefault(const RenderInfo& ri,
|
|||
}
|
||||
|
||||
|
||||
// DEPRECATED -- renderSphere_Combiners_VP should be used instead; only
|
||||
// very old drivers don't support vertex programs.
|
||||
static void renderSphere_Combiners(const RenderInfo& ri,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
|
@ -2962,6 +2964,7 @@ static void renderSphere_Combiners(const RenderInfo& ri,
|
|||
|
||||
|
||||
static void renderSphere_DOT3_VP(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
{
|
||||
|
@ -2980,11 +2983,18 @@ static void renderSphere_DOT3_VP(const RenderInfo& ri,
|
|||
|
||||
vproc->enable();
|
||||
vproc->parameter(vp::EyePosition, ri.eyePos_obj);
|
||||
vproc->parameter(vp::SunDirection, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::SpecularExponent, 0.0f, 1.0f, 0.5f, ri.specularPower);
|
||||
vproc->parameter(vp::SpecularColor, ri.sunColor * ri.specularColor);
|
||||
vproc->parameter(vp::LightDirection0, ls.lights[0].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, ls.lights[0].color * ri.color);
|
||||
vproc->parameter(vp::SpecularColor0, ls.lights[0].color * ri.specularColor);
|
||||
if (ls.nLights > 1)
|
||||
{
|
||||
vproc->parameter(vp::LightDirection1, ls.lights[1].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor1, ls.lights[1].color * ri.color);
|
||||
vproc->parameter(vp::SpecularColor1, ls.lights[1].color * ri.specularColor);
|
||||
}
|
||||
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::SpecularExponent, 0.0f, 1.0f, 0.5f, ri.specularPower);
|
||||
|
||||
if (ri.bumpTex != NULL && ri.baseTex != NULL)
|
||||
{
|
||||
|
@ -3035,7 +3045,10 @@ static void renderSphere_DOT3_VP(const RenderInfo& ri,
|
|||
}
|
||||
else
|
||||
{
|
||||
vproc->use(vp::diffuse);
|
||||
if (ls.nLights > 1)
|
||||
vproc->use(vp::diffuse_2light);
|
||||
else
|
||||
vproc->use(vp::diffuse);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
lodSphere->render(context,
|
||||
LODSphereMesh::Normals | LODSphereMesh::TexCoords0 |
|
||||
|
@ -3098,6 +3111,7 @@ static void renderSphere_DOT3_VP(const RenderInfo& ri,
|
|||
|
||||
|
||||
static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
||||
const LightingState& ls,
|
||||
const Frustum& frustum,
|
||||
const GLContext& context)
|
||||
{
|
||||
|
@ -3139,10 +3153,17 @@ static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
|||
vproc->enable();
|
||||
|
||||
vproc->parameter(vp::EyePosition, ri.eyePos_obj);
|
||||
vproc->parameter(vp::SunDirection, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::LightDirection0, ls.lights[0].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, ls.lights[0].color * ri.color);
|
||||
vproc->parameter(vp::SpecularColor0, ls.lights[0].color * ri.specularColor);
|
||||
if (ls.nLights > 1)
|
||||
{
|
||||
vproc->parameter(vp::LightDirection1, ls.lights[1].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor1, ls.lights[1].color * ri.color);
|
||||
vproc->parameter(vp::SpecularColor1, ls.lights[1].color * ri.specularColor);
|
||||
}
|
||||
|
||||
vproc->parameter(vp::SpecularExponent, 0.0f, 1.0f, 0.5f, ri.specularPower);
|
||||
vproc->parameter(vp::SpecularColor, ri.sunColor * ri.specularColor);
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::HazeColor, ri.hazeColor);
|
||||
|
||||
|
@ -3172,7 +3193,7 @@ static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
|||
|
||||
// Disable ambient and diffuse
|
||||
vproc->parameter(vp::AmbientColor, Color::Black);
|
||||
vproc->parameter(vp::DiffuseColor, Color::Black);
|
||||
vproc->parameter(vp::DiffuseColor0, Color::Black);
|
||||
SetupCombinersGlossMap(ri.glossTex != NULL ? GL_TEXTURE0_ARB : 0);
|
||||
|
||||
textures[0] = ri.glossTex != NULL ? ri.glossTex : ri.baseTex;
|
||||
|
@ -3182,7 +3203,7 @@ static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
|||
textures, 1);
|
||||
|
||||
// re-enable diffuse
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::DiffuseColor0, ri.sunColor * ri.color);
|
||||
|
||||
DisableCombiners();
|
||||
glDisable(GL_COLOR_SUM_EXT);
|
||||
|
@ -3192,7 +3213,10 @@ static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
|||
else if (ri.specularColor != Color::Black)
|
||||
{
|
||||
glEnable(GL_COLOR_SUM_EXT);
|
||||
vproc->use(vp::specular);
|
||||
if (ls.nLights > 1)
|
||||
vproc->use(vp::specular_2light);
|
||||
else
|
||||
vproc->use(vp::specular);
|
||||
SetupCombinersGlossMapWithFog(ri.glossTex != NULL ? GL_TEXTURE1_ARB : 0);
|
||||
unsigned int attributes = LODSphereMesh::Normals | LODSphereMesh::TexCoords0 |
|
||||
LODSphereMesh::VertexProgParams;
|
||||
|
@ -3204,10 +3228,21 @@ static void renderSphere_Combiners_VP(const RenderInfo& ri,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (hazeDensity > 0.0f)
|
||||
vproc->use(vp::diffuseHaze);
|
||||
if (ls.nLights > 1)
|
||||
{
|
||||
if (hazeDensity > 0.0f)
|
||||
vproc->use(vp::diffuseHaze_2light);
|
||||
else
|
||||
vproc->use(vp::diffuse_2light);
|
||||
}
|
||||
else
|
||||
vproc->use(vp::diffuse);
|
||||
{
|
||||
if (hazeDensity > 0.0f)
|
||||
vproc->use(vp::diffuseHaze);
|
||||
else
|
||||
vproc->use(vp::diffuse);
|
||||
}
|
||||
|
||||
lodSphere->render(context,
|
||||
LODSphereMesh::Normals | LODSphereMesh::TexCoords0 |
|
||||
LODSphereMesh::VertexProgParams,
|
||||
|
@ -3293,10 +3328,10 @@ static void renderSphere_FP_VP(const RenderInfo& ri,
|
|||
vproc->enable();
|
||||
|
||||
vproc->parameter(vp::EyePosition, ri.eyePos_obj);
|
||||
vproc->parameter(vp::SunDirection, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::LightDirection0, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::SpecularExponent, 0.0f, 1.0f, 0.5f, ri.specularPower);
|
||||
vproc->parameter(vp::SpecularColor, ri.sunColor * ri.specularColor);
|
||||
vproc->parameter(vp::SpecularColor0, ri.sunColor * ri.specularColor);
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::HazeColor, ri.hazeColor);
|
||||
|
||||
|
@ -3326,7 +3361,7 @@ static void renderSphere_FP_VP(const RenderInfo& ri,
|
|||
|
||||
// Disable ambient and diffuse
|
||||
vproc->parameter(vp::AmbientColor, Color::Black);
|
||||
vproc->parameter(vp::DiffuseColor, Color::Black);
|
||||
vproc->parameter(vp::DiffuseColor0, Color::Black);
|
||||
SetupCombinersGlossMap(ri.glossTex != NULL ? GL_TEXTURE0_ARB : 0);
|
||||
|
||||
textures[0] = ri.glossTex != NULL ? ri.glossTex : ri.baseTex;
|
||||
|
@ -3336,7 +3371,7 @@ static void renderSphere_FP_VP(const RenderInfo& ri,
|
|||
textures, 1);
|
||||
|
||||
// re-enable diffuse
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::DiffuseColor0, ri.sunColor * ri.color);
|
||||
|
||||
DisableCombiners();
|
||||
glDisable(GL_COLOR_SUM_EXT);
|
||||
|
@ -3491,7 +3526,7 @@ static void renderShadowedModelVertexShader(const RenderInfo& ri,
|
|||
assert(vproc != NULL);
|
||||
|
||||
vproc->enable();
|
||||
vproc->parameter(vp::SunDirection, lightDir);
|
||||
vproc->parameter(vp::LightDirection0, lightDir);
|
||||
vproc->parameter(vp::TexGen_S, sPlane);
|
||||
vproc->parameter(vp::TexGen_T, tPlane);
|
||||
vproc->use(vp::shadowTexture);
|
||||
|
@ -3543,8 +3578,8 @@ static void renderRings(RingSystem& rings,
|
|||
{
|
||||
vproc->enable();
|
||||
vproc->use(vp::ringIllum);
|
||||
vproc->parameter(vp::SunDirection, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * rings.color);
|
||||
vproc->parameter(vp::LightDirection0, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, ri.sunColor * rings.color);
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::Constant0, Vec3f(0, 0.5, 1.0));
|
||||
}
|
||||
|
@ -3974,7 +4009,7 @@ renderEclipseShadows_Shaders(Model* model,
|
|||
vproc->parameter(vp::TexGen_T4, tPlanes[3]);
|
||||
}
|
||||
|
||||
//vproc->parameter(vp::SunDirection, lightDir);
|
||||
//vproc->parameter(vp::LightDirection0, lightDir);
|
||||
|
||||
lodSphere->render(context,
|
||||
LODSphereMesh::Normals | LODSphereMesh::Multipass,
|
||||
|
@ -4171,8 +4206,8 @@ renderRingShadowsVS(Model* model,
|
|||
|
||||
vproc->enable();
|
||||
vproc->use(vp::ringShadow);
|
||||
vproc->parameter(vp::SunDirection, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor, 1, 1, 1, alpha); // color = white
|
||||
vproc->parameter(vp::LightDirection0, ri.sunDir_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, 1, 1, 1, alpha); // color = white
|
||||
vproc->parameter(vp::TexGen_S,
|
||||
rings.innerRadius / planetRadius,
|
||||
1.0f / (ringWidth / planetRadius),
|
||||
|
@ -4316,6 +4351,7 @@ void Renderer::renderLocations(const vector<Location*>& locations,
|
|||
static void
|
||||
setupObjectLighting(const vector<Renderer::LightSource>& suns,
|
||||
const Point3d& objPosition,
|
||||
const Quatf& objOrientation,
|
||||
LightingState& ls)
|
||||
{
|
||||
unsigned int nLights = min(MaxLights, suns.size());
|
||||
|
@ -4326,9 +4362,11 @@ setupObjectLighting(const vector<Renderer::LightSource>& suns,
|
|||
for (i = 0; i < nLights; i++)
|
||||
{
|
||||
Vec3d dir = suns[i].position - objPosition;
|
||||
ls.lights[i].direction =
|
||||
ls.lights[i].direction_eye =
|
||||
Vec3f((float) dir.x, (float) dir.y, (float) dir.z);
|
||||
float distance = astro::kilometersToAU(ls.lights[i].direction.length());
|
||||
float distance = ls.lights[i].direction_eye.length();
|
||||
ls.lights[i].direction_eye *= 1.0f / distance;
|
||||
distance = astro::kilometersToAU((float) dir.length());
|
||||
ls.lights[i].intensity = suns[i].luminosity / (distance * distance);
|
||||
ls.lights[i].color = suns[i].color;
|
||||
}
|
||||
|
@ -4347,6 +4385,7 @@ setupObjectLighting(const vector<Renderer::LightSource>& suns,
|
|||
|
||||
// After sorting, the first light is always the brightest
|
||||
float maxIntensity = ls.lights[0].intensity;
|
||||
Mat3f m = (~objOrientation).toMatrix3();
|
||||
|
||||
// Normalize the brightnesses of the light sources.
|
||||
// TODO: Skip this step when high dynamic range rendering to floating point
|
||||
|
@ -4357,12 +4396,15 @@ setupObjectLighting(const vector<Renderer::LightSource>& suns,
|
|||
for (i = 0; i < nLights; i++)
|
||||
{
|
||||
ls.lights[i].intensity /= maxIntensity;
|
||||
|
||||
|
||||
// Cull light sources that don't contribute significantly (less than
|
||||
// the resolution of an 8-bit color channel.)
|
||||
if (ls.lights[i].intensity < 1.0f / 255.0f)
|
||||
break;
|
||||
|
||||
// Compute the direction of the light in object space
|
||||
ls.lights[i].direction_obj = ls.lights[i].direction_eye * m;
|
||||
|
||||
ls.nLights++;
|
||||
}
|
||||
}
|
||||
|
@ -4383,13 +4425,14 @@ void Renderer::renderObject(Point3f pos,
|
|||
float discSizeInPixels = obj.radius /
|
||||
(max(nearPlaneDistance, altitude) * pixelSize);
|
||||
|
||||
// HACK
|
||||
Vec3f sunDirection(0.0f, 1.0f, 0.0f);
|
||||
Color sunColor(0.0f, 0.0f, 0.0f);
|
||||
ri.sunDir_eye = Vec3f(0.0f, 1.0f, 0.0f);
|
||||
ri.sunDir_obj = Vec3f(0.0f, 1.0f, 0.0f);
|
||||
ri.sunColor = Color(0.0f, 0.0f, 0.0f);
|
||||
if (ls.nLights > 0)
|
||||
{
|
||||
sunDirection = ls.lights[0].direction;
|
||||
sunColor = ls.lights[0].color;// * ls.lights[0].intensity;
|
||||
ri.sunDir_eye = ls.lights[0].direction_eye;
|
||||
ri.sunDir_obj = ls.lights[0].direction_obj;
|
||||
ri.sunColor = ls.lights[0].color;// * ls.lights[0].intensity;
|
||||
}
|
||||
|
||||
// Enable depth buffering
|
||||
|
@ -4429,9 +4472,6 @@ void Renderer::renderObject(Point3f pos,
|
|||
glScale(semiMajorAxes);
|
||||
|
||||
Mat4f planetMat = (~obj.orientation).toMatrix4();
|
||||
ri.sunDir_eye = sunDirection;
|
||||
ri.sunDir_eye.normalize();
|
||||
ri.sunDir_obj = ri.sunDir_eye * planetMat;
|
||||
ri.eyeDir_obj = (Point3f(0, 0, 0) - pos) * planetMat;
|
||||
ri.eyeDir_obj.normalize();
|
||||
ri.eyePos_obj = Point3f(-pos.x / radius,
|
||||
|
@ -4449,8 +4489,7 @@ void Renderer::renderObject(Point3f pos,
|
|||
ri.color = obj.surface->color;
|
||||
}
|
||||
|
||||
ri.sunColor = sunColor;
|
||||
ri.ambientColor = ambientColor * ri.sunColor;
|
||||
ri.ambientColor = ambientColor;
|
||||
ri.hazeColor = obj.surface->hazeColor;
|
||||
ri.specularColor = obj.surface->specularColor;
|
||||
ri.specularPower = obj.surface->specularPower;
|
||||
|
@ -4459,42 +4498,50 @@ void Renderer::renderObject(Point3f pos,
|
|||
// See if the surface should be lit
|
||||
bool lit = (obj.surface->appearanceFlags & Surface::Emissive) == 0;
|
||||
|
||||
// Set up the light source for the sun
|
||||
glLightDirection(GL_LIGHT0, ri.sunDir_obj);
|
||||
// Set the OpenGL light state
|
||||
unsigned int i;
|
||||
for (i = 0; i < ls.nLights; i++)
|
||||
{
|
||||
const DirectionalLight& light = ls.lights[i];
|
||||
|
||||
// RANT ALERT!
|
||||
// This sucks, but it's necessary. glScale is used to scale a unit
|
||||
// sphere up to planet size. Since normals are transformed by the
|
||||
// inverse transpose of the model matrix, this means they end up
|
||||
// getting scaled by a factor of 1.0 / planet radius (in km). This
|
||||
// has terrible effects on lighting: the planet appears almost
|
||||
// completely dark. To get around this, the GL_rescale_normal
|
||||
// extension was introduced and eventually incorporated into into the
|
||||
// OpenGL 1.2 standard. Of course, not everyone implemented this
|
||||
// incredibly simple and essential little extension. Microsoft is
|
||||
// notorious for half-assed support of OpenGL, but 3dfx should have
|
||||
// known better: no Voodoo 1/2/3 drivers seem to support this
|
||||
// extension. The following is an attempt to get around the problem by
|
||||
// scaling the light brightness by the planet radius. According to the
|
||||
// OpenGL spec, this should work fine, as clamping of colors to [0, 1]
|
||||
// occurs *after* lighting. It works fine on my GeForce3 when I
|
||||
// disable EXT_rescale_normal, but I'm not certain whether other
|
||||
// drivers are as well behaved as nVidia's.
|
||||
//
|
||||
// Addendum: Unsurprisingly, using color values outside [0, 1] produces
|
||||
// problems on Savage4 cards.
|
||||
//
|
||||
if (useRescaleNormal)
|
||||
{
|
||||
glLightColor(GL_LIGHT0, GL_DIFFUSE, ri.sunColor);
|
||||
glLightColor(GL_LIGHT0, GL_SPECULAR, ri.sunColor);
|
||||
glLightDirection(GL_LIGHT0 + i, ls.lights[i].direction_obj);
|
||||
|
||||
// RANT ALERT!
|
||||
// This sucks, but it's necessary. glScale is used to scale a unit
|
||||
// sphere up to planet size. Since normals are transformed by the
|
||||
// inverse transpose of the model matrix, this means they end up
|
||||
// getting scaled by a factor of 1.0 / planet radius (in km). This
|
||||
// has terrible effects on lighting: the planet appears almost
|
||||
// completely dark. To get around this, the GL_rescale_normal
|
||||
// extension was introduced and eventually incorporated into into the
|
||||
// OpenGL 1.2 standard. Of course, not everyone implemented this
|
||||
// incredibly simple and essential little extension. Microsoft is
|
||||
// notorious for half-assed support of OpenGL, but 3dfx should have
|
||||
// known better: no Voodoo 1/2/3 drivers seem to support this
|
||||
// extension. The following is an attempt to get around the problem by
|
||||
// scaling the light brightness by the planet radius. According to the
|
||||
// OpenGL spec, this should work fine, as clamping of colors to [0, 1]
|
||||
// occurs *after* lighting. It works fine on my GeForce3 when I
|
||||
// disable EXT_rescale_normal, but I'm not certain whether other
|
||||
// drivers are as well behaved as nVidia's.
|
||||
//
|
||||
// Addendum: Unsurprisingly, using color values outside [0, 1] produces
|
||||
// problems on Savage4 cards.
|
||||
|
||||
Vec3f lightColor = Vec3f(light.color.red(),
|
||||
light.color.green(),
|
||||
light.color.blue()) * light.intensity;
|
||||
if (useRescaleNormal)
|
||||
{
|
||||
glLightColor(GL_LIGHT0 + i, GL_DIFFUSE, lightColor);
|
||||
glLightColor(GL_LIGHT0 + i, GL_SPECULAR, lightColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
glLightColor(GL_LIGHT0 + i, GL_DIFFUSE, lightColor * radius);
|
||||
}
|
||||
glEnable(GL_LIGHT0 + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
glLightColor(GL_LIGHT0, GL_DIFFUSE,
|
||||
Vec3f(ri.sunColor.red(), ri.sunColor.green(), ri.sunColor.blue()) * radius);
|
||||
}
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
// Compute the inverse model/view matrix
|
||||
Mat4f invMV = (cameraOrientation.toMatrix4() *
|
||||
|
@ -4530,7 +4577,7 @@ void Renderer::renderObject(Point3f pos,
|
|||
|
||||
case GLContext::GLPath_NvCombiner_ARBVP:
|
||||
case GLContext::GLPath_NvCombiner_NvVP:
|
||||
renderSphere_Combiners_VP(ri, viewFrustum, *context);
|
||||
renderSphere_Combiners_VP(ri, ls, viewFrustum, *context);
|
||||
break;
|
||||
|
||||
case GLContext::GLPath_NvCombiner:
|
||||
|
@ -4538,7 +4585,7 @@ void Renderer::renderObject(Point3f pos,
|
|||
break;
|
||||
|
||||
case GLContext::GLPath_DOT3_ARBVP:
|
||||
renderSphere_DOT3_VP(ri, viewFrustum, *context);
|
||||
renderSphere_DOT3_VP(ri, ls, viewFrustum, *context);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4665,11 +4712,23 @@ void Renderer::renderObject(Point3f pos,
|
|||
if (vproc != NULL)
|
||||
{
|
||||
vproc->enable();
|
||||
vproc->use(vp::diffuseTexOffset);
|
||||
vproc->parameter(vp::DiffuseColor, ri.sunColor * ri.color);
|
||||
vproc->parameter(vp::LightDirection0, ls.lights[0].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor0, ls.lights[0].color * ri.color);
|
||||
vproc->parameter(vp::AmbientColor, ri.ambientColor * ri.color);
|
||||
vproc->parameter(vp::TextureTranslation,
|
||||
texOffset, 0.0f, 0.0f, 0.0f);
|
||||
if (ls.nLights > 1)
|
||||
{
|
||||
vproc->use(vp::diffuseTexOffset_2light);
|
||||
vproc->parameter(vp::LightDirection1,
|
||||
ls.lights[1].direction_obj);
|
||||
vproc->parameter(vp::DiffuseColor1,
|
||||
ls.lights[1].color * ri.color);
|
||||
}
|
||||
else
|
||||
{
|
||||
vproc->use(vp::diffuseTexOffset);
|
||||
}
|
||||
}
|
||||
|
||||
lodSphere->render(*context,
|
||||
|
@ -4779,6 +4838,11 @@ void Renderer::renderObject(Point3f pos,
|
|||
detailOptions.ringSystemSections);
|
||||
}
|
||||
|
||||
// Disable all light sources other than the first
|
||||
for (i = 0; i < ls.nLights; i++)
|
||||
glDisable(GL_LIGHT0 + i);
|
||||
|
||||
|
||||
if (obj.locations != NULL && (labelMode & LocationLabels) != 0)
|
||||
renderLocations(*obj.locations,
|
||||
cameraOrientation,
|
||||
|
@ -5033,6 +5097,7 @@ void Renderer::renderPlanet(Body& body,
|
|||
LightingState lights;
|
||||
setupObjectLighting(lightSources,
|
||||
body.getHeliocentricPosition(now),
|
||||
rp.orientation,
|
||||
lights);
|
||||
renderObject(pos, distance, now,
|
||||
orientation, nearPlaneDistance, farPlaneDistance,
|
||||
|
|
|
@ -33,6 +33,10 @@ unsigned int vp::nightLights = 0;
|
|||
unsigned int vp::glossMap = 0;
|
||||
unsigned int vp::perFragmentSpecular = 0;
|
||||
unsigned int vp::perFragmentSpecularAlpha = 0;
|
||||
unsigned int vp::diffuse_2light = 0;
|
||||
unsigned int vp::diffuseHaze_2light = 0;
|
||||
unsigned int vp::diffuseTexOffset_2light = 0;
|
||||
unsigned int vp::specular_2light = 0;
|
||||
|
||||
|
||||
class VertexProcessorNV : public VertexProcessor
|
||||
|
@ -188,6 +192,7 @@ static bool LoadARBVertexProgram(const string& filename, unsigned int& id)
|
|||
}
|
||||
|
||||
|
||||
// ARB path is preferred; NV vertex program path will eventually go away
|
||||
VertexProcessor* vp::initNV()
|
||||
{
|
||||
cout << "Initializing NV vertex programs . . .\n";
|
||||
|
@ -213,6 +218,14 @@ VertexProcessor* vp::initNV()
|
|||
return NULL;
|
||||
// if (!LoadNvVertexProgram("shaders/comet.vp", cometTail))
|
||||
// return false;
|
||||
|
||||
// Two light shaders have only been written for the ARB vertex program path
|
||||
// Fall back to the the one light versions.
|
||||
diffuse_2light = diffuse;
|
||||
diffuseHaze_2light = diffuseHaze;
|
||||
diffuseTexOffset_2light = diffuseTexOffset;
|
||||
specular_2light = specular;
|
||||
|
||||
everything = 0;
|
||||
cout << "All NV vertex programs loaded successfully.\n";
|
||||
|
||||
|
@ -250,6 +263,14 @@ VertexProcessor* vp::initARB()
|
|||
return NULL;
|
||||
if (!LoadARBVertexProgram("shaders/glossmap_arb.vp", glossMap))
|
||||
return NULL;
|
||||
if (!LoadARBVertexProgram("shaders/diffuse2_arb.vp", diffuse_2light))
|
||||
return NULL;
|
||||
if (!LoadARBVertexProgram("shaders/haze2_arb.vp", diffuseHaze_2light))
|
||||
return NULL;
|
||||
if (!LoadARBVertexProgram("shaders/diffuse_texoff2_arb.vp", diffuseTexOffset_2light))
|
||||
return NULL;
|
||||
if (!LoadARBVertexProgram("shaders/specular2_arb.vp", specular_2light))
|
||||
return NULL;
|
||||
|
||||
// Load vertex programs that are only required with fragment programs
|
||||
if (ExtensionSupported("GL_NV_fragment_program") ||
|
||||
|
@ -368,17 +389,17 @@ void VertexProcessor::parameter(vp::Parameter param, const Color& c)
|
|||
|
||||
static unsigned int parameterMappings[] =
|
||||
{
|
||||
16, // SunDirection,
|
||||
15, // EyePosition,
|
||||
20, // DiffuseColor
|
||||
34, // SpecularColor
|
||||
16, // LightDirection0
|
||||
15, // EyePosition
|
||||
20, // DiffuseColor0
|
||||
34, // SpecularColor0
|
||||
40, // SpecularExponent
|
||||
32, // AmbientColor
|
||||
33, // HazeColor
|
||||
41, // TextureTranslation
|
||||
90, // Constant0 - relevant for NV_vertex_program only
|
||||
0, // Unused
|
||||
41, // TexGen_S,
|
||||
41, // TexGen_S
|
||||
42, // TexGen_T
|
||||
0, // TexGen_S2
|
||||
0, // TexGen_T2
|
||||
|
@ -386,6 +407,9 @@ static unsigned int parameterMappings[] =
|
|||
0, // TexGen_T3
|
||||
0, // TexGen_S4
|
||||
0, // TexGen_T4
|
||||
50, // LightDirection1
|
||||
51, // DiffuseColor1,
|
||||
52, // SpecularColor1
|
||||
};
|
||||
|
||||
VertexProcessorNV::VertexProcessorNV()
|
||||
|
|
|
@ -30,10 +30,10 @@ namespace vp
|
|||
void parameter(unsigned int, float, float, float, float);
|
||||
|
||||
enum Parameter {
|
||||
SunDirection = 0,
|
||||
LightDirection0 = 0,
|
||||
EyePosition = 1,
|
||||
DiffuseColor = 2,
|
||||
SpecularColor = 3,
|
||||
DiffuseColor0 = 2,
|
||||
SpecularColor0 = 3,
|
||||
SpecularExponent = 4,
|
||||
AmbientColor = 5,
|
||||
HazeColor = 6,
|
||||
|
@ -47,6 +47,9 @@ namespace vp
|
|||
TexGen_T3 = 15,
|
||||
TexGen_S4 = 16,
|
||||
TexGen_T4 = 17,
|
||||
LightDirection1 = 18,
|
||||
DiffuseColor1 = 19,
|
||||
SpecularColor1 = 20,
|
||||
};
|
||||
|
||||
extern unsigned int specular;
|
||||
|
@ -65,25 +68,15 @@ namespace vp
|
|||
extern unsigned int glossMap;
|
||||
extern unsigned int perFragmentSpecular;
|
||||
extern unsigned int perFragmentSpecularAlpha;
|
||||
extern unsigned int diffuse_2light;
|
||||
extern unsigned int diffuseTexOffset_2light;
|
||||
extern unsigned int diffuseHaze_2light;
|
||||
extern unsigned int specular_2light;
|
||||
};
|
||||
|
||||
|
||||
namespace arbvp
|
||||
{
|
||||
enum EnvParam {
|
||||
SunDirection = 0,
|
||||
EyePosition = 1,
|
||||
DiffuseColor = 2,
|
||||
SpecularColor = 3,
|
||||
SpecularExponent = 4,
|
||||
AmbientColor = 5,
|
||||
HazeColor = 6,
|
||||
TextureTranslation = 7,
|
||||
Constant0 = 8,
|
||||
TexGen_S = 10,
|
||||
TexGen_T = 11,
|
||||
};
|
||||
|
||||
void parameter(unsigned int, const Vec3f&);
|
||||
void parameter(unsigned int, const Point3f&);
|
||||
void parameter(unsigned int, const Color&);
|
||||
|
|
Loading…
Reference in New Issue