[Scummvm-cvs-logs] SF.net SVN: scummvm: [32913] residual/trunk

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Sat Jul 5 10:48:39 CEST 2008


Revision: 32913
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32913&view=rev
Author:   aquadran
Date:     2008-07-05 01:48:39 -0700 (Sat, 05 Jul 2008)

Log Message:
-----------
added initial support for shadows in software renderer but still a bit broken

Modified Paths:
--------------
    residual/trunk/dists/msvc7/residual.vcproj
    residual/trunk/dists/msvc71/residual.vcproj
    residual/trunk/dists/msvc8/residual.vcproj
    residual/trunk/dists/msvc9/residual.vcproj
    residual/trunk/engine/actor.cpp
    residual/trunk/engine/actor.h
    residual/trunk/engine/backend/driver.h
    residual/trunk/engine/backend/sdl/driver_gl.cpp
    residual/trunk/engine/backend/sdl/driver_gl.h
    residual/trunk/engine/backend/sdl/driver_tinygl.cpp
    residual/trunk/engine/backend/sdl/driver_tinygl.h
    residual/trunk/engine/engine.cpp
    residual/trunk/engine/engine.h
    residual/trunk/engine/lua.cpp
    residual/trunk/engine/scene.cpp
    residual/trunk/engine/tinygl/README.residual
    residual/trunk/engine/tinygl/api.cpp
    residual/trunk/engine/tinygl/clip.cpp
    residual/trunk/engine/tinygl/gl.h
    residual/trunk/engine/tinygl/init.cpp
    residual/trunk/engine/tinygl/misc.cpp
    residual/trunk/engine/tinygl/module.mk
    residual/trunk/engine/tinygl/zbuffer.cpp
    residual/trunk/engine/tinygl/zbuffer.h
    residual/trunk/engine/tinygl/zgl.h
    residual/trunk/engine/tinygl/ztriangle.cpp

Added Paths:
-----------
    residual/trunk/engine/tinygl/ztriangle_shadow.cpp

Modified: residual/trunk/dists/msvc7/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc7/residual.vcproj	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/dists/msvc7/residual.vcproj	2008-07-05 08:48:39 UTC (rev 32913)
@@ -578,6 +578,9 @@
 				<File
 					RelativePath="..\..\engine\tinygl\ztriangle.h">
 				</File>
+				<File
+					RelativePath="..\..\engine\tinygl\ztriangle_shadow.cpp">
+				</File>
 			</Filter>
 			<Filter
 				Name="imuse">

Modified: residual/trunk/dists/msvc71/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc71/residual.vcproj	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/dists/msvc71/residual.vcproj	2008-07-05 08:48:39 UTC (rev 32913)
@@ -592,6 +592,9 @@
 				<File
 					RelativePath="..\..\engine\tinygl\ztriangle.h">
 				</File>
+				<File
+					RelativePath="..\..\engine\tinygl\ztriangle_shadow.cpp">
+				</File>
 			</Filter>
 			<Filter
 				Name="imuse">

Modified: residual/trunk/dists/msvc8/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc8/residual.vcproj	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/dists/msvc8/residual.vcproj	2008-07-05 08:48:39 UTC (rev 32913)
@@ -810,6 +810,10 @@
 					RelativePath="..\..\engine\tinygl\ztriangle.h"
 					>
 				</File>
+				<File
+					RelativePath="..\..\engine\tinygl\ztriangle_shadow.cpp"
+					>
+				</File>
 			</Filter>
 			<Filter
 				Name="imuse"

Modified: residual/trunk/dists/msvc9/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc9/residual.vcproj	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/dists/msvc9/residual.vcproj	2008-07-05 08:48:39 UTC (rev 32913)
@@ -815,6 +815,10 @@
 					RelativePath="..\..\engine\tinygl\ztriangle.h"
 					>
 				</File>
+				<File
+					RelativePath="..\..\engine\tinygl\ztriangle_shadow.cpp"
+					>
+				</File>
 			</Filter>
 			<Filter
 				Name="imuse"

Modified: residual/trunk/engine/actor.cpp
===================================================================
--- residual/trunk/engine/actor.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/actor.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -62,7 +62,8 @@
 	_shadowArray = new Shadow[5];
 
 	for (int i = 0; i < 5; i++) {
-		_shadowArray[i].active = true;
+		_shadowArray[i].active = false;
+		_shadowArray[i].shadowMask = NULL;
 	}
 
 	for (int i = 0; i < 10; i++) {
@@ -599,12 +600,36 @@
 	for (std::list<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); i++)
 		(*i)->setupTextures();
 
