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

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Fri Sep 26 13:59:47 CEST 2008


Revision: 34651
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34651&view=rev
Author:   aquadran
Date:     2008-09-26 11:59:46 +0000 (Fri, 26 Sep 2008)

Log Message:
-----------
calculate screen bounding boxes for each mesh object

Modified Paths:
--------------
    residual/trunk/engine/backend/platform/driver.h
    residual/trunk/engine/backend/platform/sdl/driver_gl.cpp
    residual/trunk/engine/backend/platform/sdl/driver_gl.h
    residual/trunk/engine/backend/platform/sdl/driver_tinygl.cpp
    residual/trunk/engine/backend/platform/sdl/driver_tinygl.h
    residual/trunk/engine/model.cpp
    residual/trunk/engine/tinygl/get.cpp

Modified: residual/trunk/engine/backend/platform/driver.h
===================================================================
--- residual/trunk/engine/backend/platform/driver.h	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/backend/platform/driver.h	2008-09-26 11:59:46 UTC (rev 34651)
@@ -84,6 +84,7 @@
 	virtual void clearScreen() = 0;
 	virtual void flipBuffer() = 0;
 
+	virtual void getBoundingBoxPos(const Model::Mesh *model, int *x1, int *y1, int *x2, int *y2) = 0;
 	virtual void startActorDraw(Vector3d pos, float yaw, float pitch, float roll) = 0;
 	virtual void finishActorDraw() = 0;
 	virtual void setShadow(Shadow *shadow) = 0;

Modified: residual/trunk/engine/backend/platform/sdl/driver_gl.cpp
===================================================================
--- residual/trunk/engine/backend/platform/sdl/driver_gl.cpp	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/backend/platform/sdl/driver_gl.cpp	2008-09-26 11:59:46 UTC (rev 34651)
@@ -182,6 +182,72 @@
 	glMultMatrixf((GLfloat *)mat);
 }
 
+void DriverGL::getBoundingBoxPos(const Model::Mesh *model, int *x1, int *y1, int *x2, int *y2) {
+	if (_currentShadowArray)
+		return;
+
+	GLfloat top = 1000;
+	GLfloat right = -1000;
+	GLfloat left = 1000;
+	GLfloat bottom = -1000;
+	GLdouble winX, winY, winZ;
+
+	for (int i = 0; i < model->_numFaces; i++) {
+		Vector3d v;
+		float* pVertices;
+
+		for (int j = 0; j < model->_faces[i]._numVertices; j++) {
+			GLdouble modelView[16], projection[16];
+			GLint viewPort[4];
+
+			glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
+			glGetDoublev(GL_PROJECTION_MATRIX, projection);
+			glGetIntegerv(GL_VIEWPORT, viewPort);
+
+			pVertices = model->_vertices + 3 * model->_faces[i]._vertices[j];
+
+			v.set(*(pVertices), *(pVertices + 1), *(pVertices + 2));
+
+			gluProject(v.x(), v.y(), v.z(), modelView, projection, viewPort, &winX, &winY, &winZ);
+
+			if (winX > right)
+				right = winX;
+			if (winX < left)
+				left = winX;
+			if (winY < top)
+				top = winY;
+			if (winY > bottom)
+				bottom = winY;
+		}
+	}
+
+	float t = bottom;
+	bottom = 480 - top;
+	top = 480 - t;
+
+	if (left < 0)
+		left = 0;
+	if (right > 639)
+		right = 639;
+	if (top < 0)
+		top = 0;
+	if (bottom > 479)
+		bottom = 479;
+
+	if (top > 479 || left > 639 || bottom < 0 || right < 0) {
+		*x1 = -1;
+		*y1 = -1;
+		*x2 = -1;
+		*y2 = -1;
+		return;
+	}
+
+	*x1 = (int)left;
+	*y1 = (int)top;
+	*x2 = (int)right;
+	*y2 = (int)bottom;
+}
+
 void DriverGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
 	glEnable(GL_TEXTURE_2D);
 	glMatrixMode(GL_MODELVIEW);

Modified: residual/trunk/engine/backend/platform/sdl/driver_gl.h
===================================================================
--- residual/trunk/engine/backend/platform/sdl/driver_gl.h	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/backend/platform/sdl/driver_gl.h	2008-09-26 11:59:46 UTC (rev 34651)
@@ -55,6 +55,8 @@
 
 	bool isHardwareAccelerated();
 
+	void getBoundingBoxPos(const Model::Mesh *model, int *x1, int *y1, int *x2, int *y2);
+
 	void startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
 	void finishActorDraw();
 	void setShadow(Shadow *shadow);

Modified: residual/trunk/engine/backend/platform/sdl/driver_tinygl.cpp
===================================================================
--- residual/trunk/engine/backend/platform/sdl/driver_tinygl.cpp	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/backend/platform/sdl/driver_tinygl.cpp	2008-09-26 11:59:46 UTC (rev 34651)
@@ -36,7 +36,7 @@
 #include "engine/tinygl/gl.h"
 #include "engine/tinygl/zgl.h"
 
-// func below is from Mesa glu sources
+// below funcs lookAt, transformPoint and tgluProject are from Mesa glu sources
 static void lookAt(TGLfloat eyex, TGLfloat eyey, TGLfloat eyez, TGLfloat centerx,
 		TGLfloat centery, TGLfloat centerz, TGLfloat upx, TGLfloat upy, TGLfloat upz) {
 	TGLfloat m[16];
@@ -102,6 +102,40 @@
 	tglTranslatef(-eyex, -eyey, -eyez);
 }
 
+static void transformPoint(TGLfloat out[4], const TGLfloat m[16], const TGLfloat in[4]) {
+#define M(row,col)  m[col * 4 + row]
+   out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
+   out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
+   out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
+   out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
+#undef M
+}
+
+TGLint tgluProject(TGLfloat objx, TGLfloat objy, TGLfloat objz, const TGLfloat model[16], const TGLfloat proj[16],
+		const TGLint viewport[4], TGLfloat *winx, TGLfloat *winy, TGLfloat *winz) {
+	TGLfloat in[4], out[4];
+
+	in[0] = objx;
+	in[1] = objy;
+	in[2] = objz;
+	in[3] = 1.0;
+	transformPoint(out, model, in);
+	transformPoint(in, proj, out);
+
+	if (in[3] == 0.0)
+		return TGL_FALSE;
+
+	in[0] /= in[3];
+	in[1] /= in[3];
+	in[2] /= in[3];
+
+	*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
+	*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
+	*winz = (1 + in[2]) / 2;
+
+	return TGL_TRUE;
+}
+
 DriverTinyGL::DriverTinyGL(int screenW, int screenH, int screenBPP, bool fullscreen) {
 	uint32 flags = SDL_HWSURFACE;
 
@@ -241,6 +275,87 @@
 	tglMultMatrixf(mat);
 }
 
+void DriverTinyGL::getBoundingBoxPos(const Model::Mesh *model, int *x1, int *y1, int *x2, int *y2) {
+	if (_currentShadowArray)
+		return;
+
+	TGLfloat top = 1000;
+	TGLfloat right = -1000;
+	TGLfloat left = 1000;
+	TGLfloat bottom = -1000;
+	TGLfloat winX, winY, winZ;
+
+	for (int i = 0; i < model->_numFaces; i++) {
+		Vector3d v;
+		float* pVertices;
+
+		for (int j = 0; j < model->_faces[i]._numVertices; j++) {
+			TGLfloat modelView[16], projection[16];
+			TGLint viewPort[4];
+
+			tglGetFloatv(TGL_MODELVIEW_MATRIX, modelView);
+			tglGetFloatv(TGL_PROJECTION_MATRIX, projection);
+			tglGetIntegerv(TGL_VIEWPORT, viewPort);
+
+			pVertices = model->_vertices + 3 * model->_faces[i]._vertices[j];
+
+			v.set(*(pVertices), *(pVertices + 1), *(pVertices + 2));
+
+			tgluProject(v.x(), v.y(), v.z(), modelView, projection, viewPort, &winX, &winY, &winZ);
+
+			if (winX > right)
+				right = winX;
+			if (winX < left)
+				left = winX;
+			if (winY < top)
+				top = winY;
+			if (winY > bottom)
+				bottom = winY;
+		}
+	}
+
+	float t = bottom;
+	bottom = 480 - top;
+	top = 480 - t;
+
+	if (left < 0)
+		left = 0;
+	if (right > 639)
+		right = 639;
+	if (top < 0)
+		top = 0;
+	if (bottom > 479)
+		bottom = 479;
+
+	if (top > 479 || left > 639 || bottom < 0 || right < 0) {
+		*x1 = -1;
+		*y1 = -1;
+		*x2 = -1;
+		*y2 = -1;
+		return;
+	}
+
+	*x1 = (int)left;
+	*y1 = (int)top;
+	*x2 = (int)right;
+	*y2 = (int)bottom;
+/*
+	uint16 *dst = (uint16 *)_zb->pbuf;
+	uint16 c = 0xffff;
+	for (int x = left; x <= right; x++) {
+		WRITE_LE_UINT16(dst + 640 * (int)top + x, c);
+	}
+	for (int x = left; x <= right; x++) {
+		WRITE_LE_UINT16(dst + 640 * (int)bottom + x, c);
+	}
+	for (int y = top; y <= bottom; y++) {
+		WRITE_LE_UINT16(dst + 640 * y + (int)left, c);
+	}
+	for (int y = top; y <= bottom; y++) {
+		WRITE_LE_UINT16(dst + 640 * y + (int)right, c);
+	}*/
+}
+
 void DriverTinyGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
 	tglEnable(TGL_TEXTURE_2D);
 	tglMatrixMode(TGL_MODELVIEW);
@@ -254,6 +369,7 @@
 		Sector *shadowSector = *i;
 		tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
 	}
+
 	tglTranslatef(pos.x(), pos.y(), pos.z());
 	tglRotatef(yaw, 0, 0, 1);
 	tglRotatef(pitch, 1, 0, 0);

Modified: residual/trunk/engine/backend/platform/sdl/driver_tinygl.h
===================================================================
--- residual/trunk/engine/backend/platform/sdl/driver_tinygl.h	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/backend/platform/sdl/driver_tinygl.h	2008-09-26 11:59:46 UTC (rev 34651)
@@ -55,6 +55,8 @@
 
 	bool isHardwareAccelerated();
 
+	void getBoundingBoxPos(const Model::Mesh *model, int *x1, int *y1, int *x2, int *y2);
+
 	void startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
 	void finishActorDraw();
 	void setShadow(Shadow *shadow);

Modified: residual/trunk/engine/model.cpp
===================================================================
--- residual/trunk/engine/model.cpp	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/model.cpp	2008-09-26 11:59:46 UTC (rev 34651)
@@ -503,6 +503,9 @@
 }
 
 void Model::Mesh::draw() const {
+	int winX1, winY1, winX2, winY2;
+	g_driver->getBoundingBoxPos(this, &winX1, &winY1, &winX2, &winY2);
+
 	for (int i = 0; i < _numFaces; i++)
 		_faces[i].draw(_vertices, _vertNormals, _textureVerts);
 }

Modified: residual/trunk/engine/tinygl/get.cpp
===================================================================
--- residual/trunk/engine/tinygl/get.cpp	2008-09-26 11:57:56 UTC (rev 34650)
+++ residual/trunk/engine/tinygl/get.cpp	2008-09-26 11:59:46 UTC (rev 34651)
@@ -1,7 +1,7 @@
 
 #include "engine/tinygl/zgl.h"
 
-void glGetIntegerv(int pname,int *params) {
+void tglGetIntegerv(int pname,int *params) {
 	GLContext *c=gl_get_context();
 
 	switch (pname) {
@@ -32,7 +32,7 @@
 	}
 }
 
-void glGetFloatv(int pname, float *v) {
+void tglGetFloatv(int pname, float *v) {
 	int i;
 	int mnr = 0; // just a trick to return the correct matrix
 	GLContext *c = gl_get_context();


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