Added support for bump mapped planets.
parent
3638a4347a
commit
967e2233c1
|
@ -17,7 +17,7 @@
|
|||
|
||||
void SetupCombinersBumpMap(CTexture& bumpTexture,
|
||||
CTexture& normalizationTexture,
|
||||
float* ambientColor)
|
||||
Color ambientColor)
|
||||
{
|
||||
glEnable(GL_REGISTER_COMBINERS_NV);
|
||||
|
||||
|
@ -33,7 +33,11 @@ void SetupCombinersBumpMap(CTexture& bumpTexture,
|
|||
// Just a single combiner stage required . . .
|
||||
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
|
||||
|
||||
glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, ambientColor);
|
||||
float ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
ambient[0] = ambientColor.red();
|
||||
ambient[1] = ambientColor.green();
|
||||
ambient[2] = ambientColor.blue();
|
||||
glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, ambient);
|
||||
|
||||
// Compute N dot L in the RGB portion of combiner 0
|
||||
// Load register A with a normal N from the normal map
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
#define _REGCOMBINE_H_
|
||||
|
||||
#include "texture.h"
|
||||
#include "color.h"
|
||||
|
||||
extern void SetupCombinersBumpMap(CTexture& bumpTexture,
|
||||
CTexture& normalizationTexture,
|
||||
float* ambientColor);
|
||||
Color ambientColor);
|
||||
extern void DisableCombiners();
|
||||
|
||||
#endif // _REGCOMBINE_H_
|
||||
|
|
130
src/render.cpp
130
src/render.cpp
|
@ -17,6 +17,7 @@
|
|||
#include "texfont.h"
|
||||
#include "console.h"
|
||||
#include "gui.h"
|
||||
#include "regcombine.h"
|
||||
#include "render.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -55,6 +56,7 @@ Renderer::Renderer() :
|
|||
renderMode(GL_FILL),
|
||||
labelMode(NoLabels),
|
||||
ambientLightLevel(0.1f),
|
||||
perPixelLightingEnabled(false),
|
||||
console(NULL),
|
||||
nSimultaneousTextures(1),
|
||||
useRegisterCombiners(false),
|
||||
|
@ -227,6 +229,9 @@ bool Renderer::init(int winWidth, int winHeight)
|
|||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
// LEQUAL rather than LESS required for multipass rendering
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
// We need this enabled because we use glScale, but only
|
||||
// with uniform scale factors
|
||||
// TODO: Do a proper check for this extension before enabling
|
||||
|
@ -323,6 +328,22 @@ void Renderer::setAmbientLightLevel(float level)
|
|||
}
|
||||
|
||||
|
||||
bool Renderer::getPerPixelLighting() const
|
||||
{
|
||||
return perPixelLightingEnabled;
|
||||
}
|
||||
|
||||
void Renderer::setPerPixelLighting(bool enable)
|
||||
{
|
||||
perPixelLightingEnabled = enable && perPixelLightingSupported();
|
||||
}
|
||||
|
||||
bool Renderer::perPixelLightingSupported() const
|
||||
{
|
||||
return useCubeMaps && useRegisterCombiners;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::addLabel(string text, Color color, Point3f pos)
|
||||
{
|
||||
double winX, winY, winZ;
|
||||
|
@ -714,6 +735,97 @@ void Renderer::renderBodyAsParticle(Point3f position,
|
|||
}
|
||||
|
||||
|
||||
static void renderBumpMappedMesh(Mesh& mesh,
|
||||
CTexture& bumpTexture,
|
||||
Vec3f lightDirection,
|
||||
Quatf orientation,
|
||||
Color ambientColor)
|
||||
{
|
||||
// We're doing our own per-pixel lighting, so disable GL's lighting
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
// Render the base texture on the first pass . . . The base
|
||||
// texture and color should have been set up already by the
|
||||
// caller.
|
||||
mesh.render();
|
||||
|
||||
// The 'default' light vector for the bump map is (0, 0, 1). Determine
|
||||
// a rotation transformation that will move the sun direction to
|
||||
// this vector.
|
||||
Quatf lightOrientation;
|
||||
{
|
||||
Vec3f zeroLightDirection(0, 0, 1);
|
||||
Vec3f axis = lightDirection ^ zeroLightDirection;
|
||||
float cosAngle = zeroLightDirection * lightDirection;
|
||||
float angle = 0.0f;
|
||||
float epsilon = 1e-5f;
|
||||
|
||||
if (cosAngle + 1 < epsilon)
|
||||
{
|
||||
axis = Vec3f(0, 1, 0);
|
||||
angle = (float) PI;
|
||||
}
|
||||
else if (cosAngle - 1 > -epsilon)
|
||||
{
|
||||
axis = Vec3f(0, 1, 0);
|
||||
angle = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
axis.normalize();
|
||||
angle = (float) acos(cosAngle);
|
||||
}
|
||||
lightOrientation.setAxisAngle(axis, angle);
|
||||
}
|
||||
|
||||
// Set up the bump map with one directional light source
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
|
||||
SetupCombinersBumpMap(bumpTexture, *normalizationTex, ambientColor);
|
||||
|
||||
// The second set texture coordinates will contain the light
|
||||
// direction in tangent space. We'll generate the texture coordinates
|
||||
// from the surface normals using GL_NORMAL_MAP_EXT and then
|
||||
// use the texture matrix to rotate them into tangent space.
|
||||
// This method of generating tangent space light direction vectors
|
||||
// isn't as general as transforming the light direction by an
|
||||
// orthonormal basis for each mesh vertex, but it works well enough
|
||||
// for spheres illuminated by directional light sources.
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
|
||||
// Set up GL_NORMAL_MAP_EXT texture coordinate generation. This
|
||||
// mode is part of the cube map extension.
|
||||
glEnable(GL_TEXTURE_GEN_R);
|
||||
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
|
||||
glEnable(GL_TEXTURE_GEN_S);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
|
||||
glEnable(GL_TEXTURE_GEN_T);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
|
||||
|
||||
// Set up the texture transformation--the light direction and the
|
||||
// viewer orientation both need to be considered.
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glRotate(lightOrientation * orientation);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
mesh.render();
|
||||
|
||||
// Reset the second texture unit
|
||||
glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glDisable(GL_TEXTURE_GEN_R);
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
|
||||
DisableCombiners();
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderPlanet(const Body& body,
|
||||
Point3f pos,
|
||||
Vec3f sunDirection,
|
||||
|
@ -740,12 +852,22 @@ void Renderer::renderPlanet(const Body& body,
|
|||
const Surface& surface = body.getSurface();
|
||||
// Get the texture . . .
|
||||
CTexture* tex = NULL;
|
||||
CTexture* bumpTex = NULL;
|
||||
if (surface.baseTexture != "")
|
||||
{
|
||||
if (!textureManager->find(surface.baseTexture, &tex))
|
||||
tex = textureManager->load(surface.baseTexture);
|
||||
}
|
||||
|
||||
// If this renderer can support bump mapping then get the bump texture
|
||||
if ((surface.appearanceFlags & Surface::ApplyBumpMap) != 0 &&
|
||||
(perPixelLightingEnabled && useRegisterCombiners && useCubeMaps) &&
|
||||
surface.bumpTexture != "")
|
||||
{
|
||||
if (!textureManager->find(surface.bumpTexture, &bumpTex))
|
||||
bumpTex = textureManager->loadBumpMap(surface.bumpTexture);
|
||||
}
|
||||
|
||||
if (tex == NULL)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
@ -814,7 +936,13 @@ void Renderer::renderPlanet(const Body& body,
|
|||
}
|
||||
|
||||
if (mesh != NULL)
|
||||
mesh->render();
|
||||
{
|
||||
if (bumpTex != NULL)
|
||||
renderBumpMappedMesh(*mesh, *bumpTex, sunDirection, orientation,
|
||||
Color(ambientLightLevel, ambientLightLevel, ambientLightLevel));
|
||||
else
|
||||
mesh->render();
|
||||
}
|
||||
|
||||
// If the planet has a ring system, render it.
|
||||
if (body.getRings() != NULL)
|
||||
|
|
|
@ -61,6 +61,9 @@ class Renderer
|
|||
void clearLabelledStars();
|
||||
float getAmbientLightLevel() const;
|
||||
void setAmbientLightLevel(float);
|
||||
bool getPerPixelLighting() const;
|
||||
void setPerPixelLighting(bool);
|
||||
bool perPixelLightingSupported() const;
|
||||
|
||||
typedef struct {
|
||||
string text;
|
||||
|
@ -148,6 +151,7 @@ class Renderer
|
|||
int renderMode;
|
||||
int labelMode;
|
||||
float ambientLightLevel;
|
||||
bool perPixelLightingEnabled;
|
||||
|
||||
vector<RenderListEntry> renderList;
|
||||
vector<Particle> starParticles;
|
||||
|
|
|
@ -170,12 +170,16 @@ static Body* CreatePlanet(PlanetarySystem* system,
|
|||
Surface surface;
|
||||
surface.color = Color(1.0f, 1.0f, 1.0f);
|
||||
planetData->getColor("Color", surface.color);
|
||||
planetData->getString("Texture", surface.baseTexture);
|
||||
planetData->getString("BumpMap", surface.bumpTexture);
|
||||
bool applyBaseTexture = planetData->getString("Texture", surface.baseTexture);
|
||||
bool applyBumpMap = planetData->getString("BumpMap", surface.bumpTexture);
|
||||
bool blendTexture = false;
|
||||
planetData->getBoolean("BlendTexture", blendTexture);
|
||||
if (blendTexture)
|
||||
surface.appearanceFlags |= Surface::BlendTexture;
|
||||
if (applyBaseTexture)
|
||||
surface.appearanceFlags |= Surface::ApplyBaseTexture;
|
||||
if (applyBumpMap)
|
||||
surface.appearanceFlags |= Surface::ApplyBumpMap;
|
||||
body->setSurface(surface);
|
||||
|
||||
string mesh("");
|
||||
|
|
|
@ -24,7 +24,7 @@ class Surface
|
|||
// Appearance flags
|
||||
enum {
|
||||
BlendTexture = 0x1,
|
||||
ApplyDecalTexture = 0x2,
|
||||
ApplyBaseTexture = 0x2,
|
||||
ApplyBumpMap = 0x4,
|
||||
};
|
||||
|
||||
|
|
|
@ -34,3 +34,17 @@ CTexture* TextureManager::load(string name)
|
|||
return tex;
|
||||
}
|
||||
|
||||
|
||||
CTexture* TextureManager::loadBumpMap(string name)
|
||||
{
|
||||
DPRINTF("Loading bump map: %s\n", name.c_str());
|
||||
CTexture* tex = LoadTextureFromFile(baseDir + "\\" + name);
|
||||
if (tex != NULL)
|
||||
{
|
||||
tex->normalMap(5.0f, true);
|
||||
tex->bindName();
|
||||
}
|
||||
addResource(name, static_cast<void*>(tex));
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ class TextureManager : public ResourceManager
|
|||
~TextureManager();
|
||||
|
||||
bool find(string name, CTexture**);
|
||||
CTexture* load(string name);
|
||||
CTexture* load(std::string name);
|
||||
CTexture* loadBumpMap(std::string name);
|
||||
};
|
||||
|
||||
#endif // _TEXMANAGER_H_
|
||||
|
|
Loading…
Reference in New Issue