+	if (!g_driver->isHardwareAccelerated()/* && g_engine->getFlagRefreshShadowMask()*/) {
+		for (int l = 0; l < 5; l++) {
+			if (!_shadowArray[l].active)
+				continue;
+			g_driver->setShadow(&_shadowArray[l]);
+			g_driver->drawShadowPlanes();
+			g_driver->setShadow(NULL);
+		}
+	}
+
 	if (!_costumeStack.empty()) {
-		setupDrawShadow();
+		Costume *costume = _costumeStack.back();
+		if (!g_driver->isHardwareAccelerated()) {
+			for (int l = 0; l < 5; l++) {
+				if (!_shadowArray[l].active)
+					continue;
+				g_driver->setShadow(&_shadowArray[l]);
+				g_driver->setShadowMode();
+				g_driver->startActorDraw(_pos, _yaw, _pitch, _roll);
+				costume->draw();
+				g_driver->finishActorDraw();
+				g_driver->setShadow(NULL);
+				g_driver->clearShadowMode();
+			}
+		}
+
+		// normal draw actor
 		g_driver->startActorDraw(_pos, _yaw, _pitch, _roll);
-		_costumeStack.back()->draw();
+		costume->draw();
 		g_driver->finishActorDraw();
-		finishDrawShadow();
 	}
 }
 
@@ -640,8 +665,22 @@
 	assert(shadowId >= 0 && shadowId <= 4);
 
 	_activeShadowSlot = shadowId;
+	_shadowArray[_activeShadowSlot].active = true;
 }
 
+void Actor::setShadowValid(int valid) {
+/*	if (valid == -1)
+		_shadowArray[_activeShadowSlot].active = false;
+	else
+		_shadowArray[_activeShadowSlot].active = true;*/
+}
+
+void Actor::setActivateShadow(int shadowId, bool state) {
+	assert(shadowId >= 0 && shadowId <= 4);
+
+	_shadowArray[shadowId].active = state;
+}
+
 void Actor::setShadowPoint(Vector3d pos) {
 	assert(_activeShadowSlot != -1);
 
@@ -654,16 +693,9 @@
 		while (!shadow->planeList.empty()) {
 			shadow->planeList.pop_back();
 		}
+		delete[] shadow->shadowMask;
+		shadow->shadowMask = NULL;
+		shadow->active = false;
 	}
 }
 
-void Actor::setupDrawShadow() {
-	if (_activeShadowSlot == -1)
-		return;
-
-	g_driver->setupShadower(_shadowArray);
-}
-
-void Actor::finishDrawShadow() {
-	g_driver->setupShadower(NULL);
-}

Modified: residual/trunk/engine/actor.h
===================================================================
--- residual/trunk/engine/actor.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/actor.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -46,6 +46,7 @@
 	std::string name;
 	Vector3d pos;
 	SectorListType planeList;
+	byte *shadowMask;
 	bool active;
 };
 
@@ -132,8 +133,8 @@
 	void setShadowPlane(const char *name);
 	void addShadowPlane(const char *name);
 	void clearShadowPlanes();
-	void setupDrawShadow();
-	void finishDrawShadow();
+	void setShadowValid(int);
+	void setActivateShadow(int, bool);
 
 	void setConstrain(bool constrain) {
 		_constrain = constrain;

Modified: residual/trunk/engine/backend/driver.h
===================================================================
--- residual/trunk/engine/backend/driver.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/backend/driver.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -78,7 +78,11 @@
 
 	virtual void startActorDraw(Vector3d pos, float yaw, float pitch, float roll) = 0;
 	virtual void finishActorDraw() = 0;
-	virtual void setupShadower(Shadow *shadow) = 0;
+	virtual void setShadow(Shadow *shadow) = 0;
+	virtual void drawShadowPlanes() = 0;
+	virtual void setShadowMode() = 0;
+	virtual void clearShadowMode() = 0;
+	virtual void setShadowColor(byte r, byte g, byte b) = 0;
 
 	virtual void set3DMode() = 0;
 
@@ -296,6 +300,9 @@
 	int _screenWidth, _screenHeight, _screenBPP;
 	bool _isFullscreen;
 	Shadow *_currentShadowArray;
+	unsigned char _shadowColorR;
+	unsigned char _shadowColorG;
+	unsigned char _shadowColorB;
 };
 
 extern Driver *g_driver;

Modified: residual/trunk/engine/backend/sdl/driver_gl.cpp
===================================================================
--- residual/trunk/engine/backend/sdl/driver_gl.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/backend/sdl/driver_gl.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -131,9 +131,21 @@
 	glDisable(GL_TEXTURE_2D);
 }
 
-void DriverGL::setupShadower(Shadow *shadow) {
+void DriverGL::setShadow(Shadow *shadow) {
 }
 
+void DriverGL::drawShadowPlanes() {
+}
+
+void DriverGL::setShadowMode() {
+}
+
+void DriverGL::clearShadowMode() {
+}
+
+void DriverGL::setShadowColor(byte r, byte g, byte b) {
+}
+
 void DriverGL::set3DMode() {
 	glMatrixMode(GL_MODELVIEW);
 	glEnable(GL_DEPTH_TEST);

Modified: residual/trunk/engine/backend/sdl/driver_gl.h
===================================================================
--- residual/trunk/engine/backend/sdl/driver_gl.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/backend/sdl/driver_gl.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -57,8 +57,12 @@
 
 	void startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
 	void finishActorDraw();
-	void setupShadower(Shadow *shadow);
-	
+	void setShadow(Shadow *shadow);
+	void drawShadowPlanes();
+	void setShadowMode();
+	void clearShadowMode();
+	void setShadowColor(byte r, byte g, byte b);
+
 	void set3DMode();
 
 	void translateViewpoint(Vector3d pos, float pitch, float yaw, float roll);

Modified: residual/trunk/engine/backend/sdl/driver_tinygl.cpp
===================================================================
--- residual/trunk/engine/backend/sdl/driver_tinygl.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/backend/sdl/driver_tinygl.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -26,6 +26,7 @@
 #include "common/sys.h"
 #include "common/endian.h"
 #include "common/debug.h"
+#include "common/vector3d.h"
 
 #include "engine/colormap.h"
 #include "engine/material.h"
@@ -184,10 +185,61 @@
 	return false;
 }
 
+void tglShadowProjection(Vector3d *light, Vector3d *plane, Vector3d *normal) {
+	// Based on GPL shadow projection example by
+	// (c) 2002-2003 Phaetos <phaetos at gaffga.de>
+	float d, c;
+	float mat[16];
+	float nx, ny, nz, lx, ly, lz, px, py, pz;
+
+	nx = normal->x();
+	ny = normal->y();
+	nz = -normal->z(); // for some unknown for me reason it need negate
+	lx = light->x();
+	ly = light->y();
+	lz = light->z();
+	px = plane->x();
+	py = plane->y();
+	pz = plane->z();
+
+	d = nx * lx + ny * ly + nz * lz;
+	c = px * nx + py * ny + pz * nz - d;
+
+	mat[0] = lx * nx + c;
+	mat[4] = ny * lx;
+	mat[8] = nz * lx;
+	mat[12] = -lx * c - lx * d;
+
+	mat[1] = nx * ly;
+	mat[5] = ly * ny + c;
+	mat[9] = nz * ly;
+	mat[13] = -ly * c - ly * d;
+
+	mat[2] = nx * lz;
+	mat[6] = ny * lz;
+	mat[10] = lz * nz + c;
+	mat[14] = -lz * c - lz * d;
+
+	mat[3] = nx;
+	mat[7] = ny;
+	mat[11] = nz;
+	mat[15] = -d;
+
+	tglMultMatrixf(mat);
+}
+
 void DriverTinyGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
 	tglEnable(TGL_TEXTURE_2D);
 	tglMatrixMode(TGL_MODELVIEW);
 	tglPushMatrix();
+	if (_currentShadowArray) {
+		assert(_currentShadowArray->shadowMask);
+		tglSetShadowColor(_shadowColorR, _shadowColorG, _shadowColorB);
+		tglSetShadowMaskBuf(_currentShadowArray->shadowMask);
+		SectorListType::iterator i = _currentShadowArray->planeList.begin();
+		Sector *shadowSector = *i;
+		tglShadowProjection(&_currentShadowArray->pos, &shadowSector->getVertices()[1], &shadowSector->getNormal());
+	}
 	tglTranslatef(pos.x(), pos.y(), pos.z());
 	tglRotatef(yaw, 0, 0, 1);
 	tglRotatef(pitch, 1, 0, 0);
@@ -199,35 +251,59 @@
 	tglPopMatrix();
 	tglDisable(TGL_TEXTURE_2D);
 
-/*	// enable to draw shadow planes (Special Sectors)
-	int k, r;
-	if (!_currentShadowArray)
-		return;
+	if (_currentShadowArray) {
+		tglSetShadowMaskBuf(NULL);
+	}
+}
 
-	tglColor3f(0.8,0.8,0.8);
-	for (r = 0; r < 5; r++) {
-		_currentShadowArray[r].planeList.begin();
-		for (SectorListType::iterator i = _currentShadowArray[r].planeList.begin(); i != _currentShadowArray[r].planeList.end(); i++) {
-			Sector *shadowSector = *i;
-			tglBegin(TGL_POLYGON);
-			tglNormal3f(shadowSector->getNormal().x(), shadowSector->getNormal().y(), shadowSector->getNormal().z());
-			for (k = 0; k < shadowSector->getNumVertices(); k++) {
-				tglVertex3f(shadowSector->getVertices()[k].x(), shadowSector->getVertices()[k].y(), shadowSector->getVertices()[k].z());
-			}
-			tglEnd();
+void DriverTinyGL::drawShadowPlanes() {
+	tglEnable(TGL_SHADOW_MASK_MODE);
+	if (_currentShadowArray->shadowMask)
+		memset(_currentShadowArray->shadowMask, 0, _screenWidth * _screenHeight);
+	else
+		_currentShadowArray->shadowMask = new byte[_screenWidth * _screenHeight];
+
+	tglSetShadowMaskBuf(_currentShadowArray->shadowMask);
+	_currentShadowArray->planeList.begin();
+	for (SectorListType::iterator i = _currentShadowArray->planeList.begin(); i != _currentShadowArray->planeList.end(); i++) {
+		Sector *shadowSector = *i;
+		tglBegin(TGL_POLYGON);
+		for (int k = 0; k < shadowSector->getNumVertices(); k++) {
+			tglVertex3f(shadowSector->getVertices()[k].x(), shadowSector->getVertices()[k].y(), shadowSector->getVertices()[k].z());
 		}
-	}*/
+		tglEnd();
+	}
+	tglSetShadowMaskBuf(NULL);
+	tglDisable(TGL_SHADOW_MASK_MODE);
 }
 
