calculate screen bounding boxes for each mesh object
This commit is contained in:
parent
f5d455b561
commit
9ad158effd
7 changed files with 193 additions and 3 deletions
|
@ -84,6 +84,7 @@ public:
|
||||||
virtual void clearScreen() = 0;
|
virtual void clearScreen() = 0;
|
||||||
virtual void flipBuffer() = 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 startActorDraw(Vector3d pos, float yaw, float pitch, float roll) = 0;
|
||||||
virtual void finishActorDraw() = 0;
|
virtual void finishActorDraw() = 0;
|
||||||
virtual void setShadow(Shadow *shadow) = 0;
|
virtual void setShadow(Shadow *shadow) = 0;
|
||||||
|
|
|
@ -182,6 +182,72 @@ static void glShadowProjection(Vector3d light, Vector3d plane, Vector3d normal,
|
||||||
glMultMatrixf((GLfloat *)mat);
|
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) {
|
void DriverGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
|
@ -55,6 +55,8 @@ public:
|
||||||
|
|
||||||
bool isHardwareAccelerated();
|
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 startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
|
||||||
void finishActorDraw();
|
void finishActorDraw();
|
||||||
void setShadow(Shadow *shadow);
|
void setShadow(Shadow *shadow);
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "engine/tinygl/gl.h"
|
#include "engine/tinygl/gl.h"
|
||||||
#include "engine/tinygl/zgl.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,
|
static void lookAt(TGLfloat eyex, TGLfloat eyey, TGLfloat eyez, TGLfloat centerx,
|
||||||
TGLfloat centery, TGLfloat centerz, TGLfloat upx, TGLfloat upy, TGLfloat upz) {
|
TGLfloat centery, TGLfloat centerz, TGLfloat upx, TGLfloat upy, TGLfloat upz) {
|
||||||
TGLfloat m[16];
|
TGLfloat m[16];
|
||||||
|
@ -102,6 +102,40 @@ static void lookAt(TGLfloat eyex, TGLfloat eyey, TGLfloat eyez, TGLfloat centerx
|
||||||
tglTranslatef(-eyex, -eyey, -eyez);
|
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) {
|
DriverTinyGL::DriverTinyGL(int screenW, int screenH, int screenBPP, bool fullscreen) {
|
||||||
uint32 flags = SDL_HWSURFACE;
|
uint32 flags = SDL_HWSURFACE;
|
||||||
|
|
||||||
|
@ -241,6 +275,87 @@ static void tglShadowProjection(Vector3d light, Vector3d plane, Vector3d normal,
|
||||||
tglMultMatrixf(mat);
|
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) {
|
void DriverTinyGL::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) {
|
||||||
tglEnable(TGL_TEXTURE_2D);
|
tglEnable(TGL_TEXTURE_2D);
|
||||||
tglMatrixMode(TGL_MODELVIEW);
|
tglMatrixMode(TGL_MODELVIEW);
|
||||||
|
@ -254,6 +369,7 @@ void DriverTinyGL::startActorDraw(Vector3d pos, float yaw, float pitch, float ro
|
||||||
Sector *shadowSector = *i;
|
Sector *shadowSector = *i;
|
||||||
tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
tglTranslatef(pos.x(), pos.y(), pos.z());
|
tglTranslatef(pos.x(), pos.y(), pos.z());
|
||||||
tglRotatef(yaw, 0, 0, 1);
|
tglRotatef(yaw, 0, 0, 1);
|
||||||
tglRotatef(pitch, 1, 0, 0);
|
tglRotatef(pitch, 1, 0, 0);
|
||||||
|
|
|
@ -55,6 +55,8 @@ public:
|
||||||
|
|
||||||
bool isHardwareAccelerated();
|
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 startActorDraw(Vector3d pos, float yaw, float pitch, float roll);
|
||||||
void finishActorDraw();
|
void finishActorDraw();
|
||||||
void setShadow(Shadow *shadow);
|
void setShadow(Shadow *shadow);
|
||||||
|
|
|
@ -503,6 +503,9 @@ void Model::HierNode::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::Mesh::draw() const {
|
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++)
|
for (int i = 0; i < _numFaces; i++)
|
||||||
_faces[i].draw(_vertices, _vertNormals, _textureVerts);
|
_faces[i].draw(_vertices, _vertNormals, _textureVerts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#include "engine/tinygl/zgl.h"
|
#include "engine/tinygl/zgl.h"
|
||||||
|
|
||||||
void glGetIntegerv(int pname,int *params) {
|
void tglGetIntegerv(int pname,int *params) {
|
||||||
GLContext *c=gl_get_context();
|
GLContext *c=gl_get_context();
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
|
@ -32,7 +32,7 @@ void glGetIntegerv(int pname,int *params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void glGetFloatv(int pname, float *v) {
|
void tglGetFloatv(int pname, float *v) {
|
||||||
int i;
|
int i;
|
||||||
int mnr = 0; // just a trick to return the correct matrix
|
int mnr = 0; // just a trick to return the correct matrix
|
||||||
GLContext *c = gl_get_context();
|
GLContext *c = gl_get_context();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue