Skip to content

Commit

Permalink
NWN: Switch on lighting (WIP!)
Browse files Browse the repository at this point in the history
Horribly wrong and broken in several places.
Also, very very slow.
  • Loading branch information
DrMcCoy committed Jan 6, 2013
1 parent 6526845 commit fc2e578
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 28 deletions.
57 changes: 52 additions & 5 deletions src/engines/nwn/area.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "graphics/graphics.h"

#include "graphics/aurora/cursorman.h"
#include "graphics/aurora/modelnode.h"
#include "graphics/aurora/model.h"

#include "sound/sound.h"
Expand Down Expand Up @@ -214,13 +215,17 @@ void Area::show() {
GfxMan.lockFrame();

// Show tiles
for (std::vector<Tile>::iterator t = _tiles.begin(); t != _tiles.end(); ++t)
t->model->show();
for (std::vector<Tile>::iterator t = _tiles.begin(); t != _tiles.end(); ++t) {
if (t->model)
t->model->show();
}

// Show objects
for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
(*o)->show();

LightMan.updateLighting();

GfxMan.unlockFrame();

// Play music and sound
Expand All @@ -246,7 +251,8 @@ void Area::hide() {

// Hide tiles
for (std::vector<Tile>::iterator t = _tiles.begin(); t != _tiles.end(); ++t)
t->model->hide();
if (t->model)
t->model->hide();

GfxMan.unlockFrame();

Expand Down Expand Up @@ -364,8 +370,8 @@ void Area::loadTile(const Aurora::GFFStruct &t, Tile &tile) {
tile.mainLight[0] = t.getUint("Tile_MainLight1", 0);
tile.mainLight[1] = t.getUint("Tile_MainLight2", 0);

tile.srcLight[0] = t.getUint("Tile_SrcLight1", 0);
tile.srcLight[1] = t.getUint("Tile_SrcLight2", 0);
tile.srcLight[0] = t.getUint("Tile_SrcLight1", 0) * 2;
tile.srcLight[1] = t.getUint("Tile_SrcLight2", 0) * 2;

// Tile animations

Expand Down Expand Up @@ -432,9 +438,12 @@ void Area::unloadTileset() {
_tileset = 0;
}

static int H = 0;
void Area::loadTiles() {
for (uint32 y = 0; y < _height; y++) {
for (uint32 x = 0; x < _width; x++) {
if (x == 8 && y == 8)
continue;
uint32 n = y * _width + x;

Tile &t = _tiles[n];
Expand All @@ -453,12 +462,47 @@ void Area::loadTiles() {
// The actual height of a tile is dictated by the tileset.
const float tileZ = t.height * _tileset->getTilesHeight();

H = t.height;

t.model->setPosition(tileX, tileY, tileZ);
t.model->setRotation(0.0, 0.0, -(((int) t.orientation) * 90.0));

createLight(t.light[0], t.model, t.mainLight[0], t.tile->model + "ml1");
createLight(t.light[1], t.model, t.mainLight[1], t.tile->model + "ml2");
createLight(t.light[2], t.model, t.srcLight [0], t.tile->model + "sl1");
createLight(t.light[3], t.model, t.srcLight [1], t.tile->model + "sl2");
}
}
}

void Area::createLight(Graphics::LightHandle &light, Graphics::Aurora::Model *model,
uint8 color, const Common::UString &nodeName) {

if ((color == 0) || (color > 31))
return;

Graphics::Aurora::ModelNode *node = model->getNode(nodeName);
if (!node)
return;

float x, y, z;
node->getWorldPosition(x, y, z);

light = LightMan.addLight();

const Aurora::TwoDAFile &lightColor = TwoDAReg.get("lightcolor");

float r = lightColor.getRow(color).getFloat("TOOLSETRED");
float g = lightColor.getRow(color).getFloat("TOOLSETGREEN");
float b = lightColor.getRow(color).getFloat("TOOLSETBLUE");

LightMan.setAmbient (light, 0.0, 0.0, 0.0, 1.0);
LightMan.setDiffuse (light, r, g, b, 1.0);
LightMan.setSpecular(light, 0.0, 0.0, 0.0, 1.0);
LightMan.setPosition(light, x, y, z);
LightMan.switchOnOff(light, true);
}

void Area::unloadTiles() {
for (uint32 y = 0; y < _height; y++) {
for (uint32 x = 0; x < _width; x++) {
Expand All @@ -470,6 +514,9 @@ void Area::unloadTiles() {

delete t.model;
t.model = 0;

for (int i = 0; i < 4; i++)
t.light[i].clear();
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/engines/nwn/area.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

#include "aurora/nwscript/object.h"

#include "graphics/lightman.h"

#include "graphics/aurora/types.h"

#include "sound/types.h"
Expand Down Expand Up @@ -144,6 +146,8 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable,
const Tileset::Tile *tile; ///< The actual tile within the tileset.

Graphics::Aurora::Model *model; ///< The tile's model.

Graphics::LightHandle light[4]; ///< The tile's lights.
};

typedef std::list<Engines::NWN::Object *> ObjectList;
Expand Down Expand Up @@ -232,6 +236,9 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable,
void loadTiles();
void unloadTiles();

void createLight(Graphics::LightHandle &light, Graphics::Aurora::Model *model,
uint8 color, const Common::UString &nodeName);

// Highlight / active helpers

void checkActive(int x = -1, int y = -1);
Expand Down
4 changes: 4 additions & 0 deletions src/engines/nwn/nwn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

#include "events/events.h"

#include "graphics/lightman.h"

#include "graphics/aurora/cursorman.h"
#include "graphics/aurora/fontman.h"
#include "graphics/aurora/fps.h"
Expand Down Expand Up @@ -144,6 +146,8 @@ void NWNEngine::run(const Common::UString &target) {
_fps->show();
}

LightMan.enableLighting(true);

mainMenuLoop();

deinit();
Expand Down
47 changes: 45 additions & 2 deletions src/graphics/aurora/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Model::Model(ModelType type) : Renderable((RenderableType) type),
for (int i = 0; i < kRenderPassAll; i++)
_needBuild[i] = true;

_needEvalLights = true;

_position[0] = 0.0; _position[1] = 0.0; _position[2] = 0.0;
_rotation[0] = 0.0; _rotation[1] = 0.0; _rotation[2] = 0.0;

Expand Down Expand Up @@ -168,6 +170,20 @@ Animation *Model::selectDefaultAnimation() const {
return 0;
}

void Model::show() {
Renderable::show();

needRebuild();
}

void Model::hide() {
Renderable::hide();

for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
(*n)->clearLights();
}

void Model::getPosition(float &x, float &y, float &z) const {
x = _position[0] * _modelScale[0];
y = _position[1] * _modelScale[1];
Expand Down Expand Up @@ -417,9 +433,34 @@ void Model::calculateDistance() {
_distance = x + y + z;
}

void Model::evaluateLights() {
Common::TransformationMatrix position;

// Apply our global model transformation

position.scale(_modelScale[0], _modelScale[1], _modelScale[2]);

if (_type == kModelTypeObject)
// Aurora world objects have a rotated axis
position.rotate(90.0, -1.0, 0.0, 0.0);

position.translate(_position[0], _position[1], _position[2]);

position.rotate( _rotation[0], 1.0, 0.0, 0.0);
position.rotate( _rotation[1], 0.0, 1.0, 0.0);
position.rotate(-_rotation[2], 0.0, 0.0, 1.0);

for (NodeList::iterator n = _currentState->rootNodes.begin();
n != _currentState->rootNodes.end(); ++n) {

(*n)->evaluateLights(position);
}

_needEvalLights = false;
}

bool Model::buildList(RenderPass pass) {
if (!_needBuild[pass])
return false;
evaluateLights();

if (_lists == 0)
_lists = glGenLists(kRenderPassAll);
Expand Down Expand Up @@ -617,6 +658,8 @@ void Model::finalize() {
void Model::needRebuild() {
for (int i = 0; i < kRenderPassAll; i++)
_needBuild[i] = true;

_needEvalLights = true;
}

void Model::createStateNamesList() {
Expand Down
5 changes: 5 additions & 0 deletions src/graphics/aurora/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class Model : public GLContainer, public Renderable {
/** Should a bounding box be drawn around this model? */
void drawBound(bool enabled);

void show();
void hide();


/** Is that point within the model's bounding box? */
bool isIn(float x, float y) const;
Expand Down Expand Up @@ -240,12 +243,14 @@ class Model : public GLContainer, public Renderable {

private:
bool _needBuild[kRenderPassAll];
bool _needEvalLights;
bool _drawBound;
float _elapsedTime; ///< Track animation duration

ListID _lists; ///< OpenGL display lists for the model


void evaluateLights();
bool buildList(RenderPass pass);

void createStateNamesList(); ///< Create the list of all state names.
Expand Down
71 changes: 69 additions & 2 deletions src/graphics/aurora/modelnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,62 @@ void ModelNode::orderChildren() {
(*c)->orderChildren();
}

void ModelNode::clearLights() {
_lighting.clear();
}

#define SQR(x) ((x) * (x))
void ModelNode::evaluateLights(Common::TransformationMatrix position) {
clearLights();

_lighting.reserve(_faceCount);
for (uint32 i = 0; i < _faceCount; i++)
_lighting.push_back(LightMan.createLighting());

// Transform by our position/orientation/rotation
position.translate(_position[0], _position[1], _position[2]);
position.rotate(_orientation[3], _orientation[0], _orientation[1], _orientation[2]);

position.rotate(_rotation[0], 1.0, 0.0, 0.0);
position.rotate(_rotation[1], 0.0, 1.0, 0.0);
position.rotate(_rotation[2], 0.0, 0.0, 1.0);

// Evaluate the lighting for each vertex

const float *vX = _vX;
const float *vY = _vY;
const float *vZ = _vZ;

for (uint32 i = 0; i < _faceCount; i++, vX += 3, vY += 3, vZ += 3) {
const float a = sqrt(SQR(vX[1] - vX[2]) + SQR(vY[1] - vY[2]) + SQR(vZ[1] - vZ[2]));
const float b = sqrt(SQR(vX[0] - vX[2]) + SQR(vY[0] - vY[2]) + SQR(vZ[0] - vZ[2]));
const float c = sqrt(SQR(vX[0] - vX[1]) + SQR(vY[0] - vY[1]) + SQR(vZ[0] - vZ[1]));
const float p = a + b + c;

const float x = (a * vX[0] + b * vX[1] + c * vX[2]) / p;
const float y = (a * vY[0] + b * vY[1] + c * vY[2]) / p;
const float z = (a * vZ[0] + b * vZ[1] + c * vZ[2]) / p;

/*
const float x = _center[0];
const float y = _center[1];
const float z = _center[2];
*/


Common::TransformationMatrix vPos = position;

vPos.translate(x, y, z);

LightMan.evaluateLighting(_lighting[i], vPos.getX(), vPos.getY(), vPos.getZ());
}

// Recurse into the children
for (std::list<ModelNode *>::iterator c = _children.begin(); c != _children.end(); ++c)
(*c)->evaluateLights(position);
}
#undef SQR

void ModelNode::renderGeometry() {
// Enable all needed texture units
for (uint32 t = 0; t < _textures.size(); t++) {
Expand All @@ -483,11 +539,16 @@ void ModelNode::renderGeometry() {
const float *tX = _tX;
const float *tY = _tY;

glBegin(GL_TRIANGLES);
for (uint32 f = 0; f < _faceCount; f++, vX += 3, vY += 3, vZ += 3,
nX += 3, nY += 3, nZ += 3,
tX += 3 * textureCount, tY += 3 * textureCount) {


// Lighting vertex A
LightMan.renderLights(_lighting[f]);

glBegin(GL_TRIANGLES);

// Texture vertex A
for (uint32 t = 0; t < textureCount; t++)
TextureMan.textureCoord2f(t, tX[3 * t + 0], tY[3 * t + 0]);
Expand All @@ -498,6 +559,9 @@ void ModelNode::renderGeometry() {
glVertex3f(vX[0], vY[0], vZ[0]);


// Lighting vertex B
//LightMan.renderLights(_lighting[3 * f + 1]);

// Texture vertex B
for (uint32 t = 0; t < textureCount; t++)
TextureMan.textureCoord2f(t, tX[3 * t + 1], tY[3 * t + 1]);
Expand All @@ -508,6 +572,9 @@ void ModelNode::renderGeometry() {
glVertex3f(vX[1], vY[1], vZ[1]);


// Lighting vertex C
//LightMan.renderLights(_lighting[3 * f + 2]);

// Texture vertex C
for (uint32 t = 0; t < textureCount; t++)
TextureMan.textureCoord2f(t, tX[3 * t + 2], tY[3 * t + 2]);
Expand All @@ -516,8 +583,8 @@ void ModelNode::renderGeometry() {
glNormal3f(nX[2], nY[2], nZ[2]);
// Geometry vertex C
glVertex3f(vX[2], vY[2], vZ[2]);
}
glEnd();
}


// Disable the texture units again
Expand Down

0 comments on commit fc2e578

Please sign in to comment.