+void DriverTinyGL::setShadowMode() {
+	tglEnable(TGL_SHADOW_MODE);
+}
+
+void DriverTinyGL::clearShadowMode() {
+	tglDisable(TGL_SHADOW_MODE);
+}
+
 void DriverTinyGL::set3DMode() {
 	tglMatrixMode(TGL_MODELVIEW);
 	tglEnable(TGL_DEPTH_TEST);
 }
 
-void DriverTinyGL::setupShadower(Shadow *shadow) {
+void DriverTinyGL::setShadow(Shadow *shadow) {
 	_currentShadowArray = shadow;
+	if (shadow)
+		tglDisable(TGL_LIGHTING);
+	else
+		tglEnable(TGL_LIGHTING);
 }
 
+void DriverTinyGL::setShadowColor(byte r, byte g, byte b) {
+	_shadowColorR = r;
+	_shadowColorG = g;
+	_shadowColorB = b;
+}
+
 void DriverTinyGL::drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts) {
 	tglNormal3fv((float *)face->_normal._coords);
 	tglBegin(TGL_POLYGON);

Modified: residual/trunk/engine/backend/sdl/driver_tinygl.h
===================================================================
--- residual/trunk/engine/backend/sdl/driver_tinygl.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/backend/sdl/driver_tinygl.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -57,8 +57,12 @@
 
 	void startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
 	void finishActorDraw();
-	void setupShadower(Shadow *shadow);
-	
+	void setShadow(Shadow *shadow);
+	void drawShadowPlanes();
+	void setShadowMode();
+	void clearShadowMode();
+	void setShadowColor(byte r, byte g, byte b);
+
 	void set3DMode();
 
 	void translateViewpoint(Vector3d pos, float pitch, float yaw, float roll);

Modified: residual/trunk/engine/engine.cpp
===================================================================
--- residual/trunk/engine/engine.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/engine.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -358,6 +358,7 @@
 				a->draw();
 			a->undraw(a->inSet(_currScene->name()) && a->visible());
 		}
+		flagRefreshShadowMask(false);
 
 		// Draw overlying scene components
 		// The overlay objects should be drawn on top of everything else,
@@ -413,6 +414,7 @@
 	_savegameLoadRequest = false;
 	_savegameSaveRequest = false;
 	_savegameFileName = NULL;
+	_refreshShadowMask = false;
 
 	for (;;) {
 		if (_savegameLoadRequest) {
@@ -644,6 +646,7 @@
 	if (b == NULL)
 		warning("Could not find scene file %s\n", name);
 	_currScene = new Scene(name, b->data(), b->len());
+	flagRefreshShadowMask(true);
 	registerScene(_currScene);
 	_currScene->setSoundParameters(20, 127);
 	// should delete the old scene after creating the new one
@@ -673,7 +676,3 @@
 		_textSpeed = 10;
 	_textSpeed = speed;
 }
-
-void Engine::setShadowColor(Color c) {
-	_shadowColor = c;
-}

Modified: residual/trunk/engine/engine.h
===================================================================
--- residual/trunk/engine/engine.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/engine.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -69,7 +69,6 @@
 	bool getFlipEnable() { return _flipEnable; }
 	void refreshDrawMode() { _refreshDrawNeeded = true; }
 	void drawPrimitives();
-	void setShadowColor(Color c);
 
 	void mainLoop();
 	unsigned frameStart() const { return _frameStart; }
@@ -106,6 +105,13 @@
 		_scenes.remove(a);
 	}
 
+	void flagRefreshShadowMask(bool flag) {
+		_refreshShadowMask = flag;
+	}
+	bool getFlagRefreshShadowMask() {
+		return _refreshShadowMask;
+	}
+
 	// Actor registration
 	typedef std::list<Actor *> ActorListType;
 	ActorListType::const_iterator actorsBegin() const {
@@ -187,7 +193,7 @@
 	bool _refreshDrawNeeded;
 	char _fps[8];
 	bool _doFlip;
-	Color _shadowColor;
+	bool _refreshShadowMask;
 
 	unsigned _frameStart, _frameTime, _movieTime;
 	unsigned int _frameTimeCollection;

Modified: residual/trunk/engine/lua.cpp
===================================================================
--- residual/trunk/engine/lua.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/lua.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -1431,7 +1431,7 @@
 	int g = check_int(2);
 	int b = check_int(3);
 
-	g_engine->setShadowColor(Color(r, g, b));
+	g_driver->setShadowColor(r, g, b);
 }
 
 static void KillActorShadows() {
@@ -1483,20 +1483,22 @@
 static void ActivateActorShadow() {
 	DEBUG_FUNCTION();
 
-	/*Actor *act = */check_actor(1);
-	/*int shadowId = */check_int(2);
-	/*bool state = */getbool(3);
+	Actor *act = check_actor(1);
+	int shadowId = check_int(2);
+	bool state = getbool(3);
 
-	//act->setActivateShadow(shadowId, state);
+	act->setActivateShadow(shadowId, state);
 }
 
 static void SetActorShadowValid() {
 	DEBUG_FUNCTION();
 
-	/*Actor *act = */check_actor(1);
-	/*int valid = */check_int(2);
+	Actor *act = check_actor(1);
+	int valid = check_int(2);
 
-	//act->setShadowValid(valid);
+	warning("SetActorShadowValid(%d) unknown purpose", valid);
+
+	act->setShadowValid(valid);
 }
 
 // 0 - translate from '/msgId/'

Modified: residual/trunk/engine/scene.cpp
===================================================================
--- residual/trunk/engine/scene.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/scene.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -219,6 +219,7 @@
 		return;
 	}
 	_currSetup = _setups + num;
