a mini patch separated from my old obsolete draw patch and make it
compatible with gerard_'s recent improvements:
1.added Vector3f to shadowcastingshap struct to store the light info
2.changed shadow loop to accept another BOOL to determine whether to store
light info from the first pass into shadowshape.light,then use them later in
the second pass,this should eliminate the useless invert matrix operation
and light x,y,z calculations on CPU in the second pass for card/driver
without stencil_two_side_EXT
3.removed the display list and static BOOL in drawshadows,since they are
never used
4.improved gerard_'s y_scale function by adding a 'const float RaiseScale =
1/pie_RAISE_SCALE' and replaced the costly '/pie_RAISE_SCALE' on float with
'* RaiseScale',since multiplication on float is almost as fast as integer's
on modern cpus,while division on float is up to 10x slower than on integer.
Index: piedraw.c
===================================================================
--- piedraw.c (revision 946)
+++ piedraw.c (working copy)
@@ -323,6 +323,7 @@
iIMDShape* shape;
int flag;
int flag_data;
+ Vector3f light;
} shadowcasting_shape_t;
typedef struct {
@@ -519,12 +520,13 @@
static inline float scale_y(float y, int flag, int flag_data)
{
float tempY = y;
+ const float RaiseScale = 1/pie_RAISE_SCALE;
if (flag & pie_RAISE) {
tempY = y - flag_data;
if (y - flag_data < 0) tempY = 0;
} else if (flag & pie_HEIGHT_SCALED) {
if(y>0) {
- tempY = (y * flag_data)/pie_RAISE_SCALE;
+ tempY = (y * flag_data) * RaiseScale;
}
}
return tempY;
@@ -763,28 +765,57 @@
dst[8] = invdet*(src[0]*src[5]-src[4]*src[1]);
}
-static void pie_ShadowDrawLoop(float pos_lgt0[4])
+static void pie_ShadowDrawLoop(float pos_lgt0[4], BOOL bProcessLight)
{
float invmat[9];
- Vector3f light;
+ Vector3f light;
unsigned int i;
+ static BOOL bSecondPass = FALSE;
- for (i = 0; i < nb_scshapes; i++)
+ if (bProcessLight)
{
- glLoadIdentity();
- glMultMatrixf( scshapes[i].matrix );
- inverse_matrix( scshapes[i].matrix, invmat );
- light.x = invmat[0] * pos_lgt0[0] + invmat[3] * pos_lgt0[1] +
invmat[6] * pos_lgt0[2];
- light.y = invmat[1] * pos_lgt0[0] + invmat[4] * pos_lgt0[1] +
invmat[7] * pos_lgt0[2];
- light.z = invmat[2] * pos_lgt0[0] + invmat[5] * pos_lgt0[1] +
invmat[8] * pos_lgt0[2];
- pie_DrawShadow(scshapes[i].shape, scshapes[i].flag,
scshapes[i].flag_data, &light);
+ if (bSecondPass)
+ {
+ for (i = 0; i < nb_scshapes; i++)
+ {
+ glLoadIdentity();
+ glMultMatrixf( scshapes[i].matrix );
+ pie_DrawShadow(scshapes[i].shape,
scshapes[i].flag, scshapes[i].flag_data, &scshapes[i].light);
+ }
+ bSecondPass = FALSE;
+ }
+ else
+ {
+ for (i = 0; i < nb_scshapes; i++)
+ {
+ glLoadIdentity();
+ glMultMatrixf( scshapes[i].matrix );
+ inverse_matrix( scshapes[i].matrix, invmat );
+ scshapes[i].light.x = invmat[0] * pos_lgt0[0] +
invmat[3] * pos_lgt0[1] + invmat[6] * pos_lgt0[2];
+ scshapes[i].light.y = invmat[1] * pos_lgt0[0] +
invmat[4] * pos_lgt0[1] + invmat[7] * pos_lgt0[2];
+ scshapes[i].light.z = invmat[2] * pos_lgt0[0] +
invmat[5] * pos_lgt0[1] + invmat[8] * pos_lgt0[2];
+ pie_DrawShadow(scshapes[i].shape,
scshapes[i].flag, scshapes[i].flag_data, &scshapes[i].light);
+ }
+ bSecondPass = TRUE;
+ }
}
+ else
+ {
+ for (i = 0; i < nb_scshapes; i++)
+ {
+ glLoadIdentity();
+ glMultMatrixf( scshapes[i].matrix );
+ inverse_matrix( scshapes[i].matrix, invmat );
+ light.x = invmat[0] * pos_lgt0[0] + invmat[3] *
pos_lgt0[1] + invmat[6] * pos_lgt0[2];
+ light.y = invmat[1] * pos_lgt0[0] + invmat[4] *
pos_lgt0[1] + invmat[7] * pos_lgt0[2];
+ light.z = invmat[2] * pos_lgt0[0] + invmat[5] *
pos_lgt0[1] + invmat[8] * pos_lgt0[2];
+ pie_DrawShadow(scshapes[i].shape, scshapes[i].flag,
scshapes[i].flag_data, &light);
+ }
+ }
}
static void pie_DrawShadows(void)
{
- static BOOL dlist_defined = FALSE;
- static GLuint dlist;
float pos_lgt0[4];
float width = pie_GetVideoBufferWidth();
float height = pie_GetVideoBufferHeight();
@@ -812,14 +843,10 @@
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
glStencilFunc(GL_ALWAYS, 0, ~0);
- pie_ShadowDrawLoop(pos_lgt0);
+ pie_ShadowDrawLoop(pos_lgt0, FALSE);
glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
} else {
- if (!dlist_defined) {
- dlist = glGenLists(1);
- dlist_defined = TRUE;
- }
// Setup stencil for back faces.
glStencilMask(~0);
glStencilFunc(GL_ALWAYS, 0, ~0);
@@ -827,14 +854,14 @@
glCullFace(GL_BACK);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
- pie_ShadowDrawLoop(pos_lgt0);
+ pie_ShadowDrawLoop(pos_lgt0, TRUE);
// Setup stencil for front faces.
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
// Draw shadows again
- pie_ShadowDrawLoop(pos_lgt0);
+ pie_ShadowDrawLoop(pos_lgt0, TRUE);
}
glEnable(GL_CULL_FACE);
_______________________________________________
Warzone-dev mailing list
[email protected]
https://mail.gna.org/listinfo/warzone-dev