+	g_engine->flagRefreshShadowMask(true);
 }
 
 void Scene::drawBitmaps(ObjectState::Position stage) {

Modified: residual/trunk/engine/tinygl/README.residual
===================================================================
--- residual/trunk/engine/tinygl/README.residual	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/README.residual	2008-07-05 08:48:39 UTC (rev 32913)
@@ -10,3 +10,4 @@
 * Removed unneeded code.
 * Introduced second 32-bit z-buffer for 3d objects only,
   and kept 16-bit only for static z-buffer bitmaps.
+* Added support for drawing in shadow mode (generate mask and polygon shadow).

Modified: residual/trunk/engine/tinygl/api.cpp
===================================================================
--- residual/trunk/engine/tinygl/api.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/api.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -604,3 +604,15 @@
 	GLContext *c = gl_get_context();
 	c->print_flag = mode;
 }
+
+void tglSetShadowMaskBuf(unsigned char *buf) {
+	GLContext *c = gl_get_context();
+	c->zb->shadow_mask_buf = buf;
+}
+
+void tglSetShadowColor(unsigned char r, unsigned char g, unsigned char b) {
+	GLContext *c = gl_get_context();
+	c->zb->shadow_color_r = r << 8;
+	c->zb->shadow_color_g = g << 8;
+	c->zb->shadow_color_b = b << 8;
+}

Modified: residual/trunk/engine/tinygl/clip.cpp
===================================================================
--- residual/trunk/engine/tinygl/clip.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/clip.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -388,7 +388,13 @@
 	}
 #endif
     
-	if (c->texture_2d_enabled) {
+	if (c->shadow_mode & 1) {
+		assert(c->zb->shadow_mask_buf);
+		ZB_fillTriangleFlatShadowMask(c->zb, &p0->zp, &p1->zp, &p2->zp);
+	} else if (c->shadow_mode & 2) {
+		assert(c->zb->shadow_mask_buf);
+		ZB_fillTriangleFlatShadow(c->zb, &p0->zp, &p1->zp, &p2->zp);
+	} else if (c->texture_2d_enabled) {
 #ifdef PROFILE
 		count_triangles_textured++;
 #endif

Modified: residual/trunk/engine/tinygl/gl.h
===================================================================
--- residual/trunk/engine/tinygl/gl.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/gl.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -125,6 +125,8 @@
 	TGL_POLYGON_OFFSET_POINT		= 0x2A01,
 	TGL_POLYGON_OFFSET_LINE			= 0x2A02,
 	TGL_POLYGON_OFFSET_FILL			= 0x8037,
+	TGL_SHADOW_MASK_MODE			= 0x0C40,
+	TGL_SHADOW_MODE					= 0x0C41,
 
 	// Display Lists
 	TGL_COMPILE						= 0x1300,
@@ -783,6 +785,9 @@
 void tglGetFloatv(int pname, float *v);
 void tglFrontFace(int mode);
 
+void tglSetShadowMaskBuf(unsigned char *buf);
+void tglSetShadowColor(unsigned char r, unsigned char g, unsigned char b);
+
 // opengl 1.2 arrays
 void tglEnableClientState(TGLenum array);
 void tglDisableClientState(TGLenum array);

Modified: residual/trunk/engine/tinygl/init.cpp
===================================================================
--- residual/trunk/engine/tinygl/init.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/init.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -164,6 +164,9 @@
 	// opengl 1.1 polygon offset
 	c->offset_states = 0;
 
+	// shadow mode
+	c->shadow_mode = 0;
+
 	// clear the resize callback function pointer
 	c->gl_resize_viewport = NULL;
 

Modified: residual/trunk/engine/tinygl/misc.cpp
===================================================================
--- residual/trunk/engine/tinygl/misc.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/misc.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -82,6 +82,18 @@
 		else
 			c->offset_states &= ~TGL_OFFSET_LINE;
 		break; 
+	case TGL_SHADOW_MASK_MODE:
+		if (v)
+			c->shadow_mode |= 1;
+		else
+			c->shadow_mode &= ~1;
+		break; 
+	case TGL_SHADOW_MODE:
+		if (v)
+			c->shadow_mode |= 2;
+		else
+			c->shadow_mode &= ~2;
+		break; 
 	default:
 		if (code>=TGL_LIGHT0 && code<TGL_LIGHT0+MAX_LIGHTS) {
 			gl_enable_disable_light(c,code - TGL_LIGHT0, v);

Modified: residual/trunk/engine/tinygl/module.mk
===================================================================
--- residual/trunk/engine/tinygl/module.mk	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/module.mk	2008-07-05 08:48:39 UTC (rev 32913)
@@ -22,7 +22,8 @@
 	zbuffer.o \
 	zline.o \
 	zmath.o \
-	ztriangle.o
+	ztriangle.o \
+	ztriangle_shadow.o
 
 # Include common rules
 include $(srcdir)/rules.mk

Modified: residual/trunk/engine/tinygl/zbuffer.cpp
===================================================================
--- residual/trunk/engine/tinygl/zbuffer.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/zbuffer.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -14,7 +14,7 @@
 
 	zb = (ZBuffer *)gl_malloc(sizeof(ZBuffer));
 	if (zb == NULL)
-	return NULL;
+		return NULL;
 
 	zb->xsize = xsize;
 	zb->ysize = ysize;
@@ -55,6 +55,7 @@
 	}
 
 	zb->current_texture = NULL;
+	zb->shadow_mask_buf = NULL;
 
 	return zb;
 error:
@@ -182,7 +183,7 @@
 		memset_s(zb->zbuf, z, zb->xsize * zb->ysize);
 	}
 	if (clear_z) {
-		memset_l(zb->zbuf, z, zb->xsize * zb->ysize);
+		memset_l(zb->zbuf2, z, zb->xsize * zb->ysize);
 	}
 	if (clear_color) {
 		pp = zb->pbuf;

Modified: residual/trunk/engine/tinygl/zbuffer.h
===================================================================
--- residual/trunk/engine/tinygl/zbuffer.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/zbuffer.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -29,12 +29,16 @@
 #define PSZSH 4 
 
 typedef struct {
-	int xsize,ysize;
+	int xsize, ysize;
 	int linesize; // line size, in bytes
 	int mode;
 
 	unsigned short *zbuf;
 	unsigned long *zbuf2;
+	unsigned char *shadow_mask_buf;
+	int shadow_color_r;
+	int shadow_color_g;
+	int shadow_color_b;
 	PIXEL *pbuf;
 	int frame_buffer_allocated;
 
@@ -59,6 +63,7 @@
 void ZB_clear(ZBuffer *zb, int clear_z, int z, int clear_color, int r, int g, int b);
 // linesize is in BYTES
 void ZB_copyFrameBuffer(ZBuffer *zb, void *buf, int linesize);
+//void ZB_setShadowMaskBuf(
 
 // zline.c
 
@@ -71,6 +76,10 @@
 void ZB_setTexture(ZBuffer *zb, PIXEL *texture);
 void ZB_fillTriangleFlat(ZBuffer *zb, ZBufferPoint *p1, 
 						 ZBufferPoint *p2, ZBufferPoint *p3);
+void ZB_fillTriangleFlatShadowMask(ZBuffer *zb, ZBufferPoint *p1, 
+						 ZBufferPoint *p2, ZBufferPoint *p3);
+void ZB_fillTriangleFlatShadow(ZBuffer *zb, ZBufferPoint *p1, 
+						 ZBufferPoint *p2, ZBufferPoint *p3);
 void ZB_fillTriangleSmooth(ZBuffer *zb, ZBufferPoint *p1,
 						   ZBufferPoint *p2, ZBufferPoint *p3);
 void ZB_fillTriangleMapping(ZBuffer *zb, ZBufferPoint *p1,

Modified: residual/trunk/engine/tinygl/zgl.h
===================================================================
--- residual/trunk/engine/tinygl/zgl.h	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/zgl.h	2008-07-05 08:48:39 UTC (rev 32913)
@@ -260,7 +260,9 @@
   float offset_factor;
   float offset_units;
   int offset_states;
-  
+
+  int shadow_mode;
+
   /* specular buffer. could probably be shared between contexts, 
     but that wouldn't be 100% thread safe */
   GLSpecBuf *specbuf_first;

Modified: residual/trunk/engine/tinygl/ztriangle.cpp
===================================================================
--- residual/trunk/engine/tinygl/ztriangle.cpp	2008-07-05 08:20:10 UTC (rev 32912)
+++ residual/trunk/engine/tinygl/ztriangle.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -14,7 +14,7 @@
 #define DRAW_INIT()	{							\
 	color = RGB_TO_PIXEL(p2->r, p2->g, p2->b);	\
 }
-  
+
 #define PUT_PIXEL(_a) {						\
 	zz = z >> ZB_POINT_Z_FRAC_BITS;			\
 	if ((ZCMP(zz, pz[_a])) && (ZCMP(z, pz_2[_a]))) {	\

Added: residual/trunk/engine/tinygl/ztriangle_shadow.cpp
===================================================================
--- residual/trunk/engine/tinygl/ztriangle_shadow.cpp	                        (rev 0)
+++ residual/trunk/engine/tinygl/ztriangle_shadow.cpp	2008-07-05 08:48:39 UTC (rev 32913)
@@ -0,0 +1,364 @@
+
+#include "engine/tinygl/zbuffer.h"
+
+#define ZCMP(z, zpix) ((z) >= (zpix))
+
+void ZB_fillTriangleFlatShadowMask(ZBuffer *zb, ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
+	ZBufferPoint *t, *pr1, *pr2, *l1, *l2;
+	float fdx1, fdx2, fdy1, fdy2, fz;
+	unsigned char *pm1;
+	int part, update_left, update_right;
+
+	int nb_lines, dx1, dy1, tmp, dx2, dy2;
+
+	int error, derror;
+	int x1, dxdy_min, dxdy_max;
+	// warning: x2 is multiplied by 2^16
+	int x2, dx2dy2;  
+
+	// we sort the vertex with increasing y
+	if (p1->y < p0->y) {
+		t = p0;
+		p0 = p1;
+		p1 = t;
+	}
+	if (p2->y < p0->y) {
+		t = p2;
+		p2 = p1;
+		p1 = p0;
+		p0 = t;
+	} else if (p2->y < p1->y) {
+		t = p1;
+		p1 = p2;
+		p2 = t;
+	}
+
+	// we compute dXdx and dXdy for all interpolated values
+
+	fdx1 = (float)(p1->x - p0->x);
+	fdy1 = (float)(p1->y - p0->y);
+
+	fdx2 = (float)(p2->x - p0->x);
+	fdy2 = (float)(p2->y - p0->y);
+
+	fz = fdx1 * fdy2 - fdx2 * fdy1;
+	if (fz == 0)
+		return;
+	fz = (float)(1.0 / fz);
+
+	fdx1 *= fz;
+	fdy1 *= fz;
+	fdx2 *= fz;
+	fdy2 *= fz;
+
+	// screen coordinates
+
+	pm1 = zb->shadow_mask_buf + zb->xsize * p0->y;
+
+	for (part = 0; part < 2; part++) {
+		if (part == 0) {
+			if (fz > 0) {
+				update_left = 1;
+				update_right = 1;
+				l1 = p0;
+				l2 = p2;
+				pr1 = p0;
+				pr2 = p1;
+			} else {
+				update_left = 1;
+				update_right = 1;
+				l1 = p0;
+				l2 = p1;
+				pr1 = p0;
+				pr2 = p2;
+			}
+			nb_lines = p1->y - p0->y;
+		} else {
+			// second part
+			if (fz > 0) {
+				update_left = 0;
+				update_right = 1;
+				pr1 = p1;
+				pr2 = p2;
+			} else {
+				update_left = 1;
+				update_right = 0;
+				l1 = p1;
+				l2 = p2;
+			}
+			nb_lines = p2->y - p1->y + 1;
+		}
+
+		// compute the values for the left edge
+		if (update_left) {
+			dy1 = l2->y - l1->y;
+			dx1 = l2->x - l1->x;
+			if (dy1 > 0) 
+				tmp = (dx1 << 16) / dy1;
+			else
+				tmp = 0;
+			x1 = l1->x;
+			error = 0;
+			derror = tmp & 0x0000ffff;
+			dxdy_min = tmp >> 16;
+			dxdy_max = dxdy_min + 1;
+		}
+
+		// compute values for the right edge
+
+		if (update_right) {
+			dx2 = (pr2->x - pr1->x);
+			dy2 = (pr2->y - pr1->y);
+			if (dy2 > 0) 
+				dx2dy2 = ( dx2 << 16) / dy2;
+			else
+				dx2dy2 = 0;
+			x2 = pr1->x << 16;
+		}
+
+		// we draw all the scan line of the part
+		while (nb_lines > 0) {
+			nb_lines--;
+			// generic draw line
+			{
+				register unsigned char *pm;
+				register int n;
+
+				n = (x2 >> 16) - x1;
+				pm = pm1 + x1;
+				while (n >= 3) {
+					for (int a = 0; a <= 3; a++) {
+						pm[a] = 0xff;
+					}
+					pm += 4;
+					n -= 4;
+				}
+				while (n >= 0) {
+					pm[0] = 0xff;
+					pm += 1;
+					n -= 1;
+				}
+			}
+	  
+			// left edge
+			error += derror;
+			if (error > 0) {
+				error -= 0x10000;
+				x1 += dxdy_max;
+			} else {
+				x1 += dxdy_min;
+			} 
+	  
+			// right edge
+			x2 += dx2dy2;
+
+			// screen coordinates
+			pm1 = pm1 + zb->xsize;
+		}
+	}
+}
+
+void ZB_fillTriangleFlatShadow(ZBuffer *zb, ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
+	int color;
+	ZBufferPoint *t, *pr1, *pr2, *l1, *l2;
+	float fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
+	unsigned char *pm1;
+	unsigned short *pz1;
+	unsigned long *pz2;
+	PIXEL *pp1;
+	int part, update_left, update_right;
+
+	int nb_lines, dx1, dy1, tmp, dx2, dy2;
+
+	int error, derror;
+	int x1, dxdy_min, dxdy_max;
+	// warning: x2 is multiplied by 2^16
+	int x2, dx2dy2;  
+
+	int z1, dzdx, dzdy, dzdl_min, dzdl_max;
+
+	// we sort the vertex with increasing y
+	if (p1->y < p0->y) {
+		t = p0;
+		p0 = p1;
+		p1 = t;
+	}
+	if (p2->y < p0->y) {
+		t = p2;
+		p2 = p1;
+		p1 = p0;
+		p0 = t;
+	} else if (p2->y < p1->y) {
+		t = p1;
+		p1 = p2;
+		p2 = t;
+	}
+
+	// we compute dXdx and dXdy for all interpolated values
+
+	fdx1 = (float)(p1->x - p0->x);
+	fdy1 = (float)(p1->y - p0->y);
+
+	fdx2 = (float)(p2->x - p0->x);
+	fdy2 = (float)(p2->y - p0->y);
+
+	fz = fdx1 * fdy2 - fdx2 * fdy1;
+	if (fz == 0)
+		return;
+	fz = (float)(1.0 / fz);
+
+	fdx1 *= fz;
+	fdy1 *= fz;
+	fdx2 *= fz;
+	fdy2 *= fz;
+
+	d1 = (float)(p1->z - p0->z);
+	d2 = (float)(p2->z - p0->z);
+	dzdx = (int)(fdy2 * d1 - fdy1 * d2);
+	dzdy = (int)(fdx1 * d2 - fdx2 * d1);
+
+	// screen coordinates
+
+	pp1 = (PIXEL *)((char *)zb->pbuf + zb->linesize * p0->y);
+	pm1 = zb->shadow_mask_buf + p0->y * zb->xsize;
+	pz1 = zb->zbuf + p0->y * zb->xsize;
+	pz2 = zb->zbuf2 + p0->y * zb->xsize;
+
+	color = RGB_TO_PIXEL(zb->shadow_color_r, zb->shadow_color_g, zb->shadow_color_b);
+
+	for (part = 0; part < 2; part++) {
+		if (part == 0) {
+			if (fz > 0) {
+				update_left = 1;
+				update_right = 1;
+				l1 = p0;
+				l2 = p2;
+				pr1 = p0;
+				pr2 = p1;
+			} else {
+				update_left = 1;
+				update_right = 1;
+				l1 = p0;
+				l2 = p1;
+				pr1 = p0;
+				pr2 = p2;
+			}
+			nb_lines = p1->y - p0->y;
+		} else {
+			// second part
+			if (fz > 0) {
+				update_left = 0;
+				update_right = 1;
+				pr1 = p1;
+				pr2 = p2;
+			} else {
+				update_left = 1;
+				update_right = 0;
+				l1 = p1; 
+				l2 = p2;
+			}
+			nb_lines = p2->y - p1->y + 1;
+		}
+
+		// compute the values for the left edge
+
+		if (update_left) {
+			dy1 = l2->y - l1->y;
+			dx1 = l2->x - l1->x;
+			if (dy1 > 0) 
+				tmp = (dx1 << 16) / dy1;
+			else
+				tmp = 0;
+			x1 = l1->x;
+			error = 0;
+			derror = tmp & 0x0000ffff;
+			dxdy_min = tmp >> 16;
+			dxdy_max = dxdy_min + 1;
+
+			z1 = l1->z;
+			dzdl_min = (dzdy + dzdx * dxdy_min); 
+			dzdl_max = dzdl_min + dzdx;
+		}
+
+		// compute values for the right edge
+
+		if (update_right) {
+			dx2 = (pr2->x - pr1->x);
+			dy2 = (pr2->y - pr1->y);
+			if (dy2>0) 
+				dx2dy2 = ( dx2 << 16) / dy2;
+			else
+				dx2dy2 = 0;
+			x2 = pr1->x << 16;
+		}
+
+		// we draw all the scan line of the part
+
+		while (nb_lines > 0) {
+			nb_lines--;
+			// generic draw line
+			{
+				register PIXEL *pp;
+				register unsigned char *pm;
+				register int n;
+				register unsigned short *pz;
+				register unsigned long *pz_2;
+				register unsigned int z, zz;
+
+				n = (x2 >> 16) - x1;
+				pp = (PIXEL *)((char *)pp1 + x1 * PSZB);
+				pm = pm1 + x1;
+				pz = pz1 + x1;
+				pz_2 = pz2 + x1;
+				z = z1;
+				while (n >= 3) {
+					for (int a = 0; a < 4; a++) {
+						zz = z >> ZB_POINT_Z_FRAC_BITS;
+						if ((ZCMP(zz, pz[a])) && (ZCMP(z, pz_2[a])) && pm[0]) {
+							pp[a] = color;
+							pz_2[a] = z;
+						}
+						z += dzdx;
+					}
+					pz += 4;
+					pz_2 += 4;
+					pm += 4;
+					pp = (PIXEL *)((char *)pp + 4 * PSZB);
+					n -= 4;
+				}
+				while (n >= 0) {
+					zz = z >> ZB_POINT_Z_FRAC_BITS;
+					if ((ZCMP(zz, pz[0])) && (ZCMP(z, pz_2[0])) && pm[0]) {
+						pp[0] = color;
+						pz_2[0] = z;
+					}
+					pz += 1;
+					pz_2 += 1;
+					pm += 1;
+					pp = (PIXEL *)((char *)pp + PSZB);
+					n -= 1;
+				}
+			}
+      
+			// left edge
+			error += derror;
+			if (error > 0) {
+				error -= 0x10000;
+				x1 += dxdy_max;
+				z1 += dzdl_max;
+			} else {
+				x1 += dxdy_min;
+				z1 += dzdl_min;
+			} 
+      
+			// right edge
+			x2 += dx2dy2;
+
+			// screen coordinates
+			pp1 = (PIXEL *)((char *)pp1 + zb->linesize);
+			pz1 += zb->xsize;
+			pz2 += zb->xsize;
+			pm1 += zb->xsize;
+		}
+	}
+}


Property changes on: residual/trunk/engine/tinygl/ztriangle_shadow.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list