123
This commit is contained in:
662
RenderDll/Common/3DUtils.cpp
Normal file
662
RenderDll/Common/3DUtils.cpp
Normal file
@@ -0,0 +1,662 @@
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4244) // conversion from 'double' to 'float', possible loss of data
|
||||
#pragma warning(disable:4305) // truncation from 'double' to 'float'
|
||||
|
||||
void utlMtx2Euler(int ord, float m[3][3], float rot[3]);
|
||||
static void utlMtx2Quat(float m[3][3], float quat[4]);
|
||||
|
||||
|
||||
// ========== utlDecompMatrix ==========
|
||||
//
|
||||
// SYNOPSIS
|
||||
// Decompose a matrix to it's components, translate,
|
||||
// rotate ( a quaternion) and scale.
|
||||
//
|
||||
static void utlDecompMatrix( const float *mat, DECOMP_MAT *dmat, char *rotOrder)
|
||||
{
|
||||
int i, j,
|
||||
order;
|
||||
static float Sxy, Sxz,
|
||||
rot[3], quat[4],
|
||||
det,
|
||||
m[3][3];
|
||||
|
||||
dmat->translate[0] = mat[3*4+0];
|
||||
dmat->translate[1] = mat[3*4+1];
|
||||
dmat->translate[2] = mat[3*4+2];
|
||||
|
||||
m[0][0] = mat[0*4+0];
|
||||
m[0][1] = mat[0*4+1];
|
||||
m[0][2] = mat[0*4+2];
|
||||
|
||||
dmat->scale[0] = sqrt_tpl( m[0][0]*m[0][0] + m[0][1]*m[0][1] + m[0][2]*m[0][2]);
|
||||
|
||||
/* Normalize second row */
|
||||
m[0][0] /= dmat->scale[0];
|
||||
m[0][1] /= dmat->scale[0];
|
||||
m[0][2] /= dmat->scale[0];
|
||||
|
||||
/* Determine xy shear */
|
||||
Sxy = mat[0*4+0] * mat[1*4+0] +
|
||||
mat[0*4+1] * mat[1*4+1] +
|
||||
mat[0*4+2] * mat[1*4+2];
|
||||
|
||||
m[1][0] = mat[1*4+0] - Sxy * mat[0*4+0];
|
||||
m[1][1] = mat[1*4+1] - Sxy * mat[0*4+1];
|
||||
m[1][2] = mat[1*4+2] - Sxy * mat[0*4+2];
|
||||
|
||||
dmat->scale[1] = sqrt_tpl( m[1][0]*m[1][0] + m[1][1]*m[1][1] + m[1][2]*m[1][2]);
|
||||
|
||||
/* Normalize second row */
|
||||
m[1][0] /= dmat->scale[1];
|
||||
m[1][1] /= dmat->scale[1];
|
||||
m[1][2] /= dmat->scale[1];
|
||||
|
||||
/* Determine xz shear */
|
||||
Sxz = mat[0*4+0] * mat[2*4+0] +
|
||||
mat[0*4+1] * mat[2*4+1] +
|
||||
mat[0*4+2] * mat[2*4+2];
|
||||
|
||||
m[2][0] = mat[2*4+0] - Sxz * mat[0*4+0];
|
||||
m[2][1] = mat[2*4+1] - Sxz * mat[0*4+1];
|
||||
m[2][2] = mat[2*4+2] - Sxz * mat[0*4+2];
|
||||
|
||||
dmat->scale[2] = sqrt_tpl( m[2][0]*m[2][0] + m[2][1]*m[2][1] + m[2][2]*m[2][2]);
|
||||
|
||||
/* Normalize third row */
|
||||
m[2][0] /= dmat->scale[2];
|
||||
m[2][1] /= dmat->scale[2];
|
||||
m[2][2] /= dmat->scale[2];
|
||||
|
||||
det = (m[0][0]*m[1][1]*m[2][2]) + (m[0][1]*m[1][2]*m[2][0]) + (m[0][2]*m[1][0]*m[2][1]) -
|
||||
(m[0][2]*m[1][1]*m[2][0]) - (m[0][0]*m[1][2]*m[2][1]) - (m[0][1]*m[1][0]*m[2][2]);
|
||||
|
||||
/* If the determinant of the rotation matrix is negative, */
|
||||
/* negate the matrix and scale factors. */
|
||||
|
||||
if ( det < 0.0) {
|
||||
for ( i = 0; i < 3; i++) {
|
||||
for ( j = 0; j < 3; j++)
|
||||
m[i][j] *= -1.0;
|
||||
dmat->scale[i] *= -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the 3x3 rotation matrix into the decomposition
|
||||
// structure.
|
||||
//
|
||||
memcpy( dmat->rotMatrix, m, sizeof( float)*9);
|
||||
|
||||
/*rot[1] = asin( -m[0][2]);
|
||||
if ( fabsf( cos( rot[1])) > 0.0001) {
|
||||
rot[0] = asin( m[1][2]/cos( rot[1]));
|
||||
rot[2] = asin( m[0][1]/cos( rot[1]));
|
||||
} else {
|
||||
rot[0] = acos( m[1][1]);
|
||||
rot[2] = 0.0;
|
||||
}*/
|
||||
|
||||
switch( rotOrder[2]) {
|
||||
case XROT:
|
||||
if ( rotOrder[1] == YROT)
|
||||
order = UTL_ROT_XYZ;
|
||||
else
|
||||
order = UTL_ROT_XZY;
|
||||
break;
|
||||
|
||||
case YROT:
|
||||
if ( rotOrder[1] == XROT)
|
||||
order = UTL_ROT_YXZ;
|
||||
else
|
||||
order = UTL_ROT_YZX;
|
||||
break;
|
||||
|
||||
case ZROT:
|
||||
if ( rotOrder[1] == XROT)
|
||||
order = UTL_ROT_ZXY;
|
||||
else
|
||||
order = UTL_ROT_ZYX;
|
||||
break;
|
||||
|
||||
default:
|
||||
order = UTL_ROT_XYZ;
|
||||
break;
|
||||
}
|
||||
|
||||
utlMtx2Euler( order, m, rot);
|
||||
dmat->rotation[0] = rot[0];
|
||||
dmat->rotation[1] = rot[1];
|
||||
dmat->rotation[2] = rot[2];
|
||||
|
||||
utlMtx2Quat(m,quat);
|
||||
dmat->quaternion[0] = quat[0];
|
||||
dmat->quaternion[1] = quat[1];
|
||||
dmat->quaternion[2] = quat[2];
|
||||
dmat->quaternion[3] = quat[3];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ========== CapQuat2Euler ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Convert a quaternion to Euler angles.
|
||||
*
|
||||
* PARAMETERS
|
||||
* int The order of rotations
|
||||
* float mat[3][3] rotation matrix
|
||||
* float rot[3] xyz-rotation values
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This routine converts a mateix to Euler angles.
|
||||
* There are a few caveats:
|
||||
* The rotation order for the returned angles is always zyx.
|
||||
* The derivation of this algorithm is taken from Ken Shoemake's
|
||||
* paper:
|
||||
* SIGGRAPH 1985, Vol. 19, # 3, pp. 253-254
|
||||
*
|
||||
* RETURN VALUE
|
||||
* None.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#define M_PI_2 3.14159/2.0
|
||||
#endif
|
||||
|
||||
void utlMtx2Euler(int ord, float m[3][3], float rot[3])
|
||||
{
|
||||
/*
|
||||
* Ken Shoemake's recommended algorithm is to convert the
|
||||
* quaternion to a matrix and the matrix to Euler angles.
|
||||
* We do this, of course, without generating unused matrix
|
||||
* elements.
|
||||
*/
|
||||
float zr, sxr, cxr,
|
||||
yr, syr, cyr,
|
||||
xr, szr, czr;
|
||||
static float epsilon = 1.0e-5f;
|
||||
|
||||
switch ( ord) {
|
||||
|
||||
case UTL_ROT_ZYX:
|
||||
syr = -m[0][2];
|
||||
cyr = sqrt_tpl(1 - syr * syr);
|
||||
|
||||
if (cyr < epsilon) {
|
||||
/* Insufficient accuracy, assume that yr = PI/2 && zr = 0 */
|
||||
xr = cry_atan2f(-m[2][1], m[1][1]);
|
||||
yr = (syr > 0) ? M_PI_2 : -M_PI_2; /* +/- 90 deg */
|
||||
zr = 0.0;
|
||||
} else {
|
||||
xr = cry_atan2f(m[1][2], m[2][2]);
|
||||
yr = cry_atan2f(syr, cyr);
|
||||
zr = cry_atan2f(m[0][1], m[0][0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case UTL_ROT_YZX:
|
||||
szr = m[0][1];
|
||||
czr = sqrt_tpl(1 - szr * szr);
|
||||
if (czr < epsilon) {
|
||||
/* Insufficient accuracy, assume that zr = +/- PI/2 && yr = 0 */
|
||||
xr = cry_atan2f(m[1][2], m[2][2]);
|
||||
yr = 0.0;
|
||||
zr = (szr > 0) ? M_PI_2 : -M_PI_2;
|
||||
} else {
|
||||
xr = cry_atan2f(-m[2][1], m[1][1]);
|
||||
yr = cry_atan2f(-m[0][2], m[0][0]);
|
||||
zr = cry_atan2f(szr, czr);
|
||||
}
|
||||
break;
|
||||
|
||||
case UTL_ROT_ZXY:
|
||||
sxr = m[1][2];
|
||||
cxr = sqrt_tpl(1 - sxr * sxr);
|
||||
|
||||
if (cxr < epsilon) {
|
||||
/* Insufficient accuracy, assume that xr = PI/2 && zr = 0 */
|
||||
xr = (sxr > 0) ? M_PI_2 : -M_PI_2;
|
||||
yr = cry_atan2f(m[2][0], m[0][0]);
|
||||
zr = 0.0;
|
||||
} else {
|
||||
xr = cry_atan2f( sxr, cxr);
|
||||
yr = cry_atan2f(-m[0][2], m[2][2]);
|
||||
zr = cry_atan2f(-m[1][0], m[1][1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case UTL_ROT_XZY:
|
||||
szr = -m[1][0];
|
||||
czr = sqrt_tpl(1 - szr * szr);
|
||||
if (czr < epsilon) {
|
||||
/* Insufficient accuracy, assume that zr = PI / 2 && xr = 0 */
|
||||
xr = 0.0;
|
||||
yr = cry_atan2f(-m[0][2], m[2][2]);
|
||||
zr = (szr > 0) ? M_PI_2 : -M_PI_2;
|
||||
} else {
|
||||
xr = cry_atan2f(m[0][2], m[1][1]);
|
||||
yr = cry_atan2f(m[2][0], m[0][0]);
|
||||
zr = cry_atan2f(szr, czr);
|
||||
}
|
||||
break;
|
||||
|
||||
case UTL_ROT_YXZ:
|
||||
sxr = -m[2][1];
|
||||
cxr = sqrt_tpl(1 - sxr * sxr);
|
||||
|
||||
if (cxr < epsilon) {
|
||||
/* Insufficient accuracy, assume that xr = PI/2 && yr = 0 */
|
||||
xr = (sxr > 0) ? M_PI_2 : -M_PI_2;
|
||||
yr = 0.0;
|
||||
zr = cry_atan2f(-m[1][0], m[0][0]);
|
||||
} else {
|
||||
xr = cry_atan2f(sxr, cxr);
|
||||
yr = cry_atan2f(m[2][0], m[2][2]);
|
||||
zr = cry_atan2f(m[0][1], m[1][1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case UTL_ROT_XYZ:
|
||||
syr = m[2][0];
|
||||
cyr = sqrt_tpl(1 - syr * syr);
|
||||
if (cyr < epsilon) {
|
||||
/* Insufficient accuracy, assume that yr = PI / 2 && xr = 0 */
|
||||
xr = 0.0;
|
||||
yr = (syr > 0) ? M_PI_2 : -M_PI_2;
|
||||
zr = cry_atan2f(m[0][1], m[1][1]);
|
||||
} else {
|
||||
xr = cry_atan2f(-m[2][1], m[2][2]);
|
||||
yr = cry_atan2f( syr, cyr);
|
||||
zr = cry_atan2f(-m[1][1], m[0][0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
rot[0] = xr;
|
||||
rot[1] = yr;
|
||||
rot[2] = zr;
|
||||
}
|
||||
|
||||
/*
|
||||
* ========= utlMtx2Quat ====================
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Returns the w,x,y,z coordinates of the quaternion
|
||||
* given the rotation matrix.
|
||||
*/
|
||||
static void utlMtx2Quat(float m[3][3], float quat[4])
|
||||
{
|
||||
// m stores the 3x3 rotation matrix.
|
||||
// Convert it to quaternion.
|
||||
float trace = m[0][0] + m[1][1] + m[2][2];
|
||||
float s;
|
||||
if (trace > 0.0) {
|
||||
s = sqrt_tpl(trace + 1.0);
|
||||
quat[0] = s*0.5;
|
||||
s = 0.5/s;
|
||||
quat[1] = (m[1][2] - m[2][1])*s;
|
||||
quat[2] = (m[2][0] - m[0][2])*s;
|
||||
quat[3] = (m[0][1] - m[1][0])*s;
|
||||
|
||||
}
|
||||
else {
|
||||
int i = 0; // i represents index of quaternion, so 0=scalar, 1=xaxis, etc.
|
||||
int nxt[3] = {1,2,0}; // next index for each component.
|
||||
if (m[1][1] > m[0][0]) i = 1;
|
||||
if (m[2][2] > m[i][i]) i = 2;
|
||||
int j = nxt[i]; int k = nxt[j];
|
||||
s = sqrt_tpl( (m[i][i] - (m[j][j] + m[k][k])) + 1.0);
|
||||
float q[4];
|
||||
q[i+1] = s*0.5;
|
||||
s=0.5/s;
|
||||
q[0] = (m[j][k] - m[k][j])*s;
|
||||
q[j+1] = (m[i][j]+m[j][i])*s;
|
||||
q[k+1] = (m[i][k]+m[k][i])*s;
|
||||
quat[0] = q[0];
|
||||
quat[1] = q[1];
|
||||
quat[2] = q[2];
|
||||
quat[3] = q[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ========== DtMatrixGetTranslation ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Return the x,y,z translation components of the
|
||||
* given matrix. The priority order is assumed to be ---.
|
||||
*/
|
||||
|
||||
int DtMatrixGetTranslation( float *matrix, float *xTrans, float *yTrans, float *zTrans)
|
||||
{
|
||||
DECOMP_MAT dmat;
|
||||
if (matrix)
|
||||
{
|
||||
utlDecompMatrix( matrix, &dmat, "xyz" );
|
||||
*xTrans = dmat.translate[0];
|
||||
*yTrans = dmat.translate[1];
|
||||
*zTrans = dmat.translate[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*xTrans = *yTrans = *zTrans = 0.0;
|
||||
}
|
||||
return(1);
|
||||
|
||||
} /* DtMatrixGetTranslation */
|
||||
|
||||
/*
|
||||
* ========== DtMatrixGetQuaternion ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Return the quaternion (scalar, xAxis, yAxis, zAxis)
|
||||
* defining the orientation represented in the given matrix.
|
||||
*/
|
||||
int DtMatrixGetQuaternion(float *matrix, float *scalar, float *xAxis, float *yAxis, float *zAxis)
|
||||
{
|
||||
DECOMP_MAT dmat;
|
||||
if (matrix)
|
||||
{
|
||||
utlDecompMatrix( matrix, &dmat, "xyz" );
|
||||
*scalar = dmat.quaternion[0];
|
||||
*xAxis = dmat.quaternion[1];
|
||||
*yAxis = dmat.quaternion[2];
|
||||
*zAxis = dmat.quaternion[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
*scalar = 1.0; *xAxis = *yAxis = *zAxis = 0.0;
|
||||
}
|
||||
return(1);
|
||||
} /* DtMatrixGetQuaternion */
|
||||
|
||||
/*
|
||||
* ========== DtMatrixGetRotation ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Return the x,y,z rotation components of the
|
||||
* given matrix. The priority order is assumed to be ---.
|
||||
*/
|
||||
|
||||
int DtMatrixGetRotation(float *matrix, float *xRotation, float *yRotation, float *zRotation)
|
||||
{
|
||||
|
||||
DECOMP_MAT dmat;
|
||||
if (matrix)
|
||||
{
|
||||
utlDecompMatrix( matrix, &dmat, "xyz" );
|
||||
*xRotation = dmat.rotation[0];
|
||||
*yRotation = dmat.rotation[1];
|
||||
*zRotation = dmat.rotation[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*xRotation = *yRotation = *zRotation = 0.0;
|
||||
}
|
||||
return(1);
|
||||
|
||||
} /* DtMatrixGetRotation */
|
||||
|
||||
|
||||
/*
|
||||
* ========== DtMatrixGetScale ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Return the x,y,z scale components of the given
|
||||
* matrix. The priority order is assumed to be ---.
|
||||
*/
|
||||
|
||||
int DtMatrixGetScale(float *matrix, float *xScale, float *yScale, float *zScale)
|
||||
{
|
||||
|
||||
DECOMP_MAT dmat;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
utlDecompMatrix( matrix, &dmat, "xyz" );
|
||||
*xScale = dmat.scale[0];
|
||||
*yScale = dmat.scale[1];
|
||||
*zScale = dmat.scale[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*xScale = *yScale = *zScale = 1.0;
|
||||
}
|
||||
return(1);
|
||||
|
||||
} /* DtMatrixGetScale */
|
||||
/*
|
||||
* ========== DtMatrixGetTransforms ==========
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Return the x,y,z translation, scale quaternion and
|
||||
* Euler angles in "xyz" order of the given
|
||||
* matrix.
|
||||
*/
|
||||
|
||||
int DtMatrixGetTransforms(float *matrix, float *translate,
|
||||
float *scale, float *quaternion, float *rotation)
|
||||
{
|
||||
DECOMP_MAT dmat;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
utlDecompMatrix( matrix, &dmat, "xyz" );
|
||||
|
||||
if (translate) {
|
||||
translate[0] = dmat.translate[0];
|
||||
translate[1] = dmat.translate[1];
|
||||
translate[2] = dmat.translate[2];
|
||||
}
|
||||
if (scale) {
|
||||
scale[0] = dmat.scale[0];
|
||||
scale[1] = dmat.scale[1];
|
||||
scale[2] = dmat.scale[2];
|
||||
}
|
||||
if (quaternion) {
|
||||
quaternion[0] = dmat.quaternion[0];
|
||||
quaternion[1] = dmat.quaternion[1];
|
||||
quaternion[2] = dmat.quaternion[2];
|
||||
quaternion[3] = dmat.quaternion[3];
|
||||
}
|
||||
if (rotation) {
|
||||
rotation[0] = dmat.rotation[0];
|
||||
rotation[1] = dmat.rotation[1];
|
||||
rotation[2] = dmat.rotation[2];
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
float gSinTable[1024] = {
|
||||
0.000000,0.001534,0.003068,0.004602,0.006136,0.007670,0.009204,0.010738,
|
||||
0.012272,0.013805,0.015339,0.016873,0.018407,0.019940,0.021474,0.023008,
|
||||
0.024541,0.026075,0.027608,0.029142,0.030675,0.032208,0.033741,0.035274,
|
||||
0.036807,0.038340,0.039873,0.041406,0.042938,0.044471,0.046003,0.047535,
|
||||
0.049068,0.050600,0.052132,0.053664,0.055195,0.056727,0.058258,0.059790,
|
||||
0.061321,0.062852,0.064383,0.065913,0.067444,0.068974,0.070505,0.072035,
|
||||
0.073565,0.075094,0.076624,0.078153,0.079682,0.081211,0.082740,0.084269,
|
||||
0.085797,0.087326,0.088854,0.090381,0.091909,0.093436,0.094963,0.096490,
|
||||
0.098017,0.099544,0.101070,0.102596,0.104122,0.105647,0.107172,0.108697,
|
||||
0.110222,0.111747,0.113271,0.114795,0.116319,0.117842,0.119365,0.120888,
|
||||
0.122411,0.123933,0.125455,0.126977,0.128498,0.130019,0.131540,0.133061,
|
||||
0.134581,0.136101,0.137620,0.139139,0.140658,0.142177,0.143695,0.145213,
|
||||
0.146730,0.148248,0.149765,0.151281,0.152797,0.154313,0.155828,0.157343,
|
||||
0.158858,0.160372,0.161886,0.163400,0.164913,0.166426,0.167938,0.169450,
|
||||
0.170962,0.172473,0.173984,0.175494,0.177004,0.178514,0.180023,0.181532,
|
||||
0.183040,0.184548,0.186055,0.187562,0.189069,0.190575,0.192080,0.193586,
|
||||
0.195090,0.196595,0.198098,0.199602,0.201105,0.202607,0.204109,0.205610,
|
||||
0.207111,0.208612,0.210112,0.211611,0.213110,0.214609,0.216107,0.217604,
|
||||
0.219101,0.220598,0.222094,0.223589,0.225084,0.226578,0.228072,0.229565,
|
||||
0.231058,0.232550,0.234042,0.235533,0.237024,0.238514,0.240003,0.241492,
|
||||
0.242980,0.244468,0.245955,0.247442,0.248928,0.250413,0.251898,0.253382,
|
||||
0.254866,0.256349,0.257831,0.259313,0.260794,0.262275,0.263755,0.265234,
|
||||
0.266713,0.268191,0.269668,0.271145,0.272621,0.274097,0.275572,0.277046,
|
||||
0.278520,0.279993,0.281465,0.282937,0.284408,0.285878,0.287347,0.288816,
|
||||
0.290285,0.291752,0.293219,0.294685,0.296151,0.297616,0.299080,0.300543,
|
||||
0.302006,0.303468,0.304929,0.306390,0.307850,0.309309,0.310767,0.312225,
|
||||
0.313682,0.315138,0.316593,0.318048,0.319502,0.320955,0.322408,0.323859,
|
||||
0.325310,0.326760,0.328210,0.329658,0.331106,0.332553,0.334000,0.335445,
|
||||
0.336890,0.338334,0.339777,0.341219,0.342661,0.344101,0.345541,0.346980,
|
||||
0.348419,0.349856,0.351293,0.352729,0.354164,0.355598,0.357031,0.358463,
|
||||
0.359895,0.361326,0.362756,0.364185,0.365613,0.367040,0.368467,0.369892,
|
||||
0.371317,0.372741,0.374164,0.375586,0.377007,0.378428,0.379847,0.381266,
|
||||
0.382683,0.384100,0.385516,0.386931,0.388345,0.389758,0.391170,0.392582,
|
||||
0.393992,0.395401,0.396810,0.398218,0.399624,0.401030,0.402435,0.403838,
|
||||
0.405241,0.406643,0.408044,0.409444,0.410843,0.412241,0.413638,0.415034,
|
||||
0.416430,0.417824,0.419217,0.420609,0.422000,0.423390,0.424780,0.426168,
|
||||
0.427555,0.428941,0.430326,0.431711,0.433094,0.434476,0.435857,0.437237,
|
||||
0.438616,0.439994,0.441371,0.442747,0.444122,0.445496,0.446869,0.448241,
|
||||
0.449611,0.450981,0.452350,0.453717,0.455084,0.456449,0.457813,0.459177,
|
||||
0.460539,0.461900,0.463260,0.464619,0.465976,0.467333,0.468689,0.470043,
|
||||
0.471397,0.472749,0.474100,0.475450,0.476799,0.478147,0.479494,0.480839,
|
||||
0.482184,0.483527,0.484869,0.486210,0.487550,0.488889,0.490226,0.491563,
|
||||
0.492898,0.494232,0.495565,0.496897,0.498228,0.499557,0.500885,0.502212,
|
||||
0.503538,0.504863,0.506187,0.507509,0.508830,0.510150,0.511469,0.512786,
|
||||
0.514103,0.515418,0.516732,0.518045,0.519356,0.520666,0.521975,0.523283,
|
||||
0.524590,0.525895,0.527199,0.528502,0.529804,0.531104,0.532403,0.533701,
|
||||
0.534998,0.536293,0.537587,0.538880,0.540171,0.541462,0.542751,0.544039,
|
||||
0.545325,0.546610,0.547894,0.549177,0.550458,0.551738,0.553017,0.554294,
|
||||
0.555570,0.556845,0.558119,0.559391,0.560662,0.561931,0.563199,0.564466,
|
||||
0.565732,0.566996,0.568259,0.569521,0.570781,0.572040,0.573297,0.574553,
|
||||
0.575808,0.577062,0.578314,0.579565,0.580814,0.582062,0.583309,0.584554,
|
||||
0.585798,0.587040,0.588282,0.589521,0.590760,0.591997,0.593232,0.594466,
|
||||
0.595699,0.596931,0.598161,0.599389,0.600616,0.601842,0.603067,0.604290,
|
||||
0.605511,0.606731,0.607950,0.609167,0.610383,0.611597,0.612810,0.614022,
|
||||
0.615232,0.616440,0.617647,0.618853,0.620057,0.621260,0.622461,0.623661,
|
||||
0.624859,0.626056,0.627252,0.628446,0.629638,0.630829,0.632019,0.633207,
|
||||
0.634393,0.635578,0.636762,0.637944,0.639124,0.640303,0.641481,0.642657,
|
||||
0.643832,0.645005,0.646176,0.647346,0.648514,0.649681,0.650847,0.652011,
|
||||
0.653173,0.654334,0.655493,0.656651,0.657807,0.658961,0.660114,0.661266,
|
||||
0.662416,0.663564,0.664711,0.665856,0.667000,0.668142,0.669283,0.670422,
|
||||
0.671559,0.672695,0.673829,0.674962,0.676093,0.677222,0.678350,0.679476,
|
||||
0.680601,0.681724,0.682846,0.683965,0.685084,0.686200,0.687315,0.688429,
|
||||
0.689541,0.690651,0.691759,0.692866,0.693971,0.695075,0.696177,0.697278,
|
||||
0.698376,0.699473,0.700569,0.701663,0.702755,0.703845,0.704934,0.706021,
|
||||
0.707107,0.708191,0.709273,0.710353,0.711432,0.712509,0.713585,0.714659,
|
||||
0.715731,0.716801,0.717870,0.718937,0.720003,0.721066,0.722128,0.723188,
|
||||
0.724247,0.725304,0.726359,0.727413,0.728464,0.729514,0.730563,0.731609,
|
||||
0.732654,0.733697,0.734739,0.735779,0.736817,0.737853,0.738887,0.739920,
|
||||
0.740951,0.741980,0.743008,0.744034,0.745058,0.746080,0.747101,0.748119,
|
||||
0.749136,0.750152,0.751165,0.752177,0.753187,0.754195,0.755201,0.756206,
|
||||
0.757209,0.758210,0.759209,0.760207,0.761202,0.762196,0.763188,0.764179,
|
||||
0.765167,0.766154,0.767139,0.768122,0.769103,0.770083,0.771061,0.772036,
|
||||
0.773010,0.773983,0.774953,0.775922,0.776888,0.777853,0.778817,0.779778,
|
||||
0.780737,0.781695,0.782651,0.783605,0.784557,0.785507,0.786455,0.787402,
|
||||
0.788346,0.789289,0.790230,0.791169,0.792107,0.793042,0.793975,0.794907,
|
||||
0.795837,0.796765,0.797691,0.798615,0.799537,0.800458,0.801376,0.802293,
|
||||
0.803208,0.804120,0.805031,0.805940,0.806848,0.807753,0.808656,0.809558,
|
||||
0.810457,0.811355,0.812251,0.813144,0.814036,0.814926,0.815814,0.816701,
|
||||
0.817585,0.818467,0.819348,0.820226,0.821103,0.821977,0.822850,0.823721,
|
||||
0.824589,0.825456,0.826321,0.827184,0.828045,0.828904,0.829761,0.830616,
|
||||
0.831470,0.832321,0.833170,0.834018,0.834863,0.835706,0.836548,0.837387,
|
||||
0.838225,0.839060,0.839894,0.840725,0.841555,0.842383,0.843208,0.844032,
|
||||
0.844854,0.845673,0.846491,0.847307,0.848120,0.848932,0.849742,0.850549,
|
||||
0.851355,0.852159,0.852961,0.853760,0.854558,0.855354,0.856147,0.856939,
|
||||
0.857729,0.858516,0.859302,0.860085,0.860867,0.861646,0.862424,0.863199,
|
||||
0.863973,0.864744,0.865514,0.866281,0.867046,0.867809,0.868571,0.869330,
|
||||
0.870087,0.870842,0.871595,0.872346,0.873095,0.873842,0.874587,0.875329,
|
||||
0.876070,0.876809,0.877545,0.878280,0.879012,0.879743,0.880471,0.881197,
|
||||
0.881921,0.882643,0.883363,0.884081,0.884797,0.885511,0.886223,0.886932,
|
||||
0.887640,0.888345,0.889048,0.889750,0.890449,0.891146,0.891841,0.892534,
|
||||
0.893224,0.893913,0.894599,0.895284,0.895966,0.896646,0.897325,0.898001,
|
||||
0.898674,0.899346,0.900016,0.900683,0.901349,0.902012,0.902673,0.903332,
|
||||
0.903989,0.904644,0.905297,0.905947,0.906596,0.907242,0.907886,0.908528,
|
||||
0.909168,0.909806,0.910441,0.911075,0.911706,0.912335,0.912962,0.913587,
|
||||
0.914210,0.914830,0.915449,0.916065,0.916679,0.917291,0.917901,0.918508,
|
||||
0.919114,0.919717,0.920318,0.920917,0.921514,0.922109,0.922701,0.923291,
|
||||
0.923880,0.924465,0.925049,0.925631,0.926210,0.926787,0.927363,0.927935,
|
||||
0.928506,0.929075,0.929641,0.930205,0.930767,0.931327,0.931884,0.932440,
|
||||
0.932993,0.933544,0.934093,0.934639,0.935184,0.935726,0.936266,0.936803,
|
||||
0.937339,0.937872,0.938404,0.938932,0.939459,0.939984,0.940506,0.941026,
|
||||
0.941544,0.942060,0.942573,0.943084,0.943593,0.944100,0.944605,0.945107,
|
||||
0.945607,0.946105,0.946601,0.947094,0.947586,0.948075,0.948561,0.949046,
|
||||
0.949528,0.950008,0.950486,0.950962,0.951435,0.951906,0.952375,0.952842,
|
||||
0.953306,0.953768,0.954228,0.954686,0.955141,0.955594,0.956045,0.956494,
|
||||
0.956940,0.957385,0.957826,0.958266,0.958703,0.959139,0.959572,0.960002,
|
||||
0.960431,0.960857,0.961280,0.961702,0.962121,0.962538,0.962953,0.963366,
|
||||
0.963776,0.964184,0.964590,0.964993,0.965394,0.965793,0.966190,0.966584,
|
||||
0.966976,0.967366,0.967754,0.968139,0.968522,0.968903,0.969281,0.969657,
|
||||
0.970031,0.970403,0.970772,0.971139,0.971504,0.971866,0.972226,0.972584,
|
||||
0.972940,0.973293,0.973644,0.973993,0.974339,0.974684,0.975025,0.975365,
|
||||
0.975702,0.976037,0.976370,0.976700,0.977028,0.977354,0.977677,0.977999,
|
||||
0.978317,0.978634,0.978948,0.979260,0.979570,0.979877,0.980182,0.980485,
|
||||
0.980785,0.981083,0.981379,0.981673,0.981964,0.982253,0.982539,0.982824,
|
||||
0.983105,0.983385,0.983662,0.983937,0.984210,0.984480,0.984749,0.985014,
|
||||
0.985278,0.985539,0.985798,0.986054,0.986308,0.986560,0.986809,0.987057,
|
||||
0.987301,0.987544,0.987784,0.988022,0.988258,0.988491,0.988722,0.988950,
|
||||
0.989177,0.989400,0.989622,0.989841,0.990058,0.990273,0.990485,0.990695,
|
||||
0.990903,0.991108,0.991311,0.991511,0.991710,0.991906,0.992099,0.992291,
|
||||
0.992480,0.992666,0.992850,0.993032,0.993212,0.993389,0.993564,0.993737,
|
||||
0.993907,0.994075,0.994240,0.994404,0.994565,0.994723,0.994879,0.995033,
|
||||
0.995185,0.995334,0.995481,0.995625,0.995767,0.995907,0.996045,0.996180,
|
||||
0.996313,0.996443,0.996571,0.996697,0.996820,0.996941,0.997060,0.997176,
|
||||
0.997290,0.997402,0.997511,0.997618,0.997723,0.997825,0.997925,0.998023,
|
||||
0.998118,0.998211,0.998302,0.998390,0.998476,0.998559,0.998640,0.998719,
|
||||
0.998795,0.998870,0.998941,0.999011,0.999078,0.999142,0.999205,0.999265,
|
||||
0.999322,0.999378,0.999431,0.999481,0.999529,0.999575,0.999619,0.999660,
|
||||
0.999699,0.999735,0.999769,0.999801,0.999831,0.999858,0.999882,0.999905,
|
||||
0.999925,0.999942,0.999958,0.999971,0.999981,0.999989,0.999995,0.999999
|
||||
};
|
||||
|
||||
typedef union FastSqrtUnion
|
||||
{
|
||||
float f;
|
||||
unsigned int i;
|
||||
} FastSqrtUnion;
|
||||
|
||||
unsigned int gFastSqrtTable[0x10000]; // declare table of square roots
|
||||
|
||||
void build_sqrt_table()
|
||||
{
|
||||
unsigned int i;
|
||||
FastSqrtUnion s;
|
||||
|
||||
for (i = 0; i <= 0x7FFF; i++)
|
||||
{
|
||||
|
||||
// Build a float with the bit pattern i as mantissa
|
||||
// and an exponent of 0, stored as 127
|
||||
|
||||
s.i = (i << 8) | (0x7F << 23);
|
||||
s.f = (float)sqrt_tpl(s.f);
|
||||
|
||||
// Take the square root then strip the first 7 bits of
|
||||
// the mantissa into the table
|
||||
|
||||
gFastSqrtTable[i + 0x8000] = (s.i & 0x7FFFFF);
|
||||
|
||||
// Repeat the process, this time with an exponent of 1,
|
||||
// stored as 128
|
||||
|
||||
s.i = (i << 8) | (0x80 << 23);
|
||||
s.f = (float)sqrt_tpl(s.f);
|
||||
|
||||
gFastSqrtTable[i] = (s.i & 0x7FFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
/*
|
||||
* Initialize tables, etc for fast math functions.
|
||||
*/
|
||||
void init_math(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
build_sqrt_table();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
55
RenderDll/Common/3DUtils.h
Normal file
55
RenderDll/Common/3DUtils.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//==============================================================================
|
||||
//
|
||||
// 3D math file
|
||||
//
|
||||
//==============================================================================
|
||||
|
||||
#ifndef __3DUTILS_H__
|
||||
#define __3DUTILS_H__
|
||||
|
||||
#include <math.h>
|
||||
|
||||
typedef struct {
|
||||
float translate[3];
|
||||
float scale[3];
|
||||
float rotation[3]; /* Euler angles */
|
||||
float quaternion[4]; /* quaternion */
|
||||
float rotMatrix[3][3]; /* rotation matrix */
|
||||
} DECOMP_MAT;
|
||||
|
||||
|
||||
#define UTL_ROT_XYZ 0
|
||||
#define UTL_ROT_XZY 1
|
||||
#define UTL_ROT_YXZ 2
|
||||
#define UTL_ROT_YZX 3
|
||||
#define UTL_ROT_ZXY 4
|
||||
#define UTL_ROT_ZYX 5
|
||||
|
||||
#define XROT 'x'
|
||||
#define YROT 'y'
|
||||
#define ZROT 'z'
|
||||
|
||||
void utlMtx2Euler(int ord, float m[3][3], float rot[3]);
|
||||
int DtMatrixGetTransforms(float *matrix, float *translate, float *scale, float *quaternion, float *rotation);
|
||||
|
||||
void init_math(void);
|
||||
|
||||
//==========================================================================
|
||||
|
||||
#define FP_BITS(fp) (*(DWORD *)&(fp))
|
||||
extern unsigned int gFastSqrtTable[0x10000]; // declare table of square roots
|
||||
extern float gSinTable[1024];
|
||||
|
||||
_inline float crySqrtf(float n)
|
||||
{
|
||||
|
||||
if (FP_BITS(n) == 0)
|
||||
return 0.0; // check for square root of 0
|
||||
|
||||
FP_BITS(n) = gFastSqrtTable[(FP_BITS(n) >> 8) & 0xFFFF] | ((((FP_BITS(n) - 0x3F800000) >> 1) + 0x3F800000) & 0x7F800000);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
92
RenderDll/Common/3Dc/CompressorLib.h
Normal file
92
RenderDll/Common/3Dc/CompressorLib.h
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Header file for compression library
|
||||
//
|
||||
|
||||
#ifndef _COMPRESSORLIB_H
|
||||
#define _COMPRESSORLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(LINUX)
|
||||
#define _stdcall
|
||||
#else
|
||||
#include "Windows.h"
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FORMAT_COMP_ATI2N,
|
||||
FORMAT_COMP_ATI2N_DXT5,
|
||||
FORMAT_COMP_TOOBIG
|
||||
} COMPRESSED_FORMAT;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FORMAT_ARGB_8888,
|
||||
FORMAT_ARGB_TOOBIG
|
||||
} UNCOMPRESSED_FORMAT;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMPRESSOR_ERROR_NONE,
|
||||
COMPRESSOR_ERROR_NO_INPUT_DATA,
|
||||
COMPRESSOR_ERROR_NO_OUTPUT_POINTER,
|
||||
COMPRESSOR_ERROR_UNSUPPORTED_SOURCE_FORMAT,
|
||||
COMPRESSOR_ERROR_UNSUPPORTED_DESTINATION_FORMAT,
|
||||
COMPRESSOR_ERROR_UNABLE_TO_INIT_CODEC,
|
||||
COMPRESSOR_ERROR_GENERIC
|
||||
} COMPRESSOR_ERROR;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Compressor entry point
|
||||
//
|
||||
// Parameters -
|
||||
//
|
||||
// width - width of input image in pixels
|
||||
// height - height of input image in pixels
|
||||
// sourceFormat - format of source texture (must be ARGB_8888 at the moment)
|
||||
// destinationFormat - format of output texture (can be ATI2N or ATI2N_DXT5)
|
||||
// inputData - pointer to uncompressed texture data
|
||||
// dataOut - address of pointer that will point to the compressed data
|
||||
// outDataSize - filled with the size of the compressed data buffer (can be NULL)
|
||||
//
|
||||
|
||||
COMPRESSOR_ERROR _stdcall CompressTexture(DWORD width,
|
||||
DWORD height,
|
||||
UNCOMPRESSED_FORMAT sourceFormat,
|
||||
COMPRESSED_FORMAT destinationFormat,
|
||||
void *inputData,
|
||||
void **dataOut,
|
||||
DWORD *outDataSize);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
typedef void (*FnDeleteDataATI)(void *pData);
|
||||
typedef COMPRESSOR_ERROR (*FnCompressTextureATI)(DWORD width,
|
||||
DWORD height,
|
||||
UNCOMPRESSED_FORMAT sourceFormat,
|
||||
COMPRESSED_FORMAT destinationFormat,
|
||||
void *inputData,
|
||||
void **dataOut,
|
||||
DWORD *outDataSize);
|
||||
|
||||
extern void (*DeleteDataATI)(void *pData);
|
||||
extern COMPRESSOR_ERROR (*CompressTextureATI)(DWORD width,
|
||||
DWORD height,
|
||||
UNCOMPRESSED_FORMAT sourceFormat,
|
||||
COMPRESSED_FORMAT destinationFormat,
|
||||
void *inputData,
|
||||
void **dataOut,
|
||||
DWORD *outDataSize);
|
||||
|
||||
#endif // _COMPRESSORLIB_H
|
||||
15
RenderDll/Common/CRT.cpp
Normal file
15
RenderDll/Common/CRT.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#if defined(LINUX)
|
||||
#include "platform.h"
|
||||
#else
|
||||
#include "Windows.h"
|
||||
#endif
|
||||
|
||||
void CRTFreeData(void *pData)
|
||||
{
|
||||
free(pData);
|
||||
}
|
||||
|
||||
void CRTDeleteArray(void *pData)
|
||||
{
|
||||
delete [] pData;
|
||||
}
|
||||
169
RenderDll/Common/CommonRender.h
Normal file
169
RenderDll/Common/CommonRender.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/*=============================================================================
|
||||
CommonRender.h: Crytek Common render helper functions and structures declarations.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(COMMONRENDER_H__THIS_LINE_INSERTED_BY_VVP__15_10_1999__INCLUDED_)
|
||||
#define COMMONRENDER_H__THIS_LINE_INSERTED_BY_VVP__15_10_1999__INCLUDED_
|
||||
|
||||
#include "Cry_Math.h"
|
||||
|
||||
#include "Defs.h"
|
||||
#include "ColorDefs.h"
|
||||
#include "Shaders/Shader.h"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
extern CRenderer *gRenDev;
|
||||
extern bool g_bProfilerEnabled;
|
||||
|
||||
|
||||
class CryModel;
|
||||
|
||||
// Cull functions
|
||||
int gfCullBox(Vec3d& min, Vec3d& max);
|
||||
bool gfCullPoint(Vec3d& org);
|
||||
int gfCullSphere(Vec3d& cent, float radius);
|
||||
int gfCullBoundBox(float *minmax);
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define CR_LITTLE_ENDIAN
|
||||
|
||||
|
||||
extern TArray <CFColor> gCurLightStyles;
|
||||
|
||||
struct SWaveForm;
|
||||
struct SShader;
|
||||
|
||||
extern bool gbRgb;
|
||||
|
||||
_inline DWORD COLCONV (DWORD clr)
|
||||
{
|
||||
return ((clr & 0xff00ff00) | ((clr & 0xff0000)>>16) | ((clr & 0xff)<<16));
|
||||
}
|
||||
_inline void COLCONV (CFColor& col)
|
||||
{
|
||||
float v = col[0];
|
||||
col[0] = col[2];
|
||||
col[2] = v;
|
||||
}
|
||||
|
||||
_inline void f2d(double *dst, float *src)
|
||||
{
|
||||
for (int i=0; i<16; i++)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
_inline void d2f(float *dst, double *src)
|
||||
{
|
||||
for (int i=0; i<16; i++)
|
||||
{
|
||||
dst[i] = (float)src[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
#define SF_TRANS 4
|
||||
|
||||
//==============================================================================
|
||||
|
||||
struct SGenTC_NormalMap : public SGenTC
|
||||
{
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_NormalMap);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct SGenTC_ReflectionMap : public SGenTC
|
||||
{
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_ReflectionMap);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct SGenTC_SphereMap : public SGenTC
|
||||
{
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_SphereMap);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct SGenTC_EmbossMap : public SGenTC
|
||||
{
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_EmbossMap);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct SGenTC_ObjectLinear : public SGenTC
|
||||
{
|
||||
TArray<SParam> m_Params;
|
||||
|
||||
virtual ~SGenTC_ObjectLinear()
|
||||
{
|
||||
m_Params.Free();
|
||||
}
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_ObjectLinear);
|
||||
nSize += m_Params.GetSize() * sizeof(SParam);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct SGenTC_EyeLinear : public SGenTC
|
||||
{
|
||||
TArray<SParam> m_Params;
|
||||
|
||||
virtual ~SGenTC_EyeLinear()
|
||||
{
|
||||
m_Params.Free();
|
||||
}
|
||||
virtual SGenTC *mfCopy();
|
||||
virtual bool mfSet(bool bEnable);
|
||||
virtual void mfCompile(char *params, SShader *ef);
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(SGenTC_EyeLinear);
|
||||
nSize += m_Params.GetSize() * sizeof(SParam);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=================================================================
|
||||
|
||||
#endif
|
||||
149
RenderDll/Common/Defs.h
Normal file
149
RenderDll/Common/Defs.h
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(x) ((x)<0?-(x):(x))
|
||||
#endif
|
||||
|
||||
#if !defined(SIGN) && !defined(DO_AMIGAOS)
|
||||
#define SIGN(x) ((x)<0?-1:((x)>0?1:0))
|
||||
#endif
|
||||
|
||||
#define EPSILON 0.001f /* Small value */
|
||||
#define SMALL_EPSILON 0.000001f /* Very small value */
|
||||
#ifndef OS_WIN32
|
||||
//#define INFINITE 999999000 /* Very large number */
|
||||
#endif
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323f /* You know this number, don't you? */
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI PI
|
||||
#endif
|
||||
|
||||
#undef DEBUG
|
||||
#define DEBUG 1
|
||||
|
||||
#if !defined(LINUX)
|
||||
#if defined(COMP_WCC)
|
||||
#define strcasecmp stricmp
|
||||
#define strncasecmp strnicmp
|
||||
#endif
|
||||
|
||||
#if defined(COMP_VC)
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#endif
|
||||
#endif//LINUX
|
||||
|
||||
# ifdef PROC_INTEL
|
||||
|
||||
// This is 'stolen' from someone (I don't remember who anymore). It
|
||||
// is a nice and fast way to convert a floating point number to int
|
||||
// (only works on a i386 type processor).
|
||||
// It is equivalent to 'i=(int)(f+.5)'.
|
||||
#define FIST_MAGIC ((float)((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)))
|
||||
_inline long QuickRound (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC + inval;
|
||||
return ((*(long *)&dtemp) - 0x80000000);
|
||||
}
|
||||
|
||||
_inline long QuickInt (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC + (inval-.4999f);
|
||||
return ((*(long *)&dtemp) - 0x80000000);
|
||||
}
|
||||
|
||||
// This is my own invention derived from the previous one. This converts
|
||||
// a floating point number to a 16.16 fixed point integer. It is
|
||||
// equivalent to 'i=(int)(f*65536.)'.
|
||||
#define FIST_MAGIC2 ((float)((((65536.0 * 16)+(0.5))* 65536.0)))
|
||||
inline long QuickInt16 (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC2 + inval;
|
||||
return ((*(long *)&dtemp) - 0x80000000);
|
||||
}
|
||||
#endif //PROC_INTEL
|
||||
|
||||
#ifdef PROC_M68K
|
||||
|
||||
#define FIST_MAGIC ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))
|
||||
inline long QuickRound (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC + inval;
|
||||
return (*(((long *)&dtemp) + 1)) - 0x80000000;
|
||||
}
|
||||
|
||||
inline long QuickInt (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC + (inval-.4999);
|
||||
return (*(((long *)&dtemp) + 1)) - 0x80000000;
|
||||
}
|
||||
|
||||
#define FIST_MAGIC2 ((((65536.0 * 16)+(0.5))* 65536.0))
|
||||
inline long QuickInt16 (float inval)
|
||||
{
|
||||
double dtemp = FIST_MAGIC2 + inval;
|
||||
return (*(((long *)&dtemp) + 1)) - 0x80000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PROC_INTEL) || defined(PROC_M68K)
|
||||
# define QRound(x) QuickRound(x)
|
||||
# define QInt(x) QuickInt(x)
|
||||
# define QInt16(x) QuickInt16(x)
|
||||
#else
|
||||
# define QRound(x) ((int)((x)+.5))
|
||||
# define QInt(x) ((int)(x))
|
||||
# define QInt16(x) ((int)((x)*65536.))
|
||||
#endif
|
||||
|
||||
// @@@ I don't know if there is a better way to convert
|
||||
// a floating point to 8:24 fixed point (one with constants
|
||||
// like the tricks above instead of the multiplication).
|
||||
#define QInt24(x) (QInt16(((x)*256.0f)))
|
||||
|
||||
#if STATS
|
||||
#define STAT(x) x
|
||||
#else
|
||||
#define STAT(x)
|
||||
#endif
|
||||
|
||||
|
||||
//#define SMALL_Z .01
|
||||
#define SMALL_Z 0.1f
|
||||
|
||||
#define USE_OCCLUSION 0 // Experimental feature, will not work in this version.
|
||||
|
||||
// Some useful macros: these should be true at least for 32-bit processors
|
||||
#define LONGFROM2SHORT(s1,s2) (((short)s1) << 16 | (((short)s2) & 0xffff))
|
||||
#define SHORT1FROMLONG(l) (short)(((long)l) >> 16)
|
||||
#define SHORT2FROMLONG(l) (short)(((long)l) & 0xffff)
|
||||
|
||||
#endif /*DEF_H*/
|
||||
116
RenderDll/Common/EvalFuncs.h
Normal file
116
RenderDll/Common/EvalFuncs.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*=============================================================================
|
||||
EvalFuncs.h : Funcs for evaluating shader parms.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef __EVALFUNCS_H__
|
||||
#define __EVALFUNCS_H__
|
||||
|
||||
const int HALF_RAND = (RAND_MAX / 2);
|
||||
_inline float RandomNum()
|
||||
{
|
||||
int rn;
|
||||
rn = rand();
|
||||
return ((float)(rn - HALF_RAND) / (float)HALF_RAND);
|
||||
}
|
||||
_inline float UnsRandomNum()
|
||||
{
|
||||
int rn;
|
||||
rn = rand();
|
||||
return ((float)rn / (float)RAND_MAX);
|
||||
}
|
||||
|
||||
#define SHINE_TABLE_SIZE 16384
|
||||
|
||||
|
||||
struct SEvalFuncs
|
||||
{
|
||||
static float EvalWaveForm(SWaveForm *wf);
|
||||
static float EvalWaveForm(SWaveForm2 *wf);
|
||||
static float EvalWaveForm2(SWaveForm *wf, float frac);
|
||||
|
||||
virtual void ETC_ShadowMap(int ns)=0;
|
||||
virtual void ETC_Environment(int ns)=0;
|
||||
virtual void ETC_Projection(int ns, float *Mat, float wdt, float hgt)=0;
|
||||
virtual void ETC_SphereMap(int ns)=0;
|
||||
virtual void ETC_SphereMapEnvironment(int ns)=0;
|
||||
|
||||
virtual void EALPHA_Object()=0;
|
||||
virtual void EALPHA_OneMinusObject()=0;
|
||||
virtual void EALPHA_Wave(SWaveForm *wf, UCol& color)=0;
|
||||
virtual void EALPHA_Noise(SAlphaGenNoise *wf, UCol& color)=0;
|
||||
virtual void EALPHA_Beam()=0;
|
||||
|
||||
virtual void ERGB_Object()=0;
|
||||
virtual void ERGB_OneMinusObject()=0;
|
||||
virtual void ERGB_Wave(SWaveForm *wf, UCol& col)=0;
|
||||
virtual void ERGB_Noise(SRGBGenNoise *wf, UCol& col)=0;
|
||||
|
||||
virtual void EMOD_Deform(void)=0;
|
||||
virtual void WaveDeform(SDeform *df)=0;
|
||||
virtual void VerticalWaveDeform(SDeform *df)=0;
|
||||
virtual void BulgeDeform(SDeform *df)=0;
|
||||
virtual void SqueezeDeform(SDeform *df)=0;
|
||||
virtual void FromCenterDeform(SDeform *df)=0;
|
||||
virtual void FlareDeform(SDeform *df)=0;
|
||||
virtual void BeamDeform(SDeform *df)=0;
|
||||
};
|
||||
|
||||
// Shader evaluating functions for mergable geometry
|
||||
// Software shader pipeline
|
||||
struct SEvalFuncs_C : public SEvalFuncs
|
||||
{
|
||||
virtual void ETC_ShadowMap(int ns);
|
||||
virtual void ETC_Environment(int ns);
|
||||
virtual void ETC_Projection(int ns, float *Mat, float wdt, float hgt);
|
||||
virtual void ETC_SphereMap(int ns);
|
||||
virtual void ETC_SphereMapEnvironment(int ns);
|
||||
|
||||
virtual void EALPHA_Object();
|
||||
virtual void EALPHA_OneMinusObject();
|
||||
virtual void EALPHA_Wave(SWaveForm *wf, UCol& color);
|
||||
virtual void EALPHA_Noise(SAlphaGenNoise *wf, UCol& color);
|
||||
virtual void EALPHA_Beam() {};
|
||||
|
||||
virtual void ERGB_Object();
|
||||
virtual void ERGB_OneMinusObject();
|
||||
virtual void ERGB_Wave(SWaveForm *wf, UCol& col);
|
||||
virtual void ERGB_Noise(SRGBGenNoise *wf, UCol& col);
|
||||
|
||||
virtual void EMOD_Deform(void);
|
||||
virtual void WaveDeform(SDeform *df);
|
||||
virtual void VerticalWaveDeform(SDeform *df);
|
||||
virtual void BulgeDeform(SDeform *df);
|
||||
virtual void SqueezeDeform(SDeform *df);
|
||||
virtual void FromCenterDeform(SDeform *df);
|
||||
virtual void FlareDeform(SDeform *df);
|
||||
virtual void BeamDeform(SDeform *df);
|
||||
};
|
||||
|
||||
// Shader evaluating functions for render elements
|
||||
struct SEvalFuncs_RE : public SEvalFuncs_C
|
||||
{
|
||||
virtual void ETC_ShadowMap(int ns);
|
||||
virtual void ETC_Environment(int ns);
|
||||
virtual void ETC_Projection(int ns, float *Mat, float wdt, float hgt);
|
||||
virtual void ETC_SphereMap(int ns);
|
||||
virtual void ETC_SphereMapEnvironment(int ns);
|
||||
|
||||
virtual void EALPHA_Beam();
|
||||
|
||||
virtual void BeamDeform(SDeform *df);
|
||||
virtual void WaveDeform(SDeform *df);
|
||||
virtual void FlareDeform(SDeform *df);
|
||||
virtual void VerticalWaveDeform(SDeform *df);
|
||||
virtual void BulgeDeform(SDeform *df);
|
||||
virtual void SqueezeDeform(SDeform *df);
|
||||
};
|
||||
|
||||
|
||||
//===================================================================================
|
||||
|
||||
#endif // __EVALFUNCS_H__
|
||||
748
RenderDll/Common/EvalFuncs_C.cpp
Normal file
748
RenderDll/Common/EvalFuncs_C.cpp
Normal file
@@ -0,0 +1,748 @@
|
||||
/*=============================================================================
|
||||
EvalFuncs_C : implementation of evaluator functions (Render Buffer data changing).
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#define EVALFUNCS_C_CPP
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "shadow_renderer.h"
|
||||
#include <IEntityRenderState.h>
|
||||
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Wave evaluator
|
||||
|
||||
float SEvalFuncs::EvalWaveForm(SWaveForm *wf)
|
||||
{
|
||||
int val;
|
||||
|
||||
float Amp;
|
||||
float Freq;
|
||||
float Phase;
|
||||
float Level;
|
||||
|
||||
if (wf->m_Flags & WFF_LERP)
|
||||
{
|
||||
val = (int)(gRenDev->m_RP.m_RealTime * 597.0f);
|
||||
val &= 0x3ff;
|
||||
float fLerp = gRenDev->m_RP.m_tSinTable[val] * 0.5f + 0.5f;
|
||||
|
||||
if (wf->m_Amp != wf->m_Amp1)
|
||||
Amp = LERP(wf->m_Amp, wf->m_Amp1, fLerp);
|
||||
else
|
||||
Amp = wf->m_Amp;
|
||||
|
||||
if (wf->m_Freq != wf->m_Freq1)
|
||||
Freq = LERP(wf->m_Freq, wf->m_Freq1, fLerp);
|
||||
else
|
||||
Freq = wf->m_Freq;
|
||||
|
||||
if (wf->m_Phase != wf->m_Phase1)
|
||||
Phase = LERP(wf->m_Phase, wf->m_Phase1, fLerp);
|
||||
else
|
||||
Phase = wf->m_Phase;
|
||||
|
||||
if (wf->m_Level != wf->m_Level1)
|
||||
Level = LERP(wf->m_Level, wf->m_Level1, fLerp);
|
||||
else
|
||||
Level = wf->m_Level;
|
||||
}
|
||||
else
|
||||
{
|
||||
Level = wf->m_Level;
|
||||
Amp = wf->m_Amp;
|
||||
Phase = wf->m_Phase;
|
||||
Freq = wf->m_Freq;
|
||||
}
|
||||
|
||||
switch(wf->m_eWFType)
|
||||
{
|
||||
case eWF_None:
|
||||
Warning( 0,0,"WARNING: SEvalFuncs::EvalWaveForm called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
|
||||
case eWF_Sin:
|
||||
val = (int)((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
return Amp*gRenDev->m_RP.m_tSinTable[val&0x3ff]+Level;
|
||||
|
||||
case eWF_HalfSin:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
return Amp*gRenDev->m_RP.m_tHalfSinTable[val&0x3ff]+Level;
|
||||
|
||||
case eWF_InvHalfSin:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
return Amp*(1.0f-gRenDev->m_RP.m_tHalfSinTable[val&0x3ff])+Level;
|
||||
|
||||
case eWF_SawTooth:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*gRenDev->m_RP.m_tSawtoothTable[val]+Level;
|
||||
|
||||
case eWF_InvSawTooth:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*gRenDev->m_RP.m_tInvSawtoothTable[val]+Level;
|
||||
|
||||
case eWF_Square:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*gRenDev->m_RP.m_tSquareTable[val]+Level;
|
||||
|
||||
case eWF_Triangle:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*gRenDev->m_RP.m_tTriTable[val]+Level;
|
||||
|
||||
case eWF_Hill:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*gRenDev->m_RP.m_tHillTable[val]+Level;
|
||||
|
||||
case eWF_InvHill:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*Freq+Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return Amp*(1.0f-gRenDev->m_RP.m_tHillTable[val])+Level;
|
||||
|
||||
default:
|
||||
Warning( 0,0,"WARNING: SEvalFuncs::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
float SEvalFuncs::EvalWaveForm(SWaveForm2 *wf)
|
||||
{
|
||||
int val;
|
||||
|
||||
switch(wf->m_eWFType)
|
||||
{
|
||||
case eWF_None:
|
||||
Warning( 0,0,"WARNING: SEvalFuncs::EvalWaveForm called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
|
||||
case eWF_Sin:
|
||||
val = FtoI((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSinTable[val&0x3ff]+wf->m_Level;
|
||||
|
||||
case eWF_HalfSin:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tHalfSinTable[val&0x3ff]+wf->m_Level;
|
||||
|
||||
case eWF_InvHalfSin:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
return wf->m_Amp*(1.0f-gRenDev->m_RP.m_tHalfSinTable[val&0x3ff])+wf->m_Level;
|
||||
|
||||
case eWF_SawTooth:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvSawTooth:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tInvSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Square:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSquareTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Triangle:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tTriTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Hill:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tHillTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvHill:
|
||||
val = QRound((gRenDev->m_RP.m_RealTime*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*(1.0f-gRenDev->m_RP.m_tHillTable[val])+wf->m_Level;
|
||||
|
||||
default:
|
||||
Warning( 0,0,"WARNING: SEvalFuncs::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
float SEvalFuncs::EvalWaveForm2(SWaveForm *wf, float frac)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (!(wf->m_Flags & WFF_CLAMP))
|
||||
switch(wf->m_eWFType)
|
||||
{
|
||||
case eWF_None:
|
||||
Warning( 0,0,"EvalWaveForm2 called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
|
||||
case eWF_Sin:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSinTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_SawTooth:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvSawTooth:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tInvSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Square:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSquareTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Triangle:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tTriTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Hill:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tHillTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvHill:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val &= 0x3ff;
|
||||
return wf->m_Amp*(1-gRenDev->m_RP.m_tHillTable[val])+wf->m_Level;
|
||||
|
||||
default:
|
||||
Warning( 0,0,"Warning: EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch(wf->m_eWFType)
|
||||
{
|
||||
case eWF_None:
|
||||
Warning( 0,0,"Warning: EvalWaveForm2 called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
|
||||
case eWF_Sin:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSinTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_SawTooth:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvSawTooth:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tInvSawtoothTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Square:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tSquareTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Triangle:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tTriTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_Hill:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*gRenDev->m_RP.m_tHillTable[val]+wf->m_Level;
|
||||
|
||||
case eWF_InvHill:
|
||||
val = QRound((frac*wf->m_Freq+wf->m_Phase)*1024.0f);
|
||||
val = min(val, 1023);
|
||||
return wf->m_Amp*(1.0f-gRenDev->m_RP.m_tHillTable[val])+wf->m_Level;
|
||||
|
||||
default:
|
||||
Warning( 0,0,"Warning: EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
//Calc Lights and generate per-vertex colors
|
||||
|
||||
|
||||
void SEvalFuncs_C::ERGB_Object()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gRenDev->m_RP.m_pCurObject)
|
||||
{
|
||||
uint col = gRenDev->m_RP.m_pCurObject->m_Color.GetTrue();
|
||||
col = COLCONV(col);
|
||||
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(ptr) = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ERGB_OneMinusObject()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gRenDev->m_RP.m_pCurObject)
|
||||
{
|
||||
uint col = !gRenDev->m_RP.m_pCurObject->m_Color.GetTrue();
|
||||
col = COLCONV(col);
|
||||
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(ptr) = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::EALPHA_Object()
|
||||
{
|
||||
int i;
|
||||
byte a;
|
||||
|
||||
if (gRenDev->m_RP.m_pCurObject)
|
||||
{
|
||||
a = (byte)(gRenDev->m_RP.m_pCurObject->m_Color[3] * 255.0f);
|
||||
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD + 3;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr[0] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::EALPHA_OneMinusObject()
|
||||
{
|
||||
int i;
|
||||
byte a;
|
||||
|
||||
if (gRenDev->m_RP.m_pCurObject)
|
||||
{
|
||||
a = 255 - (byte)(gRenDev->m_RP.m_pCurObject->m_Color[3] * 255.0f);
|
||||
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD + 3;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr[0] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ERGB_Wave(SWaveForm *wf, UCol& col)
|
||||
{
|
||||
int i;
|
||||
float val = EvalWaveForm(wf);
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
if (val > 1)
|
||||
val = 1;
|
||||
|
||||
int v = (int)(val * 255.0f);
|
||||
v = CLAMP(v, 0, 255);
|
||||
col.bcolor[0] = col.bcolor[1] = col.bcolor[2] = v;
|
||||
col.bcolor[3] = 255;
|
||||
COLCONV(col.dcolor);
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(ptr) = col.dcolor;
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::EALPHA_Wave(SWaveForm *wf, UCol& col)
|
||||
{
|
||||
int i;
|
||||
float val = EvalWaveForm(wf);
|
||||
|
||||
int v = (int)(val * 255.0f);
|
||||
v = CLAMP(v, 0, 255);
|
||||
col.bcolor[3] = v;
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD + 3;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*ptr = v;
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ERGB_Noise(SRGBGenNoise *wf, UCol& col)
|
||||
{
|
||||
int i;
|
||||
|
||||
float v = RandomNum();
|
||||
byte r = (byte)(CLAMP(v * wf->m_RangeR + wf->m_ConstR, 0.0f, 1.0f) * 255.0f);
|
||||
v = RandomNum();
|
||||
byte g = (byte)(CLAMP(v * wf->m_RangeG + wf->m_ConstG, 0.0f, 1.0f) * 255.0f);
|
||||
v = RandomNum();
|
||||
byte b = (byte)(CLAMP(v * wf->m_RangeB + wf->m_ConstB, 0.0f, 1.0f) * 255.0f);
|
||||
|
||||
col.bcolor[0] = r;
|
||||
col.bcolor[1] = g;
|
||||
col.bcolor[2] = b;
|
||||
COLCONV(col.dcolor);
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(ptr) = col.dcolor;
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::EALPHA_Noise(SAlphaGenNoise *wf, UCol& col)
|
||||
{
|
||||
int i;
|
||||
float v = RandomNum();
|
||||
byte a = (byte)(CLAMP(v * wf->m_RangeA + wf->m_ConstA, 0.0f, 1.0f) * 255.0f);
|
||||
|
||||
col.bcolor[3] = a;
|
||||
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsD + 3;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*ptr = a;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// RT Deformations
|
||||
|
||||
void SEvalFuncs_C::EMOD_Deform(void)
|
||||
{
|
||||
}
|
||||
|
||||
_inline void Deform(float val, Vec3d& vrt, byte *nrm)
|
||||
{
|
||||
float *vnrm = (float *)nrm;
|
||||
vrt[0] += val * vnrm[0];
|
||||
vrt[1] += val * vnrm[1];
|
||||
vrt[2] += val * vnrm[2];
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::WaveDeform(SDeform *df)
|
||||
{
|
||||
int i, val;
|
||||
float f;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_VERT;
|
||||
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_Ptr;
|
||||
byte *vnrm = ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
float *WaveTable;
|
||||
switch (df->m_DeformGen.m_eWFType)
|
||||
{
|
||||
case eWF_Sin:
|
||||
default:
|
||||
WaveTable = gRenDev->m_RP.m_tSinTable;
|
||||
break;
|
||||
case eWF_Triangle:
|
||||
WaveTable = gRenDev->m_RP.m_tTriTable;
|
||||
break;
|
||||
case eWF_Square:
|
||||
WaveTable = gRenDev->m_RP.m_tSquareTable;
|
||||
break;
|
||||
case eWF_SawTooth:
|
||||
WaveTable = gRenDev->m_RP.m_tSawtoothTable;
|
||||
break;
|
||||
case eWF_InvSawTooth:
|
||||
WaveTable = gRenDev->m_RP.m_tInvSawtoothTable;
|
||||
break;
|
||||
case eWF_Hill:
|
||||
WaveTable = gRenDev->m_RP.m_tHillTable;
|
||||
break;
|
||||
}
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, vnrm+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
f = ptr.VBPtr_0->x + ptr.VBPtr_0->y + ptr.VBPtr_0->z;
|
||||
f = f*df->m_ScaleVerts + gRenDev->m_RP.m_RealTime*df->m_DeformGen.m_Freq + df->m_DeformGen.m_Phase;
|
||||
f *= 1024.0;
|
||||
val = QRound(f);
|
||||
|
||||
f = df->m_DeformGen.m_Amp * CRenderer::CV_r_wavescale * WaveTable[val&0x3ff] + df->m_DeformGen.m_Level;
|
||||
|
||||
Deform(f, *ptr.VBPtr_0, vnrm);
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::VerticalWaveDeform(SDeform *df)
|
||||
{
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::FlareDeform(SDeform *df)
|
||||
{
|
||||
}
|
||||
void SEvalFuncs_C::BeamDeform(SDeform *df)
|
||||
{
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::SqueezeDeform(SDeform *df)
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_Ptr;
|
||||
byte *nrm = ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_VERT;
|
||||
|
||||
f = EvalWaveForm(&df->m_DeformGen);
|
||||
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, nrm+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
float *vnrm = (float *)nrm;
|
||||
ptr.VBPtr_0->x += f * vnrm[0];
|
||||
ptr.VBPtr_0->y += f * vnrm[1];
|
||||
ptr.VBPtr_0->z += f * vnrm[2];
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::BulgeDeform(SDeform *df)
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
int val;
|
||||
Vec3d v;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_VERT;
|
||||
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_Ptr;
|
||||
byte *nrm = ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, nrm+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
f = gRenDev->m_RP.m_pBaseTexCoordPointer[i].vert[0] + gRenDev->m_RP.m_pBaseTexCoordPointer[i].vert[1] + ptr.VBPtr_0->x + ptr.VBPtr_0->y + ptr.VBPtr_0->z;
|
||||
f = f * df->m_ScaleVerts + df->m_DeformGen.m_Phase + gRenDev->m_RP.m_RealTime*df->m_DeformGen.m_Freq;
|
||||
f *= 1024;
|
||||
val = QRound(f);
|
||||
val &= 0x3ff;
|
||||
|
||||
f = df->m_DeformGen.m_Amp * CRenderer::CV_r_wavescale * gRenDev->m_RP.m_tSinTable[val] + df->m_DeformGen.m_Level;
|
||||
float *vnrm = (float *)nrm;
|
||||
v[0] = f * vnrm[0];
|
||||
v[1] = f * vnrm[1];
|
||||
v[2] = f * vnrm[2];
|
||||
|
||||
*ptr.VBPtr_0 += v;
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::FromCenterDeform(SDeform *df)
|
||||
{
|
||||
if (!gRenDev->m_RP.m_pCurObject)
|
||||
return;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_VERT;
|
||||
|
||||
int i;
|
||||
float f;
|
||||
Vec3d v;
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_Ptr;
|
||||
Vec3d cent;
|
||||
|
||||
cent = gRenDev->m_RP.m_Center;
|
||||
|
||||
f = EvalWaveForm2(&df->m_DeformGen, gRenDev->m_RP.m_RealTime-gRenDev->m_RP.m_pCurObject->m_StartTime);
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
v = *ptr.VBPtr_0 - cent;
|
||||
v.Normalize();
|
||||
v *= f;
|
||||
*ptr.VBPtr_0 += v;
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
// Texture coords generate
|
||||
|
||||
void SEvalFuncs_C::ETC_Environment(int ns)
|
||||
{
|
||||
int i;
|
||||
float f, d;
|
||||
Vec3d v;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_TC;
|
||||
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_Ptr;
|
||||
byte *nrm = ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
byte *tptr = gRenDev->m_RP.m_Ptr.PtrB + gRenDev->m_RP.m_OffsT + ns*16;
|
||||
for (i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, tptr+=gRenDev->m_RP.m_Stride, nrm+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
Vec3d *vnrm = (Vec3d *)nrm;
|
||||
v = gRenDev->m_RP.m_ViewOrg - *ptr.VBPtr_0;
|
||||
v.Normalize();
|
||||
d = v | (*vnrm);
|
||||
f = d * vnrm->y;
|
||||
f += f;
|
||||
*(float *)(tptr) = ((f - v[1]) + 1.0f) * 0.5f;
|
||||
|
||||
f = d * vnrm->z;
|
||||
f += f;
|
||||
*(float *)(tptr+4) = 0.5f - ((f - v[2]) * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ETC_Projection(int ns, float *Mat, float wdt, float hgt)
|
||||
{
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ETC_SphereMap(int ns)
|
||||
{
|
||||
int i;
|
||||
CCObject *obj = gRenDev->m_RP.m_pCurObject;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_TC;
|
||||
|
||||
float r00 = gRenDev->m_ViewMatrix(0,0), r01 = gRenDev->m_ViewMatrix(0,1), r02 = gRenDev->m_ViewMatrix(0,2);
|
||||
float r10 = gRenDev->m_ViewMatrix(1,0), r11 = gRenDev->m_ViewMatrix(1,1), r12 = gRenDev->m_ViewMatrix(1,2);
|
||||
float r20 = gRenDev->m_ViewMatrix(2,0), r21 = gRenDev->m_ViewMatrix(2,1), r22 = gRenDev->m_ViewMatrix(2,2);
|
||||
|
||||
// Loop through the vertices, transforming each one and calculating
|
||||
// the correct texture coordinates.
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB+gRenDev->m_RP.m_OffsT+ns*16;
|
||||
byte *nrm = gRenDev->m_RP.m_Ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
for( i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride, nrm+=gRenDev->m_RP.m_Stride )
|
||||
{
|
||||
Vec3d *vnrm = (Vec3d *)nrm;
|
||||
float nx = vnrm->x;
|
||||
float ny = vnrm->y;
|
||||
float nz = vnrm->z;
|
||||
|
||||
// Check the z-component, to skip any vertices that face backwards
|
||||
//if( nx*m13 + ny*m23 + nz*m33 > 0.0f )
|
||||
// continue;
|
||||
|
||||
// Assign the spheremap's texture coordinates
|
||||
*(float *)(ptr) = 0.5f * ( 1.0f + ( nx*r00 + ny*r10 + nz*r20 ) );
|
||||
*(float *)(ptr+4) = 0.5f * ( 1.0f - ( nx*r01 + ny*r11 + nz*r21 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void SEvalFuncs_C::ETC_SphereMapEnvironment(int ns)
|
||||
{
|
||||
int i;
|
||||
CCObject *obj = gRenDev->m_RP.m_pCurObject;
|
||||
|
||||
gRenDev->m_RP.m_Flags |= RBF_MODIF_TC;
|
||||
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
float r00 = obj->m_Matrix(0,0), r01 = obj->m_Matrix(0,1), r02 = obj->m_Matrix(0,2);
|
||||
float r10 = obj->m_Matrix(1,0), r11 = obj->m_Matrix(1,1), r12 = obj->m_Matrix(1,2);
|
||||
float r20 = obj->m_Matrix(2,0), r21 = obj->m_Matrix(2,1), r22 = obj->m_Matrix(2,2);
|
||||
|
||||
// Loop through the vertices, transforming each one and calculating
|
||||
// the correct texture coordinates.
|
||||
byte *ptr = gRenDev->m_RP.m_Ptr.PtrB+gRenDev->m_RP.m_OffsT+ns*16;
|
||||
byte *nrm = gRenDev->m_RP.m_Ptr.PtrB+gRenDev->m_RP.m_OffsN;
|
||||
for( i=0; i<gRenDev->m_RP.m_RendNumVerts; i++, ptr+=gRenDev->m_RP.m_Stride, nrm+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
Vec3d *vnrm = (Vec3d *)nrm;
|
||||
float nx = vnrm->x;
|
||||
float ny = vnrm->y;
|
||||
float nz = vnrm->z;
|
||||
|
||||
// Check the z-component, to skip any vertices that face backwards
|
||||
//if( nx*m13 + ny*m23 + nz*m33 > 0.0f )
|
||||
// continue;
|
||||
|
||||
// Assign the spheremap's texture coordinates
|
||||
*(float *)(ptr) = 0.5f * ( 1.0f + ( nx*r00 + ny*r10 + nz*r20 ) );
|
||||
*(float *)(ptr+4) = 0.5f * ( 1.0f + ( nx*r01 + ny*r11 + nz*r21 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================================================
|
||||
|
||||
void SEvalFuncs_C::ETC_ShadowMap(int ns)
|
||||
{
|
||||
CRenderer *rd = gRenDev;
|
||||
rd->m_RP.m_RECustomTexBind[ns] = -1;
|
||||
|
||||
assert(rd->m_RP.m_FlagsPerFlush & RBSI_SHADOWPASS);
|
||||
int nsFrust;
|
||||
if (rd->m_RP.m_pShader->m_eSort == eS_TerrainShadowPass)
|
||||
nsFrust = 0;
|
||||
else
|
||||
nsFrust = ns + rd->m_RP.m_nCurStartCaster;
|
||||
|
||||
list2<ShadowMapLightSourceInstance> * lsources = (list2<ShadowMapLightSourceInstance>*)rd->m_RP.m_pCurObject->m_pShadowCasters;
|
||||
|
||||
// bool bActiveShadowReceiving = false;
|
||||
|
||||
// skip this stage if this entity was used to create this shadow map
|
||||
if(!lsources || nsFrust>=lsources->Count())
|
||||
{
|
||||
if(!lsources)
|
||||
Warning( 0,0,"Warning: SEvalFuncs_RE::ETC_ShadowMap: !lsources");
|
||||
else
|
||||
if(nsFrust<lsources->Count())
|
||||
Warning( 0,0,"Warning: SEvalFuncs_RE::ETC_ShadowMap: nsFrust<lsources->Count()");
|
||||
|
||||
if ((rd->GetFeatures() & RFT_SHADOWMAP_SELFSHADOW) && !(rd->GetFeatures() & RFT_DEPTHMAPS))
|
||||
rd->m_RP.m_RECustomTexBind[ns] = rd->m_TexMan->m_Text_Depth->m_Bind;
|
||||
else
|
||||
rd->m_RP.m_RECustomTexBind[ns] = rd->m_TexMan->m_Text_WhiteShadow->m_Bind;
|
||||
|
||||
if ((rd->GetFeatures() & RFT_SHADOWMAP_SELFSHADOW) && !(rd->GetFeatures() & RFT_DEPTHMAPS))
|
||||
{
|
||||
Matrix44 *mt = &rd->m_cEF.m_TempMatrices[ns][7];
|
||||
mt->SetIdentity();
|
||||
}
|
||||
|
||||
rd->SelectTMU(0);
|
||||
return; // cancel this stage
|
||||
}
|
||||
|
||||
if(!(*lsources)[nsFrust].m_pLS)
|
||||
return;
|
||||
|
||||
// get projection frustum
|
||||
ShadowMapFrustum * pShadowMapFrustum = (*lsources)[nsFrust].m_pLS->GetShadowMapFrustum(0);
|
||||
// if(bActiveShadowReceiving)
|
||||
// pShadowMapFrustum = (*lsources)[nsFrust].m_pLS->GetShadowMapFrustumPassiveCasters(0);
|
||||
if(!pShadowMapFrustum)
|
||||
return;
|
||||
|
||||
// detect usage of same lsource second time -> use penumbra frustum
|
||||
if( nsFrust>0 && (*lsources)[nsFrust].m_pLS == (*lsources)[nsFrust-1].m_pLS && pShadowMapFrustum->pPenumbra)
|
||||
pShadowMapFrustum = pShadowMapFrustum->pPenumbra;
|
||||
|
||||
Matrix44 *m = NULL;
|
||||
Vec3d vObjTrans;
|
||||
if (rd->m_RP.m_ObjFlags & FOB_TRANS_MASK)
|
||||
{
|
||||
m = &gRenDev->m_RP.m_pCurObject->m_Matrix;
|
||||
vObjTrans = rd->m_RP.m_pCurObject->GetTranslation();
|
||||
}
|
||||
else
|
||||
vObjTrans = Vec3(0,0,0);
|
||||
|
||||
// setup projection
|
||||
gRenDev->SetupShadowOnlyPass(ns,
|
||||
pShadowMapFrustum,
|
||||
&((*lsources)[nsFrust].m_vProjTranslation),
|
||||
(*lsources)[nsFrust].m_fProjScale,
|
||||
vObjTrans,
|
||||
1.f,
|
||||
Vec3d(0,0,0),
|
||||
m);
|
||||
}
|
||||
1018
RenderDll/Common/EvalFuncs_RE.cpp
Normal file
1018
RenderDll/Common/EvalFuncs_RE.cpp
Normal file
File diff suppressed because it is too large
Load Diff
68
RenderDll/Common/FrameProfilers-list.h
Normal file
68
RenderDll/Common/FrameProfilers-list.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
// This is an inline file: it is meant to be included in multiple places
|
||||
// to generate code out of the PROFILER macro.
|
||||
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
|
||||
// This is the list of per-frame profilers used in the renderer system
|
||||
|
||||
// per-frame profilers: collect the infromation for each frame for
|
||||
// displaying statistics at the beginning of each frame
|
||||
PROFILER(Screen_Begin, "0Screen:Begin"); //
|
||||
PROFILER(Screen_Update, "0Screen:Update"); //
|
||||
PROFILER(State_Sorting, "0State:Sorting of RI"); //
|
||||
PROFILER(State_SortingDist, "0State:Dist Sorting of RI"); //
|
||||
PROFILER(State_LightStates, "0State:VLights"); //
|
||||
PROFILER(State_RStates, "0State:RenderStates"); //
|
||||
PROFILER(Draw_ObjSprites, "0Draw:ObjSprites"); //
|
||||
PROFILER(Objects_Changes, "0O.Objects:Change"); //
|
||||
PROFILER(Objects_ChangesSkinning, "1O.Objects:Skinning"); //
|
||||
PROFILER(Objects_ObjInvTransform, "1O.Objects:InvTransform"); //
|
||||
PROFILER(Texture_Changes, "0T0.Textures:Set"); //
|
||||
PROFILER(Texture_ChangesUpload, "1T0.Textures:Stream (Immediat)"); //
|
||||
PROFILER(Texture_Precache, "0Textures:PreloadPredict"); //
|
||||
PROFILER(Texture_LoadFromCache, "0T1.Textures:LoadFromCache"); //
|
||||
PROFILER(Texture_LoadFromCacheSync, "1T1.Textures:LoadFromCacheSync"); //
|
||||
PROFILER(Texture_LoadFromCacheASync, "1T1.Textures:LoadFromCacheASync"); //
|
||||
PROFILER(Texture_LoadFromCache_UploadSync, "1T1.Textures:UploadSync"); //
|
||||
PROFILER(Texture_AsyncUpload, "0Textures:AsyncUpload"); //
|
||||
PROFILER(Shader_PShaders, "0PS.Shader:PShaders"); //
|
||||
PROFILER(Shader_PShaderActivate, "1PS.Shader:PShaderActivate"); //
|
||||
PROFILER(Shader_PShadersParms, "1PS.Shader:PShaderParms"); //
|
||||
PROFILER(Shader_VShaders, "0VS.Shader:VShaders"); //
|
||||
PROFILER(Shader_VShaderActivate, "1VS.Shader:VShaderActivate"); //
|
||||
PROFILER(Shader_VShadersParms, "1VS.Shader:VShaderParms"); //
|
||||
PROFILER(Shader_VShadersMatr, "1VS.Shader:VShaderMatrices"); //
|
||||
PROFILER(Mesh_CheckUpdate, "0CU.Mesh:CheckUpdate"); //
|
||||
PROFILER(Mesh_CheckUpdateCreateGBuf, "1CU.Mesh:CreateGeneralBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateUpdateGBuf, "1CU.Mesh:UpdateGeneralBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateCreateSysTang, "1CU.Mesh:CreateSystemTangBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateCreateTBuf, "1CU.Mesh:CreateTangentBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateUpdateTBuf, "1CU.Mesh:UpdateTangentBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateCreateLMBuf, "1CU.Mesh:CreateLMBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateUpdateLMBuf, "1CU.Mesh:UpdateLMBuf"); //
|
||||
PROFILER(Mesh_CheckUpdateUpdateInds, "1CU.Mesh:UpdateInds"); //
|
||||
PROFILER(Mesh_CheckUpdateCallback, "1CU.Mesh:Callback"); //
|
||||
PROFILER(Mesh_CheckUpdateRecreateSystem, "1CU.Mesh:CreateSystemBuffer"); //
|
||||
PROFILER(Mesh_CheckUpdateSkinning, "1CU.Anim:Skinning"); //
|
||||
PROFILER(Mesh_CreateVBuffers, "0Mesh:CreateVBuffer"); //
|
||||
PROFILER(Mesh_CreateIBuffers, "0Mesh:CreateIBuffer"); //
|
||||
PROFILER(Mesh_UpdateVBuffers, "0V.Mesh:UpdateVBuffer"); //
|
||||
PROFILER(Mesh_UpdateVBuffersLock, "1V.Mesh:UpdateVBufferLock"); //
|
||||
PROFILER(Mesh_UpdateVBuffersCopy, "1V.Mesh:UpdateVBufferCopy"); //
|
||||
PROFILER(Mesh_UpdateVBuffersDynMerge, "1V.Mesh:UpdateVBufferDynMerge"); //
|
||||
PROFILER(Mesh_UpdateIBuffers, "0I.Mesh:UpdateIBuffer"); //
|
||||
PROFILER(Mesh_UpdateIBuffersLock, "1I.Mesh:UpdateIBufferLock"); //
|
||||
PROFILER(Mesh_UpdateIBuffersCopy, "1I.Mesh:UpdateIBufferCopy"); //
|
||||
PROFILER(Mesh_UpdateIBuffersDynMerge, "1I.Mesh:UpdateIBufferDynMerge"); //
|
||||
PROFILER(Mesh_REPrepare, "0PRRE.Mesh:Preparing of RE"); //
|
||||
PROFILER(Mesh_REPrepare_FlushOcleaf, "1PRRE.Mesh:Flush REOcleaf"); //
|
||||
PROFILER(Mesh_REPrepare_Ocleaf, "1PRRE.Mesh:Prepare REOcleaf"); //
|
||||
PROFILER(Mesh_REPrepare_Flush3DPoly, "1PRRE.Mesh:Flush 3DPoly"); //
|
||||
PROFILER(Mesh_REPrepare_3DPoly, "1PRRE.Mesh:Prepare 3DPoly"); //
|
||||
PROFILER(Draw_Predraw, "0Draw:Predraw"); //
|
||||
PROFILER(Draw_IndexMesh, "0Draw:IndexedMesh"); //
|
||||
PROFILER(Draw_EFIndexMesh, "0Draw:ShaderIndexedMesh"); //
|
||||
PROFILER(Draw_2DImage, "0Draw:2DImage"); //
|
||||
PROFILER(Prep_PrepareDepthMap, "0Prep:PrepareDepthMap");
|
||||
|
||||
|
||||
272
RenderDll/Common/LZSS.H
Normal file
272
RenderDll/Common/LZSS.H
Normal file
@@ -0,0 +1,272 @@
|
||||
#define EXIT_SUCCESS 0
|
||||
//#define EXIT_FAILURE 1
|
||||
/**************************************************************
|
||||
LZSS.C -- A Data Compression Program
|
||||
(tab = 4 spaces)
|
||||
***************************************************************
|
||||
4/6/1989 Haruhiko Okumura
|
||||
Use, distribute, and modify this program freely.
|
||||
Please send me your improved versions.
|
||||
PC-VAN SCIENCE
|
||||
NIFTY-Serve PAF01022
|
||||
CompuServe 74050,1022
|
||||
**************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define N 4096 /* size of ring buffer */
|
||||
#define F 18 /* upper limit for match_length */
|
||||
#define THRESHOLD 2 /* encode string into position and length
|
||||
if match_length is greater than this */
|
||||
#define NIL N /* index for root of binary search trees */
|
||||
|
||||
unsigned long int
|
||||
textsize = 0, /* text size counter */
|
||||
codesize = 0, /* code size counter */
|
||||
printcount = 0; /* counter for reporting progress every 1K bytes */
|
||||
unsigned char
|
||||
text_buf[N + F - 1]; /* ring buffer of size N,
|
||||
with extra F-1 bytes to facilitate string comparison */
|
||||
int match_position, match_length, /* of longest match. These are
|
||||
set by the InsertNode() procedure. */
|
||||
lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children &
|
||||
parents -- These constitute binary search trees. */
|
||||
FILE *infile, *outfile; /* input & output files */
|
||||
|
||||
void InitTree(void) /* initialize trees */
|
||||
{
|
||||
int i;
|
||||
|
||||
/* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
|
||||
left children of node i. These nodes need not be initialized.
|
||||
Also, dad[i] is the parent of node i. These are initialized to
|
||||
NIL (= N), which stands for 'not used.'
|
||||
For i = 0 to 255, rson[N + i + 1] is the root of the tree
|
||||
for strings that begin with character i. These are initialized
|
||||
to NIL. Note there are 256 trees. */
|
||||
|
||||
for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
|
||||
for (i = 0; i < N; i++) dad[i] = NIL;
|
||||
}
|
||||
|
||||
void InsertNode(int r)
|
||||
/* Inserts string of length F, text_buf[r..r+F-1], into one of the
|
||||
trees (text_buf[r]'th tree) and returns the longest-match position
|
||||
and length via the global variables match_position and match_length.
|
||||
If match_length = F, then removes the old node in favor of the new
|
||||
one, because the old one will be deleted sooner.
|
||||
Note r plays double role, as tree node and position in buffer. */
|
||||
{
|
||||
int i, p, cmp;
|
||||
unsigned char *key;
|
||||
|
||||
cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
|
||||
rson[r] = lson[r] = NIL; match_length = 0;
|
||||
for ( ; ; ) {
|
||||
if (cmp >= 0) {
|
||||
if (rson[p] != NIL) p = rson[p];
|
||||
else { rson[p] = r; dad[r] = p; return; }
|
||||
} else {
|
||||
if (lson[p] != NIL) p = lson[p];
|
||||
else { lson[p] = r; dad[r] = p; return; }
|
||||
}
|
||||
for (i = 1; i < F; i++)
|
||||
if ((cmp = key[i] - text_buf[p + i]) != 0) break;
|
||||
if (i > match_length) {
|
||||
match_position = p;
|
||||
if ((match_length = i) >= F) break;
|
||||
}
|
||||
}
|
||||
dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
|
||||
dad[lson[p]] = r; dad[rson[p]] = r;
|
||||
if (rson[dad[p]] == p) rson[dad[p]] = r;
|
||||
else lson[dad[p]] = r;
|
||||
dad[p] = NIL; /* remove p */
|
||||
}
|
||||
|
||||
void DeleteNode(int p) /* deletes node p from tree */
|
||||
{
|
||||
int q;
|
||||
|
||||
if (dad[p] == NIL) return; /* not in tree */
|
||||
if (rson[p] == NIL) q = lson[p];
|
||||
else if (lson[p] == NIL) q = rson[p];
|
||||
else {
|
||||
q = lson[p];
|
||||
if (rson[q] != NIL) {
|
||||
do { q = rson[q]; } while (rson[q] != NIL);
|
||||
rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
|
||||
lson[q] = lson[p]; dad[lson[p]] = q;
|
||||
}
|
||||
rson[q] = rson[p]; dad[rson[p]] = q;
|
||||
}
|
||||
dad[q] = dad[p];
|
||||
if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
|
||||
dad[p] = NIL;
|
||||
}
|
||||
|
||||
unsigned char *getcmP;
|
||||
unsigned char *putcmP;
|
||||
int Size,Count;
|
||||
_inline int getcm()
|
||||
{
|
||||
if (Count++>=Size) return EOF;
|
||||
return (int)*getcmP++;
|
||||
};
|
||||
|
||||
_inline void putcm(int c)
|
||||
{
|
||||
*putcmP++=(unsigned char)c;
|
||||
};
|
||||
|
||||
void Encode(void)
|
||||
{
|
||||
int i, c, len, r, s, last_match_length, code_buf_ptr;
|
||||
unsigned char code_buf[17], mask;
|
||||
codesize=0;
|
||||
InitTree(); /* initialize trees */
|
||||
code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and
|
||||
code_buf[0] works as eight flags, "1" representing that the unit
|
||||
is an unencoded letter (1 byte), "0" a position-and-length pair
|
||||
(2 bytes). Thus, eight units require at most 16 bytes of code. */
|
||||
code_buf_ptr = mask = 1;
|
||||
s = 0; r = N - F;
|
||||
for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with
|
||||
any character that will appear often. */
|
||||
for (len = 0; len < F && (c = getcm()) != EOF; len++)
|
||||
text_buf[r + len] = c; /* Read F bytes into the last F bytes of
|
||||
the buffer */
|
||||
if ((textsize = len) == 0) return; /* text of size zero */
|
||||
for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings,
|
||||
each of which begins with one or more 'space' characters. Note
|
||||
the order in which these strings are inserted. This way,
|
||||
degenerate trees will be less likely to occur. */
|
||||
InsertNode(r); /* Finally, insert the whole string just read. The
|
||||
global variables match_length and match_position are set. */
|
||||
do {
|
||||
if (match_length > len) match_length = len; /* match_length
|
||||
may be spuriously long near the end of text. */
|
||||
if (match_length <= THRESHOLD) {
|
||||
match_length = 1; /* Not long enough match. Send one byte. */
|
||||
code_buf[0] |= mask; /* 'send one byte' flag */
|
||||
code_buf[code_buf_ptr++] = text_buf[r]; /* Send uncoded. */
|
||||
} else {
|
||||
code_buf[code_buf_ptr++] = (unsigned char) match_position;
|
||||
code_buf[code_buf_ptr++] = (unsigned char)
|
||||
(((match_position >> 4) & 0xf0)
|
||||
| (match_length - (THRESHOLD + 1))); /* Send position and
|
||||
length pair. Note match_length > THRESHOLD. */
|
||||
}
|
||||
if ((mask <<= 1) == 0) { /* Shift mask left one bit. */
|
||||
for (i = 0; i < code_buf_ptr; i++) /* Send at most 8 units of */
|
||||
putcm(code_buf[i]); /* code together */
|
||||
codesize += code_buf_ptr;
|
||||
code_buf[0] = 0; code_buf_ptr = mask = 1;
|
||||
}
|
||||
last_match_length = match_length;
|
||||
for (i = 0; i < last_match_length &&
|
||||
(c = getcm()) != EOF; i++) {
|
||||
DeleteNode(s); /* Delete old strings and */
|
||||
text_buf[s] = c; /* read new bytes */
|
||||
if (s < F - 1) text_buf[s + N] = c; /* If the position is
|
||||
near the end of buffer, extend the buffer to make
|
||||
string comparison easier. */
|
||||
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
|
||||
/* Since this is a ring buffer, increment the position
|
||||
modulo N. */
|
||||
InsertNode(r); /* Register the string in text_buf[r..r+F-1] */
|
||||
}
|
||||
///
|
||||
textsize += i;
|
||||
|
||||
//if ((textsize += i) > printcount) {
|
||||
// printf("%12ld\r", textsize); printcount += 1024;
|
||||
// /* Reports progress each time the textsize exceeds
|
||||
// multiples of 1024. */
|
||||
//}
|
||||
|
||||
////////
|
||||
|
||||
while (i++ < last_match_length) { /* After the end of text, */
|
||||
DeleteNode(s); /* no need to read, but */
|
||||
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
|
||||
if (--len) InsertNode(r); /* buffer may not be empty. */
|
||||
}
|
||||
} while (len > 0); /* until length of string to be processed is zero */
|
||||
if (code_buf_ptr > 1) { /* Send remaining code. */
|
||||
for (i = 0; i < code_buf_ptr; i++) putcm(code_buf[i]);
|
||||
codesize += code_buf_ptr;
|
||||
}
|
||||
// printf("In : %ld bytes\n", textsize); /* Encoding is done. */
|
||||
// printf("Out: %ld bytes\n", codesize);
|
||||
// printf("Out/In: %.3f\n", (double)codesize / textsize);
|
||||
}
|
||||
|
||||
int Encodem(unsigned char *InBuf,unsigned char *OutBuf,int ASize)
|
||||
{
|
||||
getcmP=InBuf;
|
||||
putcmP=OutBuf;
|
||||
Size=ASize;
|
||||
Count=0;
|
||||
Encode();
|
||||
return codesize;
|
||||
}
|
||||
|
||||
void Decode(void) /* Just the reverse of Encode(). */
|
||||
{
|
||||
int i, j, k, r, c;
|
||||
unsigned int flags;
|
||||
|
||||
for (i = 0; i < N - F; i++) text_buf[i] = ' ';
|
||||
r = N - F; flags = 0;
|
||||
for ( ; ; ) {
|
||||
if (((flags >>= 1) & 256) == 0) {
|
||||
if ((c = getcm()) == EOF) break;
|
||||
flags = c | 0xff00; /* uses higher byte cleverly */
|
||||
} /* to count eight */
|
||||
if (flags & 1) {
|
||||
if ((c = getcm()) == EOF) break;
|
||||
putcm(c); text_buf[r++] = c; r &= (N - 1);
|
||||
} else {
|
||||
if ((i = getcm()) == EOF) break;
|
||||
if ((j = getcm()) == EOF) break;
|
||||
i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
|
||||
for (k = 0; k <= j; k++) {
|
||||
c = text_buf[(i + k) & (N - 1)];
|
||||
putcm(c); text_buf[r++] = c; r &= (N - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Decodem(unsigned char *InBuf,unsigned char *OutBuf,int ASize)
|
||||
{
|
||||
getcmP=InBuf;
|
||||
putcmP=OutBuf;
|
||||
Size=ASize;
|
||||
Count=0;
|
||||
Decode();
|
||||
}
|
||||
|
||||
/*
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("'lzss e file1 file2' encodes file1 into file2.\n"
|
||||
"'lzss d file2 file1' decodes file2 into file1.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ((s = argv[1], s[1] || strpbrk(s, "DEde") == NULL)
|
||||
|| (s = argv[2], (infile = fopen(s, "rb")) == NULL)
|
||||
|| (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) {
|
||||
printf("??? %s\n", s); return EXIT_FAILURE;
|
||||
}
|
||||
if (toupper(*argv[1]) == 'E') Encode(); else Decode();
|
||||
fclose(infile); fclose(outfile);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
*/
|
||||
2316
RenderDll/Common/LeafBufferCreate.cpp
Normal file
2316
RenderDll/Common/LeafBufferCreate.cpp
Normal file
File diff suppressed because it is too large
Load Diff
465
RenderDll/Common/LeafBufferRender.cpp
Normal file
465
RenderDll/Common/LeafBufferRender.cpp
Normal file
@@ -0,0 +1,465 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "i3dengine.h"
|
||||
#include "cryheaders.h"
|
||||
|
||||
void CLeafBuffer::AddRE(CCObject *obj, IShader *ef, int nNumSort, IShader * pStateEff)
|
||||
{
|
||||
if(!m_NumIndices || !m_pMats->Count())
|
||||
return;
|
||||
|
||||
int nGlobalShaderTemplateId = gRenDev->GetGlobalShaderTemplateId();
|
||||
|
||||
IShader *e;
|
||||
SRenderShaderResources *sr;
|
||||
|
||||
for(int i=0; i<(*m_pMats).Count(); i++)
|
||||
// if(!CRenderer::CV_r_draw_phys_only || ((*m_pMats)[i].m_Flags & MIF_PHYSIC))
|
||||
{
|
||||
if (!(*m_pMats)[i].pRE)
|
||||
continue;
|
||||
|
||||
if (!ef)
|
||||
e = (*m_pMats)[i].shaderItem.m_pShader;
|
||||
else
|
||||
e = ef;
|
||||
sr = (*m_pMats)[i].shaderItem.m_pShaderResources;
|
||||
if (e)
|
||||
{
|
||||
assert((*m_pMats)[i].pRE->m_pChunk->nFirstIndexId<60000);
|
||||
|
||||
if (e->GetREs()->Num())
|
||||
gRenDev->EF_AddEf_NotVirtual(0, e->GetREs()->Get(0), e, sr, obj, nGlobalShaderTemplateId, pStateEff, nNumSort);
|
||||
else
|
||||
gRenDev->EF_AddEf_NotVirtual(0, (*m_pMats)[i].pRE, e, sr, obj, nGlobalShaderTemplateId, pStateEff, nNumSort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLeafBuffer::UpdateCustomLighting(float fBackSideLevel, Vec3d vStatObjAmbientColor, const Vec3d & vLight, bool bCalcLighting)
|
||||
{
|
||||
bool bRGB = (gRenDev->GetFeatures() & RFT_RGBA) != 0;
|
||||
|
||||
vStatObjAmbientColor*=0.5f; // compensate overbrightness to make it work same as other objects
|
||||
|
||||
Vec3d vSunColor = iSystem->GetI3DEngine()->GetSunColor();
|
||||
|
||||
byte *pData = (byte *)m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
|
||||
int nPosStride = m_VertexSize[m_pSecVertBuffer->m_vertexformat];
|
||||
int nNormStride, nColorStride, nInfoStride;
|
||||
bool * arrCullInfo = new bool[m_SecVertCount];
|
||||
ushort *pInds = GetIndices(NULL);
|
||||
bool bWasBark = false;
|
||||
for(int i=0; i<(*m_pMats).Count(); i++)
|
||||
{
|
||||
if (!(*m_pMats)[i].pRE)
|
||||
continue;
|
||||
CMatInfo *mi = &(*m_pMats)[i];
|
||||
IShader *ef = mi->shaderItem.m_pShader->GetTemplate(-1);
|
||||
int nFl = ef->GetFlags3();
|
||||
bool bTwoSided;
|
||||
if (nFl & EF3_HASVCOLORS)
|
||||
bTwoSided = (nFl & EF3_HASALPHATEST) != 0;
|
||||
else
|
||||
bTwoSided = (mi->shaderItem.m_pShaderResources->m_ResFlags & MTLFLAG_2SIDED)!=0;//ef && (ef->GetCull() == e CULL_None);
|
||||
if (!bTwoSided)
|
||||
bWasBark = true;
|
||||
for (int j=mi->nFirstIndexId; j<mi->nNumIndices+mi->nFirstIndexId; j++)
|
||||
{
|
||||
int nIndex = pInds[j];
|
||||
assert(nIndex>=0 && nIndex<m_SecVertCount);
|
||||
arrCullInfo[nIndex] = bTwoSided;
|
||||
}
|
||||
}
|
||||
|
||||
if (bWasBark && CRenderer::CV_r_Vegetation_PerpixelLight && m_nVertexFormat != VERTEX_FORMAT_P3F_COL4UB_COL4UB_TEX2F)
|
||||
ReCreateSystemBuffer(VERTEX_FORMAT_P3F_COL4UB_COL4UB_TEX2F);
|
||||
|
||||
// get offsets
|
||||
byte *pPos = &pData[0];
|
||||
byte *pNorm = GetNormalPtr(nNormStride);
|
||||
uchar*pColor = GetColorPtr(nColorStride);
|
||||
nInfoStride = sizeof(uint);
|
||||
bool * pInfo = arrCullInfo;
|
||||
|
||||
int nTangStride, nBinormStride, nTNormStride, nSecColStride;
|
||||
byte *pTang = GetTangentPtr(nTangStride);
|
||||
byte *pBinorm = GetBinormalPtr(nBinormStride);
|
||||
byte *pTNorm = GetTNormalPtr(nTNormStride);
|
||||
byte *pSecCol = GetSecColorPtr(nSecColStride);
|
||||
|
||||
assert(pNorm && pPos && pColor);
|
||||
assert(m_pMats);
|
||||
|
||||
float fAlpha = 1.0f; // m_pMats->Get(0)->fAlpha;
|
||||
|
||||
for(int i=0; i<m_SecVertCount; i++)
|
||||
{
|
||||
Vec3 & pos = *((Vec3*)pPos);
|
||||
|
||||
Vec3 & normal = *((Vec3*)pNorm);
|
||||
|
||||
bool bPerPixel = false;
|
||||
if (!pInfo[0] && CRenderer::CV_r_Vegetation_PerpixelLight)
|
||||
bPerPixel = true;
|
||||
|
||||
Vec3 vBr(1.f,1.f,1.f);
|
||||
Vec3 vLightVec;
|
||||
float fDot = 0;
|
||||
if(bCalcLighting)
|
||||
{
|
||||
//IVO: normal is 0 in some cases!
|
||||
//this is no solution, we have to fix it in the exporter
|
||||
if (normal != Vec3(0.0f,0.0f,0.0f))
|
||||
fDot = GetNormalized(normal).Dot(GetNormalized(vLight));
|
||||
|
||||
if(fDot<0)
|
||||
{
|
||||
if(pInfo[0])
|
||||
fDot = -fDot; // double side lighting
|
||||
else
|
||||
fDot = 0;
|
||||
}
|
||||
|
||||
if (!bPerPixel)
|
||||
{
|
||||
vBr.x = pInfo[0] ? ( vStatObjAmbientColor.x*2 + fDot*vSunColor.x*0.5f ) : ( vStatObjAmbientColor.x + fDot*vSunColor.x );
|
||||
vBr.y = pInfo[0] ? ( vStatObjAmbientColor.y*2 + fDot*vSunColor.y*0.5f ) : ( vStatObjAmbientColor.y + fDot*vSunColor.y );
|
||||
vBr.z = pInfo[0] ? ( vStatObjAmbientColor.z*2 + fDot*vSunColor.z*0.5f ) : ( vStatObjAmbientColor.z + fDot*vSunColor.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
vBr = vStatObjAmbientColor;
|
||||
vLightVec.x = vLight.Dot(*(Vec3 *)pTang);
|
||||
vLightVec.y = vLight.Dot(*(Vec3 *)pBinorm);
|
||||
vLightVec.z = vLight.Dot(*(Vec3 *)pTNorm);
|
||||
vLightVec.Normalize();
|
||||
//vLightVec = *(Vec3 *)pTang;
|
||||
//vLightVec.Set(1,0,0);
|
||||
|
||||
if(bRGB)
|
||||
{
|
||||
pSecCol[0] = (uchar)((vLightVec.x+1.0f)*127.5f);
|
||||
pSecCol[1] = (uchar)((vLightVec.y+1.0f)*127.5f);
|
||||
pSecCol[2] = (uchar)((vLightVec.z+1.0f)*127.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSecCol[0] = (uchar)((vLightVec.z+1.0f)*127.5f);
|
||||
pSecCol[1] = (uchar)((vLightVec.y+1.0f)*127.5f);
|
||||
pSecCol[2] = (uchar)((vLightVec.x+1.0f)*127.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if(fBackSideLevel<1.f)
|
||||
{ // make back side darker
|
||||
float fDot2 = Vec3(-pos.x,-pos.y,0).GetNormalized().Dot(Vec3d(vLight.x,vLight.y,vLight.z))*2;
|
||||
if(fDot2<0)
|
||||
fDot2=0;
|
||||
|
||||
vBr.x -= fDot2*(1.f-fBackSideLevel);
|
||||
vBr.y -= fDot2*(1.f-fBackSideLevel);
|
||||
vBr.z -= fDot2*(1.f-fBackSideLevel);
|
||||
|
||||
vBr.CheckMax(vStatObjAmbientColor);
|
||||
}
|
||||
}
|
||||
|
||||
Vec3d vColor; // take into account original vertex color
|
||||
if(!CRenderer::CV_r_Vegetation_IgnoreVertColors && m_pLoadedColors)
|
||||
{
|
||||
vColor.x = m_pLoadedColors[i].x*vBr.x;
|
||||
vColor.y = m_pLoadedColors[i].y*vBr.y;
|
||||
vColor.z = m_pLoadedColors[i].z*vBr.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
vColor = vBr*255.f;
|
||||
}
|
||||
|
||||
vColor.CheckMin(Vec3d(255.f,255.f,255.f));
|
||||
|
||||
if(bRGB)
|
||||
{
|
||||
pColor[0] = uchar(vColor.x);
|
||||
pColor[1] = uchar(vColor.y);
|
||||
pColor[2] = uchar(vColor.z);
|
||||
pColor[3] = uchar(fDot*255.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
pColor[0] = uchar(vColor.z);
|
||||
pColor[1] = uchar(vColor.y);
|
||||
pColor[2] = uchar(vColor.x);
|
||||
pColor[3] = uchar(fDot*255.0f);
|
||||
}
|
||||
|
||||
pPos += nPosStride;
|
||||
pNorm += nNormStride;
|
||||
pColor += nColorStride;
|
||||
|
||||
pSecCol += nSecColStride;
|
||||
pTang += nTangStride;
|
||||
pBinorm += nBinormStride;
|
||||
pTNorm += nTNormStride;
|
||||
|
||||
pInfo ++;
|
||||
}
|
||||
|
||||
if(m_pVertexBuffer)
|
||||
gRenDev->ReleaseBuffer(m_pVertexBuffer);
|
||||
delete [] arrCullInfo;
|
||||
m_pVertexBuffer=0;
|
||||
}
|
||||
/*
|
||||
void CLeafBuffer::UpdateColorInBufer(const Vec3d & vColor)
|
||||
{
|
||||
byte *pData = (byte *)m_pSecVertBuffer->m_data;
|
||||
|
||||
int nColorStride;
|
||||
uchar*pColor = GetColorPtr(nColorStride);
|
||||
|
||||
for(int i=0; i<m_SecVertCount; i++)
|
||||
{
|
||||
pColor[0] = (uchar)(vColor[0]*255.0f);
|
||||
pColor[1] = (uchar)(vColor[1]*255.0f);
|
||||
pColor[2] = (uchar)(vColor[2]*255.0f);
|
||||
pColor[3] = 255;
|
||||
|
||||
pColor += nColorStride;
|
||||
}
|
||||
|
||||
if(m_pVertexBuffer)
|
||||
gRenDev->ReleaseBuffer(m_pVertexBuffer);
|
||||
m_pVertexBuffer=0;
|
||||
}
|
||||
*/
|
||||
|
||||
void CLeafBuffer::AddRenderElements(CCObject * pObj, int DLightMask, int nTemplate, int nFogVolumeID, int nSortId, IMatInfo * pIMatInfo)
|
||||
{
|
||||
if(!m_NumIndices || !m_pMats->Count())
|
||||
return;
|
||||
|
||||
assert(m_pMats);
|
||||
|
||||
if(nTemplate<0)
|
||||
{
|
||||
int nGlobalShaderTemplateId = gRenDev->GetGlobalShaderTemplateId();
|
||||
if(nGlobalShaderTemplateId>=0)
|
||||
nTemplate = nGlobalShaderTemplateId;
|
||||
}
|
||||
|
||||
for (int i=0; i<m_pMats->Count(); i++)
|
||||
{
|
||||
CMatInfo * pMat = m_pMats->Get(i);
|
||||
// if(!pMat->nNumIndices) // stops rendering detail grass
|
||||
// continue;
|
||||
|
||||
CREOcLeaf * pOrigRE = pMat->pRE;
|
||||
|
||||
// Override object material.
|
||||
if (pIMatInfo)
|
||||
{ // Assume that the root material is the first material, sub materials start from index 1.
|
||||
if (i == 0)
|
||||
pMat = (CMatInfo*)pIMatInfo;
|
||||
else if (i-1 < pIMatInfo->GetSubMtlCount())
|
||||
pMat = (CMatInfo*)pIMatInfo->GetSubMtl(i-1);
|
||||
}
|
||||
|
||||
IShader * e = pMat->shaderItem.m_pShader;
|
||||
SRenderShaderResources *sr = pMat->shaderItem.m_pShaderResources;
|
||||
|
||||
if (e && pOrigRE)// && pMat->nNumIndices)
|
||||
{
|
||||
TArray<CRendElement *> *pREs = e->GetREs();
|
||||
if(nTemplate < EFT_USER_FIRST)
|
||||
e->AddTemplate(sr, nTemplate);
|
||||
|
||||
assert(pOrigRE->m_pChunk->nFirstIndexId<60000);
|
||||
|
||||
if (pREs && pREs->Num())
|
||||
gRenDev->EF_AddEf_NotVirtual(nFogVolumeID, pREs->Get(0), e, sr, pObj, nTemplate, 0, nSortId);
|
||||
else
|
||||
gRenDev->EF_AddEf_NotVirtual(nFogVolumeID, pOrigRE, e, sr, pObj, nTemplate, 0, nSortId);
|
||||
|
||||
if(m_nClientTextureBindID)
|
||||
break;
|
||||
}
|
||||
} //i
|
||||
}
|
||||
/*
|
||||
void CLeafBuffer::GenerateParticles(CCObject * pObj, ParticleParams * pParticleParams)
|
||||
{
|
||||
I3DEngine * pEng = (I3DEngine *)iSystem->GetIProcess();
|
||||
|
||||
// spawn particles
|
||||
PipVertex * pDst = (PipVertex *)m_pSecVertBuffer->m_data;
|
||||
for(int sn=0; sn<m_SecVertCount; sn++, pDst++)
|
||||
{
|
||||
for(int r=0; r<33 || r<99.f*rand()/RAND_MAX; r++)
|
||||
sn++, pDst++;
|
||||
|
||||
if(sn<m_SecVertCount && pDst->nor.nz>0.5)
|
||||
{
|
||||
pParticleParams->vPosition.x = pDst->pos.x + pObj->m_Trans.x;
|
||||
pParticleParams->vPosition.y = pDst->pos.y + pObj->m_Trans.y;
|
||||
pParticleParams->vPosition.z = pDst->pos.z + pObj->m_Trans.z;
|
||||
pEng->SpawnParticles( *pParticleParams );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void CLeafBuffer::Render(const SRendParams & rParams, CCObject * pObj, TArray<int> & ShaderTemplates, int e_overlay_geometry, bool bNotCurArea, IMatInfo *pMaterial, bool bSupportDefaultShaderTemplates)
|
||||
{
|
||||
int nSortValue = (rParams.dwFObjFlags & FOB_NEAREST) ? eS_Nearest : rParams.nSortValue;
|
||||
|
||||
CCObject * pObjTransp = NULL;
|
||||
for (int i=0; i<m_pMats->Count(); i++)
|
||||
{
|
||||
CMatInfo * pMat = m_pMats->Get(i);
|
||||
CRendElement * pREOcLeaf = pMat->pRE;
|
||||
|
||||
// Override default material
|
||||
if (pMaterial)
|
||||
{
|
||||
int nMatId = pMat->m_nCGFMaterialID;
|
||||
if(nMatId<0)
|
||||
continue;
|
||||
|
||||
// Assume that the root material is the first material, sub materials start from index 1.
|
||||
if (nMatId == 0)
|
||||
pMat = (CMatInfo*)pMaterial;
|
||||
else if (nMatId-1 < pMaterial->GetSubMtlCount())
|
||||
{
|
||||
pMat = (CMatInfo*)pMaterial->GetSubMtl(nMatId-1);
|
||||
}
|
||||
}
|
||||
|
||||
SShader * pShader = (SShader *)pMat->shaderItem.m_pShader;
|
||||
SRenderShaderResources* sr = pMat->shaderItem.m_pShaderResources;
|
||||
|
||||
if (pREOcLeaf && pShader)
|
||||
{
|
||||
int nTempl = rParams.nShaderTemplate;
|
||||
if (bSupportDefaultShaderTemplates && nTempl == -2 && i<ShaderTemplates.Num())
|
||||
nTempl = ShaderTemplates[i];
|
||||
|
||||
if (rParams.nShaderTemplate>0)
|
||||
pShader->AddTemplate((SRenderShaderResources*)sr, (int&)rParams.nShaderTemplate,(const char *)NULL);
|
||||
|
||||
if(rParams.dwFObjFlags & FOB_FOGPASS)
|
||||
if(pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY)
|
||||
continue; // skip overlays during fog pass - it will be fogged by base geometry fog pass
|
||||
|
||||
bool bTransparent =
|
||||
(pObj->m_Color.a<1.f || !(pShader->mfGetTemplate(-1)->m_Flags2 & EF2_OPAQUE) || (sr && sr->m_Opacity != 1.0f));
|
||||
|
||||
IShader * pStateShader = rParams.pStateShader;
|
||||
|
||||
if(bTransparent)
|
||||
{
|
||||
if((rParams.dwFObjFlags & FOB_LIGHTPASS) || (rParams.dwFObjFlags & FOB_FOGPASS) || (nTempl == EFT_INVLIGHT))
|
||||
continue;
|
||||
|
||||
if(nSortValue==eS_FogShader)
|
||||
nSortValue=eS_FogShader_Trans;
|
||||
|
||||
if(!e_overlay_geometry)
|
||||
{
|
||||
if(pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY)
|
||||
continue;
|
||||
}
|
||||
else if(e_overlay_geometry >= 2 && pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY)
|
||||
{
|
||||
if(bNotCurArea)
|
||||
continue;
|
||||
|
||||
if(e_overlay_geometry == 2)
|
||||
{
|
||||
if(int(iTimer->GetCurrTime()*5)&1)
|
||||
pStateShader = gRenDev->EF_LoadShader("NoZTestState", eSH_World, EF_SYSTEM );
|
||||
}
|
||||
else
|
||||
pStateShader = gRenDev->EF_LoadShader("ZTestGreaterState", eSH_World, EF_SYSTEM );
|
||||
}
|
||||
|
||||
if(!pObjTransp && pObj->m_DynLMMask != rParams.nStrongestDLightMask)
|
||||
{ // make object for transparent geometry since it will use different light mask and
|
||||
pObjTransp = gRenDev->EF_GetObject(true);
|
||||
pObjTransp->CloneObject(pObj);
|
||||
pObjTransp->m_DynLMMask = rParams.nStrongestDLightMask;
|
||||
}
|
||||
}
|
||||
|
||||
if( rParams.dwFObjFlags & FOB_RENDER_INTO_SHADOWMAP && (pMat->m_Flags & MIF_NOCASTSHADOWS) )
|
||||
continue;
|
||||
|
||||
if( nSortValue == EFSLIST_STENCIL && bTransparent )
|
||||
gRenDev->EF_AddEf_NotVirtual(rParams.nFogVolumeID, pREOcLeaf, pShader, sr,
|
||||
(bTransparent&&pObjTransp) ? pObjTransp : pObj,
|
||||
nTempl, pStateShader, 0);
|
||||
else
|
||||
gRenDev->EF_AddEf_NotVirtual(rParams.nFogVolumeID, pREOcLeaf, pShader, sr,
|
||||
(bTransparent&&pObjTransp) ? pObjTransp : pObj,
|
||||
nTempl, pStateShader, nSortValue);
|
||||
}
|
||||
} //i
|
||||
}
|
||||
|
||||
void CLeafBuffer::RenderDebugLightPass(const Matrix44 & mat, int nLightMask, float fAlpha)
|
||||
{
|
||||
int nLightsNum = 0;
|
||||
for(int i=0; i<32; i++)
|
||||
if(nLightMask & (1<<i))
|
||||
nLightsNum++;
|
||||
|
||||
CCObject * pObj = gRenDev->EF_GetObject(true);
|
||||
pObj->m_Matrix = mat;
|
||||
|
||||
IShader * pShader = gRenDev->EF_LoadShader("ObjectColor_VP",eSH_World,EF_SYSTEM);
|
||||
pObj->m_Color = CFColor(nLightsNum>=3,nLightsNum==2,nLightsNum==1,fAlpha);
|
||||
|
||||
for (int i=0; i<m_pMats->Count(); i++)
|
||||
{
|
||||
CRendElement * pREOcLeaf = m_pMats->Get(i)->pRE;
|
||||
if (pREOcLeaf)
|
||||
gRenDev->EF_AddEf_NotVirtual(0, pREOcLeaf, pShader, 0, pObj, 0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
void CLeafBuffer::CopyVertices(byte * pVertsNew, int nVertFormatNew, int nNewVertsCount)
|
||||
{
|
||||
SBufInfoTable *pOffsNew = &gBufInfoTable[nVertFormatNew];
|
||||
int nVertSizeNew = m_VertexSize[nVertFormatNew];
|
||||
|
||||
int nPosStride=0;
|
||||
if(byte * pPosPtr = GetPosPtr(nPosStride))
|
||||
for(int i=0; i<nNewVertsCount; i++)
|
||||
*(DWORD*)&pPosPtr[i*nPosStride] = *(DWORD*)&pVertsNew[nVertSizeNew*i];
|
||||
|
||||
int nColorStride=0;
|
||||
if(pOffsNew->OffsColor)
|
||||
if(byte * pColorPtr = GetColorPtr(nColorStride))
|
||||
for(int i=0; i<nNewVertsCount; i++)
|
||||
*(DWORD*)&pColorPtr[i*nColorStride] = *(DWORD*)&pVertsNew[pOffsNew->OffsColor + nVertSizeNew*i];
|
||||
|
||||
int nSecColorStride=0;
|
||||
if(pOffsNew->OffsSecColor)
|
||||
if(byte * pSecColorPtr = GetSecColorPtr(nSecColorStride))
|
||||
for(int i=0; i<nNewVertsCount; i++)
|
||||
*(DWORD*)&pSecColorPtr[i*nSecColorStride] = *(DWORD*)&pVertsNew[pOffsNew->OffsSecColor + nVertSizeNew*i];
|
||||
|
||||
int nNormalStride=0;
|
||||
if(pOffsNew->OffsNormal)
|
||||
if(byte * pNormalPtr = GetNormalPtr(nNormalStride))
|
||||
for(int i=0; i<nNewVertsCount; i++)
|
||||
*(DWORD*)&pNormalPtr[i*nNormalStride] = *(DWORD*)&pVertsNew[pOffsNew->OffsNormal + nVertSizeNew*i];
|
||||
|
||||
int nTCStride=0;
|
||||
if(pOffsNew->OffsTC)
|
||||
if(byte * pTCPtr = GetUVPtr(nTCStride))
|
||||
for(int i=0; i<nNewVertsCount; i++)
|
||||
*(DWORD*)&pTCPtr[i*nTCStride] = *(DWORD*)&pVertsNew[pOffsNew->OffsTC + nVertSizeNew*i];
|
||||
}
|
||||
*/
|
||||
417
RenderDll/Common/LeafBufferSerialize.cpp
Normal file
417
RenderDll/Common/LeafBufferSerialize.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: LeafBufferSerialize.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/8/2001 by Vladimir Kajalin
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: LeafBuffer serialization
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "cryheaders.h"
|
||||
#include "nvtristrip/nvtristrip.h"
|
||||
#include "serializebuffer.h"
|
||||
#include "MakMatInfoFromMAT_ENTITY.h"
|
||||
|
||||
CryIRGB CF2IRGB(CFColor in)
|
||||
{
|
||||
CryIRGB out;
|
||||
out.r = uchar(in.r*255);
|
||||
out.g = uchar(in.g*255);
|
||||
out.b = uchar(in.b*255);
|
||||
return out;
|
||||
}
|
||||
|
||||
char *SkipPath (char *pathname)
|
||||
{
|
||||
char *last;
|
||||
|
||||
last = pathname;
|
||||
while (*pathname)
|
||||
{
|
||||
if (*pathname=='/' || *pathname=='\\')
|
||||
last = pathname+1;
|
||||
pathname++;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
int CLeafBuffer__SetTexType(TextureMap3 *tm)
|
||||
{
|
||||
if (tm->type == TEXMAP_CUBIC)
|
||||
return eTT_Cubemap;
|
||||
else
|
||||
if (tm->type == TEXMAP_AUTOCUBIC)
|
||||
return eTT_AutoCubemap;
|
||||
return eTT_Base;
|
||||
}
|
||||
|
||||
bool CLeafBuffer::Serialize(int & nPos, uchar * pSerBuf, bool bSave, char * _szFolderName, char * _szFileName, double & dCIndexedMesh__LoadMaterial)
|
||||
{ // Load
|
||||
int i;
|
||||
char szSignature[16]="";
|
||||
if(!LoadBuffer(szSignature, 11, pSerBuf, nPos) || strcmp(szSignature,"LeafBuffer"))
|
||||
return false;
|
||||
|
||||
LoadBuffer(&m_SecVertCount, sizeof(m_SecVertCount), pSerBuf, nPos);
|
||||
|
||||
if((*((int*)&pSerBuf[nPos])))
|
||||
m_arrVertStripMap = new uint[(*((int*)&pSerBuf[nPos]))];
|
||||
LoadBuffer( m_arrVertStripMap, m_SecVertCount*sizeof(m_arrVertStripMap[0]), pSerBuf, nPos);
|
||||
|
||||
m_SecIndices.LoadFromBuffer(pSerBuf, nPos);
|
||||
m_NumIndices = m_SecIndices.Num();
|
||||
|
||||
if((*((int*)&pSerBuf[nPos])) && !m_pIndicesPreStrip)
|
||||
m_pIndicesPreStrip = new list2<unsigned short>;
|
||||
|
||||
m_pIndicesPreStrip->LoadFromBuffer(pSerBuf, nPos);
|
||||
LoadBuffer(&m_nPrimetiveType,sizeof(m_nPrimetiveType), pSerBuf, nPos);
|
||||
|
||||
if((*((int*)&pSerBuf[nPos])))
|
||||
{
|
||||
m_pLoadedColors = new Vec3d[(*((int*)&pSerBuf[nPos]))/sizeof(m_pLoadedColors[0])];
|
||||
assert((*((int*)&pSerBuf[nPos]))/sizeof(m_pLoadedColors[0]) == m_SecVertCount);
|
||||
}
|
||||
LoadBuffer( m_pLoadedColors, m_SecVertCount*sizeof(m_pLoadedColors[0]), pSerBuf, nPos);
|
||||
|
||||
// load mat info
|
||||
m_pMats = new list2<CMatInfo>;
|
||||
m_bMaterialsWasCreatedInRenderer = true;
|
||||
m_pMats->LoadFromBuffer(pSerBuf, nPos);
|
||||
|
||||
// create materaial
|
||||
for (i=0; i<m_pMats->Count(); i++)
|
||||
{
|
||||
m_pMats->GetAt(i).pRE = 0;
|
||||
|
||||
MAT_ENTITY * pMatEnt = new MAT_ENTITY;
|
||||
LoadBuffer(pMatEnt, sizeof(*pMatEnt), pSerBuf, nPos);
|
||||
m_pMats->Get(i)->pMatEnt = pMatEnt;
|
||||
|
||||
// skip loading of fake mats
|
||||
if(m_pMats->Get(i)->nNumIndices && m_pMats->Get(i)->nNumVerts)
|
||||
if(_szFileName && _szFolderName)
|
||||
{
|
||||
AUTO_PROFILE_SECTION(iSystem->GetITimer(), dCIndexedMesh__LoadMaterial);
|
||||
CIndexedMesh__LoadMaterial(_szFileName, _szFolderName, m_pMats->GetAt(i), gRenDev, pMatEnt);
|
||||
}
|
||||
|
||||
delete m_pMats->Get(i)->pMatEnt;
|
||||
m_pMats->Get(i)->pMatEnt=0;
|
||||
|
||||
if(m_pMats->GetAt(i).m_dwNumSections)
|
||||
{
|
||||
m_pMats->GetAt(i).m_pPrimitiveGroups = new SPrimitiveGroup[m_pMats->GetAt(i).m_dwNumSections];
|
||||
LoadBuffer((void*)m_pMats->GetAt(i).m_pPrimitiveGroups,
|
||||
sizeof(SPrimitiveGroup)*m_pMats->GetAt(i).m_dwNumSections, pSerBuf, nPos);
|
||||
}
|
||||
}
|
||||
|
||||
// make system vert buffer
|
||||
m_pSecVertBuffer = new CVertexBuffer();
|
||||
LoadBuffer( m_pSecVertBuffer, sizeof(CVertexBuffer), pSerBuf, nPos); // need to restore
|
||||
|
||||
// load positions
|
||||
if(*((int*)&pSerBuf[nPos]))
|
||||
{
|
||||
assert(m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData); // should not be zero before saving
|
||||
m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData = new uchar[m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat]];
|
||||
}
|
||||
else
|
||||
assert(!m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData);
|
||||
assert(m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat] == (*((int*)&pSerBuf[nPos])));
|
||||
LoadBuffer( m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData, m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat], pSerBuf, nPos);
|
||||
|
||||
// load tangents
|
||||
if(*((int*)&pSerBuf[nPos]))
|
||||
{
|
||||
assert(m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData); // should not be zero before saving
|
||||
m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData = new SPipTangents[m_SecVertCount];
|
||||
}
|
||||
else
|
||||
assert(!m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData);
|
||||
assert(m_SecVertCount*sizeof(SPipTangents) == (*((int*)&pSerBuf[nPos])));
|
||||
LoadBuffer( m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData, m_SecVertCount*sizeof(SPipTangents), pSerBuf, nPos);
|
||||
|
||||
assert(!m_pVertexBuffer); // not needed
|
||||
LoadBuffer(&m_vBoxMax, sizeof(m_vBoxMax), pSerBuf, nPos);
|
||||
LoadBuffer(&m_vBoxMin, sizeof(m_vBoxMin), pSerBuf, nPos);
|
||||
|
||||
int bHasVtxMap = 0;
|
||||
LoadBuffer(&bHasVtxMap, sizeof(bHasVtxMap), pSerBuf,nPos);
|
||||
if (bHasVtxMap)
|
||||
{
|
||||
m_arrVtxMap = new uint[m_SecVertCount];
|
||||
LoadBuffer(m_arrVtxMap, sizeof(uint)*m_SecVertCount, pSerBuf,nPos);
|
||||
}
|
||||
|
||||
// make REs
|
||||
for (i=0; i<(*m_pMats).Count(); i++)
|
||||
{
|
||||
if(m_pMats->Get(i)->nNumIndices && m_pMats->Get(i)->nNumVerts)
|
||||
{
|
||||
CREOcLeaf *re = (CREOcLeaf *)gRenDev->EF_CreateRE(eDATA_OcLeaf);
|
||||
re->m_pChunk = &(*m_pMats)[i];
|
||||
re->m_pBuffer = this;
|
||||
assert (re->m_pChunk->nNumIndices < 60000);
|
||||
re->m_pChunk->pRE = re;
|
||||
|
||||
// set sort offset
|
||||
// IShader * ef = m_pMats->Get(i)->shaderItem.m_pShader->GetTemplate(-1);
|
||||
// bool bTwoSided = ef && (ef->GetCull() == eCULL_None);
|
||||
bool bTwoSided = (m_pMats->Get(i)->shaderItem.m_pShaderResources->m_ResFlags & MTLFLAG_2SIDED)!=0;//ef && (ef->GetCull() == e CULL_None);
|
||||
re->m_SortId = i + 2*(!bTwoSided); // render double sided leafs last
|
||||
}
|
||||
else
|
||||
(*m_pMats)[i].pRE = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CLeafBuffer::LoadMaterial(int m,
|
||||
const char *szFileName, const char *szFolderName,
|
||||
list2<CMatInfo> & lstMatTable, IRenderer * pRenderer,
|
||||
MAT_ENTITY * me, bool bFake)
|
||||
{
|
||||
if(m<0 || bFake)//!pCGF->m_lstMaterials[m].IsStdMat)
|
||||
{
|
||||
CMatInfo fake;
|
||||
lstMatTable.Add(fake);
|
||||
return false;
|
||||
}
|
||||
|
||||
// assert(strlen(szFolderName)+strlen(pCGF->m_lstMaterials[m].map_d.name)<1024);
|
||||
// m_pSystem->GetIConsole()->Exit("LoadCGF: texture path len error");
|
||||
|
||||
SInputShaderResources Res;
|
||||
memset(&Res, 0, sizeof(Res));
|
||||
SLightMaterial LMs;
|
||||
// MAT_ENTITY *me = &pCGF->m_lstMaterials[m];
|
||||
if (me->m_New && (me->col_d.r>5 || me->col_d.g>5 || me->col_d.b>5 || me->col_s.r>5 || me->col_s.g>5 || me->col_s.b>5))
|
||||
{
|
||||
Res.m_LMaterial = &LMs;
|
||||
Res.m_LMaterial->Front.m_Ambient = CFColor(me->col_a.r/255.f,me->col_a.g/255.f,me->col_a.b/255.f);
|
||||
Res.m_LMaterial->Front.m_Diffuse = CFColor(me->col_d.r/255.f,me->col_d.g/255.f,me->col_d.b/255.f);
|
||||
Res.m_LMaterial->Front.m_Specular = CFColor(me->col_s.r/255.f,me->col_s.g/255.f,me->col_s.b/255.f);
|
||||
Res.m_LMaterial->Front.m_Specular *= me->specLevel;
|
||||
Res.m_LMaterial->Front.m_Specular.Clamp();
|
||||
Res.m_LMaterial->Front.m_Emission = Res.m_LMaterial->Front.m_Diffuse * me->selfIllum;
|
||||
Res.m_LMaterial->Front.m_SpecShininess = me->specShininess;
|
||||
}
|
||||
|
||||
char diffuse[256]="";
|
||||
strcpy(diffuse, me->map_d.name);
|
||||
|
||||
char bump[256]="";
|
||||
strcpy(bump, me->map_b.name);
|
||||
|
||||
char normalmap[256]="";
|
||||
if(me->map_displ.name[0] && (me->flags & MTLFLAG_CRYSHADER))
|
||||
strcpy(normalmap, me->map_displ.name);
|
||||
|
||||
char opacity[256]="";
|
||||
char decal[256]="";
|
||||
if(me->map_o.name[0])
|
||||
{
|
||||
if (me->flags & MTLFLAG_CRYSHADER)
|
||||
strcpy(decal, me->map_o.name);
|
||||
else
|
||||
strcpy(opacity, me->map_o.name);
|
||||
}
|
||||
|
||||
char gloss[256]="";
|
||||
if(me->map_g.name[0])
|
||||
strcpy(gloss, me->map_g.name);
|
||||
|
||||
char cubemap[256]="";
|
||||
|
||||
char env[256]="";
|
||||
if(me->map_e.name[0])
|
||||
strcpy(env, me->map_e.name);
|
||||
|
||||
char spec[256]="";
|
||||
if(me->map_s.name[0])
|
||||
strcpy(spec, me->map_s.name);
|
||||
|
||||
char det[256]="";
|
||||
if(me->map_detail.name[0])
|
||||
strcpy(det, me->map_detail.name);
|
||||
|
||||
char subsurf[256]="";
|
||||
if(me->map_subsurf.name[0])
|
||||
strcpy(subsurf, me->map_subsurf.name);
|
||||
|
||||
char refl[256]="";
|
||||
if(me->map_e.name[0])
|
||||
strcpy(refl, me->map_e.name);
|
||||
|
||||
char * mat_name = me->name;
|
||||
|
||||
// fill MatInfo struct
|
||||
CMatInfo & newMat = lstMatTable[m];
|
||||
// strcpy(newMat.szDiffuse, diffuse);
|
||||
|
||||
if (me->Dyn_Bounce == 1.0f)
|
||||
newMat.m_Flags |= MIF_PHYSIC;
|
||||
|
||||
if (me->Dyn_StaticFriction == 1.0f)
|
||||
newMat.m_Flags |= MIF_NOCASTSHADOWS;
|
||||
|
||||
/* if (nLM > 0)
|
||||
{
|
||||
Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic = m_pSystem->GetIRenderer()->EF_GetTextureByID(nLM);
|
||||
Res.m_Textures[EFTT_LIGHTMAP].m_Name = Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic->GetName();
|
||||
}
|
||||
if (nLM_LD > 0)
|
||||
{
|
||||
Res.m_Textures[EFTT_LIGHTMAP_DIR].m_TU.m_ITexPic = m_pSystem->GetIRenderer()->EF_GetTextureByID(nLM_LD);
|
||||
Res.m_Textures[EFTT_LIGHTMAP_DIR].m_Name = Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic->GetName();
|
||||
}*/
|
||||
|
||||
Res.m_TexturePath = szFolderName;
|
||||
Res.m_Textures[EFTT_DIFFUSE].m_Name = diffuse;
|
||||
Res.m_Textures[EFTT_GLOSS].m_Name = gloss;
|
||||
Res.m_Textures[EFTT_SUBSURFACE].m_Name = subsurf;
|
||||
Res.m_Textures[EFTT_BUMP].m_Name = bump;
|
||||
Res.m_Textures[EFTT_NORMALMAP].m_Name = normalmap;
|
||||
Res.m_Textures[EFTT_CUBEMAP].m_Name = cubemap[0] ? cubemap : env;
|
||||
Res.m_Textures[EFTT_SPECULAR].m_Name = spec;
|
||||
Res.m_Textures[EFTT_DETAIL_OVERLAY].m_Name = det;
|
||||
Res.m_Textures[EFTT_OPACITY].m_Name = opacity;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_Name = decal;
|
||||
Res.m_Textures[EFTT_SUBSURFACE].m_Name = subsurf;
|
||||
Res.m_Textures[EFTT_REFLECTION].m_Name = refl;
|
||||
Res.m_Textures[EFTT_REFLECTION].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_e);
|
||||
Res.m_Textures[EFTT_CUBEMAP].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_e);
|
||||
Res.m_Textures[EFTT_SUBSURFACE].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_subsurf);
|
||||
Res.m_Textures[EFTT_BUMP].m_TU.m_eTexType = eTT_Bumpmap;
|
||||
Res.m_ResFlags = me->flags;
|
||||
Res.m_Opacity = me->opacity;
|
||||
Res.m_AlphaRef = me->Dyn_SlidingFriction;
|
||||
if (me->flags & MTLFLAG_CRYSHADER)
|
||||
Res.m_AlphaRef = me->alpharef;
|
||||
|
||||
if (decal[0])
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_Amount = me->map_o.Amount;
|
||||
Res.m_Textures[EFTT_DIFFUSE].m_Amount = me->map_d.Amount;
|
||||
Res.m_Textures[EFTT_BUMP].m_Amount = me->map_b.Amount;
|
||||
if (me->flags & MTLFLAG_CRYSHADER)
|
||||
Res.m_Textures[EFTT_NORMALMAP].m_Amount = me->map_displ.Amount;
|
||||
Res.m_Textures[EFTT_OPACITY].m_Amount = me->map_o.Amount;
|
||||
Res.m_Textures[EFTT_REFLECTION].m_Amount = me->map_e.Amount;
|
||||
Res.m_Textures[EFTT_SUBSURFACE].m_Amount = me->map_subsurf.Amount;
|
||||
|
||||
Res.m_Textures[EFTT_DIFFUSE].m_TexFlags = me->map_d.flags;
|
||||
//Res.m_Textures[EFTT_SUBSURFACE].m_TexFlags = me->map_d.flags;
|
||||
Res.m_Textures[EFTT_GLOSS].m_TexFlags = me->map_g.flags;
|
||||
Res.m_Textures[EFTT_BUMP].m_TexFlags = me->map_b.flags;
|
||||
Res.m_Textures[EFTT_CUBEMAP].m_TexFlags = me->map_e.flags;
|
||||
Res.m_Textures[EFTT_SPECULAR].m_TexFlags = me->map_s.flags;
|
||||
Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexFlags = me->map_detail.flags;
|
||||
Res.m_Textures[EFTT_SUBSURFACE].m_TexFlags = me->map_subsurf.flags;
|
||||
|
||||
if (!Res.m_Textures[EFTT_DETAIL_OVERLAY].m_Name.empty())
|
||||
{
|
||||
Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexModificator.m_Tiling[0] = me->map_detail.uscl_val;
|
||||
Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexModificator.m_Tiling[1] = me->map_detail.vscl_val;
|
||||
}
|
||||
if (!Res.m_Textures[EFTT_OPACITY].m_Name.empty())
|
||||
{
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Tiling[0] = me->map_o.uscl_val;
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Tiling[1] = me->map_o.vscl_val;
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Rot[0] = Degr2Word(me->map_o.urot_val);
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Rot[1] = Degr2Word(me->map_o.vrot_val);
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Offs[0] = me->map_o.uoff_val;
|
||||
Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Offs[1] = me->map_o.voff_val;
|
||||
Res.m_Textures[EFTT_OPACITY].m_bUTile = me->map_o.utile;
|
||||
Res.m_Textures[EFTT_OPACITY].m_bVTile = me->map_o.vtile;
|
||||
}
|
||||
if (!Res.m_Textures[EFTT_DECAL_OVERLAY].m_Name.empty())
|
||||
{
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Tiling[0] = me->map_o.uscl_val;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Tiling[1] = me->map_o.vscl_val;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Rot[0] = Degr2Word(me->map_o.urot_val);
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Rot[1] = Degr2Word(me->map_o.vrot_val);
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Offs[0] = me->map_o.uoff_val;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Offs[1] = me->map_o.voff_val;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_bUTile = me->map_o.utile;
|
||||
Res.m_Textures[EFTT_DECAL_OVERLAY].m_bVTile = me->map_o.vtile;
|
||||
}
|
||||
|
||||
char mName[128];
|
||||
strcpy(mName, mat_name);
|
||||
char *str = strchr(mat_name, '/');
|
||||
if (str)
|
||||
{
|
||||
mName[str-mat_name] = 0;
|
||||
strncpy(newMat.sScriptMaterial, &str[1], sizeof(newMat.sScriptMaterial));
|
||||
newMat.sScriptMaterial[sizeof(newMat.sScriptMaterial)-1]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
newMat.sScriptMaterial[0] = 0;
|
||||
}
|
||||
|
||||
char *templName = NULL;;
|
||||
if(strnicmp(mName, "$s_",3)==0)
|
||||
{
|
||||
templName = &mName[3];
|
||||
}
|
||||
else
|
||||
if(str=strchr(mName, '('))
|
||||
{
|
||||
mName[str-mName] = 0;
|
||||
templName = &mName[str-mName+1];
|
||||
if(str=strchr(templName, ')'))
|
||||
templName[str-templName] = 0;
|
||||
}
|
||||
|
||||
uchar nInvert = 0;
|
||||
if (templName && templName[0] == '#')
|
||||
{
|
||||
templName++;
|
||||
nInvert = 1;
|
||||
}
|
||||
|
||||
// strcpy(newMat.szMatName, mName);
|
||||
|
||||
// load shader
|
||||
if(mName[0]==0)
|
||||
strcpy(mName,"nodraw");
|
||||
|
||||
|
||||
newMat.shaderItem = pRenderer->EF_LoadShaderItem(mName, eSH_World, true, templName, 0, &Res);
|
||||
|
||||
//newMat.shaderItem->m_pShader->AdjustResources(newMat.shaderItem->m_pShaderResources);
|
||||
|
||||
//IShader * ef = newMat.shaderItem.m_pShader->GetTemplate(-1);
|
||||
//if(ef->GetPhysMaterialFlags() & MATF_NOCLIP)
|
||||
// newMat.m_Flags &= ~MIF_PHYSIC;
|
||||
// strcpy(newMat.szFolderName, szFolderName);
|
||||
// remember polybump state
|
||||
newMat.m_Flags &= ~MIF_POLYBUMP;
|
||||
|
||||
// pFace->shader_id = m_lstMatTable.Count();
|
||||
|
||||
newMat.fAlpha = me->opacity;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CLeafBuffer::SetTexType(TextureMap3 *tm)
|
||||
{
|
||||
if (tm->type == TEXMAP_CUBIC)
|
||||
return eTT_Cubemap;
|
||||
else
|
||||
if (tm->type == TEXMAP_AUTOCUBIC)
|
||||
return eTT_AutoCubemap;
|
||||
return eTT_Base;
|
||||
}
|
||||
164
RenderDll/Common/LightMaterial.cpp
Normal file
164
RenderDll/Common/LightMaterial.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/*=============================================================================
|
||||
LightMaterial.cpp : implementation of LightMaterial interface.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#define LIGHTMATERIAL_CPP
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CommonRender.h"
|
||||
|
||||
|
||||
|
||||
SLightMaterial* SLightMaterial::current_material = 0;
|
||||
int SLightMaterial::m_ObjFrame = 0;
|
||||
TArray<SLightMaterial *> SLightMaterial::known_materials;
|
||||
|
||||
void SLightMaterial::Release()
|
||||
{
|
||||
m_nRefCounter--;
|
||||
if (!m_nRefCounter)
|
||||
{
|
||||
SLightMaterial::known_materials[Id] = NULL;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void SLightMaterial::mfApply(int Flags)
|
||||
{
|
||||
if (current_material == this && gRenDev->m_RP.m_FrameObject == m_ObjFrame && gRenDev->m_RP.m_CurrentVLightFlags == Flags)
|
||||
return;
|
||||
|
||||
gRenDev->m_RP.m_CurrentVLights = 0;
|
||||
gRenDev->m_RP.m_CurrentVLightFlags = Flags;
|
||||
|
||||
//if (!CRenderer::CV_r_hwlights)
|
||||
// return;
|
||||
|
||||
if (Flags & LMF_DISABLE)
|
||||
return;
|
||||
|
||||
m_ObjFrame = gRenDev->m_RP.m_FrameObject;
|
||||
current_material = this;
|
||||
|
||||
if (Flags & LMF_BUMPMATERIAL)
|
||||
gRenDev->m_RP.m_pCurLightMaterial = this;
|
||||
else
|
||||
gRenDev->EF_LightMaterial(this, Flags);
|
||||
}
|
||||
|
||||
SLightMaterial *SLightMaterial::mfAdd(char *name, SLightMaterial *Compare)
|
||||
{
|
||||
int i;
|
||||
SLightMaterial* mat;
|
||||
|
||||
if (Compare)
|
||||
{
|
||||
for (i=0; i<known_materials.Num(); i++)
|
||||
{
|
||||
mat = known_materials[i];
|
||||
if (!mat)
|
||||
continue;
|
||||
if (mat->Front == Compare->Front)
|
||||
{
|
||||
mat->m_nRefCounter++;
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
char name[128];
|
||||
int n = 0;
|
||||
int nFirstUse = -1;
|
||||
while (true)
|
||||
{
|
||||
sprintf(name, "$Auto_%d", n);
|
||||
for (i=0; i<known_materials.Num(); i++)
|
||||
{
|
||||
mat = known_materials[i];
|
||||
if (!mat)
|
||||
{
|
||||
if (nFirstUse < 0)
|
||||
nFirstUse = i;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(mat->name, name))
|
||||
break;
|
||||
}
|
||||
if (i == known_materials.Num())
|
||||
{
|
||||
SLightMaterial *mt = new SLightMaterial;
|
||||
mt->m_nRefCounter = 1;
|
||||
if (nFirstUse >= 0)
|
||||
i = nFirstUse;
|
||||
else
|
||||
known_materials.AddIndex(1);
|
||||
mt->Id = i;
|
||||
known_materials[i] = mt;
|
||||
strcpy (mt->name, name);
|
||||
mt->Front = Compare->Front;
|
||||
mt->side = FRONT;
|
||||
return known_materials[i];
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !name[0])
|
||||
iConsole->Exit("SLightMaterial::mfAdd: NULL name\n");
|
||||
|
||||
//
|
||||
// search the currently loaded materials
|
||||
//
|
||||
for (i=0; i<known_materials.Num(); i++)
|
||||
{
|
||||
mat = known_materials[i];
|
||||
|
||||
if (!stricmp (mat->name, name) )
|
||||
{
|
||||
//ShPrintf(MSG_WARNING, "LightMaterial '%s' is duplicated\n", name);
|
||||
mat->m_nRefCounter++;
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
SLightMaterial *mt = new SLightMaterial;
|
||||
mt->m_nRefCounter = 1;
|
||||
known_materials.AddIndex(1);
|
||||
strcpy (mt->name, name);
|
||||
mt->Id = i;
|
||||
known_materials[i] = mt;
|
||||
|
||||
return known_materials[i];
|
||||
}
|
||||
|
||||
SLightMaterial *SLightMaterial::mfGet(char *name)
|
||||
{
|
||||
int i;
|
||||
SLightMaterial* mat;
|
||||
|
||||
if (!name || !name[0])
|
||||
iConsole->Exit ("SLightMaterial::mfGet: NULL name\n");
|
||||
|
||||
//
|
||||
// search the currently loaded materials
|
||||
//
|
||||
for (i=0; i<known_materials.Num(); i++)
|
||||
{
|
||||
mat = known_materials[i];
|
||||
|
||||
if (!stricmp (mat->name, name) )
|
||||
{
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
|
||||
Warning( 0,0,"Couldn't find LightMaterial '%s' (use <Default>\n", name);
|
||||
if (known_materials.Num())
|
||||
return known_materials[0];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
250
RenderDll/Common/Names.cpp
Normal file
250
RenderDll/Common/Names.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/*=============================================================================
|
||||
Names.cpp : implementation of the CName class using hash tables.
|
||||
Copyright 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "Names.int"
|
||||
|
||||
|
||||
TArray<SNameEntry *> CName::mNames;
|
||||
TArray<int> CName::mAvailable;
|
||||
SNameEntry* CName::mNameHash[8192];
|
||||
int CName::mDuplicate;
|
||||
|
||||
int CName::Size()
|
||||
{
|
||||
INT_PTR nSize = 0; //AMD Port
|
||||
nSize += mAvailable.GetMemoryUsage();
|
||||
for (int i=0; i<mNames.GetSize(); i++)
|
||||
{
|
||||
if (i < mNames.Num())
|
||||
{
|
||||
nSize += 4;
|
||||
if (mNames[i])
|
||||
nSize += mNames[i]->Size();
|
||||
}
|
||||
else
|
||||
nSize += 4;
|
||||
}
|
||||
nSize += sizeof(long) * 256;
|
||||
|
||||
return nSize;
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
SNameEntry* CreateNewNameEntry(const char *str, int num, int m, SNameEntry *sFNE)
|
||||
{
|
||||
SNameEntry *lsFNE;
|
||||
|
||||
lsFNE = (SNameEntry *)malloc( strlen(str)+sizeof(SNameEntry)-MAX_SNAME_LEN+1);
|
||||
lsFNE->mNumName = num;
|
||||
lsFNE->mFlags = m;
|
||||
lsFNE->mNext = sFNE;
|
||||
|
||||
strcpy(lsFNE->mName, str);
|
||||
|
||||
return lsFNE;
|
||||
}
|
||||
|
||||
void DestroyNameEntry(SNameEntry* sFNE)
|
||||
{
|
||||
free(sFNE);
|
||||
}
|
||||
|
||||
|
||||
CName::CName(const char* str, EFindName efn)
|
||||
{
|
||||
char tstr[MAX_SNAME_LEN];
|
||||
SNameEntry * sFNE;
|
||||
|
||||
assert( str );
|
||||
|
||||
if ( !mNames.Num() )
|
||||
mfInitTables();
|
||||
|
||||
if ( *str == 0 )
|
||||
mNameIndex = 0;
|
||||
|
||||
strncpy(tstr, str, MAX_SNAME_LEN);
|
||||
|
||||
int i = 0;
|
||||
long hash = mfGetHash(tstr);
|
||||
sFNE = mNameHash[hash];
|
||||
while ( sFNE )
|
||||
{
|
||||
if ( !stricmp(tstr,sFNE->mName) )
|
||||
{
|
||||
mNameIndex = sFNE->mNumName;
|
||||
return;
|
||||
}
|
||||
sFNE = sFNE->mNext;
|
||||
}
|
||||
if ( efn == eFN_Find )
|
||||
mNameIndex = 0;
|
||||
else
|
||||
{
|
||||
if ( mAvailable.Num() )
|
||||
{
|
||||
mNameIndex = mAvailable[mAvailable.Num()-1];
|
||||
mAvailable._Remove(mAvailable.Num()-1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = mNames.Num();
|
||||
mNames.AddIndex(1);
|
||||
mNameIndex = i;
|
||||
}
|
||||
sFNE = CreateNewNameEntry(str, mNameIndex, 0, mNameHash[hash] );
|
||||
mNameHash[hash] = sFNE;
|
||||
mNames[mNameIndex] = sFNE;
|
||||
if ( efn == eFN_Intrinsic )
|
||||
mNames[mNameIndex]->mFlags |= NF_Intrinsic;
|
||||
}
|
||||
}
|
||||
|
||||
void CName::mfInitTables(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i=0; i<8192; i++ )
|
||||
{
|
||||
mNameHash[i] = NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(gIntrinsicNames[i].mName[0])
|
||||
{
|
||||
mfRegister(gIntrinsicNames[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CName::mfRegister(SNameEntry& sFNE)
|
||||
{
|
||||
long hash;
|
||||
int i, l;
|
||||
|
||||
hash = mfGetHash(sFNE.mName);
|
||||
sFNE.mNext = mNameHash[hash];
|
||||
mNameHash[hash] = &sFNE;
|
||||
l = mNames.Num();
|
||||
while ( l <= sFNE.mNumName )
|
||||
{
|
||||
i = mNames.Num();
|
||||
mNames.AddIndex(1);
|
||||
mNames[i] = NULL;
|
||||
l++;
|
||||
}
|
||||
if ( mNames[sFNE.mNumName] != NULL )
|
||||
mDuplicate = sFNE.mNumName;
|
||||
|
||||
mNames[sFNE.mNumName] = &sFNE;
|
||||
}
|
||||
|
||||
void CName::mfDisplayHash(void)
|
||||
{
|
||||
int i, l, m;
|
||||
SNameEntry* sFNE;
|
||||
|
||||
l = m = 0;
|
||||
for ( i=0; i<8192; i++ )
|
||||
{
|
||||
sFNE = mNameHash[i];
|
||||
if ( sFNE )
|
||||
m++;
|
||||
while ( sFNE )
|
||||
{
|
||||
l++;
|
||||
sFNE = sFNE->mNext;
|
||||
}
|
||||
}
|
||||
iLog->Log( "Hash: %i names, %i/%i hash bins", l, m, 8192);
|
||||
}
|
||||
|
||||
void CName::mfInitSubsystem(void)
|
||||
{
|
||||
SNameEntry* sFNE;
|
||||
SNameEntry* sFNE1;
|
||||
int i;
|
||||
|
||||
CName("None");
|
||||
|
||||
assert( mNames.Num() );
|
||||
|
||||
if ( mDuplicate )
|
||||
{
|
||||
Warning( 0,0,"WARNING: name %i was duplicated", mDuplicate);
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i=0; i<8192; i++ )
|
||||
{
|
||||
sFNE = mNameHash[i];
|
||||
while ( sFNE )
|
||||
{
|
||||
sFNE1 = sFNE->mNext;
|
||||
if ( sFNE1 )
|
||||
{
|
||||
if ( !stricmp(sFNE->mName, sFNE1->mName) )
|
||||
Warning( 0,0,"WARNING: Name '%s' was duplicated", sFNE->mName);
|
||||
}
|
||||
sFNE = sFNE->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CName::mfExitSubsystem(void)
|
||||
{
|
||||
SNameEntry* sFNE;
|
||||
int i;
|
||||
|
||||
for ( i=0; i<mNames.Num(); i++ )
|
||||
{
|
||||
sFNE = mNames[i];
|
||||
if ( sFNE && !(sFNE->mFlags & NF_Intrinsic) )
|
||||
DestroyNameEntry(sFNE);
|
||||
}
|
||||
mNames.Free();
|
||||
}
|
||||
|
||||
void CName::mfDeleteEntry(int num)
|
||||
{
|
||||
SNameEntry* sFNE;
|
||||
SNameEntry** sFNE1;
|
||||
int i;
|
||||
long hash;
|
||||
|
||||
sFNE = mNames[num];
|
||||
|
||||
assert(sFNE);
|
||||
assert(!(sFNE->mFlags & NF_Intrinsic));
|
||||
|
||||
hash = mfGetHash(sFNE->mName);
|
||||
sFNE1 = &mNameHash[hash];
|
||||
|
||||
while ( *sFNE1 && *sFNE1!=sFNE )
|
||||
{
|
||||
sFNE1 = &((*sFNE1)->mNext);
|
||||
}
|
||||
if ( !*sFNE1 )
|
||||
{
|
||||
Warning( 0,0,"WARNING: Unhashed name '%s'\n", sFNE->mName);
|
||||
return;
|
||||
}
|
||||
|
||||
*sFNE1 = (*sFNE1)->mNext;
|
||||
mNames[num] = NULL;
|
||||
i = mAvailable.Num();
|
||||
mAvailable.AddIndex(1);
|
||||
mAvailable[i] = num;
|
||||
DestroyNameEntry(sFNE);
|
||||
}
|
||||
|
||||
75
RenderDll/Common/Names.int
Normal file
75
RenderDll/Common/Names.int
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
SNameEntry gIntrinsicNames [] =
|
||||
{
|
||||
{ 0, NF_Intrinsic, NULL, "None" },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
long gHashTable[256] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
311
RenderDll/Common/NvTriStrip/NvTriStrip.cpp
Normal file
311
RenderDll/Common/NvTriStrip/NvTriStrip.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
#ifdef WIN64
|
||||
#include "WinDef.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "NvTriStripObjects.h"
|
||||
#include "NvTriStrip.h"
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4018) // signed/unsigned mismatch
|
||||
#ifdef WIN64 //AMD Port
|
||||
#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'xxx', possible loss of data
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//private data
|
||||
static unsigned int cacheSize = CACHESIZE_GEFORCE3;// CACHESIZE_GEFORCE1_2;
|
||||
static bool bStitchStrips = true;
|
||||
static unsigned int minStripSize = 0;
|
||||
static bool bListsOnly = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool _bListsOnly)
|
||||
{
|
||||
bListsOnly = _bListsOnly;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int _cacheSize)
|
||||
{
|
||||
cacheSize = _cacheSize;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool _bStitchStrips)
|
||||
{
|
||||
bStitchStrips = _bStitchStrips;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int _minStripSize)
|
||||
{
|
||||
minStripSize = _minStripSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups)
|
||||
{
|
||||
//put data in format that the stripifier likes
|
||||
int i;
|
||||
WordVec tempIndices;
|
||||
tempIndices.resize(in_numIndices);
|
||||
unsigned short maxIndex = 0;
|
||||
for(i = 0; i < (int)in_numIndices; i++)
|
||||
{
|
||||
tempIndices[i] = in_indices[i];
|
||||
if(in_indices[i] > maxIndex)
|
||||
maxIndex = in_indices[i];
|
||||
}
|
||||
NvStripInfoVec tempStrips;
|
||||
NvFaceInfoVec tempFaces;
|
||||
|
||||
NvStripifier stripifier;
|
||||
|
||||
//do actual stripification
|
||||
stripifier.Stripify(tempIndices, cacheSize, minStripSize, maxIndex, tempStrips, tempFaces);
|
||||
|
||||
//stitch strips together
|
||||
IntVec stripIndices;
|
||||
unsigned int numSeparateStrips = 0;
|
||||
|
||||
if(bListsOnly)
|
||||
{
|
||||
//if we're outputting only lists, we're done
|
||||
*numGroups = 1;
|
||||
(*primGroups) = new PrimitiveGroup[*numGroups];
|
||||
PrimitiveGroup* primGroupArray = *primGroups;
|
||||
|
||||
//count the total number of indices
|
||||
unsigned int numIndices = 0;
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
numIndices += tempStrips[i]->m_faces.size() * 3;
|
||||
}
|
||||
|
||||
//add in the list
|
||||
numIndices += tempFaces.size() * 3;
|
||||
|
||||
primGroupArray[0].type = PT_LIST;
|
||||
primGroupArray[0].numIndices = numIndices;
|
||||
primGroupArray[0].indices = new unsigned short[numIndices];
|
||||
|
||||
//do strips
|
||||
unsigned int indexCtr = 0;
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
for(int j = 0; j < tempStrips[i]->m_faces.size(); j++)
|
||||
{
|
||||
//degenerates are of no use with lists
|
||||
if(!NvStripifier::IsDegenerate(tempStrips[i]->m_faces[j]))
|
||||
{
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v0;
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v1;
|
||||
primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we've removed a tri, reduce the number of indices
|
||||
primGroupArray[0].numIndices -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//do lists
|
||||
for(i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v0;
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v1;
|
||||
primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stripifier.CreateStrips(tempStrips, stripIndices, bStitchStrips, numSeparateStrips);
|
||||
|
||||
//if we're stitching strips together, we better get back only one strip from CreateStrips()
|
||||
assert( (bStitchStrips && (numSeparateStrips == 1)) || !bStitchStrips);
|
||||
|
||||
//convert to output format
|
||||
*numGroups = numSeparateStrips; //for the strips
|
||||
if(tempFaces.size() != 0)
|
||||
(*numGroups)++; //we've got a list as well, increment
|
||||
(*primGroups) = new PrimitiveGroup[*numGroups];
|
||||
|
||||
PrimitiveGroup* primGroupArray = *primGroups;
|
||||
|
||||
//first, the strips
|
||||
int startingLoc = 0;
|
||||
for(int stripCtr = 0; stripCtr < numSeparateStrips; stripCtr++)
|
||||
{
|
||||
int stripLength = 0;
|
||||
|
||||
if(!bStitchStrips)
|
||||
{
|
||||
//if we've got multiple strips, we need to figure out the correct length
|
||||
for(i = startingLoc; i < stripIndices.size(); i++)
|
||||
{
|
||||
if(stripIndices[i] == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
stripLength = i - startingLoc;
|
||||
}
|
||||
else
|
||||
stripLength = stripIndices.size();
|
||||
|
||||
primGroupArray[stripCtr].type = PT_STRIP;
|
||||
primGroupArray[stripCtr].indices = new unsigned short[stripLength];
|
||||
primGroupArray[stripCtr].numIndices = stripLength;
|
||||
|
||||
int indexCtr = 0;
|
||||
for(int i = startingLoc; i < stripLength + startingLoc; i++)
|
||||
primGroupArray[stripCtr].indices[indexCtr++] = stripIndices[i];
|
||||
|
||||
//we add 1 to account for the -1 separating strips
|
||||
//this doesn't break the stitched case since we'll exit the loop
|
||||
startingLoc += stripLength + 1;
|
||||
}
|
||||
|
||||
//next, the list
|
||||
if(tempFaces.size() != 0)
|
||||
{
|
||||
int faceGroupLoc = (*numGroups) - 1; //the face group is the last one
|
||||
primGroupArray[faceGroupLoc].type = PT_LIST;
|
||||
primGroupArray[faceGroupLoc].indices = new unsigned short[tempFaces.size() * 3];
|
||||
primGroupArray[faceGroupLoc].numIndices = tempFaces.size() * 3;
|
||||
int indexCtr = 0;
|
||||
for(int i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v0;
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v1;
|
||||
primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//clean up everything
|
||||
|
||||
//delete strips
|
||||
for(i = 0; i < tempStrips.size(); i++)
|
||||
{
|
||||
for(int j = 0; j < tempStrips[i]->m_faces.size(); j++)
|
||||
{
|
||||
delete tempStrips[i]->m_faces[j];
|
||||
tempStrips[i]->m_faces[j] = NULL;
|
||||
}
|
||||
tempStrips[i]->m_faces.resize(0);
|
||||
delete tempStrips[i];
|
||||
tempStrips[i] = NULL;
|
||||
}
|
||||
|
||||
//delete faces
|
||||
for(i = 0; i < tempFaces.size(); i++)
|
||||
{
|
||||
delete tempFaces[i];
|
||||
tempFaces[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups)
|
||||
{
|
||||
(*remappedGroups) = new PrimitiveGroup[numGroups];
|
||||
|
||||
//caches oldIndex --> newIndex conversion
|
||||
int *indexCache;
|
||||
indexCache = new int[numVerts];
|
||||
memset(indexCache, -1, sizeof(int)*numVerts);
|
||||
|
||||
//loop over primitive groups
|
||||
unsigned int indexCtr = 0;
|
||||
for(int i = 0; i < numGroups; i++)
|
||||
{
|
||||
unsigned int numIndices = in_primGroups[i].numIndices;
|
||||
|
||||
//init remapped group
|
||||
(*remappedGroups)[i].type = in_primGroups[i].type;
|
||||
(*remappedGroups)[i].numIndices = numIndices;
|
||||
(*remappedGroups)[i].indices = new unsigned short[numIndices];
|
||||
|
||||
for(int j = 0; j < numIndices; j++)
|
||||
{
|
||||
int cachedIndex = indexCache[in_primGroups[i].indices[j]];
|
||||
if(cachedIndex == -1) //we haven't seen this index before
|
||||
{
|
||||
//point to "last" vertex in VB
|
||||
(*remappedGroups)[i].indices[j] = indexCtr;
|
||||
|
||||
//add to index cache, increment
|
||||
indexCache[in_primGroups[i].indices[j]] = indexCtr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//we've seen this index before
|
||||
(*remappedGroups)[i].indices[j] = cachedIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] indexCache;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
131
RenderDll/Common/NvTriStrip/NvTriStrip.h
Normal file
131
RenderDll/Common/NvTriStrip/NvTriStrip.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef NVTRISTRIP_H
|
||||
#define NVTRISTRIP_H
|
||||
|
||||
#if !defined(NULL) && !defined(LINUX64)
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public interface for stripifier
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//GeForce1 and 2 cache size
|
||||
#define CACHESIZE_GEFORCE1_2 16
|
||||
|
||||
//GeForce3 cache size
|
||||
#define CACHESIZE_GEFORCE3 24
|
||||
|
||||
enum PrimType
|
||||
{
|
||||
PT_LIST,
|
||||
PT_STRIP,
|
||||
PT_FAN
|
||||
};
|
||||
|
||||
struct SPrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned int offsIndex;
|
||||
unsigned int numTris;
|
||||
unsigned int nFirstFace;
|
||||
};
|
||||
|
||||
struct PrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned short* indices;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
|
||||
~PrimitiveGroup()
|
||||
{
|
||||
if(indices)
|
||||
delete[] indices;
|
||||
indices = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int cacheSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool bStitchStrips);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int minSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool bListsOnly);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
// Credit goes to the MS Xbox crew for the idea for this interface.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups);
|
||||
|
||||
#endif
|
||||
1798
RenderDll/Common/NvTriStrip/NvTriStripObjects.cpp
Normal file
1798
RenderDll/Common/NvTriStrip/NvTriStripObjects.cpp
Normal file
File diff suppressed because it is too large
Load Diff
244
RenderDll/Common/NvTriStrip/NvTriStripObjects.h
Normal file
244
RenderDll/Common/NvTriStrip/NvTriStripObjects.h
Normal file
@@ -0,0 +1,244 @@
|
||||
|
||||
#ifndef NV_TRISTRIP_OBJECTS_H
|
||||
#define NV_TRISTRIP_OBJECTS_H
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "VertexCache.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Types defined for stripification
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct MyVertex {
|
||||
float x, y, z;
|
||||
float nx, ny, nz;
|
||||
};
|
||||
|
||||
typedef MyVertex MyVector;
|
||||
|
||||
struct MyFace {
|
||||
int v1, v2, v3;
|
||||
float nx, ny, nz;
|
||||
};
|
||||
|
||||
|
||||
class NvFaceInfo {
|
||||
public:
|
||||
|
||||
// vertex indices
|
||||
NvFaceInfo(int v0, int v1, int v2, bool bIsFake = false){
|
||||
m_v0 = v0; m_v1 = v1; m_v2 = v2;
|
||||
m_stripId = -1;
|
||||
m_testStripId = -1;
|
||||
m_experimentId = -1;
|
||||
m_bIsFake = bIsFake;
|
||||
}
|
||||
|
||||
// data members are left public
|
||||
int m_v0, m_v1, m_v2;
|
||||
int m_stripId; // real strip Id
|
||||
int m_testStripId; // strip Id in an experiment
|
||||
int m_experimentId; // in what experiment was it given an experiment Id?
|
||||
bool m_bIsFake; //if true, will be deleted when the strip it's in is deleted
|
||||
};
|
||||
|
||||
class NvEdgeInfo {
|
||||
public:
|
||||
|
||||
// constructor puts 1 ref on us
|
||||
NvEdgeInfo (int v0, int v1){
|
||||
m_v0 = v0;
|
||||
m_v1 = v1;
|
||||
m_face0 = NULL;
|
||||
m_face1 = NULL;
|
||||
m_nextV0 = NULL;
|
||||
m_nextV1 = NULL;
|
||||
|
||||
// we will appear in 2 lists. this is a good
|
||||
// way to make sure we delete it the second time
|
||||
// we hit it in the edge infos
|
||||
m_refCount = 2;
|
||||
|
||||
}
|
||||
|
||||
// ref and unref
|
||||
void Unref () { if (--m_refCount == 0) delete this; }
|
||||
|
||||
// data members are left public
|
||||
unsigned int m_refCount;
|
||||
NvFaceInfo *m_face0, *m_face1;
|
||||
int m_v0, m_v1;
|
||||
NvEdgeInfo *m_nextV0, *m_nextV1;
|
||||
};
|
||||
|
||||
|
||||
// This class is a quick summary of parameters used
|
||||
// to begin a triangle strip. Some operations may
|
||||
// want to create lists of such items, so they were
|
||||
// pulled out into a class
|
||||
class NvStripStartInfo {
|
||||
public:
|
||||
NvStripStartInfo(NvFaceInfo *startFace, NvEdgeInfo *startEdge, bool toV1){
|
||||
m_startFace = startFace;
|
||||
m_startEdge = startEdge;
|
||||
m_toV1 = toV1;
|
||||
}
|
||||
NvFaceInfo *m_startFace;
|
||||
NvEdgeInfo *m_startEdge;
|
||||
bool m_toV1;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<NvFaceInfo*> NvFaceInfoVec;
|
||||
typedef std::list <NvFaceInfo*> NvFaceInfoList;
|
||||
typedef std::list <NvFaceInfoVec*> NvStripList;
|
||||
typedef std::vector<NvEdgeInfo*> NvEdgeInfoVec;
|
||||
|
||||
typedef std::vector<unsigned short> WordVec;
|
||||
typedef std::vector<int> IntVec;
|
||||
typedef std::vector<MyVertex> MyVertexVec;
|
||||
typedef std::vector<MyFace> MyFaceVec;
|
||||
|
||||
template<class T>
|
||||
inline void SWAP(T& first, T& second)
|
||||
{
|
||||
T temp = first;
|
||||
first = second;
|
||||
second = temp;
|
||||
}
|
||||
|
||||
// This is a summary of a strip that has been built
|
||||
class NvStripInfo {
|
||||
public:
|
||||
|
||||
// A little information about the creation of the triangle strips
|
||||
NvStripInfo(const NvStripStartInfo &startInfo, int stripId, int experimentId = -1) :
|
||||
m_startInfo(startInfo)
|
||||
{
|
||||
m_stripId = stripId;
|
||||
m_experimentId = experimentId;
|
||||
visited = false;
|
||||
m_numDegenerates = 0;
|
||||
}
|
||||
|
||||
// This is an experiment if the experiment id is >= 0
|
||||
inline bool IsExperiment () const { return m_experimentId >= 0; }
|
||||
|
||||
inline bool IsInStrip (const NvFaceInfo *faceInfo) const
|
||||
{
|
||||
if(faceInfo == NULL)
|
||||
return false;
|
||||
|
||||
return (m_experimentId >= 0 ? faceInfo->m_testStripId == m_stripId : faceInfo->m_stripId == m_stripId);
|
||||
}
|
||||
|
||||
bool SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
// take the given forward and backward strips and combine them together
|
||||
void Combine(const NvFaceInfoVec &forward, const NvFaceInfoVec &backward);
|
||||
|
||||
//returns true if the face is "unique", i.e. has a vertex which doesn't exist in the faceVec
|
||||
bool Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face);
|
||||
|
||||
// mark the triangle as taken by this strip
|
||||
bool IsMarked (NvFaceInfo *faceInfo);
|
||||
void MarkTriangle(NvFaceInfo *faceInfo);
|
||||
|
||||
// build the strip
|
||||
void Build(NvEdgeInfoVec &edgeInfos, NvFaceInfoVec &faceInfos);
|
||||
|
||||
// public data members
|
||||
NvStripStartInfo m_startInfo;
|
||||
NvFaceInfoVec m_faces;
|
||||
int m_stripId;
|
||||
int m_experimentId;
|
||||
|
||||
bool visited;
|
||||
|
||||
int m_numDegenerates;
|
||||
};
|
||||
|
||||
typedef std::vector<NvStripInfo*> NvStripInfoVec;
|
||||
|
||||
|
||||
//The actual stripifier
|
||||
class NvStripifier {
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
NvStripifier();
|
||||
~NvStripifier();
|
||||
|
||||
//the target vertex cache size, the structure to place the strips in, and the input indices
|
||||
void Stripify(const WordVec &in_indices, const int in_cacheSize, const int in_minStripLength,
|
||||
const unsigned short maxIndex, NvStripInfoVec &allStrips, NvFaceInfoVec &allFaces);
|
||||
void CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, unsigned int& numSeparateStrips);
|
||||
|
||||
static int GetUniqueVertexInB(NvFaceInfo *faceA, NvFaceInfo *faceB);
|
||||
//static int GetSharedVertex(NvFaceInfo *faceA, NvFaceInfo *faceB);
|
||||
static void GetSharedVertices(NvFaceInfo *faceA, NvFaceInfo *faceB, int* vertex0, int* vertex1);
|
||||
|
||||
static bool IsDegenerate(const NvFaceInfo* face);
|
||||
|
||||
protected:
|
||||
|
||||
WordVec indices;
|
||||
int cacheSize;
|
||||
int minStripLength;
|
||||
float meshJump;
|
||||
bool bFirstTimeResetPoint;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Big mess of functions called during stripification
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//********************
|
||||
bool IsMoneyFace(const NvFaceInfo& face);
|
||||
bool FaceContainsIndex(const NvFaceInfo& face, const unsigned int index);
|
||||
|
||||
bool IsCW(NvFaceInfo *faceInfo, int v0, int v1);
|
||||
bool NextIsCW(const int numIndices);
|
||||
|
||||
bool IsDegenerate(const unsigned short v0, const unsigned short v1, const unsigned short v2);
|
||||
|
||||
static int GetNextIndex(const WordVec &indices, NvFaceInfo *face);
|
||||
static NvEdgeInfo *FindEdgeInfo(NvEdgeInfoVec &edgeInfos, int v0, int v1);
|
||||
static NvFaceInfo *FindOtherFace(NvEdgeInfoVec &edgeInfos, int v0, int v1, NvFaceInfo *faceInfo);
|
||||
NvFaceInfo *FindGoodResetPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
void FindAllStrips(NvStripInfoVec &allStrips, NvFaceInfoVec &allFaceInfos, NvEdgeInfoVec &allEdgeInfos, int numSamples);
|
||||
void SplitUpStripsAndOptimize(NvStripInfoVec &allStrips, NvStripInfoVec &outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList);
|
||||
void RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList);
|
||||
|
||||
bool FindTraversal(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, NvStripInfo *strip, NvStripStartInfo &startInfo);
|
||||
int CountRemainingTris(std::list<NvStripInfo*>::iterator iter, std::list<NvStripInfo*>::iterator end);
|
||||
|
||||
void CommitStrips(NvStripInfoVec &allStrips, const NvStripInfoVec &strips);
|
||||
|
||||
float AvgStripSize(const NvStripInfoVec &strips);
|
||||
int FindStartPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos);
|
||||
|
||||
void UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip);
|
||||
void UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face);
|
||||
float CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip);
|
||||
int CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face);
|
||||
int NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec);
|
||||
|
||||
void BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, const unsigned short maxIndex);
|
||||
bool AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos);
|
||||
|
||||
// let our strip info classes and the other classes get
|
||||
// to these protected stripificaton methods if they want
|
||||
friend class NvStripInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
79
RenderDll/Common/NvTriStrip/VertexCache.h
Normal file
79
RenderDll/Common/NvTriStrip/VertexCache.h
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
#ifndef VERTEX_CACHE_H
|
||||
|
||||
#define VERTEX_CACHE_H
|
||||
|
||||
class VertexCache
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
VertexCache(int size)
|
||||
{
|
||||
numEntries = size;
|
||||
|
||||
entries = new int[numEntries];
|
||||
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
entries[i] = -1;
|
||||
}
|
||||
|
||||
VertexCache() { VertexCache(16); }
|
||||
~VertexCache() { delete[] entries; entries = 0; }
|
||||
|
||||
bool InCache(int entry)
|
||||
{
|
||||
bool returnVal = false;
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
{
|
||||
if(entries[i] == entry)
|
||||
{
|
||||
returnVal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
int AddEntry(int entry)
|
||||
{
|
||||
int removed;
|
||||
|
||||
removed = entries[numEntries - 1];
|
||||
|
||||
//push everything right one
|
||||
for(int i = numEntries - 2; i >= 0; i--)
|
||||
{
|
||||
entries[i + 1] = entries[i];
|
||||
}
|
||||
|
||||
entries[0] = entry;
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
memset(entries, -1, sizeof(int) * numEntries);
|
||||
}
|
||||
|
||||
void Copy(VertexCache* inVcache)
|
||||
{
|
||||
for(int i = 0; i < numEntries; i++)
|
||||
{
|
||||
inVcache->Set(i, entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int At(int index) { return entries[index]; }
|
||||
void Set(int index, int value) { entries[index] = value; }
|
||||
|
||||
private:
|
||||
|
||||
int *entries;
|
||||
int numEntries;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
18
RenderDll/Common/RendElements/CRE2DQuad.cpp
Normal file
18
RenderDll/Common/RendElements/CRE2DQuad.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "CRE2DQuad.h"
|
||||
|
||||
|
||||
void *CRE2DQuad::mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags)
|
||||
{
|
||||
*Stride = sizeof(m_arrVerts[0]);
|
||||
|
||||
switch(ePT)
|
||||
{
|
||||
case eSrcPointer_Vert:
|
||||
return &m_arrVerts[0].xyz.x;
|
||||
case eSrcPointer_Tex:
|
||||
return &m_arrVerts[0].st[0];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
243
RenderDll/Common/RendElements/CREBeam.cpp
Normal file
243
RenderDll/Common/RendElements/CREBeam.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "I3dengine.h"
|
||||
|
||||
void CREBeam::mfPrepare(void)
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
int Features = gRenDev->GetFeatures();
|
||||
|
||||
if (!m_pBuffer)
|
||||
{
|
||||
I3DEngine *eng = (I3DEngine *)iSystem->GetI3DEngine();
|
||||
IStatObj *pObj = eng->MakeObject(m_ModelName.c_str(), NULL, evs_ShareAndSortForCache, false, false);
|
||||
m_pBuffer = pObj->GetLeafBuffer();
|
||||
if (!m_pBuffer)
|
||||
{
|
||||
gRenDev->m_RP.m_pRE = NULL;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
return;
|
||||
}
|
||||
Vec3d Mins = m_pBuffer->m_vBoxMin;
|
||||
Vec3d Maxs = m_pBuffer->m_vBoxMax;
|
||||
|
||||
m_fLengthScale = Maxs.x;
|
||||
m_fWidthScale = Maxs.z;
|
||||
}
|
||||
|
||||
CLeafBuffer *lb = m_pBuffer;
|
||||
CMatInfo *mi = &(*lb->m_pMats)[0];
|
||||
|
||||
gRenDev->m_RP.m_pShader = (SShader *)mi->shaderItem.m_pShader->GetTemplate(-1);
|
||||
gRenDev->m_RP.m_pShaderResources = mi->shaderItem.m_pShaderResources;
|
||||
gRenDev->m_RP.m_pRE = mi->pRE;
|
||||
|
||||
// Choose appropriate shader technique depend on some input parameters
|
||||
if (gRenDev->m_RP.m_pShader->m_HWTechniques.Num())
|
||||
{
|
||||
int nHW = gRenDev->EF_SelectHWTechnique(gRenDev->m_RP.m_pShader);
|
||||
if (nHW >= 0)
|
||||
gRenDev->m_RP.m_pCurTechnique = gRenDev->m_RP.m_pShader->m_HWTechniques[nHW];
|
||||
else
|
||||
gRenDev->m_RP.m_pCurTechnique = NULL;
|
||||
}
|
||||
else
|
||||
gRenDev->m_RP.m_pCurTechnique = NULL;
|
||||
|
||||
CCObject *obj = gRenDev->m_RP.m_pCurObject;
|
||||
obj->m_RE = this;
|
||||
UParamVal pv;
|
||||
pv.m_Float = m_fLengthScale;
|
||||
SShaderParam::SetParam("origlength", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Float = m_fWidthScale;
|
||||
SShaderParam::SetParam("origwidth", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Float = m_fLength;
|
||||
SShaderParam::SetParam("length", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Float = m_fStartRadius;
|
||||
SShaderParam::SetParam("startradius", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Float = m_fEndRadius;
|
||||
SShaderParam::SetParam("endradius", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Color[0] = m_StartColor[0];
|
||||
pv.m_Color[1] = m_StartColor[1];
|
||||
pv.m_Color[2] = m_StartColor[2];
|
||||
pv.m_Color[3] = m_StartColor[3];
|
||||
if (m_LightStyle == 0)
|
||||
{
|
||||
pv.m_Color[0] = obj->m_Color[0];
|
||||
pv.m_Color[1] = obj->m_Color[1];
|
||||
pv.m_Color[2] = obj->m_Color[2];
|
||||
}
|
||||
SShaderParam::SetParam("startcolor", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
pv.m_Color[0] = m_EndColor[0];
|
||||
pv.m_Color[1] = m_EndColor[1];
|
||||
pv.m_Color[2] = m_EndColor[2];
|
||||
pv.m_Color[3] = m_EndColor[3];
|
||||
if (m_LightStyle == 0)
|
||||
{
|
||||
pv.m_Color[0] = obj->m_Color[0];
|
||||
pv.m_Color[1] = obj->m_Color[1];
|
||||
pv.m_Color[2] = obj->m_Color[2];
|
||||
}
|
||||
SShaderParam::SetParam("endcolor", &gRenDev->m_RP.m_pShader->m_PublicParams, pv, -1);
|
||||
|
||||
obj->m_ShaderParams = &gRenDev->m_RP.m_pShader->m_PublicParams;
|
||||
|
||||
gRenDev->m_RP.m_FirstVertex = mi->nFirstVertId;
|
||||
gRenDev->m_RP.m_RendNumIndices = mi->nNumIndices;
|
||||
gRenDev->m_RP.m_RendNumVerts = mi->nNumVerts;
|
||||
gRenDev->m_RP.m_FirstIndex = mi->nFirstIndexId;
|
||||
}
|
||||
|
||||
bool CREBeam::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
char* name;
|
||||
long cmd;
|
||||
char *params;
|
||||
char *data;
|
||||
|
||||
enum {eModel = 1, eLength, eStartRadius, eEndRadius, eStartColor, eEndColor, eLightStyle};
|
||||
static tokenDesc commands[] =
|
||||
{
|
||||
{eModel, "Model"},
|
||||
{eStartRadius, "StartRadius"},
|
||||
{eEndRadius, "EndRadius"},
|
||||
{eStartColor, "StartColor"},
|
||||
{eEndColor, "EndColor"},
|
||||
{eLightStyle, "LightStyle"},
|
||||
{eLength, "Length"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
I3DEngine *eng = (I3DEngine *)iSystem->GetI3DEngine();
|
||||
|
||||
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
||||
{
|
||||
data = NULL;
|
||||
if (name)
|
||||
data = name;
|
||||
else
|
||||
if (params)
|
||||
data = params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eModel:
|
||||
{
|
||||
m_ModelName = data;
|
||||
//IStatObj *pObj = eng->MakeObject(data, NULL, 0, false, false);
|
||||
//m_pBuffer = pObj->GetLeafBuffer();
|
||||
}
|
||||
break;
|
||||
|
||||
case eStartRadius:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing StartRadius argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fStartRadius = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eEndRadius:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing EndRadius argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fEndRadius = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eLightStyle:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing LightStyle argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_LightStyle = shGetInt(data);
|
||||
break;
|
||||
|
||||
case eLength:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing Length argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fLength = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eStartColor:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing StartColor argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
shGetColor(data, m_StartColor);
|
||||
break;
|
||||
|
||||
case eEndColor:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing EndColor argument for Beam Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
shGetColor(data, m_EndColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_ModelName.c_str()[0])
|
||||
return false;
|
||||
SShaderParam *sp;
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "origlength");
|
||||
sp->m_Type = eType_FLOAT;
|
||||
sp->m_Value.m_Float = 10.0f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "origwidth");
|
||||
sp->m_Type = eType_FLOAT;
|
||||
sp->m_Value.m_Float = 1.0f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "startradius");
|
||||
sp->m_Type = eType_FLOAT;
|
||||
sp->m_Value.m_Float = 0.1f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "endradius");
|
||||
sp->m_Type = eType_FLOAT;
|
||||
sp->m_Value.m_Float = 1.0f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "startcolor");
|
||||
sp->m_Type = eType_FCOLOR;
|
||||
sp->m_Value.m_Color[0] = 1.0f;
|
||||
sp->m_Value.m_Color[1] = 1.0f;
|
||||
sp->m_Value.m_Color[2] = 1.0f;
|
||||
sp->m_Value.m_Color[3] = 1.0f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
sp = new SShaderParam;
|
||||
strcpy(sp->m_Name, "endcolor");
|
||||
sp->m_Type = eType_FCOLOR;
|
||||
sp->m_Value.m_Color[0] = 1.0f;
|
||||
sp->m_Value.m_Color[1] = 1.0f;
|
||||
sp->m_Value.m_Color[2] = 1.0f;
|
||||
sp->m_Value.m_Color[3] = 0.1f;
|
||||
m_ShaderParams.AddElem(sp);
|
||||
|
||||
return true;
|
||||
}
|
||||
50
RenderDll/Common/RendElements/CREBeam.h
Normal file
50
RenderDll/Common/RendElements/CREBeam.h
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
#ifndef __CREBEAM_H__
|
||||
#define __CREBEAM_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
|
||||
class CREBeam : public CRendElement
|
||||
{
|
||||
public:
|
||||
struct CLeafBuffer * m_pBuffer;
|
||||
float m_fFogScale;
|
||||
TArray<SShaderParam *> m_ShaderParams;
|
||||
|
||||
CFColor m_StartColor;
|
||||
CFColor m_EndColor;
|
||||
float m_fStartRadius;
|
||||
float m_fEndRadius;
|
||||
int m_LightStyle;
|
||||
float m_fLength;
|
||||
float m_fLengthScale;
|
||||
float m_fWidthScale;
|
||||
string m_ModelName;
|
||||
|
||||
public:
|
||||
CREBeam()
|
||||
{
|
||||
mfSetType(eDATA_Beam);
|
||||
m_fFogScale = 0;
|
||||
m_pBuffer = NULL;
|
||||
m_LightStyle = 0;
|
||||
m_fLength = 1.0f;
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
virtual ~CREBeam()
|
||||
{
|
||||
for (int i=0; i<m_ShaderParams.Num(); i++)
|
||||
{
|
||||
SShaderParam *pr = m_ShaderParams[i];
|
||||
SAFE_DELETE(pr);
|
||||
}
|
||||
m_ShaderParams.Free();
|
||||
}
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
};
|
||||
|
||||
#endif // __CREBEAM_H__
|
||||
157
RenderDll/Common/RendElements/CREClientPoly.cpp
Normal file
157
RenderDll/Common/RendElements/CREClientPoly.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/*=============================================================================
|
||||
CClientPoly.cpp : implementation of Client polygons RE.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
|
||||
TArray<CREClientPoly *> CREClientPoly::mPolysStorage[4];
|
||||
|
||||
CRendElement *CREClientPoly::mfCopyConstruct(void)
|
||||
{
|
||||
CREClientPoly *cp = new CREClientPoly;
|
||||
*cp = *this;
|
||||
return cp;
|
||||
}
|
||||
|
||||
float CREClientPoly::mfDistanceToCameraSquared(const CCObject & thisObject)
|
||||
{
|
||||
CRenderer *rd = gRenDev;
|
||||
|
||||
if (m_fDistance >= 0)
|
||||
return m_fDistance;
|
||||
|
||||
Vec3d vMid;
|
||||
vMid.Set(0,0,0);
|
||||
SColorVert *tv = mVerts;
|
||||
for (int i=0; i<mNumVerts; i++, tv++)
|
||||
{
|
||||
vMid += tv->vert;
|
||||
}
|
||||
vMid /= (float)mNumVerts;
|
||||
|
||||
vMid += thisObject.GetTranslation();
|
||||
|
||||
Vec3d Delta = rd->m_RP.m_ViewOrg - vMid;
|
||||
float fDist = GetLengthSquared(Delta);
|
||||
m_fDistance = fDist;
|
||||
|
||||
return fDist;
|
||||
}
|
||||
|
||||
void CREClientPoly::mfPrepare(void)
|
||||
{
|
||||
CRenderer *rd = gRenDev;
|
||||
SShader *ef = rd->m_RP.m_pShader;
|
||||
byte *inds;
|
||||
int i, n;
|
||||
SColorVert *tv;
|
||||
|
||||
CREClientPoly::mRS.NumRendPolys++;
|
||||
|
||||
{
|
||||
//PROFILE_FRAME_TOTAL(Mesh_REPrepare_Flush3DPoly);
|
||||
rd->EF_CheckOverflow(mNumVerts, mNumIndices, this);
|
||||
}
|
||||
|
||||
{
|
||||
//PROFILE_FRAME_TOTAL(Mesh_REPrepare_3DPoly);
|
||||
|
||||
int savev = rd->m_RP.m_RendNumVerts;
|
||||
int savei = rd->m_RP.m_RendNumIndices;
|
||||
|
||||
inds = mIndices;
|
||||
n = rd->m_RP.m_RendNumVerts;
|
||||
ushort *dinds = &rd->m_RP.m_RendIndices[rd->m_RP.m_RendNumIndices];
|
||||
for (i=0; i<mNumIndices; i++, dinds++, inds++)
|
||||
{
|
||||
*dinds = *inds+n;
|
||||
}
|
||||
rd->m_RP.m_RendNumIndices += i;
|
||||
|
||||
byte *OffsT, *OffsD;
|
||||
tv = mVerts;
|
||||
UPipeVertex ptr = rd->m_RP.m_NextPtr;
|
||||
switch(rd->m_RP.m_CurVFormat)
|
||||
{
|
||||
case VERTEX_FORMAT_P3F_COL4UB_TEX2F:
|
||||
OffsT = rd->m_RP.m_OffsT + ptr.PtrB;
|
||||
OffsD = rd->m_RP.m_OffsD + ptr.PtrB;
|
||||
for (i=0; i<mNumVerts; i++, tv++, ptr.PtrB+=rd->m_RP.m_Stride, OffsT+=rd->m_RP.m_Stride, OffsD+=rd->m_RP.m_Stride)
|
||||
{
|
||||
*(Vec3 *)ptr.PtrB = tv->vert;
|
||||
*(float *)(OffsT) = tv->dTC[0];
|
||||
*(float *)(OffsT+4) = tv->dTC[1];
|
||||
*(uint *)OffsD = tv->color.dcolor;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
if (rd->m_RP.m_OffsD && gbRgb)
|
||||
{
|
||||
OffsD = rd->m_RP.m_OffsD + rd->m_RP.m_NextPtr.PtrB;
|
||||
for (i=0; i<mNumVerts; i++, OffsD+=rd->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(OffsD) = COLCONV(*(uint *)(OffsD));
|
||||
}
|
||||
}
|
||||
|
||||
gRenDev->m_RP.m_NextPtr = ptr;
|
||||
gRenDev->m_RP.m_RendNumVerts += mNumVerts;
|
||||
|
||||
CREClientPoly::mRS.NumVerts += gRenDev->m_RP.m_RendNumVerts - savev;
|
||||
CREClientPoly::mRS.NumIndices += gRenDev->m_RP.m_RendNumIndices - savei;
|
||||
}
|
||||
}
|
||||
|
||||
bool CREClientPoly::mfCullBox(Vec3d& vmin, Vec3d& vmax)
|
||||
{
|
||||
CREClientPoly::mRS.NumOccPolys++;
|
||||
|
||||
//if(gfCullBox(vmin, vmax))
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
|
||||
SClientPolyStat CREClientPoly::mRS;
|
||||
|
||||
void CREClientPoly::mfPrintStat()
|
||||
{
|
||||
/* char str[1024];
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Indices: %i\n", mRS.NumIndices);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Verts: %i\n", mRS.NumVerts);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Render Client Polys: %i\n", mRS.NumRendPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Occluded Client Polys: %i\n", mRS.NumOccPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
gRenDev->mfPrintString ("\nClient Polygons status info:\n", PS_TRANSPARENT | PS_UP);*/
|
||||
}
|
||||
54
RenderDll/Common/RendElements/CREClientPoly.h
Normal file
54
RenderDll/Common/RendElements/CREClientPoly.h
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
#ifndef __CRECLIENTPOLY_H__
|
||||
#define __CRECLIENTPOLY_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
struct SClientPolyStat
|
||||
{
|
||||
int NumOccPolys;
|
||||
int NumRendPolys;
|
||||
int NumVerts;
|
||||
int NumIndices;
|
||||
};
|
||||
|
||||
//#define MAX_CLIENTPOLY_VERTS 16
|
||||
#define MAX_CLIENTPOLY_VERTS 32
|
||||
|
||||
class CREClientPoly : public CRendElement
|
||||
{
|
||||
public:
|
||||
SShader *mEf;
|
||||
int m_nFogID;
|
||||
short mNumVerts;
|
||||
short mNumIndices;
|
||||
CCObject *m_pObject;
|
||||
SColorVert mVerts[MAX_CLIENTPOLY_VERTS];
|
||||
byte mIndices[(MAX_CLIENTPOLY_VERTS-2)*3];
|
||||
float m_fDistance;
|
||||
|
||||
static SClientPolyStat mRS;
|
||||
static void mfPrintStat();
|
||||
|
||||
public:
|
||||
CREClientPoly()
|
||||
{
|
||||
mfSetType(eDATA_ClientPoly);
|
||||
mNumVerts = 0;
|
||||
mEf = NULL;
|
||||
m_pObject = NULL;
|
||||
mfSetFlags(FCEF_TRANSFORM | FCEF_NEEDFILLBUF);
|
||||
}
|
||||
|
||||
virtual ~CREClientPoly() {};
|
||||
|
||||
virtual void mfPrepare();
|
||||
|
||||
bool mfCullBox(Vec3d& vmin, Vec3d& vmax);
|
||||
float mfDistanceToCameraSquared(const CCObject & thisObject);
|
||||
virtual CRendElement *mfCopyConstruct(void);
|
||||
|
||||
static TArray<CREClientPoly *> mPolysStorage[4];
|
||||
};
|
||||
|
||||
#endif // __CRECLIENTPOLY_H__
|
||||
120
RenderDll/Common/RendElements/CREClientPoly2D.cpp
Normal file
120
RenderDll/Common/RendElements/CREClientPoly2D.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*=============================================================================
|
||||
CClientPoly2D.cpp : implementation of 2D Client polygons RE.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
|
||||
TArray<CREClientPoly2D *> CREClientPoly2D::mPolysStorage;
|
||||
|
||||
CRendElement *CREClientPoly2D::mfCopyConstruct(void)
|
||||
{
|
||||
CREClientPoly2D *cp = new CREClientPoly2D;
|
||||
*cp = *this;
|
||||
return cp;
|
||||
}
|
||||
|
||||
void CREClientPoly2D::mfPrepare(void)
|
||||
{
|
||||
CRenderer *rd = gRenDev;
|
||||
SShader *ef = rd->m_RP.m_pShader;
|
||||
byte *inds;
|
||||
int i, n;
|
||||
SColorVert2D *tv;
|
||||
|
||||
CREClientPoly2D::mRS.NumRendPolys++;
|
||||
|
||||
int savev = rd->m_RP.m_RendNumVerts;
|
||||
int savei = rd->m_RP.m_RendNumIndices;
|
||||
|
||||
rd->EF_CheckOverflow(mNumVerts, mNumIndices/3, this);
|
||||
|
||||
rd->m_RP.m_FlagsPerFlush |= RBSI_DRAWAS2D;
|
||||
|
||||
inds = mIndices;
|
||||
n = rd->m_RP.m_RendNumVerts;
|
||||
ushort *dinds = &rd->m_RP.m_RendIndices[gRenDev->m_RP.m_RendNumIndices];
|
||||
for (i=0; i<mNumIndices; i++, dinds++, inds++)
|
||||
{
|
||||
*dinds = *inds+n;
|
||||
}
|
||||
rd->m_RP.m_RendNumIndices += i;
|
||||
|
||||
tv = mVerts;
|
||||
UPipeVertex ptr = rd->m_RP.m_NextPtr;
|
||||
byte *OffsT, *OffsD;
|
||||
switch(rd->m_RP.m_CurVFormat)
|
||||
{
|
||||
case VERTEX_FORMAT_TRP3F_COL4UB_TEX2F:
|
||||
OffsT = rd->m_RP.m_OffsT + ptr.PtrB;
|
||||
OffsD = rd->m_RP.m_OffsD + ptr.PtrB;
|
||||
for (i=0; i<mNumVerts; i++, tv++, ptr.PtrB+=rd->m_RP.m_Stride, OffsT+=rd->m_RP.m_Stride, OffsD+=rd->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(ptr.PtrB+0) = tv->vert[0];
|
||||
*(float *)(ptr.PtrB+4) = tv->vert[1];
|
||||
*(float *)(ptr.PtrB+8) = 0.0f;
|
||||
*(float *)(ptr.PtrB+12) = 1.0f;
|
||||
*(float *)(OffsT) = tv->dTC[0];
|
||||
*(float *)(OffsT+4) = tv->dTC[1];
|
||||
*(uint *)OffsD = tv->color.dcolor;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (rd->m_RP.m_OffsD && gbRgb)
|
||||
{
|
||||
OffsD = rd->m_RP.m_OffsD + rd->m_RP.m_NextPtr.PtrB;
|
||||
for (i=0; i<mNumVerts; i++, OffsD+=rd->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(OffsD) = COLCONV(*(uint *)(OffsD));
|
||||
}
|
||||
}
|
||||
|
||||
rd->m_RP.m_NextPtr = ptr;
|
||||
rd->m_RP.m_RendNumVerts += mNumVerts;
|
||||
|
||||
CREClientPoly2D::mRS.NumVerts += rd->m_RP.m_RendNumVerts - savev;
|
||||
CREClientPoly2D::mRS.NumIndices += rd->m_RP.m_RendNumIndices - savei;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
|
||||
SClientPolyStat2D CREClientPoly2D::mRS;
|
||||
|
||||
void CREClientPoly2D::mfPrintStat()
|
||||
{
|
||||
/* char str[1024];
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Indices: %i\n", mRS.NumIndices);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Verts: %i\n", mRS.NumVerts);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Render Client Polys: %i\n", mRS.NumRendPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Occluded Client Polys: %i\n", mRS.NumOccPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
gRenDev->mfPrintString ("\nClient Polygons status info:\n", PS_TRANSPARENT | PS_UP);*/
|
||||
}
|
||||
47
RenderDll/Common/RendElements/CREClientPoly2D.h
Normal file
47
RenderDll/Common/RendElements/CREClientPoly2D.h
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
#ifndef __CRECLIENTPOLY2D_H__
|
||||
#define __CRECLIENTPOLY2D_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
struct SClientPolyStat2D
|
||||
{
|
||||
int NumOccPolys;
|
||||
int NumRendPolys;
|
||||
int NumVerts;
|
||||
int NumIndices;
|
||||
};
|
||||
|
||||
|
||||
class CREClientPoly2D : public CRendElement
|
||||
{
|
||||
public:
|
||||
SShader *mEf;
|
||||
SRenderShaderResources *m_pShaderResources;
|
||||
short mNumVerts;
|
||||
short mNumIndices;
|
||||
SColorVert2D mVerts[16];
|
||||
byte mIndices[(16-2)*3];
|
||||
|
||||
static SClientPolyStat2D mRS;
|
||||
static void mfPrintStat();
|
||||
|
||||
public:
|
||||
CREClientPoly2D()
|
||||
{
|
||||
mfSetType(eDATA_ClientPoly2D);
|
||||
mNumVerts = 0;
|
||||
mEf = NULL;
|
||||
m_pShaderResources = NULL;
|
||||
mfUpdateFlags(FCEF_TRANSFORM | FCEF_NEEDFILLBUF);
|
||||
}
|
||||
|
||||
virtual ~CREClientPoly2D() {};
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual CRendElement *mfCopyConstruct(void);
|
||||
|
||||
static TArray<CREClientPoly2D *> mPolysStorage;
|
||||
};
|
||||
|
||||
#endif // __CRECLIENTPOLY2D_H__
|
||||
17
RenderDll/Common/RendElements/CREDummy.cpp
Normal file
17
RenderDll/Common/RendElements/CREDummy.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
void CREDummy::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
bool CREDummy::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
240
RenderDll/Common/RendElements/CREFlares.cpp
Normal file
240
RenderDll/Common/RendElements/CREFlares.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/*=============================================================================
|
||||
CFlare.cpp : implementation of light coronas and flares RE.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
void CopyLightStyle(int dest, int src);
|
||||
|
||||
//===============================================================
|
||||
|
||||
CRendElement *CREFlareProp::mfCreateWorldRE(SShader *ef, SInpData *ds)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool CREFlareGeom::mfCullFlare(CCObject *obj, CREFlareProp *fp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
|
||||
// Parsing
|
||||
|
||||
bool CREFlareProp::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREFlare::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
char* name;
|
||||
long cmd;
|
||||
char *params;
|
||||
char *data;
|
||||
|
||||
enum {eMap = 1, eScale, eRGBStyle, eBlind, eColor, eDistFactor, eDistIntensityFactor, eMinLight, eSizeBlindScale, eSizeBlindBias, eIntensBlindScale, eIntensBlindBias, eLayer, eImportance, eFadeTime, eVisAreaScale};
|
||||
static tokenDesc commands[] =
|
||||
{
|
||||
{eRGBStyle, "RGBStyle"},
|
||||
{eScale, "Scale"},
|
||||
{eBlind, "Blind"},
|
||||
{eSizeBlindScale, "SizeBlindScale"},
|
||||
{eSizeBlindBias, "SizeBlindBias"},
|
||||
{eIntensBlindScale, "IntensBlindScale"},
|
||||
{eIntensBlindBias, "IntensBlindBias"},
|
||||
{eMinLight, "MinLight"},
|
||||
{eDistFactor, "DistFactor"},
|
||||
{eDistIntensityFactor, "DistIntensityFactor"},
|
||||
{eMap, "Map"},
|
||||
{eFadeTime, "FadeTime"},
|
||||
{eColor, "Color"},
|
||||
{eLayer, "Layer"},
|
||||
{eImportance, "Importance"},
|
||||
{eVisAreaScale, "VisAreaScale"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
CFColor col;
|
||||
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
||||
{
|
||||
data = NULL;
|
||||
if (name)
|
||||
data = name;
|
||||
else
|
||||
if (params)
|
||||
data = params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eMap:
|
||||
m_Map = (STexPic *)gRenDev->EF_LoadTexture(data, FT_NORESIZE, 0, eTT_Base);
|
||||
break;
|
||||
|
||||
case eColor:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing Color argument for Light Stage in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
shGetColor(data, m_fColor);
|
||||
break;
|
||||
|
||||
case eRGBStyle:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing RgbStyle argument for Light Stage in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
if (!stricmp(data, "Poly"))
|
||||
m_eLightRGB = eLIGHT_Poly;
|
||||
else
|
||||
if (!stricmp(data, "Identity"))
|
||||
m_eLightRGB = eLIGHT_Identity;
|
||||
else
|
||||
if (!strnicmp(data, "FromObj", 7) || !stricmp(data, "FromLight"))
|
||||
m_eLightRGB = eLIGHT_Object;
|
||||
else
|
||||
if (!stricmp(data, "LightStyle"))
|
||||
{
|
||||
m_eLightRGB = eLIGHT_Style;
|
||||
m_Color = CFColor(1.0f);
|
||||
if (!params || !params[0])
|
||||
{
|
||||
Warning( 0,0,"missing RgbStyle LightStyle value in Shader '%s' (use 0)\n", ef->m_Name.c_str());
|
||||
m_LightStyle = 0;
|
||||
}
|
||||
else
|
||||
m_LightStyle = shGetInt(params);
|
||||
}
|
||||
else
|
||||
if (!stricmp(data, "Fixed"))
|
||||
{
|
||||
m_eLightRGB = eLIGHT_Fixed;
|
||||
if (!params || !params[0])
|
||||
{
|
||||
Warning( 0,0,"missing RgbStyle Fixed value in Shader '%s' (use 1.0)\n", ef->m_Name.c_str());
|
||||
m_Color = CFColor(1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFColor col;
|
||||
shGetColor(params, col);
|
||||
m_Color = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_eLightRGB = eLIGHT_Identity;
|
||||
break;
|
||||
|
||||
case eScale:
|
||||
if (!name)
|
||||
m_fScaleCorona = shGetFloat(data);
|
||||
else
|
||||
{
|
||||
TArray<SParam> Params;
|
||||
gRenDev->m_cEF.mfCompileParam(params, ef, &Params);
|
||||
if (Params.Num())
|
||||
m_pScaleCoronaParams = Params[0].m_Comps[0];
|
||||
}
|
||||
break;
|
||||
|
||||
case eBlind:
|
||||
m_bBlind = true;
|
||||
break;
|
||||
|
||||
case eImportance:
|
||||
m_Importance = shGetInt(data);
|
||||
break;
|
||||
|
||||
case eFadeTime:
|
||||
m_fFadeTime = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eSizeBlindScale:
|
||||
m_fSizeBlindScale = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eSizeBlindBias:
|
||||
m_fSizeBlindBias = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eIntensBlindScale:
|
||||
m_fIntensBlindScale = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eIntensBlindBias:
|
||||
m_fIntensBlindBias = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eMinLight:
|
||||
m_fMinLight = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eDistFactor:
|
||||
m_fDistSizeFactor = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eVisAreaScale:
|
||||
m_fVisAreaScale = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eDistIntensityFactor:
|
||||
m_fDistIntensityFactor = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eLayer:
|
||||
{
|
||||
if (!m_Pass)
|
||||
m_Pass = new SShaderPassHW;
|
||||
gRenDev->m_cEF.mfCompileLayer(ef, 0, params, m_Pass);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CREFlare::mfPrepare(void)
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
|
||||
switch(m_eLightRGB)
|
||||
{
|
||||
case eLIGHT_Identity:
|
||||
m_Color = CFColor(1.0f);
|
||||
break;
|
||||
case eLIGHT_Style:
|
||||
{
|
||||
if (m_LightStyle>=0 && m_LightStyle<CLightStyle::m_LStyles.Num() && CLightStyle::m_LStyles[m_LightStyle])
|
||||
{
|
||||
CLightStyle *ls = CLightStyle::m_LStyles[m_LightStyle];
|
||||
ls->mfUpdate(gRenDev->m_RP.m_RealTime);
|
||||
m_Color = m_fColor * ls->m_fIntensity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eLIGHT_Object:
|
||||
if (gRenDev->m_RP.m_pCurObject)
|
||||
m_Color = gRenDev->m_RP.m_pCurObject->m_Color;
|
||||
else
|
||||
m_Color = CFColor(1.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
190
RenderDll/Common/RendElements/CREFlares.h
Normal file
190
RenderDll/Common/RendElements/CREFlares.h
Normal file
@@ -0,0 +1,190 @@
|
||||
|
||||
#ifndef __CREFLARES_H__
|
||||
#define __CREFLARES_H__
|
||||
|
||||
//=================================================
|
||||
// Flares
|
||||
|
||||
struct SFlareFrame
|
||||
{
|
||||
int mFrame;
|
||||
float mDecayTime;
|
||||
bool mbVis;
|
||||
int mX;
|
||||
int mY;
|
||||
float mDepth;
|
||||
CFColor mColor;
|
||||
float mScale;
|
||||
};
|
||||
|
||||
class CREFlareProp;
|
||||
|
||||
class CREFlareGeom : public CRendElement
|
||||
{
|
||||
friend class CRender3D;
|
||||
|
||||
public:
|
||||
SFlareFrame mFlareFr[8];
|
||||
CFColor mColor;
|
||||
Vec3d mNormal;
|
||||
int mLightStyle;
|
||||
int mDLightStyle;
|
||||
float mBreakTime;
|
||||
float mEndBreakTime;
|
||||
|
||||
float mfGetScale(float rtime)
|
||||
{
|
||||
float scale = 1.0f;
|
||||
|
||||
if (mBreakTime && rtime+0.01>=mBreakTime && mEndBreakTime>rtime)
|
||||
{
|
||||
float time = rtime - mBreakTime;
|
||||
|
||||
if (time<0.25)
|
||||
{
|
||||
scale = 1 - time*4;
|
||||
}
|
||||
else
|
||||
{
|
||||
time = mEndBreakTime - rtime;
|
||||
if (time<1)
|
||||
scale= 1 - time;
|
||||
else
|
||||
scale = 0;
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
CREFlareGeom()
|
||||
{
|
||||
mfSetType(eDATA_FlareGeom);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
virtual ~CREFlareGeom()
|
||||
{
|
||||
}
|
||||
|
||||
void mfCheckVis(CFColor &col, CCObject *obj);
|
||||
bool mfCullFlare(CCObject *obj, CREFlareProp *fp);
|
||||
};
|
||||
|
||||
enum ELightRGB
|
||||
{
|
||||
eLIGHT_Identity,
|
||||
eLIGHT_Fixed,
|
||||
eLIGHT_Poly,
|
||||
eLIGHT_Style,
|
||||
eLIGHT_Object,
|
||||
};
|
||||
|
||||
enum EEmitLight
|
||||
{
|
||||
eEMIT_Poly,
|
||||
eEMIT_Point,
|
||||
};
|
||||
|
||||
|
||||
class CREFlareProp : public CRendElement
|
||||
{
|
||||
friend class CRender3D;
|
||||
|
||||
public:
|
||||
SShader *FlareShader;
|
||||
ELightRGB eLightRGB;
|
||||
float LightColorScale;
|
||||
CFColor LightColor;
|
||||
int LightStyle;
|
||||
float offsLight;
|
||||
EEmitLight eLightEmit;
|
||||
|
||||
CREFlareProp()
|
||||
{
|
||||
mfSetType(eDATA_FlareProp);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
LightColorScale = 1;
|
||||
eLightEmit = eEMIT_Point;
|
||||
LightStyle = 0;
|
||||
FlareShader = 0;
|
||||
eLightRGB = eLIGHT_Identity;
|
||||
}
|
||||
virtual ~CREFlareProp()
|
||||
{
|
||||
}
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
virtual CRendElement *mfCreateWorldRE(SShader *ef, SInpData *ds);
|
||||
};
|
||||
|
||||
|
||||
class CREFlare : public CRendElement
|
||||
{
|
||||
friend class CRender3D;
|
||||
friend class CGLRenderer;
|
||||
|
||||
public:
|
||||
Vec3d mNormal;
|
||||
float m_fScaleCorona;
|
||||
SParamComp *m_pScaleCoronaParams;
|
||||
float m_fMinLight;
|
||||
float m_fDistSizeFactor;
|
||||
float m_fDistIntensityFactor;
|
||||
bool m_bBlind;
|
||||
float m_fSizeBlindBias;
|
||||
float m_fSizeBlindScale;
|
||||
float m_fIntensBlindBias;
|
||||
float m_fIntensBlindScale;
|
||||
float m_fFadeTime;
|
||||
float m_fVisAreaScale;
|
||||
STexPic *m_Map;
|
||||
ELightRGB m_eLightRGB;
|
||||
int m_LightStyle;
|
||||
CFColor m_fColor;
|
||||
int m_UpdateFrame;
|
||||
int m_nFrameQuery;
|
||||
SShaderPassHW *m_Pass;
|
||||
int m_Importance;
|
||||
|
||||
CREFlare()
|
||||
{
|
||||
mfSetType(eDATA_Flare);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
m_Map = NULL;
|
||||
m_fMinLight = 0.0f;
|
||||
m_eLightRGB = eLIGHT_Identity;
|
||||
m_fColor = Col_White;
|
||||
m_UpdateFrame = -1;
|
||||
m_fDistSizeFactor = 1.0f;
|
||||
m_fDistIntensityFactor = 1.0f;
|
||||
m_fSizeBlindBias = 0;
|
||||
m_nFrameQuery = -1;
|
||||
m_fSizeBlindScale = 1.0f;
|
||||
m_fIntensBlindBias = 0;
|
||||
m_fIntensBlindScale = 1.0f;
|
||||
m_fVisAreaScale = 1.0f;
|
||||
m_fFadeTime = -1.0f;
|
||||
m_bBlind = false;
|
||||
m_fScaleCorona = 0.6f;
|
||||
m_pScaleCoronaParams = NULL;
|
||||
m_Pass = NULL;
|
||||
m_Importance = 1;
|
||||
}
|
||||
virtual ~CREFlare()
|
||||
{
|
||||
if (m_Map)
|
||||
{
|
||||
m_Map->Release(false);
|
||||
m_Map = NULL;
|
||||
}
|
||||
SAFE_DELETE(m_Pass);
|
||||
}
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
virtual void mfPrepare(void);
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
|
||||
void mfDrawCorona(SShader *ef, CFColor &col);
|
||||
void mfDrawFlares(SShader *ef, CFColor &col);
|
||||
bool mfCheckVis(CCObject *obj);
|
||||
};
|
||||
|
||||
#endif // __CREFLARES_H__
|
||||
17
RenderDll/Common/RendElements/CREFlashBang.cpp
Normal file
17
RenderDll/Common/RendElements/CREFlashBang.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
#if !defined(LINUX)
|
||||
|
||||
void CREFlashBang::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_FlagsPerFlush |= RBSI_DRAWAS2D;
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
#endif // !defined(LINUX)
|
||||
24
RenderDll/Common/RendElements/CREGlare.cpp
Normal file
24
RenderDll/Common/RendElements/CREGlare.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
void CREGlare:: mfInit()
|
||||
{
|
||||
m_GlareWidth = 128;
|
||||
m_GlareHeight = 128;
|
||||
m_fGlareAmount=0;
|
||||
|
||||
mfSetType(eDATA_Glare);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
|
||||
void CREGlare::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 4;
|
||||
gRenDev->m_RP.m_FirstVertex = 0;
|
||||
}
|
||||
|
||||
39
RenderDll/Common/RendElements/CREGlare.h
Normal file
39
RenderDll/Common/RendElements/CREGlare.h
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#ifndef __CREGLARE_H__
|
||||
#define __CREGLARE_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
struct SByteColor
|
||||
{
|
||||
byte r,g,b,a;
|
||||
};
|
||||
|
||||
struct SLongColor
|
||||
{
|
||||
unsigned long r,g,b,a;
|
||||
};
|
||||
|
||||
class CREGlare : public CRendElement
|
||||
{
|
||||
public:
|
||||
int m_GlareWidth;
|
||||
int m_GlareHeight;
|
||||
float m_fGlareAmount;
|
||||
|
||||
public:
|
||||
CREGlare()
|
||||
{
|
||||
mfInit();
|
||||
}
|
||||
void mfInit();
|
||||
|
||||
virtual ~CREGlare()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
};
|
||||
|
||||
#endif // __CREGLARE_H__
|
||||
43
RenderDll/Common/RendElements/CREHDRProcess.cpp
Normal file
43
RenderDll/Common/RendElements/CREHDRProcess.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
=======================================================================
|
||||
FILE : CREHDRProcess.cpp
|
||||
DESC : HDR processing render element
|
||||
PROJ : Crytek Engine
|
||||
CODER: Andrey Honich
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
|
||||
// constructor/destructor
|
||||
CREHDRProcess::CREHDRProcess()
|
||||
{
|
||||
// setup screen process renderer type
|
||||
mfSetType(eDATA_HDRProcess);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
CREHDRProcess::~CREHDRProcess()
|
||||
{
|
||||
};
|
||||
|
||||
// prepare screen processing
|
||||
void CREHDRProcess:: mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_FlagsPerFlush |= RBSI_DRAWAS2D;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
void CREHDRProcess::mfReset()
|
||||
{
|
||||
}
|
||||
|
||||
void CREHDRProcess::mfActivate(int iProcess)
|
||||
{
|
||||
}
|
||||
39
RenderDll/Common/RendElements/CREHDRProcess.h
Normal file
39
RenderDll/Common/RendElements/CREHDRProcess.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
=====================================================================
|
||||
FILE : CREHDRProcess.h
|
||||
DESC : HDR processing render element
|
||||
PROJ : Crytek Engine
|
||||
CODER: Andrey Honich
|
||||
|
||||
=====================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CREHDRPROCESS_H__
|
||||
#define __CREHDRPROCESS_H__
|
||||
|
||||
|
||||
// screen processing render element
|
||||
class CREHDRProcess : public CRendElement
|
||||
{
|
||||
friend class CD3D9Renderer;
|
||||
friend class CGLRenderer;
|
||||
|
||||
public:
|
||||
|
||||
// constructor/destructor
|
||||
CREHDRProcess();
|
||||
|
||||
virtual ~CREHDRProcess();
|
||||
|
||||
// prepare screen processing
|
||||
virtual void mfPrepare();
|
||||
// render screen processing
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
|
||||
// begin screen processing
|
||||
virtual void mfActivate(int iProcess);
|
||||
// reset
|
||||
virtual void mfReset(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
31
RenderDll/Common/RendElements/CREHeat.h
Normal file
31
RenderDll/Common/RendElements/CREHeat.h
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
#ifndef __CREHEAT_H__
|
||||
#define __CREHEAT_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
|
||||
class CREHeat : public CRendElement
|
||||
{
|
||||
public:
|
||||
int m_HeatWidth;
|
||||
int m_HeatHeight;
|
||||
|
||||
public:
|
||||
CREHeat()
|
||||
{
|
||||
m_HeatWidth = CRenderer::CV_r_heatsize;
|
||||
m_HeatHeight = CRenderer::CV_r_heatsize;
|
||||
mfSetType(eDATA_Heat);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
virtual ~CREHeat()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfDraw(SShader *ef, SShadeLayer *sfm);
|
||||
};
|
||||
|
||||
#endif // __CREHEAT_H__
|
||||
96
RenderDll/Common/RendElements/CREMotionBlur.cpp
Normal file
96
RenderDll/Common/RendElements/CREMotionBlur.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#if !defined(LINUX)
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "RendElement.h"
|
||||
#include "CREMotionBlur.h"
|
||||
|
||||
#ifdef OPENGL
|
||||
#include "..\..\XRenderOGL\GL_Renderer.h"
|
||||
#endif
|
||||
|
||||
void CREMotionBlur::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_DynLMask |= m_DynMask;
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
bool CREMotionBlur::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
gRenDev->ResetToDefault();
|
||||
|
||||
static int counter=0;
|
||||
|
||||
gRenDev->EnableBlend(true);
|
||||
gRenDev->SetBlendMode();
|
||||
gRenDev->Set2DMode(true,100,100);
|
||||
gRenDev->EnableDepthWrites(false);
|
||||
gRenDev->EnableDepthTest(false);
|
||||
|
||||
for(int pass=-1; pass>-16 ; pass--)
|
||||
{
|
||||
if(!sfm->m_TUnits[0]->mfSetTexture(counter+pass))
|
||||
break;
|
||||
|
||||
gRenDev->SetEnviMode(R_MODE_MODULATE);
|
||||
gRenDev->SetMaterialColor(1,1,1,1.f/(float)fabs(pass+1));
|
||||
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
100, 100, 0, 1,1.f-1,
|
||||
100, 0, 0, 1,1.f-0,
|
||||
0, 100, 0, 0,1.f-1,
|
||||
0, 0, 0, 0,1.f-0,
|
||||
};
|
||||
|
||||
gRenDev->PushMatrix();
|
||||
gRenDev->TranslateMatrix(Vec3d(50,50,0));
|
||||
|
||||
// scale
|
||||
if(m_nEffectType == 1)
|
||||
{
|
||||
float scale = 1.0f-(float)fabs(pass/16.f)/3.0f;
|
||||
gRenDev->ScaleMatrix(scale,scale,0);
|
||||
}
|
||||
if(m_nEffectType == 2)
|
||||
{
|
||||
float scale = 1.f+(float)fabs(pass/16.f)/3;
|
||||
gRenDev->ScaleMatrix(scale,scale,0);
|
||||
}
|
||||
// rotation
|
||||
else if(m_nEffectType == 3)
|
||||
{
|
||||
gRenDev->RotateMatrix(Vec3d(0,0,pass&1 ? (float)fabs(pass/16.f)*4.0f : -(float)fabs(pass/16.f)*4.0f));
|
||||
}
|
||||
else if(m_nEffectType == 4)
|
||||
{
|
||||
gRenDev->RotateMatrix(Vec3d(0,0,pass&1 ? (float)fabs(pass/16.f)*40 : -(float)fabs(pass/16.f)*40));
|
||||
}
|
||||
// translation
|
||||
else if(m_nEffectType == 5)
|
||||
{
|
||||
gRenDev->TranslateMatrix(Vec3d(pass&1 ? (float)fabs(pass/16.f)*4.0f : -(float)fabs(pass/16.f)*4.0f,0,0));
|
||||
}
|
||||
else if(m_nEffectType == 6)
|
||||
{
|
||||
gRenDev->TranslateMatrix(Vec3d(0,pass&1 ? (float)fabs(pass/16.f)*4.0f : -(float)fabs(pass/16.f)*4.0f,0));
|
||||
}
|
||||
|
||||
gRenDev->TranslateMatrix(Vec3d(-50,-50,0));
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),4);
|
||||
gRenDev->PopMatrix();
|
||||
}
|
||||
|
||||
counter++;
|
||||
|
||||
gRenDev->Set2DMode(false,100,100);
|
||||
gRenDev->ResetToDefault();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !defined(LINUX)
|
||||
2060
RenderDll/Common/RendElements/CREOcLeaf.cpp
Normal file
2060
RenderDll/Common/RendElements/CREOcLeaf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
756
RenderDll/Common/RendElements/CREOcean.cpp
Normal file
756
RenderDll/Common/RendElements/CREOcean.cpp
Normal file
@@ -0,0 +1,756 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "CREOcean.h"
|
||||
#include "../NvTriStrip/NVTriStrip.h"
|
||||
#include "I3dengine.h"
|
||||
|
||||
SREOceanStats CREOcean::m_RS;
|
||||
CREOcean *CREOcean::m_pStaticOcean = NULL;
|
||||
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_HX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_HY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_NX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_NY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_DX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA( float, CREOcean::m_DY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
CREOcean::~CREOcean()
|
||||
{
|
||||
m_pStaticOcean = NULL;
|
||||
if (m_pBuffer)
|
||||
{
|
||||
gRenDev->ReleaseBuffer(m_pBuffer);
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
SAFE_DELETE_ARRAY(m_HMap);
|
||||
for (int i=0; i<NUM_LODS; i++)
|
||||
{
|
||||
m_pIndices[i].Free();
|
||||
}
|
||||
}
|
||||
|
||||
float CREOcean::GetWaterZElevation(float fX, float fY)
|
||||
{
|
||||
if (!m_HMap)
|
||||
return 0;
|
||||
CRenderer *r = gRenDev;
|
||||
I3DEngine *eng = (I3DEngine *)iSystem->GetI3DEngine();
|
||||
float fSize = (float)CRenderer::CV_r_oceansectorsize;
|
||||
float fHeightScale = (float)CRenderer::CV_r_oceanheightscale;
|
||||
float fWaterLevel = eng->GetWaterLevel();
|
||||
float fHScale = fabsf(gRenDev->m_RP.m_ViewOrg.z-fWaterLevel);
|
||||
float fMaxDist = eng->GetMaxViewDistance() / 1.0f;
|
||||
float fGrid = (float)OCEANGRID;
|
||||
|
||||
float fZH = GetHMap(fX, fY);
|
||||
if (fZH >= fWaterLevel)
|
||||
return fWaterLevel;
|
||||
|
||||
float fXPart = fX / fSize;
|
||||
float fYPart = fY / fSize;
|
||||
float fXLerp = (fXPart - (int)fXPart) * fGrid;
|
||||
float fYLerp = (fYPart - (int)fYPart) * fGrid;
|
||||
int nXMin = (int)fXLerp;
|
||||
int nXMax = nXMin+1;
|
||||
int nYMin = (int)fYLerp;
|
||||
int nYMax = nYMin+1;
|
||||
fXLerp = fXLerp - (int)fXLerp;
|
||||
fYLerp = fYLerp - (int)fYLerp;
|
||||
|
||||
if (fHScale < 5.0f)
|
||||
fHScale = LERP(0.1f, 0.5f, fHScale/5.0f);
|
||||
else
|
||||
if (fHScale < 20)
|
||||
fHScale = LERP(0.5f, 1.0f, (fHScale-5.0f)/15.0f);
|
||||
else
|
||||
fHScale = 1.0f;
|
||||
|
||||
float fZ00 = -m_HX[nYMin][nXMin] * fHScale;
|
||||
float fZ01 = -m_HX[nYMin][nXMax] * fHScale;
|
||||
float fZ10 = -m_HX[nYMax][nXMin] * fHScale;
|
||||
float fZ11 = -m_HX[nYMax][nXMax] * fHScale;
|
||||
float fZ0 = LERP(fZ00, fZ01, fXLerp);
|
||||
float fZ1 = LERP(fZ10, fZ11, fXLerp);
|
||||
float fZ = LERP(fZ0, fZ1, fYLerp);
|
||||
//fZ *= fHeightScale;
|
||||
|
||||
float fHeightDelta = fWaterLevel - fZH;
|
||||
fHeightScale *= CLAMP(fHeightDelta * 0.066f, 0, 1);
|
||||
|
||||
return fZ * fHeightScale + fWaterLevel;
|
||||
}
|
||||
|
||||
void CREOcean::PrepareHMap()
|
||||
{
|
||||
int nDim=0;
|
||||
|
||||
I3DEngine *eng = (I3DEngine *)iSystem->GetI3DEngine();
|
||||
m_nHMUnitSize = eng->GetHeightMapUnitSize();
|
||||
int nExp = 8;
|
||||
m_fExpandHMap = (float)nExp;
|
||||
m_fExpandHM = (float)m_nHMUnitSize * (float)nExp;
|
||||
m_fInvHMUnitSize = 1.0f / (float)m_nHMUnitSize;
|
||||
m_fTerrainSize = (float)eng->GetTerrainSize();
|
||||
eng->MakeUnderWaterSmoothHMap(m_nHMUnitSize);
|
||||
ushort *shm = eng->GetUnderWaterSmoothHMap(nDim);
|
||||
|
||||
if(!nDim)
|
||||
return; // terrain not present
|
||||
|
||||
float fWaterLevel = eng->GetWaterLevel();
|
||||
|
||||
if (m_HMap)
|
||||
delete [] m_HMap;
|
||||
int nDimO = nDim+nExp*2;
|
||||
m_nHMapSize = nDimO;
|
||||
m_HMap = new float [nDimO*nDimO];
|
||||
float f;
|
||||
for (int y=-nExp; y<nDim+nExp; y++)
|
||||
{
|
||||
for (int x=-nExp; x<nDim+nExp; x++)
|
||||
{
|
||||
if (x>0 && x<nDim-1 && y>0 && y<nDim-1)
|
||||
m_HMap[(y+nExp)*nDimO+x+nExp] = (float)shm[y*nDim+x] / 256.0f;
|
||||
else
|
||||
{
|
||||
int nX = x;
|
||||
int nY = y;
|
||||
float fLerpX = -1.0f;
|
||||
float fLerpY = -1.0f;
|
||||
|
||||
if (nX<=0)
|
||||
nX = 1;
|
||||
else
|
||||
if (nX>=nDim-1)
|
||||
nX = nDim-2;
|
||||
|
||||
if (nY<=0)
|
||||
nY = 1;
|
||||
else
|
||||
if (nY>=nDim-1)
|
||||
nY = nDim-2;
|
||||
|
||||
f = (float)shm[nY*nDim+nX] / 256.0f;
|
||||
|
||||
if (nX != x)
|
||||
fLerpX = 1.0f - fabsf((float)(nX-x)) / (float)(nExp+1);
|
||||
if (nY != y)
|
||||
fLerpY = 1.0f - fabsf((float)(nY-y)) / (float)(nExp+1);
|
||||
|
||||
float fX, fY;
|
||||
|
||||
if (fLerpX >= 0)
|
||||
fX = LERP(fWaterLevel/2.0f, f, fLerpX);
|
||||
if (fLerpY >= 0)
|
||||
fY = LERP(fWaterLevel/2.0f, f, fLerpY);
|
||||
if (fLerpX >= 0 && fLerpY >= 0)
|
||||
m_HMap[(y+nExp)*nDimO+x+nExp] = (fX + fY) / 2.0f;
|
||||
else
|
||||
if (fLerpX >= 0)
|
||||
m_HMap[(y+nExp)*nDimO+x+nExp] = fX;
|
||||
else
|
||||
if (fLerpY >= 0)
|
||||
m_HMap[(y+nExp)*nDimO+x+nExp] = fY;
|
||||
else
|
||||
m_HMap[(y+nExp)*nDimO+x+nExp] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::mfPrepare()
|
||||
{
|
||||
CRenderer *rd = gRenDev;
|
||||
|
||||
if (m_nFrameLoad != rd->m_nFrameLoad)
|
||||
{
|
||||
m_nFrameLoad = rd->m_nFrameLoad;
|
||||
PrepareHMap();
|
||||
}
|
||||
|
||||
rd->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
Update(rd->m_RP.m_RealTime * m_fSpeed);
|
||||
|
||||
double time0 = 0;
|
||||
ticks(time0);
|
||||
|
||||
I3DEngine *eng = (I3DEngine *)iSystem->GetI3DEngine();
|
||||
float fWaterLevel = eng->GetWaterLevel();
|
||||
float fHScale = fabsf(gRenDev->m_RP.m_ViewOrg.z-fWaterLevel);
|
||||
if (fHScale < 5.0f)
|
||||
fHScale = LERP(0.1f, 0.5f, fHScale/5.0f);
|
||||
else
|
||||
if (fHScale < 20)
|
||||
fHScale = LERP(0.5f, 1.0f, (fHScale-5.0f)/15.0f);
|
||||
else
|
||||
fHScale = 1.0f;
|
||||
m_MinBound.Set(9999.0f, 9999.0f, 9999.0f);
|
||||
m_MaxBound.Set(-9999.0f, -9999.0f, -9999.0f);
|
||||
|
||||
if (!m_pBuffer)
|
||||
m_pBuffer = gRenDev->CreateBuffer((OCEANGRID+1)*(OCEANGRID+1), VERTEX_FORMAT_P3F_N, "Ocean", true);
|
||||
rd->UpdateBuffer(m_pBuffer, NULL, 0, 0, 0, 1);
|
||||
|
||||
static const float fScale = 1.0f / (float)OCEANGRID;
|
||||
|
||||
struct_VERTEX_FORMAT_P3F_N *pVertices = (struct_VERTEX_FORMAT_P3F_N *)m_pBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
for(int vy=0; vy<OCEANGRID+1; vy++)
|
||||
{
|
||||
int y = vy & (OCEANGRID-1);
|
||||
for(int vx=0; vx<(OCEANGRID+1); vx++)
|
||||
{
|
||||
int x = vx & (OCEANGRID-1);
|
||||
m_Pos[vy][vx][0] = vx * fScale + m_DX[y][x] * m_fChoppyWaveFactor;
|
||||
m_Pos[vy][vx][1] = vy * fScale + m_DY[y][x] * m_fChoppyWaveFactor;
|
||||
pVertices->xyz.x = m_Pos[vy][vx][0];
|
||||
pVertices->xyz.y = m_Pos[vy][vx][1];
|
||||
float fZ = -m_HX[y][x] * fHScale;
|
||||
pVertices->xyz.z = fZ;
|
||||
m_MinBound.x = min(m_Pos[vy][vx][0], m_MinBound.x);
|
||||
m_MinBound.y = min(m_Pos[vy][vx][1], m_MinBound.y);
|
||||
m_MinBound.z = min(fZ, m_MinBound.z);
|
||||
|
||||
m_MaxBound.x = max(m_Pos[vy][vx][0], m_MaxBound.x);
|
||||
m_MaxBound.y = max(m_Pos[vy][vx][1], m_MaxBound.y);
|
||||
m_MaxBound.z = max(fZ, m_MaxBound.z);
|
||||
|
||||
m_Normals[vy][vx] = Vec3d(m_NX[y][x], m_NY[y][x], 64.0f);
|
||||
pVertices->normal = m_Normals[vy][vx];
|
||||
m_Normals[vy][vx].NormalizeFast();
|
||||
|
||||
pVertices++;
|
||||
}
|
||||
}
|
||||
unticks(time0);
|
||||
m_RS.m_StatsTimeUpdateVerts = (float)(time0*1000.0*g_SecondsPerCycle);
|
||||
|
||||
UpdateTexture();
|
||||
|
||||
rd->m_RP.m_pRE = this;
|
||||
rd->m_RP.m_RendNumIndices = 0;
|
||||
rd->m_RP.m_RendNumVerts = (OCEANGRID+1)*(OCEANGRID+1);
|
||||
rd->m_RP.m_FirstVertex = 0;
|
||||
}
|
||||
|
||||
int CREOcean::GetLOD(Vec3d camera, Vec3d pos)
|
||||
{
|
||||
float dist = (pos-camera).GetLength();
|
||||
dist /= CRenderer::CV_r_oceanloddist;
|
||||
|
||||
return (int)CLAMP(dist, 0.0f, (float)(NUM_LODS-1));
|
||||
}
|
||||
|
||||
void *CREOcean::mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags)
|
||||
{
|
||||
|
||||
switch(ePT)
|
||||
{
|
||||
case eSrcPointer_Vert:
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F_N *pVertices = (struct_VERTEX_FORMAT_P3F_N *)m_pBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
*Stride = sizeof(struct_VERTEX_FORMAT_P3F_N);
|
||||
return &pVertices->xyz.x;
|
||||
}
|
||||
case eSrcPointer_Normal:
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F_N *pVertices = (struct_VERTEX_FORMAT_P3F_N *)m_pBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
*Stride = sizeof(struct_VERTEX_FORMAT_P3F_N);
|
||||
return &pVertices->normal.x;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void CREOcean::GenerateGeometry()
|
||||
{
|
||||
m_pBuffer = gRenDev->CreateBuffer((OCEANGRID+1)*(OCEANGRID+1), VERTEX_FORMAT_P3F_N, "Ocean", true);
|
||||
|
||||
for (int lod=0; lod<NUM_LODS; lod++)
|
||||
{
|
||||
int nl = 1<<lod;
|
||||
// set indices
|
||||
int iIndex = 0;
|
||||
int yStep = (OCEANGRID+1) * nl;
|
||||
for(int a=0; a<(OCEANGRID+1)-1; a+=nl )
|
||||
{
|
||||
for(int i=0; i<(OCEANGRID+1); i+=nl, iIndex+=nl )
|
||||
{
|
||||
m_pIndices[lod].AddElem(iIndex);
|
||||
m_pIndices[lod].AddElem(iIndex + yStep);
|
||||
}
|
||||
|
||||
int iNextIndex = (a+nl) * (OCEANGRID+1);
|
||||
|
||||
if(a < (OCEANGRID+1)-1-nl)
|
||||
{
|
||||
m_pIndices[lod].AddElem(iIndex + yStep - nl);
|
||||
m_pIndices[lod].AddElem(iNextIndex);
|
||||
}
|
||||
iIndex = iNextIndex;
|
||||
}
|
||||
m_pIndices[lod].Shrink();
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::SmoothLods_r(SOceanSector *os, float fSize, int minLod)
|
||||
{
|
||||
if (os->m_Frame != gRenDev->m_cEF.m_Frame)
|
||||
return;
|
||||
if (os->nLod > minLod+1)
|
||||
{
|
||||
os->nLod = minLod+1;
|
||||
SOceanSector *osLeft;
|
||||
SOceanSector *osRight;
|
||||
SOceanSector *osTop;
|
||||
SOceanSector *osBottom;
|
||||
|
||||
// Left
|
||||
osLeft = GetSectorByPos(os->x-fSize, os->y, false);
|
||||
// Right
|
||||
osRight = GetSectorByPos(os->x+fSize, os->y, false);
|
||||
// Top
|
||||
osTop = GetSectorByPos(os->x, os->y-fSize, false);
|
||||
// Bottom
|
||||
osBottom = GetSectorByPos(os->x, os->y+fSize, false);
|
||||
if (osLeft)
|
||||
SmoothLods_r(osLeft, fSize, os->nLod);
|
||||
if (osRight)
|
||||
SmoothLods_r(osRight, fSize, os->nLod);
|
||||
if (osTop)
|
||||
SmoothLods_r(osTop, fSize, os->nLod);
|
||||
if (osBottom)
|
||||
SmoothLods_r(osBottom, fSize, os->nLod);
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::LinkVisSectors(float fSize)
|
||||
{
|
||||
for (int i=0; i<m_VisOceanSectors.Num(); i++)
|
||||
{
|
||||
SOceanSector *os = m_VisOceanSectors[i];
|
||||
SOceanSector *osLeft;
|
||||
SOceanSector *osRight;
|
||||
SOceanSector *osTop;
|
||||
SOceanSector *osBottom;
|
||||
|
||||
// Left
|
||||
osLeft = GetSectorByPos(os->x-fSize, os->y, false);
|
||||
// Right
|
||||
osRight = GetSectorByPos(os->x+fSize, os->y, false);
|
||||
// Top
|
||||
osTop = GetSectorByPos(os->x, os->y-fSize, false);
|
||||
// Bottom
|
||||
osBottom = GetSectorByPos(os->x, os->y+fSize, false);
|
||||
if (osLeft)
|
||||
SmoothLods_r(osLeft, fSize, os->nLod);
|
||||
if (osRight)
|
||||
SmoothLods_r(osRight, fSize, os->nLod);
|
||||
if (osTop)
|
||||
SmoothLods_r(osTop, fSize, os->nLod);
|
||||
if (osBottom)
|
||||
SmoothLods_r(osBottom, fSize, os->nLod);
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::PostLoad(unsigned long ulSeed, float fWindDirection, float fWindSpeed, float fWaveHeight, float fDirectionalDependence, float fChoppyWavesFactor, float fSuppressSmallWavesFactor)
|
||||
{
|
||||
m_fWindX = cry_cosf( fWindDirection );
|
||||
m_fWindY = cry_sinf( fWindDirection );
|
||||
m_fWindSpeed = fWindSpeed;
|
||||
m_fWaveHeight = fWaveHeight;
|
||||
m_fDirectionalDependence = fDirectionalDependence;
|
||||
m_fChoppyWaveFactor = fChoppyWavesFactor;
|
||||
m_fSuppressSmallWavesFactor = fSuppressSmallWavesFactor;
|
||||
|
||||
m_fLargestPossibleWave = m_fWindSpeed * m_fWindSpeed / m_fGravity;
|
||||
m_fSuppressSmallWaves = m_fLargestPossibleWave * m_fSuppressSmallWavesFactor;
|
||||
|
||||
// init H0
|
||||
CRERandom kRnd( ulSeed );
|
||||
float fOneBySqrtTwo = 1.0f / cry_sqrtf(2.0f);
|
||||
int i, j;
|
||||
for(j=-OCEANGRID/2; j<=OCEANGRID/2; j++)
|
||||
{
|
||||
int y = j + OCEANGRID/2;
|
||||
for(i=-OCEANGRID/2; i<=OCEANGRID/2; i++)
|
||||
{
|
||||
int x = i + OCEANGRID/2;
|
||||
float rndX = (float)kRnd.GetGauss();
|
||||
float rndY = (float)kRnd.GetGauss();
|
||||
rndX *= fOneBySqrtTwo * cry_sqrtf(PhillipsSpectrum(2.0f*PI*i, 2.0f*PI*j));
|
||||
rndY *= fOneBySqrtTwo * cry_sqrtf(PhillipsSpectrum(2.0f*PI*i, 2.0f*PI*j));
|
||||
|
||||
m_H0X[y][x] = rndX;
|
||||
m_H0Y[y][x] = rndY;
|
||||
}
|
||||
}
|
||||
|
||||
// precalc length of K
|
||||
for(j=-OCEANGRID/2; j<OCEANGRID/2; j++)
|
||||
{
|
||||
int y = j + OCEANGRID/2;
|
||||
for(i=-OCEANGRID/2; i<OCEANGRID/2; i++)
|
||||
{
|
||||
int x = i + OCEANGRID/2;
|
||||
float fKLength = cry_sqrtf(sqrf(2.0f*PI*i) + sqrf(2.0f*PI*j));
|
||||
if( fKLength < 1e-8f )
|
||||
fKLength = 1e-8f;
|
||||
m_aKScale[y][x] = 1.0f / fKLength;
|
||||
}
|
||||
}
|
||||
|
||||
// init angular frequencies
|
||||
for(j=-OCEANGRID/2; j<OCEANGRID/2; j++)
|
||||
{
|
||||
int y = j + OCEANGRID/2;
|
||||
for(i=-OCEANGRID/2; i<OCEANGRID/2; i++)
|
||||
{
|
||||
int x = i + OCEANGRID/2;
|
||||
float fKLength = cry_sqrtf(sqrf(2.0f*PI*i) + sqrf(2.0f*PI*j));
|
||||
m_aAngularFreq[y][x] = cry_sqrtf(m_fGravity * fKLength) * cry_tanhf(fKLength * m_fDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::FFT( int iDir, float* real, float* imag )
|
||||
{
|
||||
long nn,i,i1,j,k,i2,l,l1,l2;
|
||||
float c1,c2,treal,timag,t1,t2,u1,u2,z;
|
||||
|
||||
nn = OCEANGRID;
|
||||
|
||||
// Do the bit reversal
|
||||
i2 = nn >> 1;
|
||||
j = 0;
|
||||
for( i = 0; i < nn - 1; ++i )
|
||||
{
|
||||
if( i < j )
|
||||
{
|
||||
treal = real[ i ];
|
||||
timag = imag[ i ];
|
||||
real[ i ] = real[ j ];
|
||||
imag[ i ] = imag[ j ];
|
||||
real[ j ] = treal;
|
||||
imag[ j ] = timag;
|
||||
}
|
||||
|
||||
k = i2;
|
||||
while( k <= j )
|
||||
{
|
||||
j -= k;
|
||||
k >>= 1;
|
||||
}
|
||||
|
||||
j += k;
|
||||
}
|
||||
|
||||
// Compute the FFT
|
||||
c1 = -1.0f;
|
||||
c2 = 0.0f;
|
||||
l2 = 1;
|
||||
for(l=0; l<LOG_OCEANGRID; l++)
|
||||
{
|
||||
l1 = l2;
|
||||
l2 <<= 1;
|
||||
u1 = 1.0;
|
||||
u2 = 0.0;
|
||||
for( j = 0; j < l1; ++j )
|
||||
{
|
||||
for( i = j; i < nn; i += l2 )
|
||||
{
|
||||
i1 = i + l1;
|
||||
t1 = u1 * real[i1] - u2 * imag[i1];
|
||||
t2 = u1 * imag[i1] + u2 * real[i1];
|
||||
real[i1] = real[i] - t1;
|
||||
imag[i1] = imag[i] - t2;
|
||||
real[i] += t1;
|
||||
imag[i] += t2;
|
||||
}
|
||||
|
||||
z = u1 * c1 - u2 * c2;
|
||||
u2 = u1 * c2 + u2 * c1;
|
||||
u1 = z;
|
||||
}
|
||||
|
||||
c2 = crySqrtf(( 1.0f - c1 ) / 2.0f);
|
||||
|
||||
if( 1 == iDir )
|
||||
{
|
||||
c2 = -c2;
|
||||
}
|
||||
|
||||
c1 = crySqrtf(( 1.0f + c1 ) / 2.0f);
|
||||
}
|
||||
|
||||
// Scaling for forward transform
|
||||
if( 1 == iDir )
|
||||
{
|
||||
for(i=0; i<nn; ++i)
|
||||
{
|
||||
real[i] /= (float) nn;
|
||||
imag[i] /= (float) nn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FFTSSE_64(float* ar, float* ai);
|
||||
|
||||
void CREOcean::FFT2D(int iDir, float cmpX[OCEANGRID][OCEANGRID], float cmpY[OCEANGRID][OCEANGRID])
|
||||
{
|
||||
float real[OCEANGRID];
|
||||
float imag[OCEANGRID];
|
||||
|
||||
|
||||
#if !defined(_XBOX) && !defined(WIN64) && !defined(LINUX)
|
||||
// NOTE: AMD64 port: implement
|
||||
if ((g_CpuFlags & CPUF_SSE) && CRenderer::CV_r_sse && !(((int)&cmpX[0][0]) & 0xf) && !(((int)&cmpY[0][0]) & 0xf) && OCEANGRID == 64)
|
||||
{
|
||||
FFTSSE_64(&cmpY[0][0], &cmpX[0][0]);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int i, j;
|
||||
|
||||
// Transform the rows
|
||||
for(j=0; j<OCEANGRID; j++)
|
||||
{
|
||||
for(i=0; i<OCEANGRID; i++)
|
||||
{
|
||||
real[i] = cmpX[j][i];
|
||||
imag[i] = cmpY[j][i];
|
||||
}
|
||||
|
||||
FFT( iDir, real, imag );
|
||||
|
||||
for(i=0; i<OCEANGRID; i++)
|
||||
{
|
||||
cmpX[j][i] = real[i];
|
||||
cmpY[j][i] = imag[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the columns
|
||||
for(i=0; i<OCEANGRID; i++)
|
||||
{
|
||||
for(j=0; j<OCEANGRID; j++)
|
||||
{
|
||||
real[j] = cmpX[j][i];
|
||||
imag[j] = cmpY[j][i];
|
||||
}
|
||||
|
||||
FFT( iDir, real, imag );
|
||||
|
||||
for(j=0; j<OCEANGRID; j++)
|
||||
{
|
||||
cmpX[j][i] = real[j];
|
||||
cmpY[j][i] = imag[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CREOcean::Update( float fTime )
|
||||
{
|
||||
double time0 = 0;
|
||||
ticks(time0);
|
||||
|
||||
float fK = 2.0f * PI;
|
||||
for(int j=-OCEANGRID/2; j<OCEANGRID/2; j++)
|
||||
{
|
||||
int jn = j & (OCEANGRID-1);
|
||||
for(int i=-OCEANGRID/2; i<OCEANGRID/2; i++)
|
||||
{
|
||||
int x = i + OCEANGRID/2;
|
||||
int y = j + OCEANGRID/2;
|
||||
unsigned int val = (int)(m_aAngularFreq[y][x] * 1024.0f / (PI*2) * fTime);
|
||||
float fSin = gRenDev->m_RP.m_tSinTable[val&0x3ff];
|
||||
float fCos = gRenDev->m_RP.m_tSinTable[(val+512)&0x3ff];
|
||||
|
||||
int x1 = -i + OCEANGRID/2;
|
||||
int y1 = -j + OCEANGRID/2;
|
||||
|
||||
float hx = (m_H0X[y][x] + m_H0X[y1][x1]) * fCos -
|
||||
(m_H0Y[y][x] + m_H0Y[y1][x1]) * fSin;
|
||||
|
||||
float hy = (m_H0X[y][x] - m_H0X[y1][x1]) * fSin +
|
||||
(m_H0Y[y][x] - m_H0Y[y1][x1]) * fCos;
|
||||
|
||||
int in = i & (OCEANGRID-1);
|
||||
|
||||
// update height
|
||||
m_HX[jn][in] = hx;
|
||||
m_HY[jn][in] = hy;
|
||||
|
||||
// update normal
|
||||
float fKx = fK * i;
|
||||
float fKy = fK * j;
|
||||
m_NX[jn][in] = (-hy * fKx - hx * fKy);
|
||||
m_NY[jn][in] = ( hx * fKx - hy * fKy);
|
||||
|
||||
// update displacement vector for choppy waves
|
||||
fKx *= m_aKScale[y][x];
|
||||
fKy *= m_aKScale[y][x];
|
||||
m_DX[jn][in] = ( hy * fKx + hx * fKy);
|
||||
m_DY[jn][in] = (-hx * fKx + hy * fKy);
|
||||
}
|
||||
}
|
||||
unticks(time0);
|
||||
m_RS.m_StatsTimeFFTTable = (float)(time0*1000.0*g_SecondsPerCycle);
|
||||
|
||||
ticks(time0);
|
||||
FFT2D(-1, m_HX, m_HY);
|
||||
FFT2D(-1, m_NX, m_NY);
|
||||
FFT2D(-1, m_DX, m_DY);
|
||||
unticks(time0);
|
||||
m_RS.m_StatsTimeFFT = (float)(time0*1000.0*g_SecondsPerCycle);
|
||||
}
|
||||
|
||||
bool CREOcean::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
char* name;
|
||||
long cmd;
|
||||
char *params;
|
||||
char *data;
|
||||
|
||||
enum {eSeed = 1, eSpeed, eGravity, eDepth, eWindSpeed, eWindDirection, eWaveHeight, eDirectionalDependence, eChoppyWaveFactor, eSuppressSmallWavesFactor};
|
||||
static tokenDesc commands[] =
|
||||
{
|
||||
{eSpeed, "Speed"},
|
||||
{eGravity, "Gravity"},
|
||||
{eDepth, "Depth"},
|
||||
{eWindDirection, "WindDirection"},
|
||||
{eWindSpeed, "WindSpeed"},
|
||||
{eWaveHeight, "WaveHeight"},
|
||||
{eDirectionalDependence, "DirectionalDependence"},
|
||||
{eChoppyWaveFactor, "ChoppyWaveFactor"},
|
||||
{eSuppressSmallWavesFactor, "SuppressSmallWavesFactor"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
float fWindDirection = 90.0f;
|
||||
float fWindSpeed = m_fWindSpeed;
|
||||
float fWaveHeight = m_fWaveHeight;
|
||||
float fDirectionalDependence = m_fDirectionalDependence;
|
||||
float fChoppyWaveFactor = m_fChoppyWaveFactor;
|
||||
float fSuppressSmallWavesFactor = m_fSuppressSmallWavesFactor;
|
||||
m_fSpeed = 1.0f;
|
||||
m_fGravity = 9.81f;
|
||||
m_fDepth = 10;
|
||||
|
||||
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
||||
{
|
||||
data = NULL;
|
||||
if (name)
|
||||
data = name;
|
||||
else
|
||||
if (params)
|
||||
data = params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eGravity:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing Gravity argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fGravity = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eDepth:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing Depth argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fDepth = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eSpeed:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing Speed argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
m_fSpeed = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eWindDirection:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing WindDirection argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fWindDirection = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eWindSpeed:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing WindSpeed argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fWindSpeed = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eWaveHeight:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing WaveHeight argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fWaveHeight = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eDirectionalDependence:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing DirectionalDependence argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fDirectionalDependence = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eChoppyWaveFactor:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing ChoppyWaveFactor argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fChoppyWaveFactor = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eSuppressSmallWavesFactor:
|
||||
if (!data || !data[0])
|
||||
{
|
||||
Warning( 0,0,"missing SuppressSmallWavesFactor argument for Ocean Effect in Shader '%s'\n", ef->m_Name.c_str());
|
||||
break;
|
||||
}
|
||||
fSuppressSmallWavesFactor = shGetFloat(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PostLoad(4357, fWindDirection, fWindSpeed, fWaveHeight, fDirectionalDependence, fChoppyWaveFactor, fSuppressSmallWavesFactor);
|
||||
m_CustomTexBind[0] = 0;
|
||||
|
||||
#if !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
if (!m_VPs[OVP_NOHEIGHT])
|
||||
{
|
||||
m_VPs[OVP_NOHEIGHT] = CVProgram::mfForName("CGVProgOcean_NoHeight");
|
||||
m_VPs[OVP_NOHEIGHT_SPL] = CVProgram::mfForName("CGVProgOcean_NoHeight_Splash");
|
||||
|
||||
m_VPs[OVP_HEIGHT] = CVProgram::mfForName("CGVProgOcean");
|
||||
m_VPs[OVP_HEIGHT_SPL] = CVProgram::mfForName("CGVProgOcean_Splash");
|
||||
}
|
||||
if (!m_VPQ)
|
||||
m_VPQ = CVProgram::mfForName("CGVProgOcean_SL");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
471
RenderDll/Common/RendElements/CREOcean.h
Normal file
471
RenderDll/Common/RendElements/CREOcean.h
Normal file
@@ -0,0 +1,471 @@
|
||||
#ifndef _CREOCEAN_H_
|
||||
#define _CREOCEAN_H_
|
||||
|
||||
#include "../nvTriStrip/nvTriStrip.h"
|
||||
|
||||
struct SREOceanStats
|
||||
{
|
||||
float m_StatsTimeFFTTable;
|
||||
float m_StatsTimeFFT;
|
||||
float m_StatsTimeUpdateVerts;
|
||||
float m_StatsTimeTexUpdate;
|
||||
float m_StatsTimeRendOcean;
|
||||
int m_StatsAllocatedSectors;
|
||||
int m_StatsNumRendOceanSectors;
|
||||
};
|
||||
|
||||
#define OCEANPI 3.141592654f
|
||||
#define OCEANGRID 64
|
||||
#define LOG_OCEANGRID 6
|
||||
|
||||
#define NUM_LODS 5
|
||||
#define LOD_MASK 7
|
||||
#define LOD_LEFTSHIFT 3
|
||||
#define LOD_RIGHTSHIFT 4
|
||||
#define LOD_TOPSHIFT 5
|
||||
#define LOD_BOTTOMSHIFT 6
|
||||
|
||||
#define OSF_VISIBLE 1
|
||||
#define OSF_FIRSTTIME 2
|
||||
#define OSF_NEEDHEIGHTS 4
|
||||
#define OSF_LODUPDATED 8
|
||||
#define OSF_BLEND 0x10
|
||||
|
||||
#define OVP_NOHEIGHT 0
|
||||
#define OVP_NOHEIGHT_SPL 1
|
||||
#define OVP_HEIGHT 2
|
||||
#define OVP_HEIGHT_SPL 3
|
||||
#define NUM_OVP 4
|
||||
|
||||
#define NUM_OCEANVBS 8
|
||||
|
||||
struct SOceanSector
|
||||
{
|
||||
float x, y;
|
||||
int RenderState;
|
||||
int nLod;
|
||||
int m_Frame;
|
||||
int m_Flags;
|
||||
|
||||
SOceanSector ()
|
||||
{
|
||||
m_Flags = OSF_FIRSTTIME;
|
||||
m_Frame = -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct SOceanIndicies
|
||||
{
|
||||
float m_fLastAccess;
|
||||
int m_nInds;
|
||||
ushort *m_pIndicies;
|
||||
TArray<SPrimitiveGroup> m_Groups;
|
||||
};
|
||||
|
||||
/**
|
||||
* A random number class. It implements the <em>mersenne twister</em> algorithm to produce
|
||||
* "high quality" pseudo random numbers.
|
||||
*/
|
||||
class CRERandom
|
||||
{
|
||||
public:
|
||||
enum EMersenneTwisterInitialSeed
|
||||
{
|
||||
INITIAL_SEED = 4357U
|
||||
};
|
||||
|
||||
public:
|
||||
CRERandom( unsigned long ulSeed = INITIAL_SEED ) : m_ulIndex( 0 )
|
||||
{
|
||||
SetSeed( ulSeed );
|
||||
}
|
||||
|
||||
~CRERandom() {};
|
||||
|
||||
void SetSeed( unsigned long ulSeed )
|
||||
{
|
||||
m_ulState[ 0 ] = ( ulSeed | 1 ) & 0xFFFFFFFFU;
|
||||
for( m_ulIndex = 1; m_ulIndex < N; ++m_ulIndex )
|
||||
{
|
||||
m_ulState[ m_ulIndex ] = ( m_ulState[ m_ulIndex - 1 ] * GENERATOR ) & 0xFFFFFFFFU;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long GetInteger()
|
||||
{
|
||||
if( N == m_ulIndex )
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
|
||||
unsigned long ulY = m_ulState[ m_ulIndex++ ];
|
||||
ulY ^= TemperingShiftU( ulY );
|
||||
ulY ^= TemperingShiftS( ulY ) & TEMPERING_MASK_B;
|
||||
ulY ^= TemperingShiftT( ulY ) & TEMPERING_MASK_C;
|
||||
ulY ^= TemperingShiftL( ulY );
|
||||
|
||||
return( ulY );
|
||||
}
|
||||
|
||||
double Get()
|
||||
{
|
||||
return( GetInteger() * (double) 2.3283064365386963e-10 ); // i.e. GetInteger() / 2^32
|
||||
}
|
||||
|
||||
double GetInRange( double dLower = 0.0, double dUpper = 1.0 )
|
||||
{
|
||||
return( dLower + Get() * ( dUpper - dLower ) );
|
||||
}
|
||||
|
||||
double GetGauss( double dMean = 0.0, double dStdDeviation = 1.0 )
|
||||
{
|
||||
double dX1;
|
||||
double dX2;
|
||||
double dW;
|
||||
|
||||
// perform box muller test
|
||||
do
|
||||
{
|
||||
dX1 = 2.0 * Get() - 1.0;
|
||||
dX2 = 2.0 * Get() - 1.0;
|
||||
dW = dX1 * dX1 + dX2 * dX2;
|
||||
} while( dW >= 1.0 );
|
||||
|
||||
dW = sqrt_tpl( -2.0f * log_tpl( dW ) / dW );
|
||||
dX1 *= dW;
|
||||
|
||||
return( dMean + dX1 * dStdDeviation );
|
||||
}
|
||||
|
||||
private:
|
||||
enum EMersenneTwisterConstants
|
||||
{
|
||||
GENERATOR = 69069U,
|
||||
|
||||
N = 624U,
|
||||
M = 397U,
|
||||
|
||||
MATRIX_A = 0x9908B0DFU,
|
||||
UPPER_MASK = 0x80000000U,
|
||||
LOWER_MASK = 0x7FFFFFFFU,
|
||||
|
||||
TEMPERING_MASK_B = 0x9D2C5680U,
|
||||
TEMPERING_MASK_C = 0xEFC60000U
|
||||
};
|
||||
|
||||
void Reload()
|
||||
{
|
||||
const unsigned long c_ulMag01[ 2 ] = { 0x0, MATRIX_A };
|
||||
|
||||
unsigned long ulY;
|
||||
for( m_ulIndex = 0; m_ulIndex < N - M; ++m_ulIndex )
|
||||
{
|
||||
ulY = ( m_ulState[ m_ulIndex ] & UPPER_MASK ) |
|
||||
( m_ulState[ m_ulIndex + 1 ] & LOWER_MASK );
|
||||
|
||||
m_ulState[ m_ulIndex ] = m_ulState[ m_ulIndex + M ] ^ ( ulY >> 1 ) ^ c_ulMag01[ ulY & 0x1 ];
|
||||
}
|
||||
|
||||
for( ; m_ulIndex < N - 1; ++m_ulIndex)
|
||||
{
|
||||
ulY = ( m_ulState[ m_ulIndex ] & UPPER_MASK ) |
|
||||
( m_ulState[ m_ulIndex + 1 ] & LOWER_MASK );
|
||||
|
||||
m_ulState[ m_ulIndex ] = m_ulState[ m_ulIndex + ( M - N ) ] ^ ( ulY >> 1 ) ^ c_ulMag01[ ulY & 0x1 ];
|
||||
}
|
||||
|
||||
ulY = ( m_ulState[ N - 1 ] & UPPER_MASK ) | ( m_ulState[ 0 ] & LOWER_MASK );
|
||||
m_ulState[ N - 1 ] = m_ulState[ M - 1 ] ^ ( ulY >> 1 ) ^ c_ulMag01[ ulY & 0x1 ];
|
||||
|
||||
m_ulIndex = 0;
|
||||
}
|
||||
|
||||
unsigned long TemperingShiftU( unsigned long ulX )
|
||||
{
|
||||
return( ulX >> 11 );
|
||||
}
|
||||
|
||||
unsigned long TemperingShiftS( unsigned long ulX )
|
||||
{
|
||||
return( ulX << 7 );
|
||||
}
|
||||
|
||||
unsigned long TemperingShiftT( unsigned long ulX )
|
||||
{
|
||||
return( ulX << 15 );
|
||||
}
|
||||
|
||||
unsigned long TemperingShiftL( unsigned long ulX )
|
||||
{
|
||||
return( ulX >> 18 );
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned long m_ulIndex;
|
||||
|
||||
unsigned long m_ulState[ N ];
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class CREOcean : public CRendElement
|
||||
{
|
||||
friend class CRender3D;
|
||||
friend class CGLRenderer;
|
||||
friend class CD3D9Renderer;
|
||||
|
||||
public:
|
||||
|
||||
static CREOcean *m_pStaticOcean;
|
||||
CREOcean()
|
||||
{
|
||||
m_nFrameLoad = 0;
|
||||
m_pBuffer = NULL;
|
||||
mfSetType(eDATA_Ocean);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
GenerateGeometry();
|
||||
m_pStaticOcean = this;
|
||||
}
|
||||
|
||||
virtual ~CREOcean();
|
||||
|
||||
public:
|
||||
|
||||
void GenerateGeometry();
|
||||
void GenerateIndices(int nLodCode);
|
||||
void DrawOceanSector(SOceanIndicies *oi);
|
||||
void SmoothLods_r(SOceanSector *os, float fSize, int minLod);
|
||||
void LinkVisSectors(float fSize);
|
||||
float GetWaterZElevation(float fX, float fY);
|
||||
|
||||
void PostLoad( unsigned long ulSeed, float fWindDirection, float fWindSpeed, float fWaveHeight, float fDirectionalDependence, float fChoppyWavesFactor, float fSuppressSmallWavesFactor );
|
||||
void Update( float fTime );
|
||||
void UpdateTexture(void);
|
||||
void PrepareHMap();
|
||||
|
||||
private:
|
||||
int m_nFrameLoad;
|
||||
float m_fGravity;
|
||||
float m_fDepth;
|
||||
|
||||
TArray <unsigned short> m_pIndices[NUM_LODS];
|
||||
|
||||
private:
|
||||
float *mfFillAdditionalBuffer(SOceanSector *os, int nSplashes, SSplash *pSplashes[], int& nCurSize, int nLod, float fSize);
|
||||
|
||||
void FFT(int iDir, float* real, float* imag);
|
||||
void FFT2DReal(float cmpX[OCEANGRID][OCEANGRID]);
|
||||
void FFT2D(int iDir, float cmpX[OCEANGRID][OCEANGRID], float cmpY[OCEANGRID][OCEANGRID] );
|
||||
_inline float sqrf( float x )
|
||||
{
|
||||
return (x * x);
|
||||
}
|
||||
|
||||
_inline float PhillipsSpectrum( float fKx, float fKy )
|
||||
{
|
||||
float fKLength = cry_sqrtf(sqrf(fKx) + sqrf(fKy));
|
||||
|
||||
if( fKLength < 1e-8f )
|
||||
fKLength = 1e-8f;
|
||||
|
||||
float fScale = 1.0f / fKLength;
|
||||
fKx *= fScale;
|
||||
fKy *= fScale;
|
||||
|
||||
return (m_fWaveHeight * cry_expf(-1.0f / sqrf(fKLength * m_fLargestPossibleWave) - sqrf(fKLength * m_fSuppressSmallWaves)) * cry_powf(fKx*m_fWindX + fKy*m_fWindY, m_fDirectionalDependence) / cry_powf(fKLength, 4.0f));
|
||||
}
|
||||
|
||||
_inline int GetHash(float x, float y)
|
||||
{
|
||||
return (int)(x*0.133f+y*0.356f) & 255;
|
||||
}
|
||||
|
||||
_inline SOceanSector *GetSectorByPos(float x, float y, bool bCreate=true)
|
||||
{
|
||||
int i;
|
||||
|
||||
int hash = GetHash(x, y);
|
||||
for (i=0; i<m_OceanSectorsHash[hash].Num(); i++)
|
||||
{
|
||||
SOceanSector *os = &m_OceanSectorsHash[hash][i];
|
||||
if (os->x == x && os->y == y)
|
||||
return os;
|
||||
}
|
||||
m_RS.m_StatsAllocatedSectors++;
|
||||
SOceanSector os;
|
||||
os.x = x;
|
||||
os.y = y;
|
||||
os.m_Flags |= OSF_FIRSTTIME;
|
||||
os.nLod = NUM_LODS-1;
|
||||
int n = m_OceanSectorsHash[hash].Num();
|
||||
m_OceanSectorsHash[hash].AddElem(os);
|
||||
return &m_OceanSectorsHash[hash][n];
|
||||
}
|
||||
int GetLOD(Vec3d camera, Vec3d pos);
|
||||
|
||||
private:
|
||||
|
||||
TArray<SOceanSector> m_OceanSectorsHash[256];
|
||||
SOceanIndicies *m_OceanIndicies[1<<(LOD_BOTTOMSHIFT+1)];
|
||||
TArray<SOceanSector *> m_VisOceanSectors;
|
||||
float m_fSectorSize;
|
||||
|
||||
TArray<unsigned short> m_DWQIndices;
|
||||
TArray<struct_VERTEX_FORMAT_P3F_COL4UB> m_DWQVertices;
|
||||
|
||||
float m_H0X[OCEANGRID+1][OCEANGRID+1];
|
||||
float m_H0Y[OCEANGRID+1][OCEANGRID+1];
|
||||
|
||||
//static _declspec(align(16)) float m_HX[OCEANGRID][OCEANGRID];
|
||||
//static _declspec(align(16)) float m_HY[OCEANGRID][OCEANGRID];
|
||||
|
||||
//static _declspec(align(16)) float m_NX[OCEANGRID][OCEANGRID];
|
||||
//static _declspec(align(16)) float m_NY[OCEANGRID][OCEANGRID];
|
||||
|
||||
//static _declspec(align(16)) float m_DX[OCEANGRID][OCEANGRID];
|
||||
//static _declspec(align(16)) float m_DY[OCEANGRID][OCEANGRID];
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_HX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_HY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_NX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_NY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_DX[OCEANGRID][OCEANGRID], 16 );
|
||||
DEFINE_ALIGNED_DATA_STATIC( float, m_DY[OCEANGRID][OCEANGRID], 16 );
|
||||
|
||||
vec2_t m_Pos[OCEANGRID+1][OCEANGRID+1];
|
||||
Vec3d m_Normals[OCEANGRID+1][OCEANGRID+1];
|
||||
|
||||
float m_aAngularFreq[OCEANGRID][OCEANGRID];
|
||||
float m_aKScale[OCEANGRID][OCEANGRID];
|
||||
|
||||
float m_fWindX;
|
||||
float m_fWindY;
|
||||
float m_fWindSpeed;
|
||||
float m_fSpeed;
|
||||
float m_fLargestPossibleWave;
|
||||
float m_fSuppressSmallWaves;
|
||||
float m_fWaveHeight;
|
||||
float m_fDirectionalDependence;
|
||||
float m_fChoppyWaveFactor;
|
||||
float m_fSuppressSmallWavesFactor;
|
||||
|
||||
CVertexBuffer *m_pBuffer;
|
||||
|
||||
Vec3d m_MinBound;
|
||||
Vec3d m_MaxBound;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
_inline float GetHMap(float x, float y)
|
||||
{
|
||||
float dDownLandZ;
|
||||
|
||||
if( x<-m_fExpandHM || y<-m_fExpandHM || x>=m_fTerrainSize+m_fExpandHM || y>=m_fTerrainSize+m_fExpandHM)
|
||||
dDownLandZ = 0;
|
||||
else
|
||||
{
|
||||
// convert into hmap space
|
||||
x *= m_fInvHMUnitSize;
|
||||
y *= m_fInvHMUnitSize;
|
||||
|
||||
x += m_fExpandHMap;
|
||||
y += m_fExpandHMap;
|
||||
|
||||
long nX = QInt(x);
|
||||
long nY = QInt(y);
|
||||
long nX1 = (nX+1 >= m_nHMapSize) ? nX : nX+1;
|
||||
long nY1 = (nY+1 >= m_nHMapSize) ? nY : nY+1;
|
||||
|
||||
float dx = x - nX;
|
||||
float dy = y - nY;
|
||||
|
||||
float dDownLandZ0 = (1.0f-dx) * m_HMap[nX*m_nHMapSize+nY] + dx * m_HMap[nX1*m_nHMapSize+nY];
|
||||
float dDownLandZ1 = (1.0f-dx) * m_HMap[nX*m_nHMapSize+nY1] + dx * m_HMap[nX1*m_nHMapSize+nY1];
|
||||
dDownLandZ = (1-dy) * dDownLandZ0 + dy * dDownLandZ1;
|
||||
}
|
||||
return dDownLandZ;
|
||||
}
|
||||
|
||||
public:
|
||||
#if !defined(PS2) && !defined (GC)
|
||||
CVProgram * m_VPs[NUM_OVP];
|
||||
CVProgram * m_VPQ;
|
||||
#endif
|
||||
void *m_pVertsPool[NUM_OCEANVBS];
|
||||
void *m_VertDecl;
|
||||
void *m_VertDeclHeightSplash;
|
||||
int m_nCurVB;
|
||||
int m_nNumVertsInPool;
|
||||
bool m_bLockedVB;
|
||||
|
||||
float *m_HMap;
|
||||
int m_nHMUnitSize;
|
||||
float m_fExpandHM;
|
||||
float m_fExpandHMap;
|
||||
int m_nHMapSize;
|
||||
float m_fInvHMUnitSize;
|
||||
float m_fTerrainSize;
|
||||
|
||||
void InitVB();
|
||||
struct_VERTEX_FORMAT_TEX2F *GetVBPtr(int nVerts);
|
||||
void UnlockVBPtr();
|
||||
|
||||
void mfDrawOceanSectors();
|
||||
void mfDrawOceanScreenLod();
|
||||
|
||||
public:
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
virtual void *mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags);
|
||||
virtual bool mfPreDraw(SShaderPass *sl);
|
||||
virtual void mfReset();
|
||||
virtual int Size()
|
||||
{
|
||||
int i;
|
||||
int nSize = sizeof(*this);
|
||||
nSize += m_DWQVertices.GetMemoryUsage();
|
||||
nSize += m_DWQIndices.GetMemoryUsage();
|
||||
|
||||
nSize += sizeof(m_Pos);
|
||||
nSize += sizeof(m_Normals);
|
||||
nSize += m_VisOceanSectors.GetMemoryUsage() + 12;
|
||||
for (i=0; i<(1<<(LOD_BOTTOMSHIFT+1)); i++)
|
||||
{
|
||||
SOceanIndicies *oi = m_OceanIndicies[i];
|
||||
if (!oi)
|
||||
continue;
|
||||
|
||||
nSize += sizeof(SOceanIndicies);
|
||||
nSize += oi->m_nInds * sizeof(short);
|
||||
nSize += oi->m_Groups.GetMemoryUsage();
|
||||
}
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
nSize += m_OceanSectorsHash[i].GetMemoryUsage()+12;
|
||||
}
|
||||
// CREOcean::m_HMap array
|
||||
nSize += m_nHMapSize * m_nHMapSize * sizeof(float);
|
||||
|
||||
return nSize;
|
||||
}
|
||||
|
||||
static SREOceanStats m_RS;
|
||||
|
||||
#ifdef DEBUGALLOC
|
||||
#undef new
|
||||
#endif
|
||||
void* operator new( size_t Size )
|
||||
{
|
||||
void *ptr = malloc(Size);
|
||||
memset(ptr, 0, Size);
|
||||
return ptr;
|
||||
}
|
||||
#ifdef DEBUGALLOC
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // _CREOCEAN_H_
|
||||
13
RenderDll/Common/RendElements/CREOclusionQuery.cpp
Normal file
13
RenderDll/Common/RendElements/CREOclusionQuery.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
void CREOcclusionQuery::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_FirstVertex = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 4;
|
||||
}
|
||||
|
||||
1405
RenderDll/Common/RendElements/CREParticleSpray.cpp
Normal file
1405
RenderDll/Common/RendElements/CREParticleSpray.cpp
Normal file
File diff suppressed because it is too large
Load Diff
210
RenderDll/Common/RendElements/CREParticleSpray.h
Normal file
210
RenderDll/Common/RendElements/CREParticleSpray.h
Normal file
@@ -0,0 +1,210 @@
|
||||
|
||||
#ifndef __CREPARTICLESPRAY_H__
|
||||
#define __CREPARTICLESPRAY_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
struct SParticle
|
||||
{
|
||||
SParticle *prev,*next; // LINK
|
||||
Vec3d pos; // CURRENT POSITION
|
||||
Vec3d prevPos[8]; // PREVIOUS POSITION
|
||||
Vec3d realPos; // CURRENT RENDER POSITION
|
||||
Vec3d dir; // CURRENT DIRECTION WITH SPEED
|
||||
Vec3d moveDir; // CURRENT CHANGE DIRECTION
|
||||
int life; // HOW LONG IT WILL LAST
|
||||
int startLife;
|
||||
|
||||
CFColor color; // CURRENT COLOR OF PARTICLE
|
||||
CFColor prevColor; // LAST COLOR OF PARTICLE
|
||||
CFColor deltaColor; // CHANGE OF COLOR
|
||||
|
||||
bool bSpark;
|
||||
|
||||
float curSize;
|
||||
float deltaSize;
|
||||
};
|
||||
|
||||
//================================================
|
||||
|
||||
#define MAX_PART_MOVE_STAGES 4
|
||||
|
||||
enum EMoveType
|
||||
{
|
||||
eMTWave,
|
||||
eMTWhirl,
|
||||
eMTSqueeze,
|
||||
};
|
||||
|
||||
struct SPartMoveStage
|
||||
{
|
||||
EMoveType eMoveType;
|
||||
SWaveForm WaveMove;
|
||||
};
|
||||
|
||||
//================================================
|
||||
|
||||
enum EParticleType
|
||||
{
|
||||
ePTPoint,
|
||||
ePTLine,
|
||||
ePTPolySegs,
|
||||
ePTPoly,
|
||||
ePTBeam,
|
||||
};
|
||||
|
||||
enum EParticleCollision
|
||||
{
|
||||
ePCollision_None,
|
||||
ePCollision_True,
|
||||
ePCollision_Plane
|
||||
};
|
||||
|
||||
struct SParticleInfo
|
||||
{
|
||||
// TRANSFORMATION INFO
|
||||
float yaw, yawVar; // YAW AND VARIATION
|
||||
float pitch, pitchVar; // PITCH AND VARIATION
|
||||
float speed,speedVar;
|
||||
|
||||
int life, lifeVar; // LIFE COUNT AND VARIATION
|
||||
CFColor startColor, startColorVar; // CURRENT COLOR OF PARTICLE
|
||||
CFColor endColor, endColorVar; // CURRENT COLOR OF PARTICLE
|
||||
|
||||
// Physics
|
||||
Vec3d force;
|
||||
|
||||
EParticleType ePT;
|
||||
int Flags;
|
||||
|
||||
// Move info
|
||||
SPartMoveStage mMoves[MAX_PART_MOVE_STAGES];
|
||||
int mNumMoves;
|
||||
|
||||
Vec3d moveDir;
|
||||
Vec3d moveDirVar;
|
||||
|
||||
// Geometry info
|
||||
float startSize, startSizeVar;
|
||||
float endSize, endSizeVar;
|
||||
|
||||
float segmOffs;
|
||||
int segmMax;
|
||||
|
||||
int StackSize;
|
||||
float Squeeze;
|
||||
};
|
||||
|
||||
struct SEmitter
|
||||
{
|
||||
SParticleInfo pi;
|
||||
|
||||
Vec3d startPos; // XYZ POSITION
|
||||
Vec3d startPosVar; // XYZ POSITION VARIATION
|
||||
|
||||
// Particle
|
||||
SParticle *particle; // NULL TERMINATED LINKED LIST
|
||||
int totalParticles[2]; // TOTAL EMITTED AT ANY TIME
|
||||
int particleCount[2]; // TOTAL EMITTED RIGHT NOW
|
||||
int emitsPerFrame, emitVar; // EMITS PER FRAME AND VARIATION
|
||||
|
||||
EParticleCollision eCollisionType;
|
||||
Vec3d PlaneAxis;
|
||||
Vec3d PlaneOffs;
|
||||
|
||||
SParticleInfo Spark;
|
||||
int NumSparks;
|
||||
|
||||
float Life;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Particle Definitions //////////////////////////////////////////////////////
|
||||
#define MAX_PARTICLES 4096 // MAXIMUM NUMBER OF PARTICLES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FP_ANTIALIAS 0x1
|
||||
|
||||
struct SParticleStat
|
||||
{
|
||||
int NumSprays;
|
||||
int NumRendSprays;
|
||||
int NumParticles;
|
||||
int NumVerts;
|
||||
int NumIndices;
|
||||
};
|
||||
|
||||
class CREParticleSpray : public CRendElement
|
||||
{
|
||||
public:
|
||||
SEmitter mEmitter;
|
||||
SParticle *mParticlePool[2];
|
||||
SParticle *mParticlePntr[2];
|
||||
int mFrame;
|
||||
|
||||
private:
|
||||
/// Support Function Definitions //////////////////////////////////////////////
|
||||
bool mfInitParticleSystem();
|
||||
bool mfSetDefaultEmitter(SEmitter *emitter);
|
||||
bool mfInitEmitter(SEmitter *emitter);
|
||||
|
||||
bool mfAddParticle(SEmitter *emitter, SParticleInfo *pi);
|
||||
bool mfUpdateParticle(SParticle *particle,SEmitter *emitter);
|
||||
void mfEmitSparks(SParticle *p, SEmitter *em);
|
||||
|
||||
bool mfUpdateEmitter(SEmitter *emitter); // DRAW THE SYSTEM FOR A FRAME
|
||||
SEmitter *mfGetEmitter(void) { return &mEmitter; }
|
||||
|
||||
// Parsing
|
||||
void mfCompileParticleInfo(SShader *ef, SParticleInfo *pi, char *scr);
|
||||
void mfCompileCollision(SShader *ef, SEmitter *em, char *scr, char *Collision);
|
||||
bool mfCompileMove(SShader *ef, SPartMoveStage *pm, SParticleInfo *pi, char *scr);
|
||||
bool mfCompileMoveTypeSqueeze(SShader *ef, SPartMoveStage *pm, char *scr);
|
||||
bool mfCompileMoveTypeWhirl(SShader *ef, SPartMoveStage *pm, char *scr);
|
||||
bool mfCompileMoveTypeWave(SShader *ef, SPartMoveStage *pm, char *scr);
|
||||
|
||||
public:
|
||||
CREParticleSpray()
|
||||
{
|
||||
mfSetType(eDATA_ParticleSpray);
|
||||
mfUpdateFlags(FCEF_TRANSFORM | FCEF_NEEDFILLBUF);
|
||||
mfInitEmitter(&mEmitter);
|
||||
}
|
||||
virtual ~CREParticleSpray();
|
||||
//CREParticleSpray(CREParticleSpray *Orig);
|
||||
CREParticleSpray& operator = (const CREParticleSpray& src);
|
||||
|
||||
// CRendElement interface
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfCull(CCObject *obj);
|
||||
|
||||
virtual CRendElement *mfCopyConstruct(void)
|
||||
{
|
||||
//CREParticleSpray *ps = new CREParticleSpray;
|
||||
//*ps = this;
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual bool mfIsValidTime(SShader *ef, CCObject *obj, float curtime);
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
|
||||
static SParticleStat mRS;
|
||||
static void mfPrintStat();
|
||||
|
||||
#ifdef DEBUGALLOC
|
||||
#undef new
|
||||
#endif
|
||||
void* operator new( size_t Size )
|
||||
{
|
||||
void *ptr = malloc(Size);
|
||||
memset(ptr, 0, Size);
|
||||
return ptr;
|
||||
}
|
||||
#ifdef DEBUGALLOC
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // __RENDELEMENT_H__
|
||||
651
RenderDll/Common/RendElements/CREPolyBlend.cpp
Normal file
651
RenderDll/Common/RendElements/CREPolyBlend.cpp
Normal file
@@ -0,0 +1,651 @@
|
||||
/*=============================================================================
|
||||
CPolyBlend.cpp : implementation of blended polygons RE.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
//===============================================================
|
||||
|
||||
bool CREPolyBlend::mfCull(CCObject *obj)
|
||||
{
|
||||
CREPolyBlend::mRS.NumPolys++;
|
||||
|
||||
if ((obj->m_ObjFlags & FOB_NEAREST))
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREPolyBlend_Base::mfPrepareRB(CCObject *obj, Vec3d& orgo, CFColor& col)
|
||||
{
|
||||
if (obj->m_ObjFlags & FOB_DRSUN)
|
||||
{
|
||||
orgo = gRenDev->m_RP.m_ViewOrg + 2000.0f * gRenDev->m_RP.m_SunDir;
|
||||
}
|
||||
/*else
|
||||
if (obj->m_ObjFlags & FOB_DRPLANET)
|
||||
{
|
||||
orgo = obj->m_Trans + gRenDev->m_RP.m_ViewOrg;
|
||||
orgo[2] += 2000;
|
||||
}*/
|
||||
else
|
||||
{
|
||||
orgo = obj->GetTranslation();
|
||||
}
|
||||
|
||||
col = obj->m_Color;
|
||||
|
||||
if (col[0]+col[1]+col[2] == 0)
|
||||
col = CFColor(1.0f);
|
||||
|
||||
if (obj->m_ObjFlags & FOB_DRSUN)
|
||||
{
|
||||
CREFlareGeom *fl = (CREFlareGeom *)obj->m_RE;
|
||||
fl->mfCheckVis(col, obj);
|
||||
if (!col.a)
|
||||
return false; // Flare not visible
|
||||
col.ScaleCol(col.a);
|
||||
col.a = 1;
|
||||
}
|
||||
else
|
||||
if (eColStyle || eAlphaStyle)
|
||||
{
|
||||
float frac;
|
||||
if (eColStyle)
|
||||
{
|
||||
col = Col_White;
|
||||
if (eColStyle == ePBCS_Decay)
|
||||
{
|
||||
frac = (gRenDev->m_RP.m_RealTime-obj->m_StartTime)/LiveTime;
|
||||
col.ScaleCol(frac);
|
||||
}
|
||||
}
|
||||
if (eAlphaStyle)
|
||||
{
|
||||
if (eAlphaStyle == ePBCS_Decay)
|
||||
{
|
||||
if (obj->m_StartTime+LiveTimeA < gRenDev->m_RP.m_RealTime-0.001)
|
||||
frac = 1;
|
||||
else
|
||||
frac = (gRenDev->m_RP.m_RealTime-obj->m_StartTime)/LiveTimeA;
|
||||
col[3] = ValA0 + frac * (ValA1-ValA0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLightStyle *ls = CLightStyle::m_LStyles[obj->m_LightStyle];
|
||||
ls->mfUpdate(gRenDev->m_RP.m_RealTime);
|
||||
col = ls->m_Color;
|
||||
col[3] = 1.0f;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CREPolyBlend_Base::mfSetVerts(CCObject *obj, Vec3d& orgo, uint c, SOrient *ori)
|
||||
{
|
||||
Vec3d VecX, VecY, v;
|
||||
Vec3d org;
|
||||
float distX, distY;
|
||||
float *verts[4];
|
||||
Vec3d norm;
|
||||
bvec4 *cols;
|
||||
int i;
|
||||
static int inds[] = {3, 0, 2, 2, 0, 1};
|
||||
static float tverts[4][2] =
|
||||
{
|
||||
{0, 0},
|
||||
{1, 0},
|
||||
{1, 1},
|
||||
{0, 1}
|
||||
};
|
||||
|
||||
int n = gRenDev->m_RP.m_RendNumVerts;
|
||||
byte *p = gRenDev->m_RP.m_Ptr.PtrB + n*gRenDev->m_RP.m_Stride;
|
||||
verts[0] = (float *)p;
|
||||
p += gRenDev->m_RP.m_Stride;
|
||||
verts[1] = (float *)p;
|
||||
p += gRenDev->m_RP.m_Stride;
|
||||
verts[2] = (float *)p;
|
||||
p += gRenDev->m_RP.m_Stride;
|
||||
verts[3] = (float *)p;
|
||||
|
||||
org = orgo;
|
||||
|
||||
if (ori->m_Flags & FOR_ORTHO)
|
||||
{
|
||||
VecX = gRenDev->m_RP.m_CamVecs[1];
|
||||
VecY = gRenDev->m_RP.m_CamVecs[2];
|
||||
|
||||
org += ori->m_Coord.m_Org;
|
||||
|
||||
v = org - gRenDev->m_RP.m_ViewOrg;
|
||||
distX = v.GetLength();
|
||||
norm = -gRenDev->m_RP.m_CamVecs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
VecX = ori->m_Coord.m_Vecs[1];
|
||||
VecY = ori->m_Coord.m_Vecs[2];
|
||||
|
||||
org += ori->m_Coord.m_Org;
|
||||
|
||||
v = org - gRenDev->m_RP.m_ViewOrg;
|
||||
distX = v.GetLength();
|
||||
norm = -ori->m_Coord.m_Vecs[0];
|
||||
}
|
||||
if (gRenDev->m_RP.m_PersFlags & RBPF_DRAWMIRROR)
|
||||
{
|
||||
VecY = -VecY;
|
||||
}
|
||||
|
||||
distY = distX;
|
||||
if (ScaleX > 0)
|
||||
{
|
||||
distX = ScaleX;
|
||||
distY = ScaleY;
|
||||
}
|
||||
else
|
||||
if (ScaleX < 0)
|
||||
{
|
||||
distX *= -ScaleX * 0.1f;
|
||||
distY *= -ScaleY * 0.1f;
|
||||
}
|
||||
else
|
||||
distX = distY = 10.0f;
|
||||
|
||||
VecX *= distX;
|
||||
VecY *= distY;
|
||||
|
||||
verts[0][0] = org[0]+VecX[0]+VecY[0];
|
||||
verts[0][1] = org[1]+VecX[1]+VecY[1];
|
||||
verts[0][2] = org[2]+VecX[2]+VecY[2];
|
||||
|
||||
verts[1][0] = org[0]-VecX[0]+VecY[0];
|
||||
verts[1][1] = org[1]-VecX[1]+VecY[1];
|
||||
verts[1][2] = org[2]-VecX[2]+VecY[2];
|
||||
|
||||
verts[2][0] = org[0]-VecX[0]-VecY[0];
|
||||
verts[2][1] = org[1]-VecX[1]-VecY[1];
|
||||
verts[2][2] = org[2]-VecX[2]-VecY[2];
|
||||
|
||||
verts[3][0] = org[0]+VecX[0]-VecY[0];
|
||||
verts[3][1] = org[1]+VecX[1]-VecY[1];
|
||||
verts[3][2] = org[2]+VecX[2]-VecY[2];
|
||||
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_NextPtr;
|
||||
byte *OffsT, *OffsD;
|
||||
SMRendTexVert *rtvb;
|
||||
byte *OffsN;
|
||||
switch (gRenDev->m_RP.m_FT)
|
||||
{
|
||||
case FLT_BASE:
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
OffsT = gRenDev->m_RP.m_OffsT + ptr.PtrB;
|
||||
for (i=0; i<4; i++, cols++, OffsT+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsT) = tverts[i][0];
|
||||
*(float *)(OffsT+4) = tverts[i][1];
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_COL:
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
OffsT = gRenDev->m_RP.m_OffsT + ptr.PtrB;
|
||||
for (i=0; i<4; i++, OffsT+=gRenDev->m_RP.m_Stride, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsT) = tverts[i][0];
|
||||
*(float *)(OffsT+4) = tverts[i][1];
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL:
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
for (i=0; i<4; i++, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL + FLT_SYSBASE:
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<4; i++, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
Vector2Copy(tverts[i], rtvb[i].vert);
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
for (i=0; i<4; i++, cols++)
|
||||
{
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE:
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<4; i++, cols++)
|
||||
{
|
||||
Vector2Copy(tverts[i], rtvb[i].vert);
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FLT_BASE + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
OffsT = gRenDev->m_RP.m_OffsT + ptr.PtrB;
|
||||
for (i=0; i<4; i++, cols++, OffsT+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
*(float *)(OffsT) = tverts[i][0];
|
||||
*(float *)(OffsT+4) = tverts[i][1];
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
OffsT = gRenDev->m_RP.m_OffsT + ptr.PtrB;
|
||||
for (i=0; i<4; i++, OffsT+=gRenDev->m_RP.m_Stride, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
*(float *)(OffsT) = tverts[i][0];
|
||||
*(float *)(OffsT+4) = tverts[i][1];
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
for (i=0; i<4; i++, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL + FLT_SYSBASE + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
OffsD = gRenDev->m_RP.m_OffsD + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<4; i++, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
Vector2Copy(tverts[i], rtvb[i].vert);
|
||||
*(uint *)OffsD = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0 + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
for (i=0; i<4; i++, cols++)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
cols = &gRenDev->m_RP.m_pClientColors[n];
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<4; i++, cols++)
|
||||
{
|
||||
*(float *)(OffsN) = norm.x;
|
||||
*(float *)(OffsN+4) = norm.y;
|
||||
*(float *)(OffsN+8) = norm.z;
|
||||
Vector2Copy(tverts[i], rtvb[i].vert);
|
||||
*(uint *)cols = c;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((gRenDev->m_RP.m_FT & FLT_COL) && gbRgb)
|
||||
{
|
||||
OffsD = gRenDev->m_RP.m_OffsD + gRenDev->m_RP.m_NextPtr.PtrB;
|
||||
for (i=0; i<4; i++, OffsD+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
*(uint *)(OffsD) = COLCONV(*(uint *)(OffsD));
|
||||
}
|
||||
}
|
||||
|
||||
ptr.PtrB += gRenDev->m_RP.m_Stride*4;
|
||||
gRenDev->m_RP.m_NextPtr = ptr;
|
||||
|
||||
ushort *dinds = &gRenDev->m_RP.m_RendIndices[gRenDev->m_RP.m_RendNumIndices];
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
*dinds++ = inds[i]+n;
|
||||
}
|
||||
}
|
||||
|
||||
void CREPolyBlend::mfPrepare(void)
|
||||
{
|
||||
CCObject *obj = gRenDev->m_RP.m_pCurObject;
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
int savev = gRenDev->m_RP.m_RendNumVerts;
|
||||
int savei = gRenDev->m_RP.m_RendNumIndices;
|
||||
|
||||
CREPolyBlend::mRS.NumRendPolys++;
|
||||
|
||||
SShader *ef = gRenDev->m_RP.m_pShader;
|
||||
CFColor col;
|
||||
Vec3d orgo;
|
||||
|
||||
if (!mfPrepareRB(obj, orgo, col))
|
||||
return;
|
||||
|
||||
uint c = col.GetTrue();
|
||||
|
||||
for (int o=0; o<NumOrients; o++)
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(4, 6, this);
|
||||
|
||||
mfSetVerts(obj, orgo, c, Orients[o]);
|
||||
|
||||
gRenDev->m_RP.m_RendNumVerts += 4;
|
||||
gRenDev->m_RP.m_RendNumIndices += 6;
|
||||
}
|
||||
|
||||
CREPolyBlend::mRS.NumVerts += gRenDev->m_RP.m_RendNumVerts - savev;
|
||||
CREPolyBlend::mRS.NumIndices += gRenDev->m_RP.m_RendNumIndices - savei;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
|
||||
bool CREAnimPolyBlend::mfCull(CCObject *obj)
|
||||
{
|
||||
CREPolyBlend::mRS.NumAnimPolys++;
|
||||
|
||||
//if(gfCullSphere(obj->m_Trans, 100)==2)
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREPolyBlend::mfIsValidTime(SShader *ef, CCObject *obj, float curtime)
|
||||
{
|
||||
if (!LiveTime)
|
||||
return true;
|
||||
|
||||
if (curtime > LiveTime+obj->m_StartTime)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CREAnimPolyBlend::mfIsValidTime(SShader *ef, CCObject *obj, float curtime)
|
||||
{
|
||||
int i, j;
|
||||
SShaderTexUnit *shm;
|
||||
SShaderPass *sfm;
|
||||
|
||||
for (i=0; i<ef->m_Passes.Num(); i++)
|
||||
{
|
||||
sfm = &ef->m_Passes[i];
|
||||
|
||||
for (j=0; j<sfm->m_TUnits.Num(); j++)
|
||||
{
|
||||
shm = &sfm->m_TUnits[j];
|
||||
if (!shm->m_AnimInfo)
|
||||
continue;
|
||||
if (shm->m_AnimInfo->m_Time && shm->m_AnimInfo->m_TexPics.Num())
|
||||
{
|
||||
float t = curtime - obj->m_StartTime;
|
||||
int m = (int)(t / shm->m_AnimInfo->m_Time);
|
||||
if (m >= shm->m_AnimInfo->m_TexPics.Num())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CREAnimPolyBlend::mfPrepare(void)
|
||||
{
|
||||
CCObject *obj = gRenDev->m_RP.m_pCurObject;
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
int savev = gRenDev->m_RP.m_RendNumVerts;
|
||||
int savei = gRenDev->m_RP.m_RendNumIndices;
|
||||
|
||||
CREPolyBlend::mRS.NumRendPolys++;
|
||||
|
||||
SShader *ef = gRenDev->m_RP.m_pShader;
|
||||
CFColor col;
|
||||
Vec3d orgo;
|
||||
|
||||
if (!mfPrepareRB(obj, orgo, col))
|
||||
return;
|
||||
|
||||
uint c = col.GetTrue();
|
||||
|
||||
for (int o=0; o<NumOrients; o++)
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(4, 6, this);
|
||||
|
||||
mfSetVerts(obj, orgo, c, Orients[o]);
|
||||
|
||||
gRenDev->m_RP.m_RendNumVerts += 4;
|
||||
gRenDev->m_RP.m_RendNumIndices += 6;
|
||||
}
|
||||
|
||||
CREPolyBlend::mRS.NumVerts += gRenDev->m_RP.m_RendNumVerts - savev;
|
||||
CREPolyBlend::mRS.NumIndices += gRenDev->m_RP.m_RendNumIndices - savei;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
|
||||
SPolyBlendStat CREPolyBlend::mRS;
|
||||
|
||||
void CREPolyBlend::mfPrintStat()
|
||||
{
|
||||
/* char str[1024];
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Indices: %i\n", mRS.NumIndices);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Verts: %i\n", mRS.NumVerts);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Render AnimPolys: %i\n", mRS.NumAnimRendPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Occluding AnimPolys: %i\n", mRS.NumAnimPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Render Polys: %i\n", mRS.NumRendPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Occluding Polys: %i\n", mRS.NumPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
gRenDev->mfPrintString ("\nBlended Polygons status info:\n", PS_TRANSPARENT | PS_UP);*/
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
|
||||
// Parsing
|
||||
|
||||
void CREPolyBlend_Base::mfCompileOrients(SShader *ef, int *nums, SOrient *Orients[], char *scr)
|
||||
{
|
||||
if (!scr || !scr[0])
|
||||
{
|
||||
Warning( 0,0,"Can't declare orient for effector '%s'\n", ef->m_Name.c_str());
|
||||
*nums = 1;
|
||||
Orients[0] = &gRenDev->m_cEF.m_Orients[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
int ors[16];
|
||||
*nums = sscanf(scr, "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", &ors[0], &ors[1], &ors[2], &ors[3], &ors[4], &ors[5], &ors[6], &ors[7], &ors[8], &ors[9], &ors[10], &ors[11], &ors[12], &ors[13], &ors[14], &ors[15]);
|
||||
if (!(*nums))
|
||||
{
|
||||
Warning( 0,0,"Can't declare orient for effector '%s'\n", ef->m_Name.c_str());
|
||||
*nums = 1;
|
||||
Orients[0] = &gRenDev->m_cEF.m_Orients[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<*nums; i++)
|
||||
{
|
||||
if (ors[i] >= gRenDev->m_cEF.m_NumOrients)
|
||||
{
|
||||
Warning( 0,0,"Can't declare %d orient (Use Ortho mode)\n", ors[i]);
|
||||
*nums = 1;
|
||||
Orients[0] = &gRenDev->m_cEF.m_Orients[0];
|
||||
return;
|
||||
}
|
||||
Orients[i] = &gRenDev->m_cEF.m_Orients[ors[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CREPolyBlend_Base::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
char* name;
|
||||
long cmd;
|
||||
char *params;
|
||||
char *data;
|
||||
|
||||
enum {eTrace=1, eType, eScale, eScalX, eScalY, eOrients, eRGBStyle, eAlphaStyle};
|
||||
static tokenDesc commands[] =
|
||||
{
|
||||
{eTrace, "Trace"},
|
||||
{eType, "Type"},
|
||||
{eScale, "Scale"},
|
||||
{eScalX, "ScalX"},
|
||||
{eScalY, "ScalY"},
|
||||
{eOrients, "Orients"},
|
||||
{eRGBStyle, "RGBStyle"},
|
||||
{eAlphaStyle, "AlphaStyle"},
|
||||
|
||||
{0,0}
|
||||
};
|
||||
|
||||
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
||||
{
|
||||
data = NULL;
|
||||
if (name)
|
||||
data = name;
|
||||
else
|
||||
if (params)
|
||||
data = params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eTrace:
|
||||
mfUpdateFlags(FCEFPB_TRACE);
|
||||
break;
|
||||
|
||||
case eType:
|
||||
if (!stricmp(data, "Beam"))
|
||||
this->eType = ePBT_Beam;
|
||||
else
|
||||
Warning( 0,0,"unknown Type parameter '%s' in Shader '%s' (CREPolyBlend)\n", data, ef->m_Name.c_str());
|
||||
break;
|
||||
|
||||
case eScale:
|
||||
ScaleX = ScaleY = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eScalX:
|
||||
ScaleX = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eScalY:
|
||||
ScaleY = shGetFloat(data);
|
||||
break;
|
||||
|
||||
case eRGBStyle:
|
||||
if (!stricmp(data, "Decay"))
|
||||
{
|
||||
eColStyle = ePBCS_Decay;
|
||||
if (!params || !params[0])
|
||||
{
|
||||
Warning( 0,0,"missing RgbStyle Decay value in Shader '%s' (skipped) (CREPolyBlend)\n", ef->m_Name.c_str());
|
||||
Val0 = 1;
|
||||
Val1 = 0;
|
||||
LiveTime = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(params, "%f %f %f", &Val0, &Val1, &LiveTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
Warning( 0,0,"unknown RgbStyle parameter '%s' in Shader '%s' (CREPolyBlend)\n", data, ef->m_Name.c_str());
|
||||
|
||||
case eAlphaStyle:
|
||||
if (!stricmp(data, "Decay"))
|
||||
{
|
||||
this->eAlphaStyle = ePBCS_Decay;
|
||||
if (!params || !params[0])
|
||||
{
|
||||
Warning( 0,0,"missing RgbStyle Decay value in Shader '%s' (skipped) (CREPolyBlend)\n", ef->m_Name.c_str());
|
||||
ValA0 = 1;
|
||||
ValA1 = 0;
|
||||
LiveTimeA = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(params, "%f %f %f", &ValA0, &ValA1, &LiveTimeA);
|
||||
}
|
||||
}
|
||||
else
|
||||
Warning( 0,0,"unknown RgbStyle parameter '%s' in Shader '%s' (CREPolyBlend)\n", data, ef->m_Name.c_str());
|
||||
|
||||
|
||||
case eOrients:
|
||||
mfCompileOrients(ef, &NumOrients, Orients, params);
|
||||
if (Orients[0] == &gRenDev->m_cEF.m_Orients[0])
|
||||
mfUpdateFlags(FCEFPB_ORTHO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
121
RenderDll/Common/RendElements/CREPolyBlend.h
Normal file
121
RenderDll/Common/RendElements/CREPolyBlend.h
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
#ifndef __CREPOLYBLEND_H__
|
||||
#define __CREPOLYBLEND_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
#define FCEFPB_TRACE 0x10000
|
||||
#define FCEFPB_ORTHO 0x20000
|
||||
#define FCEFPB_SCALE 0x40000
|
||||
#define FCEFPB_PLANET 0x80000
|
||||
|
||||
enum ePBColStyle
|
||||
{
|
||||
ePBCS_None,
|
||||
ePBCS_Decay,
|
||||
};
|
||||
|
||||
enum ePBType
|
||||
{
|
||||
ePBT_Sprite,
|
||||
ePBT_Beam,
|
||||
};
|
||||
|
||||
struct SPolyBlendStat
|
||||
{
|
||||
int NumPolys;
|
||||
int NumRendPolys;
|
||||
int NumAnimPolys;
|
||||
int NumAnimRendPolys;
|
||||
int NumVerts;
|
||||
int NumIndices;
|
||||
};
|
||||
|
||||
class CREPolyBlend_Base : public CRendElement
|
||||
{
|
||||
public:
|
||||
float ScaleX, ScaleY;
|
||||
int NumOrients;
|
||||
SOrient *Orients[16];
|
||||
ePBColStyle eColStyle;
|
||||
ePBColStyle eAlphaStyle;
|
||||
ePBType eType;
|
||||
float LiveTime;
|
||||
float LiveTimeA;
|
||||
float Val0;
|
||||
float Val1;
|
||||
float ValA0;
|
||||
float ValA1;
|
||||
|
||||
public:
|
||||
CREPolyBlend_Base()
|
||||
{
|
||||
ScaleX = ScaleY = 0;
|
||||
eColStyle = ePBCS_None;
|
||||
eType = ePBT_Sprite;
|
||||
LiveTime = 0;
|
||||
}
|
||||
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
|
||||
protected:
|
||||
bool mfPrepareRB(CCObject *obj, Vec3d& orgo, CFColor& col);
|
||||
void mfSetVerts(CCObject *obj, Vec3d& orgo, uint c, SOrient *ori);
|
||||
|
||||
void mfCompileOrients(SShader *ef, int *nums, SOrient *Orients[], char *scr);
|
||||
};
|
||||
|
||||
class CREPolyBlend : public CREPolyBlend_Base
|
||||
{
|
||||
public:
|
||||
|
||||
static SPolyBlendStat mRS;
|
||||
static void mfPrintStat();
|
||||
|
||||
public:
|
||||
CREPolyBlend()
|
||||
{
|
||||
mfSetType(eDATA_PolyBlend);
|
||||
Val0 = Val1 = 0;
|
||||
mfSetFlags(FCEF_NEEDFILLBUF);
|
||||
}
|
||||
|
||||
virtual ~CREPolyBlend() {};
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfCull(CCObject *obj);
|
||||
virtual CRendElement *mfCopyConstruct(void)
|
||||
{
|
||||
CREPolyBlend *pb = new CREPolyBlend;
|
||||
*pb = *this;
|
||||
return pb;
|
||||
}
|
||||
virtual bool mfIsValidTime(SShader *ef, CCObject *obj, float curtime);
|
||||
};
|
||||
|
||||
|
||||
class CREAnimPolyBlend : public CREPolyBlend_Base
|
||||
{
|
||||
public:
|
||||
int curNum;
|
||||
|
||||
public:
|
||||
CREAnimPolyBlend() : CREPolyBlend_Base()
|
||||
{
|
||||
mfSetType(eDATA_AnimPolyBlend);
|
||||
mfSetFlags(FCEF_NEEDFILLBUF);
|
||||
}
|
||||
virtual ~CREAnimPolyBlend() {};
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfCull(CCObject *obj);
|
||||
virtual CRendElement *mfCopyConstruct(void)
|
||||
{
|
||||
CREAnimPolyBlend *apb = new CREAnimPolyBlend;
|
||||
*apb = *this;
|
||||
return apb;
|
||||
}
|
||||
virtual bool mfIsValidTime(SShader *ef, CCObject *obj, float curtime);
|
||||
};
|
||||
|
||||
#endif // __CREPOLYBLEND_H__
|
||||
485
RenderDll/Common/RendElements/CREPolyMesh.cpp
Normal file
485
RenderDll/Common/RendElements/CREPolyMesh.cpp
Normal file
@@ -0,0 +1,485 @@
|
||||
/*=============================================================================
|
||||
CREPolyMesh.cpp : implementation of mesh polygons RE.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include <CREPolyMesh.h>
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
SPolyStat CREPolyMesh::mRS;
|
||||
|
||||
CREPolyMesh::~CREPolyMesh()
|
||||
{
|
||||
if (TriVerts)
|
||||
delete [] TriVerts;
|
||||
if (Indices)
|
||||
delete [] Indices;
|
||||
if (bNoDeform)
|
||||
delete [] bNoDeform;
|
||||
}
|
||||
|
||||
void CREPolyMesh::mfGetPlane(Plane& pl)
|
||||
{
|
||||
pl.n = m_Plane.n;
|
||||
pl.d = m_Plane.d;
|
||||
}
|
||||
|
||||
CRendElement *CREPolyMesh::mfCopyConstruct(void)
|
||||
{
|
||||
CREPolyMesh *pm = new CREPolyMesh;
|
||||
*pm = *this;
|
||||
return pm;
|
||||
}
|
||||
|
||||
bool CREPolyMesh::mfCullFace(ECull cl)
|
||||
{
|
||||
CREPolyMesh::mRS.NumOccPolys++;
|
||||
|
||||
if (cl != eCULL_None)
|
||||
{
|
||||
float d = m_Plane.n * gRenDev->m_RP.m_ViewOrg;
|
||||
if (cl == eCULL_Front)
|
||||
{
|
||||
if (d < m_Plane.d-8.0f)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d > m_Plane.d+8.0f)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
CREPolyMesh::mRS.NumRendPolys++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CREPolyMesh::mfCenter(Vec3d& centr, CCObject *pObj)
|
||||
{
|
||||
int i;
|
||||
|
||||
centr(0,0,0);
|
||||
for (i=0; i<NumVerts; i++)
|
||||
{
|
||||
centr += TriVerts[i].vert;
|
||||
}
|
||||
float s = 1.0f / NumVerts;
|
||||
centr *= s;
|
||||
if (pObj)
|
||||
centr += pObj->GetTranslation();
|
||||
}
|
||||
|
||||
int CREPolyMesh::mfTransform(Matrix44& ViewMatr, Matrix44& ProjMatr, vec4_t *verts, vec4_t *vertsp, int Num)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<NumVerts; i++)
|
||||
{
|
||||
if (i == Num)
|
||||
break;
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
verts[i][j] = TriVerts[i].vert[0]*ViewMatr(0,j) + TriVerts[i].vert[1]*ViewMatr(1,j) + TriVerts[i].vert[2]*ViewMatr(2,j) + ViewMatr(3,j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<NumVerts; i++)
|
||||
{
|
||||
if (i == Num)
|
||||
break;
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
vertsp[i][j] = verts[i][0]*ProjMatr(0,j) + verts[i][1]*ProjMatr(1,j) + verts[i][2]*ProjMatr(2,j) + verts[i][3]*ProjMatr(3,j);
|
||||
}
|
||||
}
|
||||
return NumVerts;
|
||||
}
|
||||
|
||||
void CREPolyMesh::mfPrepare(void)
|
||||
{
|
||||
ushort *inds;
|
||||
int i, n;
|
||||
SShader *ef = gRenDev->m_RP.m_pShader;
|
||||
|
||||
CREPolyMesh::mRS.NumVerts += NumVerts;
|
||||
CREPolyMesh::mRS.NumIndices += NumIndices;
|
||||
|
||||
// Check overflow
|
||||
gRenDev->EF_CheckOverflow(NumVerts, NumIndices, this);
|
||||
|
||||
inds = Indices;
|
||||
n = gRenDev->m_RP.m_RendNumVerts;
|
||||
#ifdef OPENGL
|
||||
ushort *dinds = &gRenDev->m_RP.m_RendIndices[gRenDev->m_RP.m_RendNumIndices];
|
||||
#else
|
||||
ushort *dinds = &gRenDev->m_RP.m_RendIndices[gRenDev->m_RP.m_RendNumIndices];
|
||||
#endif
|
||||
i = NumIndices;
|
||||
gRenDev->m_RP.m_RendNumIndices += i;
|
||||
while(i--)
|
||||
{
|
||||
*dinds++ = *inds++ + n;
|
||||
}
|
||||
|
||||
UPipeVertex ptr = gRenDev->m_RP.m_NextPtr;
|
||||
//SMRendTexVert *rtvb, *rtvl;
|
||||
SMTriVert *tv = TriVerts;
|
||||
//byte *OffsN;
|
||||
int m = NumVerts;
|
||||
|
||||
/*switch (gRenDev->m_RP.mFT)
|
||||
{
|
||||
case FLT_BASE:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_1T->st);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_COL:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_1T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_1T->st);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_COL:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_1T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_LM:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_2T->st[0]);
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_LM + FLT_COL:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_2T->st[0]);
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_LM:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_LM + FLT_COL:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_SYSLM:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
rtvl = &gRenDev->m_RP.m_pLMTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++, rtvl++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].lmTC, rtvl->vert);
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_SYSLM + FLT_COL:
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
rtvl = &gRenDev->m_RP.m_pLMTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride, rtvb++, rtvl++)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, rtvl->vert);
|
||||
Vector2Copy(tv[i].dTC, rtvb->vert);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case FLT_BASE + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_1T->st);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_1T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_1T->st);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_1T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_LM + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_2T->st[0]);
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_BASE + FLT_LM + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].dTC, ptr.Ptr_D_2T->st[0]);
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_LM + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_LM + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_SYSLM + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
rtvl = &gRenDev->m_RP.m_pLMTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
Vector2Copy(tv[i].lmTC, rtvl[i].vert);
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSBASE + FLT_SYSLM + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvb = &gRenDev->m_RP.m_pBaseTexCoordPointer[n];
|
||||
rtvl = &gRenDev->m_RP.m_pLMTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, rtvl[i].vert);
|
||||
Vector2Copy(tv[i].dTC, rtvb[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_LM + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, ptr.Ptr_D_2T->st[1]);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_SYSLM + FLT_COL + FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
rtvl = &gRenDev->m_RP.m_pLMTexCoordPointer[n];
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
Vector2Copy(tv[i].lmTC, rtvl[i].vert);
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_COL:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
ptr.Ptr_D_2T->color.dcolor = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case FLT_N:
|
||||
OffsN = gRenDev->m_RP.m_OffsN + ptr.PtrB;
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
*(float *)(OffsN) = m_Plane.n.x;
|
||||
*(float *)(OffsN+4) = m_Plane.n.y;
|
||||
*(float *)(OffsN+8) = m_Plane.n.z;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
for (i=0; i<m; i++, ptr.PtrB+=gRenDev->m_RP.m_Stride)
|
||||
{
|
||||
ptr.Ptr_D_1T->xyz = tv[i].vert;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}*/
|
||||
|
||||
gRenDev->m_RP.m_NextPtr = ptr;
|
||||
gRenDev->m_RP.m_RendNumVerts += NumVerts;
|
||||
}
|
||||
|
||||
void CREPolyMesh::mfPrintStat()
|
||||
{
|
||||
// char str[1024];
|
||||
|
||||
/* *gpCurPrX = 4;
|
||||
sprintf(str, "Num Indices: %i\n", mRS.NumIndices);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Verts: %i\n", mRS.NumVerts);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Rend. Details: %i\n", mRS.NumRendDetails);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Calc. Details: %i\n", mRS.NumDetails);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num Rend Polys: %i\n", mRS.NumRendPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
sprintf(str, "Num BSP Occluded Polys: %i\n", mRS.NumOccPolys);
|
||||
gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP);
|
||||
|
||||
*gpCurPrX = 4;
|
||||
gRenDev->mfPrintString ("\nPolys status info:\n", PS_TRANSPARENT | PS_UP);*/
|
||||
}
|
||||
76
RenderDll/Common/RendElements/CREPrefabGeom.cpp
Normal file
76
RenderDll/Common/RendElements/CREPrefabGeom.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*=============================================================================
|
||||
CREPrefabGeom.cpp : implementation of wall geometry RE for the editor.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
//===============================================================
|
||||
|
||||
CRendElement *CREPrefabGeom::mfCopyConstruct(void)
|
||||
{
|
||||
CREPrefabGeom *cp = new CREPrefabGeom;
|
||||
*cp = *this;
|
||||
return cp;
|
||||
}
|
||||
|
||||
bool CREPrefabGeom::mfCompile(SShader *ef, char *scr)
|
||||
{
|
||||
char* name;
|
||||
long cmd;
|
||||
char *params;
|
||||
char *data;
|
||||
|
||||
enum {eModel=1};
|
||||
static tokenDesc commands[] =
|
||||
{
|
||||
{eModel, "Model"},
|
||||
|
||||
{0,0}
|
||||
};
|
||||
|
||||
while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0)
|
||||
{
|
||||
data = NULL;
|
||||
if (name)
|
||||
data = name;
|
||||
else
|
||||
if (params)
|
||||
data = params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eModel:
|
||||
mModel = NULL;//(CModelCgf *)CComModel::mfForName(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mModel)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CREPrefabGeom::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
bool CREPrefabGeom::mfDraw(SShader *ef, SShaderPass *sl)
|
||||
{
|
||||
//if (mModel)
|
||||
// mModel->mfDraw(ef, bCamera);
|
||||
return true;
|
||||
}
|
||||
41
RenderDll/Common/RendElements/CREPrefabGeom.h
Normal file
41
RenderDll/Common/RendElements/CREPrefabGeom.h
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
#ifndef __CREPREFABGEOM_H__
|
||||
#define __CREPREFABGEOM_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
struct SREPrefabStat
|
||||
{
|
||||
int NumRendPolys;
|
||||
int NumVerts;
|
||||
int NumIndices;
|
||||
};
|
||||
|
||||
class CModelCgf;
|
||||
|
||||
class CREPrefabGeom : public CRendElement
|
||||
{
|
||||
public:
|
||||
void *mModel;
|
||||
|
||||
static SREPrefabStat mRS;
|
||||
static void mfPrintStat();
|
||||
|
||||
public:
|
||||
CREPrefabGeom()
|
||||
{
|
||||
mfSetType(eDATA_Prefab);
|
||||
mModel = 0;
|
||||
mfSetFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
virtual ~CREPrefabGeom() {};
|
||||
|
||||
bool mfCullBox(Vec3d vmin, Vec3d vmax);
|
||||
virtual CRendElement *mfCopyConstruct(void);
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sl);
|
||||
};
|
||||
|
||||
#endif // __CREPREFABGEOM_H__
|
||||
381
RenderDll/Common/RendElements/CREScreenCommon.h
Normal file
381
RenderDll/Common/RendElements/CREScreenCommon.h
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
=========================================================================
|
||||
FILE : CRECommon.h
|
||||
DESC : render elements common stuff
|
||||
PROJ : Crytek Engine
|
||||
CODER: Tiago Sousa
|
||||
|
||||
NOTE/TODO/FIX:
|
||||
|
||||
. All shaders, specialized textures used, should be initialized/destroyed
|
||||
in CScreenVars class
|
||||
|
||||
. All data should be fx/name independent, accessible trought data index
|
||||
|
||||
. Give better data organization..
|
||||
|
||||
Last Update: 13/10/2003
|
||||
=========================================================================
|
||||
*/
|
||||
|
||||
#ifndef _CRECOMMON_H_
|
||||
#define _CRECOMMON_H_
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// screen processing types parameter
|
||||
|
||||
|
||||
enum EProcessType
|
||||
{
|
||||
SCREENPROCESS_FADE,
|
||||
SCREENPROCESS_BLUR,
|
||||
SCREENPROCESS_COLORTRANSFER,
|
||||
SCREENPROCESS_CONTRAST,
|
||||
SCREENPROCESS_MOTIONBLUR,
|
||||
SCREENPROCESS_GLARE,
|
||||
SCREENPROCESS_NIGHTVISION,
|
||||
SCREENPROCESS_HEATVISION,
|
||||
SCREENPROCESS_FLASHBANG,
|
||||
SCREENPROCESS_CARTOON,
|
||||
SCREENPROCESS_DOF,
|
||||
|
||||
// special case, to get screen texture, after all post-processing
|
||||
SCREENPROCESS_SCREENTEX,
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// screen processing types parameters
|
||||
|
||||
enum EProcessParameter
|
||||
{
|
||||
SCREENPROCESS_FADECOLOR,
|
||||
|
||||
SCREENPROCESS_BLURAMOUNT,
|
||||
SCREENPROCESS_BLURCOLORRED,
|
||||
SCREENPROCESS_BLURCOLORGREEN,
|
||||
SCREENPROCESS_BLURCOLORBLUE,
|
||||
|
||||
SCREENPROCESS_COLORTRANSFERCOLOR,
|
||||
SCREENPROCESS_COLORTRANSFERAMOUNT,
|
||||
|
||||
SCREENPROCESS_CONTRASTAMOUNT,
|
||||
|
||||
SCREENPROCESS_MOTIONBLURTYPE,
|
||||
SCREENPROCESS_MOTIONBLURAMOUNT,
|
||||
SCREENPROCESS_MOTIONBLURDISPLACE,
|
||||
|
||||
SCREENPROCESS_GLAREAMOUNT,
|
||||
SCREENPROCESS_GLARELUMSIZE,
|
||||
SCREENPROCESS_GLAREMAXAMOUNT,
|
||||
SCREENPROCESS_GLAREBOXSIZE,
|
||||
SCREENPROCESS_GLARETHRESHOLD,
|
||||
|
||||
SCREENPROCESS_NIGHTVISIONCOLORRED,
|
||||
SCREENPROCESS_NIGHTVISIONCOLORGREEN,
|
||||
SCREENPROCESS_NIGHTVISIONCOLORBLUE,
|
||||
|
||||
SCREENPROCESS_FLASHBANGTIMESCALE,
|
||||
SCREENPROCESS_FLASHBANGFLASHPOSX,
|
||||
SCREENPROCESS_FLASHBANGFLASHPOSY,
|
||||
SCREENPROCESS_FLASHBANGFLASHSIZEX,
|
||||
SCREENPROCESS_FLASHBANGFLASHSIZEY,
|
||||
SCREENPROCESS_FLASHBANGTIMEOUT,
|
||||
SCREENPROCESS_FLASHBANGFORCEAFTERIMAGE,
|
||||
|
||||
SCREENPROCESS_DOFFOCALDISTANCE,
|
||||
SCREENPROCESS_DOFBLURAMOUNT,
|
||||
|
||||
SCREENPROCESS_TRANSITIONTIME,
|
||||
SCREENPROCESS_PRETRANSITIONTIME,
|
||||
SCREENPROCESS_ACTIVE
|
||||
};
|
||||
|
||||
#define SHADERSCHECK !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// screen processing vars class
|
||||
|
||||
class CScreenVars
|
||||
{
|
||||
public:
|
||||
|
||||
CScreenVars()
|
||||
{
|
||||
// initialize members
|
||||
|
||||
// set shaders to null...
|
||||
m_pRCColorTransfer=0;
|
||||
m_pVPColorTransfer=0;
|
||||
m_pRCMotion=0;
|
||||
m_pRCMotionAmount=0;
|
||||
m_pVPMotion=0;
|
||||
m_pRCBluryScreen=0;
|
||||
m_pVPBluryScreen=0;
|
||||
m_pRCGlareMap=0;
|
||||
m_pRCGlareAmountMap=0;
|
||||
m_pRCGlare=0;
|
||||
m_pRCRenderModeCold=0;
|
||||
m_pRCRenderModeAdv=0;
|
||||
m_pVPGlare=0;
|
||||
m_pRCNightVision=0;
|
||||
m_pVPNightVision=0;
|
||||
m_pRCHeatVision=0;
|
||||
m_pRCHeatSourceDecode=0;
|
||||
m_pRCFlashBang=0;
|
||||
m_pVPFlashBang=0;
|
||||
m_pRCFlashBang=0;
|
||||
m_pVPFlashBang=0;
|
||||
m_pRCBlur=0;
|
||||
m_pVPBlur=0;
|
||||
m_pRCReplRgbToAlpha=0;
|
||||
m_pVPCartoon=0;
|
||||
m_pRCCartoon=0;
|
||||
m_pRCCartoonSilhouette=0;
|
||||
m_pRCDof=0;
|
||||
|
||||
// fade process vars
|
||||
m_bFadeActive=0;
|
||||
m_fFadeTime=0;
|
||||
m_fFadePreTime=0;
|
||||
m_fFadeCurrPreTime=0;
|
||||
m_fFadeCurrTime=0;
|
||||
m_pFadeColor.set(0,0,0,0);
|
||||
m_pFadeCurrColor.set(0,0,0,0);
|
||||
|
||||
// color transfer vars
|
||||
m_bColorTransferActive=0;
|
||||
m_pColorTransferColor.set(0,0,0,0);
|
||||
m_fColorTransferAmount=1;
|
||||
|
||||
// motion blur vars
|
||||
m_bMotionBlurActive=0;
|
||||
m_fMotionBlurAmount=0.9f;
|
||||
m_iMotionBlurType=1;
|
||||
m_iMotionBlurDisplace=0;
|
||||
|
||||
// blury screen vars
|
||||
m_bBlurActive=0;
|
||||
m_fBlurAmount=1.0f;
|
||||
m_pBlurColor.set(1,1,1,1);
|
||||
|
||||
// glare vars
|
||||
m_bGlareActive=0;
|
||||
m_fGlareThreshold=75;
|
||||
m_iGlareBox=2;
|
||||
m_iGlareLumSize=2;
|
||||
m_iGlareSize=128;
|
||||
m_fGlareAmount=1.0f;
|
||||
m_fGlareAmountDynamic=1.0f;
|
||||
m_fGlareMaxAmount=4.0f;
|
||||
m_pCurrGlareMapConst.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
m_pCurrSaturation.set(0.0f, 0.0f, 0.0f, 0.2f);
|
||||
m_pCurrContrast.set(0.0f, 0.0f, 0.85f, 0.15f);
|
||||
|
||||
// nightvision vars
|
||||
m_iNightVisionActive=0;
|
||||
m_pNightVisionColor.set(-0.1f, 0.2f, 0.11f, 1.0f);
|
||||
|
||||
// heatvision vars
|
||||
m_iHeatVisionActive=0;
|
||||
m_pCVHeatVision=0;
|
||||
|
||||
// flashbang vars
|
||||
m_bFlashBangActive=0;
|
||||
m_iFlashBangForce=0;
|
||||
m_fFlashBangTimeScale=1.0f;
|
||||
m_fFlashBangTimeOut=1.0f;
|
||||
m_fFlashBangFlashPosX=200;
|
||||
m_fFlashBangFlashPosY=100;
|
||||
m_fFlashBangFlashSizeX=400;
|
||||
m_fFlashBangFlashSizeY=400;
|
||||
|
||||
// cartoon vars
|
||||
m_bCartoonActive=0;
|
||||
|
||||
// depth of field vars
|
||||
m_bDofActive=0;
|
||||
m_fDofFocalDistance=0;
|
||||
|
||||
// screentex vars
|
||||
m_bScreenTexActive=0;
|
||||
|
||||
// console vars
|
||||
m_pCVDisableSfx=0; //GET_CVAR("r_DisableSfx");
|
||||
m_pCVResetSfx=0; //GET_CVAR("r_ResetScreenFx");
|
||||
m_pCVNormalGlare=0; //GET_CVAR("r_Glare");
|
||||
m_pCVMotionBlur=0; //GET_CVAR("r_MotionBlur");
|
||||
m_pCVScreenColorTransfer=0; //GET_CVAR("r_ScreenColorTransfer");
|
||||
m_pCVMotionBlurAmount=0; //GET_CVAR("r_MotionBlurAmount");
|
||||
m_pCVMotionBlurDisplace=0; //GET_CVAR("r_MotionBlurDisplace");
|
||||
m_pCVRenderMode=0; //GET_CVAR("r_RenderMode");
|
||||
|
||||
// note: these are used for correct cryvision functioning
|
||||
m_pCVStencilShadows=0; //GET_CVAR("e_stencil_shadows")
|
||||
m_iPrevStencilShadows=0;
|
||||
|
||||
m_pCVShadowMaps=0; //GET_CVAR("e_shadow_maps");
|
||||
m_iPrevShadowMaps=0;
|
||||
|
||||
m_pCVVolFog=0; //GET_CVAR("r_volumetricfog");
|
||||
m_iPrevVolFog=0;
|
||||
|
||||
m_pCVFog=0; //GET_CVAR("e_fog");
|
||||
m_iPrevFog=0;
|
||||
};
|
||||
|
||||
~CScreenVars()
|
||||
{
|
||||
Release();
|
||||
};
|
||||
|
||||
// shaders used:
|
||||
|
||||
// color transfer shaders
|
||||
void *m_pRCColorTransfer;
|
||||
void *m_pVPColorTransfer;
|
||||
|
||||
// motion blur shaders
|
||||
void *m_pRCMotion,
|
||||
*m_pRCMotionAmount;
|
||||
void *m_pVPMotion;
|
||||
|
||||
// blury screen shaders
|
||||
void *m_pRCBluryScreen;
|
||||
void *m_pVPBluryScreen;
|
||||
|
||||
// image enhancement shaders
|
||||
void *m_pRCGlareMap,
|
||||
*m_pRCGlareAmountMap,
|
||||
*m_pRCGlare,
|
||||
*m_pRCRenderModeCold,
|
||||
*m_pRCRenderModeAdv;
|
||||
|
||||
void *m_pVPGlare;
|
||||
|
||||
// nightvision shaders
|
||||
void *m_pRCNightVision;
|
||||
void *m_pVPNightVision;
|
||||
|
||||
// heatvision shaders
|
||||
void *m_pRCHeatVision,
|
||||
*m_pRCHeatSourceDecode;
|
||||
|
||||
// flashbang shaders
|
||||
void *m_pRCFlashBang;
|
||||
void *m_pVPFlashBang;
|
||||
|
||||
// cartoon shaders
|
||||
void *m_pRCCartoon,
|
||||
*m_pRCCartoonSilhouette;
|
||||
void *m_pVPCartoon;
|
||||
|
||||
// depth of field shaders
|
||||
void *m_pRCDof;
|
||||
|
||||
// shared shaders
|
||||
void *m_pRCBlur;
|
||||
void *m_pRCBlurRECT;
|
||||
void *m_pVPBlur;
|
||||
void *m_pRCReplRgbToAlpha;
|
||||
|
||||
// fade process vars
|
||||
bool m_bFadeActive;
|
||||
float m_fFadeTime,
|
||||
m_fFadeCurrTime,
|
||||
m_fFadePreTime,
|
||||
m_fFadeCurrPreTime;
|
||||
|
||||
color4f m_pFadeColor,
|
||||
m_pFadeCurrColor;
|
||||
|
||||
// color transfer vars
|
||||
bool m_bColorTransferActive;
|
||||
color4f m_pColorTransferColor;
|
||||
float m_fColorTransferAmount;
|
||||
|
||||
// motion blur vars
|
||||
bool m_bMotionBlurActive;
|
||||
float m_fMotionBlurAmount;
|
||||
int m_iMotionBlurType,
|
||||
m_iMotionBlurDisplace;
|
||||
|
||||
// blury screen vars
|
||||
bool m_bBlurActive;
|
||||
float m_fBlurAmount;
|
||||
float m_iBlurWidth,
|
||||
m_iBlurHeight;
|
||||
color4f m_pBlurColor;
|
||||
|
||||
// image enhancement vars
|
||||
bool m_bGlareActive;
|
||||
int m_iGlareBox,
|
||||
m_iGlareLumSize,
|
||||
m_iGlareSize;
|
||||
float m_fGlareAmount,
|
||||
m_fGlareThreshold,
|
||||
m_fGlareAmountDynamic,
|
||||
m_fGlareMaxAmount;
|
||||
color4f m_pCurrGlareMapConst,
|
||||
m_pCurrSaturation,
|
||||
m_pCurrContrast;
|
||||
// nightvision vars
|
||||
int m_iNightVisionActive;
|
||||
color4f m_pNightVisionColor;
|
||||
|
||||
|
||||
// heatvision vars
|
||||
int m_iHeatVisionActive;
|
||||
ICVar *m_pCVHeatVision; //GET_CVAR("CV_r_cryvision");
|
||||
|
||||
// flashbang vars
|
||||
bool m_bFlashBangActive;
|
||||
int m_iFlashBangForce;
|
||||
float m_fFlashBangTimeScale,
|
||||
m_fFlashBangTimeOut,
|
||||
m_fFlashBangFlashPosX,
|
||||
m_fFlashBangFlashPosY,
|
||||
m_fFlashBangFlashSizeX,
|
||||
m_fFlashBangFlashSizeY;
|
||||
|
||||
// cartoon rendering vars
|
||||
bool m_bCartoonActive;
|
||||
|
||||
// depth of field vars
|
||||
bool m_bDofActive;
|
||||
float m_fDofFocalDistance;
|
||||
|
||||
// screen texture vars
|
||||
bool m_bScreenTexActive;
|
||||
|
||||
// console vars
|
||||
ICVar *m_pCVDisableSfx; //GET_CVAR("r_DisableSfx");
|
||||
ICVar *m_pCVResetSfx; //GET_CVAR("r_ResetScreenFx");
|
||||
ICVar *m_pCVNormalGlare; //GET_CVAR("r_Glare");
|
||||
ICVar *m_pCVMotionBlur; //GET_CVAR("r_MotionBlur");
|
||||
ICVar *m_pCVScreenColorTransfer; //GET_CVAR("r_ScreenColorTransfer");
|
||||
ICVar *m_pCVMotionBlurAmount; //GET_CVAR("r_MotionBlurAmount");
|
||||
ICVar *m_pCVMotionBlurDisplace; //GET_CVAR("r_MotionBlurDisplace");
|
||||
ICVar *m_pCVRenderMode; //GET_CVAR("r_RenderMode");
|
||||
|
||||
// note: these are used for correct cryvision functioning
|
||||
ICVar *m_pCVStencilShadows; //GET_CVAR("e_stencil_shadows")
|
||||
int m_iPrevStencilShadows;
|
||||
|
||||
ICVar *m_pCVShadowMaps; //GET_CVAR("e_shadow_maps");
|
||||
int m_iPrevShadowMaps;
|
||||
|
||||
ICVar *m_pCVVolFog; //GET_CVAR("r_volumetricfog");
|
||||
int m_iPrevVolFog;
|
||||
|
||||
ICVar *m_pCVFog; //GET_CVAR("e_fog");
|
||||
int m_iPrevFog;
|
||||
|
||||
ICVar *m_pCVMaxTexLodBias; //GET_CVAR("r_MaxTexLodBias");
|
||||
float m_fPrevMaxTexLodBias;
|
||||
|
||||
void Create(void);
|
||||
void Release(void);
|
||||
void Reset(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
670
RenderDll/Common/RendElements/CREScreenProcess.cpp
Normal file
670
RenderDll/Common/RendElements/CREScreenProcess.cpp
Normal file
@@ -0,0 +1,670 @@
|
||||
/*
|
||||
=======================================================================
|
||||
FILE : CREScreenProcess.cpp
|
||||
DESC : screen processing render element
|
||||
PROJ : Crytek Engine
|
||||
CODER: Tiago Sousa
|
||||
|
||||
TODO:
|
||||
.Convert all screen based effects into this interface
|
||||
|
||||
Last Update: 16/06/2003
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
// some helper macros
|
||||
#define SET_PARAMETER(pProcess, pParam, pType, pValue) \
|
||||
case (pProcess): (pParam)=*((pType*) pValue); break; \
|
||||
|
||||
#define RETURN_PARAMETER(pProcess, pParam) \
|
||||
case (pProcess): return (void*)&pParam;\
|
||||
|
||||
// constructor/destructor
|
||||
CREScreenProcess::CREScreenProcess()
|
||||
{
|
||||
// setup screen process renderer type
|
||||
mfSetType(eDATA_ScreenProcess);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
m_pVars=0;
|
||||
|
||||
// create class vars if necessary...
|
||||
if(!m_pVars)
|
||||
{
|
||||
m_pVars=new CScreenVars;
|
||||
m_pVars->Create();
|
||||
}
|
||||
}
|
||||
|
||||
CREScreenProcess::~CREScreenProcess()
|
||||
{
|
||||
SAFE_DELETE(m_pVars)
|
||||
};
|
||||
|
||||
// prepare screen processing
|
||||
void CREScreenProcess:: mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
// make sure this is not processed, when rendering to refractive texture..
|
||||
if (gRenDev->m_RP.m_bDrawToTexture)
|
||||
{
|
||||
gRenDev->m_RP.m_pRE = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
}
|
||||
|
||||
gRenDev->m_RP.m_FlagsPerFlush |= RBSI_DRAWAS2D;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
void CREScreenProcess::mfReset()
|
||||
{
|
||||
if(m_pVars)
|
||||
{
|
||||
m_pVars->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// activate screen processes
|
||||
void CREScreenProcess:: mfActivate(int pProcess)
|
||||
{
|
||||
switch(pProcess)
|
||||
{
|
||||
case SCREENPROCESS_FADE:
|
||||
if(m_pVars->m_fFadeTime)
|
||||
{
|
||||
m_pVars->m_bFadeActive=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset fade
|
||||
m_pVars->m_bFadeActive=0;
|
||||
m_pVars->m_fFadePreTime=0.0f;
|
||||
m_pVars->m_fFadeCurrPreTime=0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCREENPROCESS_BLUR:
|
||||
m_pVars->m_bBlurActive=1;
|
||||
break;
|
||||
case SCREENPROCESS_COLORTRANSFER:
|
||||
m_pVars->m_bColorTransferActive=1;
|
||||
break;
|
||||
case SCREENPROCESS_MOTIONBLUR:
|
||||
m_pVars->m_bMotionBlurActive=1;
|
||||
break;
|
||||
case SCREENPROCESS_GLARE:
|
||||
m_pVars->m_bGlareActive=1;
|
||||
break;
|
||||
case SCREENPROCESS_NIGHTVISION:
|
||||
// m_pVars->m_bNightVisionActive=1;
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_pCVHeatVision->Set(1);
|
||||
}
|
||||
|
||||
break;
|
||||
case SCREENPROCESS_HEATVISION:
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_pCVHeatVision->Set(1);
|
||||
}
|
||||
break;
|
||||
case SCREENPROCESS_CARTOON:
|
||||
m_pVars->m_bCartoonActive=1;
|
||||
// reset fade amount
|
||||
if(iConsole)
|
||||
{
|
||||
if(m_pVars->m_pCVMaxTexLodBias)
|
||||
{
|
||||
if(m_pVars->m_bCartoonActive)
|
||||
{
|
||||
m_pVars->m_fPrevMaxTexLodBias=m_pVars->m_pCVMaxTexLodBias->GetFVal();
|
||||
m_pVars->m_pCVMaxTexLodBias->Set(-1.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pVars->m_fPrevMaxTexLodBias=m_pVars->m_pCVMaxTexLodBias->GetFVal();
|
||||
m_pVars->m_pCVMaxTexLodBias->Set(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCREENPROCESS_FLASHBANG:
|
||||
m_pVars->m_bFlashBangActive=1;
|
||||
// reset flash time out
|
||||
m_pVars->m_fFlashBangTimeOut=1.0f;
|
||||
break;
|
||||
case SCREENPROCESS_DOF:
|
||||
m_pVars->m_bDofActive=1;
|
||||
// reset dof focal distance plane
|
||||
m_pVars->m_fDofFocalDistance=20.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// set screen processing parameters
|
||||
int CREScreenProcess:: mfSetParameter(int iProcess, int iParams, void *dwValue)
|
||||
{
|
||||
switch(iProcess)
|
||||
{
|
||||
// set screen fade parameters
|
||||
case SCREENPROCESS_FADE:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_FADECOLOR, m_pVars->m_pFadeColor, color4f, dwValue)
|
||||
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
if(*((bool*) dwValue)==1)
|
||||
{
|
||||
m_pVars->m_bFadeActive=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset fade
|
||||
m_pVars->m_bFadeActive=0;
|
||||
m_pVars->m_fFadePreTime=0.0f;
|
||||
m_pVars->m_fFadeCurrPreTime=0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCREENPROCESS_TRANSITIONTIME:
|
||||
m_pVars->m_fFadeTime=*((float*) dwValue);
|
||||
m_pVars->m_fFadeCurrTime=(float) fabs(*((float*) dwValue));
|
||||
break;
|
||||
|
||||
SET_PARAMETER(SCREENPROCESS_PRETRANSITIONTIME, m_pVars->m_fFadePreTime, float, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set screen blur parameters
|
||||
case SCREENPROCESS_BLUR:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_BLURAMOUNT, m_pVars->m_fBlurAmount, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bBlurActive, bool, dwValue)
|
||||
|
||||
case SCREENPROCESS_BLURCOLORRED:
|
||||
m_pVars->m_pBlurColor.r=*(float*)dwValue;
|
||||
break;
|
||||
case SCREENPROCESS_BLURCOLORGREEN:
|
||||
m_pVars->m_pBlurColor.g=*(float*)dwValue;
|
||||
break;
|
||||
case SCREENPROCESS_BLURCOLORBLUE:
|
||||
m_pVars->m_pBlurColor.b=*(float*)dwValue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// set color transfer parameters
|
||||
case SCREENPROCESS_COLORTRANSFER:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_COLORTRANSFERAMOUNT, m_pVars->m_fColorTransferAmount, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_COLORTRANSFERCOLOR, m_pVars->m_pColorTransferColor, color4f, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bColorTransferActive, bool, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set motion blur parameters
|
||||
case SCREENPROCESS_MOTIONBLUR:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_MOTIONBLURDISPLACE, m_pVars->m_iMotionBlurDisplace, int, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_MOTIONBLURAMOUNT, m_pVars->m_fMotionBlurAmount, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_MOTIONBLURTYPE, m_pVars->m_iMotionBlurType, int, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bMotionBlurActive, bool, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set glare parameters
|
||||
case SCREENPROCESS_GLARE:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bGlareActive, bool, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_GLAREAMOUNT, m_pVars->m_fGlareAmount, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_GLARELUMSIZE, m_pVars->m_iGlareLumSize, int, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_GLAREMAXAMOUNT, m_pVars->m_fGlareMaxAmount, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_GLAREBOXSIZE, m_pVars->m_iGlareSize, int, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_GLARETHRESHOLD, m_pVars->m_fGlareThreshold, float, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set nightvision parameters
|
||||
case SCREENPROCESS_NIGHTVISION:
|
||||
switch(iParams)
|
||||
{
|
||||
//SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bNightVisionActive, bool, dwValue)
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
// m_pVars->m_bNightVisionActive=*(bool*)dwValue;
|
||||
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_pCVHeatVision->Set(*((int*) dwValue));
|
||||
|
||||
/*
|
||||
// must disable some rendering in order to cryvision function properly
|
||||
if(m_pVars->m_pCVHeatVision->GetIVal())
|
||||
{
|
||||
m_pVars->m_iPrevStencilShadows=m_pVars->m_pCVStencilShadows->GetIVal();
|
||||
m_pVars->m_iPrevShadowMaps=m_pVars->m_pCVShadowMaps->GetIVal();
|
||||
m_pVars->m_iPrevVolFog=m_pVars->m_pCVVolFog->GetIVal();
|
||||
//m_pVars->m_iPrevFog=m_pVars->m_pCVFog->GetIVal();
|
||||
|
||||
m_pVars->m_pCVStencilShadows->Set(0);
|
||||
m_pVars->m_pCVShadowMaps->Set(0);
|
||||
m_pVars->m_pCVVolFog->Set(0);
|
||||
//m_pVars->m_pCVFog->Set(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pVars->m_pCVStencilShadows->Set(m_pVars->m_iPrevStencilShadows);
|
||||
m_pVars->m_pCVShadowMaps->Set(m_pVars->m_iPrevShadowMaps);
|
||||
m_pVars->m_pCVVolFog->Set(m_pVars->m_iPrevVolFog);
|
||||
//m_pVars->m_pCVFog->Set(m_pVars->m_iPrevFog);
|
||||
}*/
|
||||
}
|
||||
break;
|
||||
|
||||
case SCREENPROCESS_NIGHTVISIONCOLORRED:
|
||||
m_pVars->m_pNightVisionColor.r=*(float*)dwValue;
|
||||
break;
|
||||
case SCREENPROCESS_NIGHTVISIONCOLORGREEN:
|
||||
m_pVars->m_pNightVisionColor.g=*(float*)dwValue;
|
||||
break;
|
||||
case SCREENPROCESS_NIGHTVISIONCOLORBLUE:
|
||||
m_pVars->m_pNightVisionColor.b=*(float*)dwValue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// set heatvision parameters
|
||||
case SCREENPROCESS_HEATVISION:
|
||||
switch(iParams)
|
||||
{
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_pCVHeatVision->Set(*((int*) dwValue));
|
||||
}
|
||||
break;
|
||||
|
||||
//SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bHeatVisionActive, bool, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set flashbang parameters
|
||||
case SCREENPROCESS_FLASHBANG:
|
||||
switch(iParams)
|
||||
{
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
m_pVars->m_bFlashBangActive= *((bool*) dwValue);
|
||||
// reset flash time out
|
||||
m_pVars->m_fFlashBangTimeOut=1.0f;
|
||||
break;
|
||||
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGTIMESCALE, m_pVars->m_fFlashBangTimeScale, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGFLASHPOSX, m_pVars->m_fFlashBangFlashPosX, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGFLASHPOSY, m_pVars->m_fFlashBangFlashPosY, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGFLASHSIZEX, m_pVars->m_fFlashBangFlashSizeX, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGFLASHSIZEY, m_pVars->m_fFlashBangFlashSizeY, float, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_FLASHBANGFORCEAFTERIMAGE, m_pVars->m_iFlashBangForce, int, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set cartoon parameters
|
||||
case SCREENPROCESS_CARTOON:
|
||||
switch(iParams)
|
||||
{
|
||||
//SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bCartoonActive, bool, dwValue)
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
m_pVars->m_bCartoonActive= *((bool*) dwValue);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// set dof parameters
|
||||
case SCREENPROCESS_DOF:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bDofActive, bool, dwValue)
|
||||
SET_PARAMETER(SCREENPROCESS_DOFFOCALDISTANCE, m_pVars->m_fDofFocalDistance, float, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
// set screentex parameters
|
||||
case SCREENPROCESS_SCREENTEX:
|
||||
switch(iParams)
|
||||
{
|
||||
SET_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bScreenTexActive, bool, dwValue)
|
||||
}
|
||||
break;
|
||||
|
||||
//default:
|
||||
// break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get screen processing parameters
|
||||
void *CREScreenProcess:: mfGetParameter(int iProcess, int iParams)
|
||||
{
|
||||
switch(iProcess)
|
||||
{
|
||||
// return screen fade parameters
|
||||
case SCREENPROCESS_FADE:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_TRANSITIONTIME, m_pVars->m_fFadeTime)
|
||||
RETURN_PARAMETER(SCREENPROCESS_PRETRANSITIONTIME, m_pVars->m_fFadePreTime)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FADECOLOR, m_pVars->m_pFadeColor)
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bFadeActive)
|
||||
}
|
||||
break;
|
||||
|
||||
// return screen blur parameters
|
||||
case SCREENPROCESS_BLUR:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_BLURAMOUNT, m_pVars->m_fBlurAmount)
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bBlurActive)
|
||||
RETURN_PARAMETER(SCREENPROCESS_BLURCOLORRED, m_pVars->m_pBlurColor.r)
|
||||
RETURN_PARAMETER(SCREENPROCESS_BLURCOLORGREEN, m_pVars->m_pBlurColor.g)
|
||||
RETURN_PARAMETER(SCREENPROCESS_BLURCOLORBLUE, m_pVars->m_pBlurColor.b)
|
||||
}
|
||||
break;
|
||||
|
||||
// return color transfer parameters
|
||||
case SCREENPROCESS_COLORTRANSFER:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_COLORTRANSFERAMOUNT, m_pVars->m_fColorTransferAmount)
|
||||
RETURN_PARAMETER(SCREENPROCESS_COLORTRANSFERCOLOR, m_pVars->m_pColorTransferColor)
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bColorTransferActive)
|
||||
}
|
||||
break;
|
||||
|
||||
// return motion blur parameters
|
||||
case SCREENPROCESS_MOTIONBLUR:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_MOTIONBLURDISPLACE, m_pVars->m_iMotionBlurDisplace)
|
||||
RETURN_PARAMETER(SCREENPROCESS_MOTIONBLURAMOUNT, m_pVars->m_fMotionBlurAmount)
|
||||
RETURN_PARAMETER(SCREENPROCESS_MOTIONBLURTYPE, m_pVars->m_iMotionBlurType)
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bMotionBlurActive)
|
||||
}
|
||||
break;
|
||||
|
||||
// return glare parameters
|
||||
case SCREENPROCESS_GLARE:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bGlareActive)
|
||||
RETURN_PARAMETER(SCREENPROCESS_GLAREAMOUNT, m_pVars->m_fGlareAmount)
|
||||
RETURN_PARAMETER(SCREENPROCESS_GLARELUMSIZE, m_pVars->m_iGlareLumSize)
|
||||
RETURN_PARAMETER(SCREENPROCESS_GLAREMAXAMOUNT, m_pVars->m_fGlareMaxAmount)
|
||||
RETURN_PARAMETER(SCREENPROCESS_GLAREBOXSIZE, m_pVars->m_iGlareSize)
|
||||
RETURN_PARAMETER(SCREENPROCESS_GLARETHRESHOLD, m_pVars->m_fGlareThreshold)
|
||||
}
|
||||
break;
|
||||
|
||||
// return nightvision parameters
|
||||
case SCREENPROCESS_NIGHTVISION:
|
||||
switch(iParams)
|
||||
{
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
//RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bNightVisionActive)
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_iNightVisionActive=m_pVars->m_pCVHeatVision->GetIVal();
|
||||
}
|
||||
return (void*)&m_pVars->m_iNightVisionActive;
|
||||
break;
|
||||
|
||||
RETURN_PARAMETER(SCREENPROCESS_NIGHTVISIONCOLORRED, m_pVars->m_pNightVisionColor.r)
|
||||
RETURN_PARAMETER(SCREENPROCESS_NIGHTVISIONCOLORGREEN, m_pVars->m_pNightVisionColor.g)
|
||||
RETURN_PARAMETER(SCREENPROCESS_NIGHTVISIONCOLORBLUE, m_pVars->m_pNightVisionColor.b)
|
||||
}
|
||||
break;
|
||||
|
||||
// return heatvision parameters
|
||||
case SCREENPROCESS_HEATVISION:
|
||||
switch(iParams)
|
||||
{
|
||||
case SCREENPROCESS_ACTIVE:
|
||||
if(m_pVars->m_pCVHeatVision)
|
||||
{
|
||||
m_pVars->m_iHeatVisionActive=m_pVars->m_pCVHeatVision->GetIVal();
|
||||
}
|
||||
return (void*)&m_pVars->m_iHeatVisionActive;
|
||||
break;
|
||||
//RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bHeatVisionActive)
|
||||
}
|
||||
break;
|
||||
|
||||
// return flashbang parameters
|
||||
case SCREENPROCESS_FLASHBANG:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bFlashBangActive)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGTIMESCALE, m_pVars->m_fFlashBangTimeScale)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGTIMEOUT, m_pVars->m_fFlashBangTimeOut)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGFLASHPOSX, m_pVars->m_fFlashBangFlashPosX)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGFLASHPOSY, m_pVars->m_fFlashBangFlashPosY)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGFLASHSIZEX, m_pVars->m_fFlashBangFlashSizeX)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGFLASHSIZEY, m_pVars->m_fFlashBangFlashSizeY)
|
||||
RETURN_PARAMETER(SCREENPROCESS_FLASHBANGFORCEAFTERIMAGE, m_pVars->m_iFlashBangForce)
|
||||
}
|
||||
break;
|
||||
|
||||
// return cartoon parameters
|
||||
case SCREENPROCESS_CARTOON:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bCartoonActive)
|
||||
}
|
||||
break;
|
||||
|
||||
// return dof parameters
|
||||
case SCREENPROCESS_DOF:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bDofActive)
|
||||
RETURN_PARAMETER(SCREENPROCESS_DOFFOCALDISTANCE, m_pVars->m_fDofFocalDistance)
|
||||
}
|
||||
break;
|
||||
|
||||
// return screentex parameters
|
||||
case SCREENPROCESS_SCREENTEX:
|
||||
switch(iParams)
|
||||
{
|
||||
RETURN_PARAMETER(SCREENPROCESS_ACTIVE, m_pVars->m_bScreenTexActive)
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get shaders
|
||||
void CScreenVars:: Create(void)
|
||||
{
|
||||
#if SHADERSCHECK
|
||||
m_pRCBlur = CPShader::mfForName("CGRCBlur");
|
||||
#ifdef OPENGL
|
||||
m_pRCBlurRECT = CPShader::mfForName("CGRCBlurRECT");
|
||||
#else
|
||||
m_pRCBlurRECT = NULL;
|
||||
#endif
|
||||
m_pVPBlur = CVProgram::mfForName("CGVProgBlur");
|
||||
m_pRCMotion = CPShader::mfForName("CGRCMotion");
|
||||
m_pRCMotionAmount = CPShader::mfForName("CGRCMotionAmount");
|
||||
m_pVPMotion = CVProgram::mfForName("CGVProgMotion");
|
||||
m_pRCGlareMap = CPShader::mfForName("CGRCGlareMap");
|
||||
m_pRCGlareAmountMap = CPShader::mfForName("CGRCGlareAmount");
|
||||
m_pRCGlare = CPShader::mfForName("CGRCGlare");
|
||||
m_pRCRenderModeCold = CPShader::mfForName("CGRCRenderModeCold");
|
||||
m_pRCRenderModeAdv= CPShader::mfForName("CGRCRenderModeAdv");
|
||||
m_pVPGlare = CVProgram::mfForName("CGVProgGlare");
|
||||
m_pRCColorTransfer = CPShader::mfForName("CGRCColorTransfer");
|
||||
m_pVPColorTransfer = CVProgram::mfForName("CGVProgColorTransfer");
|
||||
m_pRCBluryScreen = CPShader::mfForName("CGRCBluryScreen");
|
||||
m_pVPBluryScreen = CVProgram::mfForName("CGVProgBluryScreen");
|
||||
m_pRCNightVision = CPShader::mfForName("CGRCNightVisionGlare");
|
||||
m_pVPNightVision = CVProgram::mfForName("CGVProgNightVisionGlare");
|
||||
m_pRCHeatVision = CPShader::mfForName("CGRCHeatSourcePass");
|
||||
m_pRCHeatSourceDecode = CPShader::mfForName("CGRCHeatSourceDecode");
|
||||
m_pVPFlashBang = CVProgram::mfForName("CGVProg_FlashBang");
|
||||
m_pRCFlashBang = CPShader::mfForName("CGRCFlashBang");
|
||||
m_pVPCartoon = CVProgram::mfForName("CGVProgCartoon");
|
||||
m_pRCCartoon = CPShader::mfForName("CGRCCartoon");
|
||||
m_pRCCartoonSilhouette = CPShader::mfForName("CGRCCartoonSilhouete");
|
||||
m_pRCDof = CPShader::mfForName("CGRCDof");
|
||||
m_pRCReplRgbToAlpha = CPShader::mfForName("CGRCReplRgbToAlpha");
|
||||
#endif
|
||||
|
||||
if(iConsole)
|
||||
{
|
||||
m_pCVDisableSfx= iConsole->GetCVar("r_DisableSfx");
|
||||
m_pCVResetSfx=iConsole->GetCVar("r_ResetScreenFx");
|
||||
m_pCVNormalGlare=iConsole->GetCVar("r_Glare");
|
||||
m_pCVMotionBlur=iConsole->GetCVar("r_MotionBlur");
|
||||
m_pCVScreenColorTransfer=iConsole->GetCVar("r_ScreenColorTransfer");
|
||||
m_pCVMotionBlurAmount=iConsole->GetCVar("r_MotionBlurAmount");
|
||||
m_pCVMotionBlurDisplace=iConsole->GetCVar("r_MotionBlurDisplace");
|
||||
m_pCVRenderMode=iConsole->GetCVar("r_RenderMode");
|
||||
|
||||
// note: these are used for correct cryvision functioning
|
||||
m_pCVStencilShadows=iConsole->GetCVar("e_stencil_shadows");
|
||||
m_iPrevStencilShadows=m_pCVStencilShadows->GetIVal();
|
||||
|
||||
m_pCVShadowMaps=iConsole->GetCVar("e_shadow_maps");
|
||||
m_iPrevShadowMaps=m_pCVShadowMaps->GetIVal();
|
||||
|
||||
m_pCVVolFog=iConsole->GetCVar("r_VolumetricFog");
|
||||
m_iPrevVolFog= m_pCVVolFog->GetIVal();
|
||||
|
||||
m_pCVFog=iConsole->GetCVar("e_fog");
|
||||
m_iPrevFog=m_pCVFog->GetIVal();
|
||||
|
||||
m_pCVMaxTexLodBias=iConsole->GetCVar("r_MaxTexLodBias");
|
||||
m_fPrevMaxTexLodBias=m_pCVMaxTexLodBias->GetFVal();
|
||||
|
||||
m_pCVHeatVision=iConsole->GetCVar("r_Cryvision");
|
||||
m_iHeatVisionActive=m_pCVHeatVision->GetIVal();
|
||||
|
||||
// reset fade amount
|
||||
ICVar *pHudFadeAmount=iConsole->GetCVar("hud_fadeamount");
|
||||
if(pHudFadeAmount)
|
||||
{
|
||||
pHudFadeAmount->Set(1);
|
||||
}
|
||||
}
|
||||
|
||||
// fade process vars
|
||||
m_bFadeActive=0;
|
||||
m_fFadeTime=0;
|
||||
m_fFadePreTime=0;
|
||||
m_fFadeCurrPreTime=0;
|
||||
m_fFadeCurrTime=0;
|
||||
m_pFadeColor.set(0,0,0,0);
|
||||
m_pFadeCurrColor.set(0,0,0,0);
|
||||
}
|
||||
|
||||
// release/free data..
|
||||
void CScreenVars:: Release(void)
|
||||
{
|
||||
/* // check if cryvision is active when exiting game, need to restore console vars..
|
||||
if(m_pCVHeatVision)
|
||||
{
|
||||
if(m_pCVHeatVision->GetIVal())
|
||||
{
|
||||
if(m_pCVStencilShadows)
|
||||
{
|
||||
m_pCVStencilShadows->Set(m_iPrevStencilShadows);
|
||||
}
|
||||
|
||||
if(m_pCVShadowMaps->GetIVal())
|
||||
{
|
||||
m_pCVShadowMaps->Set(m_iPrevShadowMaps);
|
||||
}
|
||||
|
||||
if(m_pCVVolFog->GetIVal())
|
||||
{
|
||||
m_pCVVolFog->Set(m_iPrevVolFog);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// reset effects state
|
||||
void CScreenVars:: Reset(void)
|
||||
{
|
||||
// color transfer vars
|
||||
m_bColorTransferActive=0;
|
||||
m_pColorTransferColor.set(0,0,0,0);
|
||||
m_fColorTransferAmount=1;
|
||||
|
||||
// blury screen vars
|
||||
m_bBlurActive=0;
|
||||
m_fBlurAmount=1.0f;
|
||||
m_pBlurColor.set(1,1,1,1);
|
||||
|
||||
// nightvision vars
|
||||
m_iNightVisionActive=0;
|
||||
m_pNightVisionColor.set(-0.1f, 0.2f, 0.11f, 1.0f);
|
||||
|
||||
// heatvision vars
|
||||
if(m_pCVHeatVision)
|
||||
{
|
||||
// m_pHeatVision->Set(0);
|
||||
m_iHeatVisionActive=m_pCVHeatVision->GetIVal();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iHeatVisionActive=0;
|
||||
}
|
||||
|
||||
// flashbang vars
|
||||
m_bFlashBangActive=0;
|
||||
m_fFlashBangTimeScale=1.0f;
|
||||
m_fFlashBangTimeOut=1.0f;
|
||||
m_fFlashBangFlashPosX=200;
|
||||
m_fFlashBangFlashPosY=100;
|
||||
m_fFlashBangFlashSizeX=400;
|
||||
m_fFlashBangFlashSizeY=400;
|
||||
|
||||
// screentex vars
|
||||
m_bScreenTexActive=0;
|
||||
m_pCurrGlareMapConst.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
m_pCurrSaturation.set(0.0f, 0.0f, 0.0f, 0.2f);
|
||||
m_pCurrContrast.set(0.0f, 0.0f, 0.85f, 0.15f);
|
||||
|
||||
|
||||
// reset fade amount
|
||||
ICVar *pHudFadeAmount=iConsole->GetCVar("hud_fadeamount");
|
||||
if(pHudFadeAmount)
|
||||
{
|
||||
pHudFadeAmount->Set(1);
|
||||
}
|
||||
|
||||
m_bFadeActive=0;
|
||||
m_fFadeTime=0;
|
||||
m_fFadePreTime=0;
|
||||
m_fFadeCurrPreTime=0;
|
||||
m_fFadeCurrTime=0;
|
||||
m_pFadeColor.set(0,0,0,0);
|
||||
m_pFadeCurrColor.set(0,0,0,0);
|
||||
}
|
||||
54
RenderDll/Common/RendElements/CREScreenProcess.h
Normal file
54
RenderDll/Common/RendElements/CREScreenProcess.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
=====================================================================
|
||||
FILE : CREScreenProcess.h
|
||||
DESC : Screen processing render element
|
||||
PROJ : Crytek Engine
|
||||
CODER: Tiago Sousa
|
||||
|
||||
Last Update: 13/06/2003
|
||||
=====================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CRESCREENPROCESS_H__
|
||||
#define __CRESCREENPROCESS_H__
|
||||
|
||||
// screen processing vars class
|
||||
class CScreenVars;
|
||||
|
||||
// screen processing render element
|
||||
class CREScreenProcess : public CRendElement
|
||||
{
|
||||
friend class CD3D9Renderer;
|
||||
friend class CGLRenderer;
|
||||
|
||||
public:
|
||||
|
||||
// constructor/destructor
|
||||
CREScreenProcess();
|
||||
|
||||
virtual ~CREScreenProcess();
|
||||
|
||||
// prepare screen processing
|
||||
virtual void mfPrepare();
|
||||
// render screen processing
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
|
||||
// begin screen processing
|
||||
virtual void mfActivate(int iProcess);
|
||||
// reset
|
||||
virtual void mfReset(void);
|
||||
|
||||
// set/get methods
|
||||
virtual int mfSetParameter(int iProcess, int iParams, void *dwValue);
|
||||
virtual void *mfGetParameter(int iProcess, int iParams);
|
||||
|
||||
CScreenVars *GetVars() { return m_pVars; }
|
||||
|
||||
private:
|
||||
virtual bool mfDrawLowSpec(SShader *ef, SShaderPass *sfm);
|
||||
|
||||
// screen processing vars class
|
||||
CScreenVars *m_pVars;
|
||||
};
|
||||
|
||||
#endif
|
||||
22
RenderDll/Common/RendElements/CREShadowMap.cpp
Normal file
22
RenderDll/Common/RendElements/CREShadowMap.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
/*
|
||||
void CREShadowMap::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_DynLMask |= m_DynMask;
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
CREShadowMap::~CREShadowMap()
|
||||
{
|
||||
if(m_CustomData)
|
||||
{
|
||||
delete m_CustomData;
|
||||
m_CustomData=0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
326
RenderDll/Common/RendElements/CRESky.cpp
Normal file
326
RenderDll/Common/RendElements/CRESky.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "CRESky.h"
|
||||
#include "i3dengine.h"
|
||||
|
||||
void CRESky::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
bool CRESky::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
int bPrevClipPl = gRenDev->m_RP.m_ClipPlaneEnabled;
|
||||
if (bPrevClipPl)
|
||||
gRenDev->EF_SetClipPlane(false, NULL, false);
|
||||
|
||||
if(sfm >= &ef->m_Passes[1] && ef->m_Sky)
|
||||
{ // draw sky sphere vertices at pass 1
|
||||
bool bPrevFog = gRenDev->EnableFog(false);
|
||||
DrawSkySphere(ef->m_Sky->m_fSkyLayerHeight);
|
||||
gRenDev->EnableFog(bPrevFog);
|
||||
if (bPrevClipPl)
|
||||
gRenDev->EF_SetClipPlane(true, &gRenDev->m_RP.m_CurClipPlane.m_Normal.x, gRenDev->m_RP.m_bClipPlaneRefract);
|
||||
return true;
|
||||
}
|
||||
|
||||
// pass 0 - skybox
|
||||
|
||||
if (!ef->m_Sky || !ef->m_Sky->m_SkyBox[0])
|
||||
{
|
||||
if (bPrevClipPl)
|
||||
gRenDev->EF_SetClipPlane(true, &gRenDev->m_RP.m_CurClipPlane.m_Normal.x, gRenDev->m_RP.m_bClipPlaneRefract);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bPrevFog = gRenDev->EnableFog(false);
|
||||
|
||||
gRenDev->SetColorOp(eCO_MODULATE, eCO_MODULATE, eCA_Texture | (eCA_Constant<<3), eCA_Texture | (eCA_Constant<<3));
|
||||
|
||||
if (gRenDev->m_bHeatVision)
|
||||
gRenDev->SetMaterialColor(0.3f,0.3f,0.3f,1.0f);
|
||||
else
|
||||
gRenDev->SetMaterialColor(1,1,1,m_fAlpha);
|
||||
if(m_fAlpha<1.f)
|
||||
gRenDev->EF_SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
|
||||
else
|
||||
gRenDev->EF_SetState(GS_NODEPTHTEST);
|
||||
gRenDev->SetCullMode(R_CULL_BACK);
|
||||
|
||||
#if !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
CPShader *fpSky = NULL;
|
||||
if (gRenDev->m_RP.m_PersFlags & RBPF_HDR)
|
||||
{
|
||||
if (!(ef->m_Flags & EF_SKY_HDR))
|
||||
fpSky = PShaderForName(gRenDev->m_RP.m_PS_HDR_SkyFake, "CGRC_HDR_SkyFake_PS20");
|
||||
else
|
||||
fpSky = PShaderForName(gRenDev->m_RP.m_PS_HDR_Sky, "CGRC_HDR_Sky_PS20");
|
||||
if (fpSky)
|
||||
fpSky->mfSet(true, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
const float fSkyBoxSize = SKY_BOX_SIZE;
|
||||
|
||||
{ // top
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
{Vec3(fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 1, 1.f-1},
|
||||
{Vec3(-fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 0, 1.f-1},
|
||||
{Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 1, 1.f-0},
|
||||
{Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 0, 1.f-0}
|
||||
};
|
||||
|
||||
gRenDev->SetTexture(ef->m_Sky->m_SkyBox[2]->m_Bind);
|
||||
gRenDev->SetTexClampMode(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),4);
|
||||
}
|
||||
|
||||
Vec3d camera = gRenDev->GetCamera().GetPos();
|
||||
camera.z = max(0,camera.z);
|
||||
|
||||
float fWaterCamDiff = max(0,camera.z-m_fTerrainWaterLevel);
|
||||
|
||||
float fMaxDist = iSystem->GetI3DEngine()->GetMaxViewDist()/1024.f;
|
||||
float P = (fWaterCamDiff)/128 + max(0,(fWaterCamDiff)*0.03f/fMaxDist);
|
||||
float D = (fWaterCamDiff)/10.0f*fSkyBoxSize/124.0f - P + 8;
|
||||
|
||||
P*=m_fSkyBoxStretching;
|
||||
|
||||
if(m_fTerrainWaterLevel>camera.z && SRendItem::m_RecurseLevel==1)
|
||||
{
|
||||
P = (fWaterCamDiff);
|
||||
D = (fWaterCamDiff);
|
||||
}
|
||||
|
||||
{ // s
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 1.0, 1.f-1.0,
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 0.0, 1.f-1.0,
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize,-P), 1.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize,-P), 0.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize,-D), 1.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize,-D), 0.0, 1.f-0.5
|
||||
};
|
||||
|
||||
gRenDev->SetTexture(ef->m_Sky->m_SkyBox[1]->m_Bind);
|
||||
gRenDev->SetTexClampMode(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),6);
|
||||
}
|
||||
{ // e
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 1.0, 1.f-0.0,
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 0.0, 1.f-0.0,
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize,-P), 1.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize,-P), 0.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize,-D), 1.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize,-fSkyBoxSize,-D), 0.0, 1.f-0.5
|
||||
};
|
||||
|
||||
gRenDev->SetTexture(ef->m_Sky->m_SkyBox[1]->m_Bind);
|
||||
gRenDev->SetTexClampMode(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),6);
|
||||
}
|
||||
{ // n
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 1.0, 1.f-1.0,
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 0.0, 1.f-1.0,
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize,-P), 1.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize,-P), 0.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize,-D), 1.0, 1.f-0.5,
|
||||
Vec3(-fSkyBoxSize, fSkyBoxSize,-D), 0.0, 1.f-0.5
|
||||
};
|
||||
|
||||
gRenDev->SetTexture(ef->m_Sky->m_SkyBox[0]->m_Bind);
|
||||
gRenDev->SetTexClampMode(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),6);
|
||||
}
|
||||
{ // w
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F data[] =
|
||||
{
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize, fSkyBoxSize), 1.0, 1.f-0.0,
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), 0.0, 1.f-0.0,
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize,-P), 1.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize,-P), 0.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize,-fSkyBoxSize,-D), 1.0, 1.f-0.5,
|
||||
Vec3(fSkyBoxSize, fSkyBoxSize,-D), 0.0, 1.f-0.5
|
||||
};
|
||||
|
||||
gRenDev->SetTexture(ef->m_Sky->m_SkyBox[0]->m_Bind);
|
||||
gRenDev->SetTexClampMode(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (data,VERTEX_FORMAT_P3F_TEX2F)),6);
|
||||
}
|
||||
#if !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
if (fpSky)
|
||||
fpSky->mfSet(false, 0);
|
||||
#endif
|
||||
|
||||
DrawFogLayer();
|
||||
|
||||
DrawBlackPortal();
|
||||
|
||||
gRenDev->EnableFog(bPrevFog);
|
||||
|
||||
if (bPrevClipPl)
|
||||
gRenDev->EF_SetClipPlane(true, &gRenDev->m_RP.m_CurClipPlane.m_Normal.x, gRenDev->m_RP.m_bClipPlaneRefract);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CRESky::DrawFogLayer()
|
||||
{
|
||||
if(!m_parrFogLayer)
|
||||
m_parrFogLayer = new list2<struct_VERTEX_FORMAT_P3F_COL4UB>;
|
||||
if(!m_parrFogLayer2)
|
||||
m_parrFogLayer2 = new list2<struct_VERTEX_FORMAT_P3F_COL4UB>;
|
||||
|
||||
m_parrFogLayer->Clear();
|
||||
m_parrFogLayer2->Clear();
|
||||
|
||||
const float fFogLayerRadius = SKY_BOX_SIZE;
|
||||
|
||||
if(gRenDev->m_FS.m_FogEnd>=256)
|
||||
return true;
|
||||
|
||||
Vec3d camera = gRenDev->GetCamera().GetPos();
|
||||
camera.z = max(0,camera.z);
|
||||
|
||||
float fLayerZ = -(max(0,gRenDev->m_FS.m_FogEnd-64)/(256-64))*SKY_BOX_SIZE - camera.z/35;
|
||||
|
||||
bool bRGB = (gRenDev->GetFeatures() & RFT_RGBA) != 0;
|
||||
|
||||
for(int i=0; i<=360; i+=30)
|
||||
{
|
||||
float rad = (i) * (gf_PI/180);
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB tmp;
|
||||
tmp.xyz.x = cry_sinf(-rad)*fFogLayerRadius;
|
||||
tmp.xyz.y = cry_cosf(-rad)*fFogLayerRadius;
|
||||
|
||||
if(bRGB)
|
||||
{
|
||||
tmp.color.bcolor[0] = uchar(gRenDev->m_FS.m_FogColor.r*255);
|
||||
tmp.color.bcolor[1] = uchar(gRenDev->m_FS.m_FogColor.g*255);
|
||||
tmp.color.bcolor[2] = uchar(gRenDev->m_FS.m_FogColor.b*255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.color.bcolor[2] = uchar(gRenDev->m_FS.m_FogColor.r*255);
|
||||
tmp.color.bcolor[1] = uchar(gRenDev->m_FS.m_FogColor.g*255);
|
||||
tmp.color.bcolor[0] = uchar(gRenDev->m_FS.m_FogColor.b*255);
|
||||
}
|
||||
|
||||
tmp.color.bcolor[3] = uchar(255.f);
|
||||
|
||||
tmp.xyz.z = fLayerZ-SKY_BOX_SIZE/2;
|
||||
m_parrFogLayer2->Add(tmp);
|
||||
tmp.xyz.z = fLayerZ+SKY_BOX_SIZE/2;
|
||||
m_parrFogLayer2->Add(tmp);
|
||||
|
||||
m_parrFogLayer->Add(tmp);
|
||||
tmp.xyz.z = fLayerZ+SKY_BOX_SIZE;
|
||||
tmp.color.bcolor[3] = 0;
|
||||
m_parrFogLayer->Add(tmp);
|
||||
}
|
||||
|
||||
#if !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
CPShader *fpSky = NULL;
|
||||
if (gRenDev->m_RP.m_PersFlags & RBPF_HDR)
|
||||
{
|
||||
fpSky = PShaderForName(gRenDev->m_RP.m_PS_HDR_BaseCol, "CGRC_HDR_BaseCol_PS20");
|
||||
if (fpSky)
|
||||
fpSky->mfSet(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
gRenDev->EF_SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA);
|
||||
gRenDev->SelectTMU(0);
|
||||
gRenDev->m_TexMan->m_Text_White->Set();
|
||||
gRenDev->EnableTMU(true);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (m_parrFogLayer->GetElements(),VERTEX_FORMAT_P3F_COL4UB)),m_parrFogLayer->Count());
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (m_parrFogLayer2->GetElements(),VERTEX_FORMAT_P3F_COL4UB)),m_parrFogLayer2->Count());
|
||||
|
||||
#if !defined(PS2) && !defined (GC) && !defined (NULL_RENDERER)
|
||||
if (fpSky)
|
||||
fpSky->mfSet(false);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CRESky::~CRESky()
|
||||
{
|
||||
delete m_parrFogLayer;
|
||||
delete m_parrFogLayer2;
|
||||
}
|
||||
|
||||
// render black occlusion volumes mostly to hide seams in indoors
|
||||
bool CRESky::DrawBlackPortal()
|
||||
{
|
||||
if(!m_arrvPortalVerts[0][0].xyz.x)
|
||||
return true;
|
||||
|
||||
gRenDev->ResetToDefault();
|
||||
|
||||
for(int i=0; i<MAX_SKY_OCCLAREAS_NUM; i++)
|
||||
{
|
||||
if(!m_arrvPortalVerts[i][0].xyz.x)
|
||||
return true;
|
||||
|
||||
gRenDev->EF_SetState(GS_DEPTHWRITE);
|
||||
gRenDev->SetCullMode(R_CULL_NONE);
|
||||
gRenDev->SelectTMU(0);
|
||||
gRenDev->EnableTMU(false);
|
||||
gRenDev->DrawTriStrip(&(CVertexBuffer (m_arrvPortalVerts[i],VERTEX_FORMAT_P3F_COL4UB)),4);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRESky::DrawSkySphere(float fHeight)
|
||||
{
|
||||
float nWSize = 256/16;
|
||||
|
||||
float a_in = 1, a_out = 1;
|
||||
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB vert;
|
||||
vert.color.bcolor[0]=255;
|
||||
vert.color.bcolor[1]=255;
|
||||
vert.color.bcolor[2]=255;
|
||||
|
||||
list2<struct_VERTEX_FORMAT_P3F_COL4UB> lstVertData;
|
||||
|
||||
for(float r=0; r<3; r++)
|
||||
{
|
||||
a_in = a_out;
|
||||
a_out = 1.f-r/2;
|
||||
a_out*=a_out; a_out*=a_out; a_out*=a_out;
|
||||
|
||||
lstVertData.Clear();
|
||||
|
||||
for(int i=0; i<=360; i+=40)
|
||||
{
|
||||
float rad = (i) * (M_PI/180);
|
||||
|
||||
vert.xyz.x = cry_sinf(rad)*nWSize*r;
|
||||
vert.xyz.y = cry_cosf(rad)*nWSize*r;
|
||||
vert.xyz.z = fHeight + 8 - (r)*8;
|
||||
vert.color.bcolor[3] = uchar(a_in*255.0f);
|
||||
lstVertData.Add(vert);
|
||||
|
||||
vert.xyz.x = cry_sinf(rad)*nWSize*(r+1);
|
||||
vert.xyz.y = cry_cosf(rad)*nWSize*(r+1);
|
||||
vert.xyz.z = fHeight + 8 - (r+1)*8;
|
||||
vert.color.bcolor[3] = uchar(a_out*255.0f);
|
||||
lstVertData.Add(vert);
|
||||
}
|
||||
|
||||
gRenDev->DrawTriStrip(&CVertexBuffer(&lstVertData[0],VERTEX_FORMAT_P3F_COL4UB),lstVertData.Count());
|
||||
}
|
||||
}
|
||||
32
RenderDll/Common/RendElements/CRESkyZone.h
Normal file
32
RenderDll/Common/RendElements/CRESkyZone.h
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#ifndef __CRESKYZONE_H__
|
||||
#define __CRESKYZONE_H__
|
||||
|
||||
//=============================================================
|
||||
class CRESkyZone : public CRendElement
|
||||
{
|
||||
public:
|
||||
Vec3d mViewPos;
|
||||
Vec3d mMins;
|
||||
Vec3d mMaxs;
|
||||
Vec3d mCenter;
|
||||
float mRadius;
|
||||
byte *mPVS;
|
||||
|
||||
CRESkyZone()
|
||||
{
|
||||
mfSetType(eDATA_SkyZone);
|
||||
mfUpdateFlags(FCEF_TRANSFORM | FCEF_NODEL);
|
||||
mPVS = NULL;
|
||||
}
|
||||
|
||||
virtual ~CRESkyZone()
|
||||
{
|
||||
if (mPVS)
|
||||
delete [] mPVS;
|
||||
}
|
||||
|
||||
virtual bool mfCompile(SShader *ef, char *scr);
|
||||
};
|
||||
|
||||
#endif // __CRESKYZONE_H__
|
||||
36
RenderDll/Common/RendElements/CRETempMesh.cpp
Normal file
36
RenderDll/Common/RendElements/CRETempMesh.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
|
||||
void CRETempMesh::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 6;
|
||||
gRenDev->m_RP.m_RendNumVerts = 4;
|
||||
gRenDev->m_RP.m_FirstVertex = 0;
|
||||
gRenDev->m_RP.m_FirstIndex = 0;
|
||||
}
|
||||
|
||||
void *CRETempMesh::mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags)
|
||||
{
|
||||
*Stride = sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F);
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *pVertices = (struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *)m_VBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
gRenDev->m_RP.m_nCurBufferID = m_VBuffer->m_VS[VSF_GENERAL].m_VertBuf.m_nID;
|
||||
SBufInfoTable *pOffs = &gBufInfoTable[m_VBuffer->m_vertexformat];
|
||||
|
||||
switch(ePT)
|
||||
{
|
||||
case eSrcPointer_Vert:
|
||||
gRenDev->m_RP.m_nCurBufferOffset = 0;
|
||||
return &pVertices->xyz.x;
|
||||
case eSrcPointer_Tex:
|
||||
gRenDev->m_RP.m_nCurBufferOffset = pOffs->OffsTC;
|
||||
return &pVertices->st[0];
|
||||
case eSrcPointer_Color:
|
||||
gRenDev->m_RP.m_nCurBufferOffset = pOffs->OffsColor;
|
||||
return &pVertices->color.dcolor;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
48
RenderDll/Common/RendElements/CRETempMesh.h
Normal file
48
RenderDll/Common/RendElements/CRETempMesh.h
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
#ifndef __CRETEMPMESH_H__
|
||||
#define __CRETEMPMESH_H__
|
||||
|
||||
//=============================================================
|
||||
|
||||
|
||||
class CRETempMesh : public CRendElement
|
||||
{
|
||||
public:
|
||||
CVertexBuffer *m_VBuffer;
|
||||
SVertexStream m_Inds;
|
||||
|
||||
public:
|
||||
CRETempMesh()
|
||||
{
|
||||
m_VBuffer = NULL;
|
||||
m_Inds.Reset();
|
||||
mfSetType(eDATA_TempMesh);
|
||||
mfUpdateFlags(FCEF_TRANSFORM);
|
||||
}
|
||||
|
||||
virtual ~CRETempMesh()
|
||||
{
|
||||
if (m_VBuffer)
|
||||
{
|
||||
gRenDev->ReleaseBuffer(m_VBuffer);
|
||||
m_VBuffer = NULL;
|
||||
}
|
||||
gRenDev->ReleaseIndexBuffer(&m_Inds);
|
||||
m_Inds.Reset();
|
||||
}
|
||||
|
||||
virtual void mfPrepare();
|
||||
virtual bool mfDraw(SShader *ef, SShaderPass *sfm);
|
||||
virtual void *mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags);
|
||||
virtual bool mfPreDraw(SShaderPass *sl);
|
||||
virtual void mfReset();
|
||||
virtual int Size()
|
||||
{
|
||||
int nSize = sizeof(*this);
|
||||
if (m_VBuffer)
|
||||
nSize += m_VBuffer->Size(0, m_VBuffer->m_NumVerts);
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CRETEMPMESH_H__
|
||||
32
RenderDll/Common/RendElements/CRETerrainSector.cpp
Normal file
32
RenderDll/Common/RendElements/CRETerrainSector.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "CRETerrainSector.h"
|
||||
#include "I3DEngine.h"
|
||||
|
||||
void CRECommon::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
bool CREFarTreeSprites::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
iSystem->GetI3DEngine()->DrawFarTrees();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRETerrainDetailTextureLayers::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
iSystem->GetI3DEngine()->DrawTerrainDetailTextureLayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRETerrainParticles::mfDraw(SShader *ef, SShaderPass *sfm)
|
||||
{
|
||||
iSystem->GetI3DEngine()->DrawTerrainParticles(ef);
|
||||
return true;
|
||||
}
|
||||
|
||||
17
RenderDll/Common/RendElements/CRETriMeshAdditionalShadow.cpp
Normal file
17
RenderDll/Common/RendElements/CRETriMeshAdditionalShadow.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
#include "RenderPCH.h"
|
||||
/*
|
||||
#include "RendElement.h"
|
||||
#include "CRETriMeshAdditionalShadow.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void CRETriMeshAdditionalShadow::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
|
||||
gRenDev->m_RP.m_DynLMask |= m_DynMask;
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
*/
|
||||
247
RenderDll/Common/RendElements/CRETriMeshShadow.cpp
Normal file
247
RenderDll/Common/RendElements/CRETriMeshShadow.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
#include "RenderPCH.h"
|
||||
#include "RendElement.h"
|
||||
#include "CRETriMeshShadow.h"
|
||||
#include "I3DEngine.h"
|
||||
|
||||
// shadow volumes rendering modified by vlad
|
||||
|
||||
// shadow volumes statistics
|
||||
int CRETriMeshShadow::m_nCRETriMeshShadowRebuildsPerFrrame = 0;
|
||||
int CRETriMeshShadow::m_nCRETriMeshShadowShadowsPerFrrame = 0;
|
||||
int CRETriMeshShadow::m_nCRETriMeshShadowAloocatedShadows = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void CRETriMeshShadow::mfPrepare()
|
||||
{
|
||||
gRenDev->EF_CheckOverflow(0, 0, this);
|
||||
gRenDev->m_RP.m_pRE = this;
|
||||
gRenDev->m_RP.m_RendNumIndices = 0;
|
||||
gRenDev->m_RP.m_RendNumVerts = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void *CRETriMeshShadow::mfGetPointer(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags)
|
||||
{
|
||||
switch (ePT)
|
||||
{
|
||||
case eSrcPointer_Vert:
|
||||
{
|
||||
if(m_nCurrInst<0)
|
||||
{
|
||||
// Warning( 0,0,"Error: CRETriMeshShadow::mfGetPointer: m_nCurrInst<0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*Stride = m_VertexSize[m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer->m_vertexformat];
|
||||
if(m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer)
|
||||
return m_arrLBuffers[m_nCurrInst].pVB->m_pVertexBuffer->m_VS[VSF_GENERAL].m_VData;
|
||||
else
|
||||
Warning( 0,0,"Error: CRETriMeshShadow::mfGetPointer: m_pBuffer->m_pVertexBuffer == 0");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CRETriMeshShadow::GetAndResetRebuildsPerFrrameCounter()
|
||||
{
|
||||
int n = m_nCRETriMeshShadowRebuildsPerFrrame;
|
||||
m_nCRETriMeshShadowRebuildsPerFrrame = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
int CRETriMeshShadow::GetAndResetShadowVolumesPerFrrameCounter()
|
||||
{
|
||||
int n = m_nCRETriMeshShadowShadowsPerFrrame;
|
||||
m_nCRETriMeshShadowShadowsPerFrrame = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
int CRETriMeshShadow::GetShadowVolumesAllocatedCounter()
|
||||
{
|
||||
return m_nCRETriMeshShadowAloocatedShadows;
|
||||
}
|
||||
|
||||
bool CRETriMeshShadow::mfCheckUpdate(int nVertFormat, int Flags)
|
||||
{
|
||||
if(m_bAnimatedObject)
|
||||
{ // character animation: everything already calculated, always use slot 0
|
||||
m_nCurrInst = 0; // will be used during drawing
|
||||
ShadVolInstanceInfo * pSVInfo = &m_arrLBuffers[0];
|
||||
if (pSVInfo->pVB->m_pMats && pSVInfo->pVB->m_pMats->Count() && pSVInfo->pVB->m_pMats->Get(0)->pRE)
|
||||
return pSVInfo->pVB->m_pMats->Get(0)->pRE->mfCheckUpdate(nVertFormat, Flags);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nCRETriMeshShadowShadowsPerFrrame++;
|
||||
|
||||
assert(m_nCurrInst == -1);
|
||||
|
||||
// find light of this shadow
|
||||
CDLight * pDLight = NULL;
|
||||
if (gRenDev->m_RP.m_DynLMask)
|
||||
{
|
||||
for (int n=0; n<gRenDev->m_RP.m_DLights[SRendItem::m_RecurseLevel].Num(); n++)
|
||||
{
|
||||
if (gRenDev->m_RP.m_DynLMask & (1<<n))
|
||||
{
|
||||
pDLight = gRenDev->m_RP.m_DLights[SRendItem::m_RecurseLevel][n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pDLight)
|
||||
return true;
|
||||
|
||||
CDLight fakeLight;
|
||||
fakeLight = *pDLight; // do not copy
|
||||
|
||||
// get obj space light pos
|
||||
CCObject *pObj = gRenDev->m_RP.m_pCurObject;
|
||||
Matrix44& tInvRot = pObj->GetInvMatrix();
|
||||
|
||||
fakeLight.m_vObjectSpacePos = tInvRot.TransformPointOLD(fakeLight.m_Origin);
|
||||
|
||||
// assert(m_nCurrInst==-1);
|
||||
|
||||
// todo: take radius into account
|
||||
|
||||
//assert(pObj->m_CustomData);
|
||||
|
||||
// find buffer for this case
|
||||
ShadVolInstanceInfo * pSVInfo = 0;
|
||||
for(int i=0; i<MAX_SV_INSTANCES; i++) // find static volume by light objspace position
|
||||
if(m_arrLBuffers[i].pVB && IsEquivalent(m_arrLBuffers[i].vObjSpaceLightPos, fakeLight.m_vObjectSpacePos, 0.001f))
|
||||
{
|
||||
pSVInfo = &m_arrLBuffers[i];
|
||||
pSVInfo->nFrameId = gRenDev->GetFrameID();
|
||||
m_nCurrInst = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!pSVInfo) // if not found - select new slot
|
||||
{
|
||||
// now find same combination of light and shadow caster
|
||||
// but only if slot was not used in prev frame -
|
||||
// outomagic double buffering of dynamic shadows
|
||||
for(int i=0; i<MAX_SV_INSTANCES; i++)
|
||||
if( m_arrLBuffers[i].pVB &&
|
||||
m_arrLBuffers[i].pLightOwner == fakeLight.m_pOwner &&
|
||||
m_arrLBuffers[i].pShadowCaster == pObj->m_CustomData &&
|
||||
m_arrLBuffers[i].nFrameId+1 < gRenDev->GetFrameID())
|
||||
{
|
||||
pSVInfo = &m_arrLBuffers[i];
|
||||
m_nCurrInst = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!pSVInfo) // if still not found
|
||||
{ // find empty slot or slot with smallest frame id
|
||||
int nSmalestFrameId = gRenDev->GetFrameID()+1;
|
||||
for(int i=0; i<MAX_SV_INSTANCES; i++)
|
||||
{
|
||||
if(!m_arrLBuffers[i].pVB)
|
||||
{ // search for free slot
|
||||
pSVInfo = &m_arrLBuffers[i];
|
||||
m_nCurrInst = i;
|
||||
nSmalestFrameId=0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_arrLBuffers[i].nFrameId<nSmalestFrameId)
|
||||
{ // search for oldest slot at the same time
|
||||
nSmalestFrameId = m_arrLBuffers[i].nFrameId;
|
||||
pSVInfo = &m_arrLBuffers[i];
|
||||
m_nCurrInst = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pSVInfo)
|
||||
{
|
||||
pSVInfo->nFrameId = gRenDev->GetFrameID();
|
||||
pSVInfo->vObjSpaceLightPos = fakeLight.m_vObjectSpacePos;
|
||||
pSVInfo->pLightOwner = fakeLight.m_pOwner;
|
||||
pSVInfo->pShadowCaster = (IEntityRender*)pObj->m_CustomData;
|
||||
}
|
||||
|
||||
if(!pSVInfo->pVB)
|
||||
m_nCRETriMeshShadowAloocatedShadows++; // will be created now
|
||||
|
||||
// pSVInfo will be used in RebuildDynamicShadowVolumeBuffer
|
||||
m_pSvObj->RebuildShadowVolumeBuffer(fakeLight, pObj->m_TempVars[0]);
|
||||
m_nCRETriMeshShadowRebuildsPerFrrame++;
|
||||
|
||||
// if(!pSVInfo->pVB)
|
||||
// iLog->Log("Warning: CRETriMeshShadow::mfCheckUpdate: !pSVInfo->pVB");
|
||||
|
||||
/*
|
||||
ICVar *pVar = iConsole->GetCVar("e_stencil_shadows");
|
||||
if(pVar && pVar->GetIVal()==3 && pSVInfo->pVB)
|
||||
iLog->Log("CRETriMeshShadow: Static shadow volume created: %d faces", pSVInfo->pVB->GetIndices().Count()/3);*/
|
||||
}
|
||||
|
||||
if (pSVInfo->pVB &&
|
||||
pSVInfo->pVB->m_pMats &&
|
||||
pSVInfo->pVB->m_pMats->Count() &&
|
||||
pSVInfo->pVB->m_pMats->Get(0)->pRE)
|
||||
pSVInfo->pVB->m_pMats->Get(0)->pRE->mfCheckUpdate(nVertFormat, Flags);
|
||||
else
|
||||
m_nCurrInst = -1;
|
||||
|
||||
fakeLight.m_vObjectSpacePos = Vec3d(0,0,0);
|
||||
|
||||
#ifdef DIRECT3D8
|
||||
assert(0); // not tested, what this line do?
|
||||
gRenDev->m_RP.m_CurD3DVFormat = pSVInfo->pVB->m_pSecVertBuffer->m_vertexformat + 16;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
CRETriMeshShadow::~CRETriMeshShadow()
|
||||
{
|
||||
for(int i=0; i<MAX_SV_INSTANCES; i++)
|
||||
{
|
||||
gRenDev->DeleteLeafBuffer(m_arrLBuffers[i].pVB);
|
||||
m_arrLBuffers[i].pVB=0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CRETriMeshShadow::mfCheckUnload()
|
||||
{ // remove all not used leafbuffers
|
||||
for(int i=0; i<MAX_SV_INSTANCES; i++)
|
||||
if(m_arrLBuffers[i].pVB)
|
||||
{
|
||||
if(m_arrLBuffers[i].nFrameId < gRenDev->GetFrameID()-100)
|
||||
{
|
||||
gRenDev->DeleteLeafBuffer(m_arrLBuffers[i].pVB);
|
||||
m_arrLBuffers[i].pVB=0;
|
||||
m_arrLBuffers[i].nFrameId=0;
|
||||
m_nCRETriMeshShadowAloocatedShadows--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(nLastCRETriMeshShadowLogFrame != gRenDev->GetFrameID())
|
||||
{
|
||||
int nRebNum = GetRETriMeshShadowRebuildsPerFrrame()/32;;
|
||||
int nShadNum = GetRETriMeshShadowShadowsPerFrrame()/32;
|
||||
ICVar *pVar = iConsole->GetCVar("e_stencil_shadows");
|
||||
if(pVar && pVar->GetIVal()==3)
|
||||
iLog->Log("CRETriMeshShadow: Allocated: %d, Used: %d, Updated: %d",
|
||||
nCRETriMeshShadowAloocatedShadows, nShadNum, nRebNum);
|
||||
nLastCRETriMeshShadowLogFrame = gRenDev->GetFrameID();
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRETriMeshShadow::PrintStats()
|
||||
{
|
||||
gRenDev->TextToScreenColor(8,20, 0,2,0,1, "Shadow volumes stats: Rebuild: %d, Used: %d, Allocated: %d",
|
||||
CRETriMeshShadow::GetAndResetRebuildsPerFrrameCounter(),
|
||||
CRETriMeshShadow::GetAndResetShadowVolumesPerFrrameCounter(),
|
||||
CRETriMeshShadow::GetShadowVolumesAllocatedCounter());
|
||||
}
|
||||
526
RenderDll/Common/RendElements/FFT_SSE.cpp
Normal file
526
RenderDll/Common/RendElements/FFT_SSE.cpp
Normal file
@@ -0,0 +1,526 @@
|
||||
#include "RenderPCH.h"
|
||||
|
||||
// Not for AMD64
|
||||
#if !defined(WIN64) && !defined(LINUX)
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
|
||||
|
||||
struct SConstSSE
|
||||
{
|
||||
float m_fVal0;
|
||||
float m_fVal1;
|
||||
float m_fVal2;
|
||||
float m_fVal3;
|
||||
};
|
||||
|
||||
_declspec(align(16)) SConstSSE _tabCoef64_1[4][6] =
|
||||
{
|
||||
{
|
||||
{1.000000f, 0.995185f, 0.980785f, 0.956940f},
|
||||
{0.000000f, -0.098017f, -0.195090f, -0.290285f},
|
||||
{1.000000f, 0.980785f, 0.923880f, 0.831470f},
|
||||
{0.000000f, -0.195090f, -0.382683f, -0.555570f},
|
||||
{1.000000f, 0.956940f, 0.831470f, 0.634393f},
|
||||
{0.000000f, -0.290285f, -0.555570f, -0.773010f},
|
||||
},
|
||||
{
|
||||
{0.923880f, 0.881921f, 0.831470f, 0.773010f},
|
||||
{-0.382683f, -0.471397f, -0.555570f, -0.634393f},
|
||||
{0.707107f, 0.555570f, 0.382683f, 0.195090f},
|
||||
{-0.707107f, -0.831470f, -0.923880f, -0.980785f},
|
||||
{0.382683f, 0.098017f, -0.195090f, -0.471397f},
|
||||
{-0.923880f, -0.995185f, -0.980785f, -0.881921f},
|
||||
},
|
||||
{
|
||||
{0.707107f, 0.634393f, 0.555570f, 0.471397f},
|
||||
{-0.707107f, -0.773010f, -0.831470f, -0.881921f},
|
||||
{0.000000f, -0.195090f, -0.382683f, -0.555570f},
|
||||
{-1.000000f, -0.980785f, -0.923880f, -0.831470f},
|
||||
{-0.707107f, -0.881921f, -0.980785f, -0.995185f},
|
||||
{-0.707107f, -0.471397f, -0.195090f, 0.098017f},
|
||||
},
|
||||
{
|
||||
{0.382683f, 0.290285f, 0.195090f, 0.098017f},
|
||||
{-0.923880f, -0.956940f, -0.980785f, -0.995185f},
|
||||
{-0.707107f, -0.831470f, -0.923880f, -0.980785f},
|
||||
{-0.707107f, -0.555570f, -0.382683f, -0.195090f},
|
||||
{-0.923880f, -0.773010f, -0.555570f, -0.290285f},
|
||||
{0.382683f, 0.634393f, 0.831470f, 0.956940f},
|
||||
}
|
||||
};
|
||||
|
||||
_declspec(align(16)) SConstSSE _tabCoef64_2[4][6] =
|
||||
{
|
||||
{
|
||||
{1.000000f, 0.923880f, 0.707107f, 0.382683f},
|
||||
{0.000000f, -0.382683f, -0.707107f, -0.923880f},
|
||||
{1.000000f, 0.707107f, 0.000000f, -0.707107f},
|
||||
{0.000000f, -0.707107f, -1.000000f, -0.707107f},
|
||||
{1.000000f, 0.382683f, -0.707107f, -0.923880f},
|
||||
{0.000000f, -0.923880f, -0.707107f, 0.382683f},
|
||||
}
|
||||
};
|
||||
|
||||
void cradix4c_64(float* ar, float* ai, int nm)
|
||||
{
|
||||
int wdt = OCEANGRID;
|
||||
float *arw = &ar[wdt];
|
||||
float *aiw = &ai[wdt];
|
||||
_asm
|
||||
{
|
||||
mov eax, arw
|
||||
mov ebx, aiw
|
||||
mov edx, ai
|
||||
mov ecx, ar
|
||||
sub esp, 20h
|
||||
mov [esp+0ch], ebp
|
||||
mov [esp], ecx
|
||||
mov [esp+4], edx
|
||||
mov ebp, ecx
|
||||
mov [esp+10h], eax
|
||||
mov [esp+14h], ebx
|
||||
mov [esp+18h], ebp
|
||||
mov [esp+1ch], edx
|
||||
lea ebx, [ebp+40h]
|
||||
lea edi, _tabCoef64_1
|
||||
mov [esp+8], ebx
|
||||
_lAlign:
|
||||
movaps xmm0,xmmword ptr [ebp]
|
||||
movaps xmm4,xmm0
|
||||
movaps xmm2,xmmword ptr [ebp+80h]
|
||||
subps xmm0,xmm2
|
||||
movaps xmm1,xmmword ptr [ebp+40h]
|
||||
addps xmm4,xmm2
|
||||
movaps xmm3,xmmword ptr [ebp+0C0h]
|
||||
movaps xmm5,xmm1
|
||||
movaps xmm2,xmmword ptr [edx]
|
||||
addps xmm5,xmm3
|
||||
jmp _lCicleAlign
|
||||
align 4
|
||||
_lStartAlign:
|
||||
movaps xmmword ptr [edx+0B0h],xmm0
|
||||
movaps xmm0,xmmword ptr [ebp]
|
||||
subps xmm7,xmm4
|
||||
movaps xmm4,xmm0
|
||||
movaps xmmword ptr [ebp+0B0h],xmm5
|
||||
addps xmm3,xmm1
|
||||
movaps xmm2,xmmword ptr [ebp+80h]
|
||||
movaps xmmword ptr [ebp+30h],xmm7
|
||||
subps xmm0,xmm2
|
||||
movaps xmm1,xmmword ptr [ebp+40h]
|
||||
addps xmm4,xmm2
|
||||
movaps xmm5,xmm1
|
||||
movaps xmmword ptr [edx+30h],xmm3
|
||||
movaps xmm2,xmmword ptr [edx]
|
||||
movaps xmm3,xmmword ptr [ebp+0C0h]
|
||||
addps xmm5,xmm3
|
||||
_lCicleAlign:
|
||||
align 4
|
||||
movaps xmm7,xmm4
|
||||
subps xmm1,xmm3
|
||||
prefetcht0 [edi]
|
||||
addps xmm4,xmm5
|
||||
movaps xmm3,xmm2
|
||||
movaps xmm6,xmmword ptr [edx+80h]
|
||||
subps xmm7,xmm5
|
||||
prefetcht0 [edi+10h]
|
||||
movaps xmmword ptr [ebp],xmm4
|
||||
addps xmm3,xmm6
|
||||
movaps xmm5,xmmword ptr [edx+40h]
|
||||
subps xmm2,xmm6
|
||||
prefetcht0 [edi+20h]
|
||||
movaps xmm4,xmmword ptr [edx+0C0h]
|
||||
movaps xmm6,xmm5
|
||||
addps xmm5,xmm4
|
||||
prefetcht0 [edi+30h]
|
||||
subps xmm6,xmm4
|
||||
movaps xmm4,xmm5
|
||||
addps xmm5,xmm3
|
||||
movaps xmmword ptr [edx],xmm5
|
||||
movaps xmm5,xmm0
|
||||
addps xmm0,xmm6
|
||||
prefetcht0 [edi+40h]
|
||||
subps xmm3,xmm4
|
||||
movaps xmm4,xmm2
|
||||
subps xmm2,xmm1
|
||||
prefetcht0 [edi+50h]
|
||||
addps xmm1,xmm4
|
||||
subps xmm5,xmm6
|
||||
movaps xmm4,xmm0
|
||||
movaps xmm6,xmm2
|
||||
mulps xmm0,xmmword ptr [edi]
|
||||
mulps xmm2,xmmword ptr [edi+10h]
|
||||
mulps xmm4,xmmword ptr [edi+10h]
|
||||
add ebp,10h
|
||||
add edx,10h
|
||||
subps xmm0,xmm2
|
||||
mulps xmm6,xmmword ptr [edi]
|
||||
movaps xmm2,xmm1
|
||||
movaps xmmword ptr [ebp+70h],xmm0
|
||||
mulps xmm1,xmmword ptr [edi+50h]
|
||||
movaps xmm0,xmm5
|
||||
addps xmm4,xmm6
|
||||
mulps xmm5,xmmword ptr [edi+40h]
|
||||
mulps xmm2,xmmword ptr [edi+40h]
|
||||
mulps xmm0,xmmword ptr [edi+50h]
|
||||
subps xmm5,xmm1
|
||||
movaps xmmword ptr [edx+70h],xmm4
|
||||
movaps xmm1,xmm7
|
||||
mulps xmm7,xmmword ptr [edi+20h]
|
||||
movaps xmm4,xmm3
|
||||
addps xmm0,xmm2
|
||||
mulps xmm3,xmmword ptr [edi+20h]
|
||||
mulps xmm4,xmmword ptr [edi+30h]
|
||||
cmp ebp,ebx
|
||||
mulps xmm1,xmmword ptr [edi+30h]
|
||||
lea edi,[edi+60h]
|
||||
jl _lStartAlign
|
||||
movaps xmmword ptr [ebp+0B0h],xmm5
|
||||
addps xmm3,xmm1
|
||||
subps xmm7,xmm4
|
||||
movaps xmmword ptr [edx+0B0h],xmm0
|
||||
movaps xmmword ptr [edx+30h],xmm3
|
||||
movaps xmmword ptr [ebp+30h],xmm7
|
||||
mov ebp,[esp]
|
||||
mov edx,[esp+4]
|
||||
add ebp,100h
|
||||
add edx,100h
|
||||
mov [esp],ebp
|
||||
mov [esp+4],edx
|
||||
cmp ebp,[esp+10h]
|
||||
lea ebx,[ebp+40h]
|
||||
mov [esp+8],ebx
|
||||
lea edi,_tabCoef64_1
|
||||
jl _lAlign
|
||||
|
||||
mov ebp, [esp+18h];
|
||||
mov edx, [esp+1ch];
|
||||
mov [esp], ebp
|
||||
mov [esp+4], edx
|
||||
lea ebx, [ebp+10h]
|
||||
lea edi, _tabCoef64_2
|
||||
mov [esp+8], ebx
|
||||
_lAlign2:
|
||||
movaps xmm0,xmmword ptr [ebp]
|
||||
movaps xmm4,xmm0
|
||||
movaps xmm2,xmmword ptr [ebp+20h]
|
||||
subps xmm0,xmm2
|
||||
movaps xmm1,xmmword ptr [ebp+10h]
|
||||
addps xmm4,xmm2
|
||||
movaps xmm3,xmmword ptr [ebp+30h]
|
||||
movaps xmm5,xmm1
|
||||
movaps xmm2,xmmword ptr [edx]
|
||||
addps xmm5,xmm3
|
||||
jmp _lCicleAlign2
|
||||
align 4
|
||||
_lStartAlign2:
|
||||
movaps xmmword ptr [edx+20h],xmm0
|
||||
movaps xmm0,xmmword ptr [ebp]
|
||||
subps xmm7,xmm4
|
||||
movaps xmm4,xmm0
|
||||
movaps xmmword ptr [ebp+20h],xmm5
|
||||
addps xmm3,xmm1
|
||||
movaps xmm2,xmmword ptr [ebp+20h]
|
||||
movaps xmmword ptr [ebp],xmm7
|
||||
subps xmm0,xmm2
|
||||
movaps xmm1,xmmword ptr [ebp+10h]
|
||||
addps xmm4,xmm2
|
||||
movaps xmm5,xmm1
|
||||
movaps xmmword ptr [edx],xmm3
|
||||
movaps xmm2,xmmword ptr [edx]
|
||||
movaps xmm3,xmmword ptr [ebp+30h]
|
||||
addps xmm5,xmm3
|
||||
_lCicleAlign2:
|
||||
movaps xmm7,xmm4
|
||||
subps xmm1,xmm3
|
||||
prefetcht0 [edi]
|
||||
addps xmm4,xmm5
|
||||
movaps xmm3,xmm2
|
||||
movaps xmm6,xmmword ptr [edx+20h]
|
||||
subps xmm7,xmm5
|
||||
prefetcht0 [edi+10h]
|
||||
movaps xmmword ptr [ebp],xmm4
|
||||
addps xmm3,xmm6
|
||||
movaps xmm5,xmmword ptr [edx+10h]
|
||||
subps xmm2,xmm6
|
||||
prefetcht0 [edi+20h]
|
||||
movaps xmm4,xmmword ptr [edx+30h]
|
||||
movaps xmm6,xmm5
|
||||
addps xmm5,xmm4
|
||||
prefetcht0 [edi+30h]
|
||||
subps xmm6,xmm4
|
||||
movaps xmm4,xmm5
|
||||
addps xmm5,xmm3
|
||||
movaps xmmword ptr [edx],xmm5
|
||||
movaps xmm5,xmm0
|
||||
addps xmm0,xmm6
|
||||
prefetcht0 [edi+40h]
|
||||
subps xmm3,xmm4
|
||||
movaps xmm4,xmm2
|
||||
subps xmm2,xmm1
|
||||
prefetcht0 [edi+50h]
|
||||
addps xmm1,xmm4
|
||||
subps xmm5,xmm6
|
||||
movaps xmm4,xmm0
|
||||
movaps xmm6,xmm2
|
||||
mulps xmm0,xmmword ptr [edi]
|
||||
mulps xmm2,xmmword ptr [edi+10h]
|
||||
mulps xmm4,xmmword ptr [edi+10h]
|
||||
add ebp,10h
|
||||
add edx,10h
|
||||
subps xmm0,xmm2
|
||||
mulps xmm6,xmmword ptr [edi]
|
||||
movaps xmm2,xmm1
|
||||
movaps xmmword ptr [ebp+10h],xmm0
|
||||
mulps xmm1,xmmword ptr [edi+50h]
|
||||
movaps xmm0,xmm5
|
||||
addps xmm4,xmm6
|
||||
mulps xmm5,xmmword ptr [edi+40h]
|
||||
mulps xmm2,xmmword ptr [edi+40h]
|
||||
mulps xmm0,xmmword ptr [edi+50h]
|
||||
subps xmm5,xmm1
|
||||
movaps xmmword ptr [edx+10h],xmm4
|
||||
movaps xmm1,xmm7
|
||||
mulps xmm7,xmmword ptr [edi+20h]
|
||||
movaps xmm4,xmm3
|
||||
addps xmm0,xmm2
|
||||
mulps xmm3,xmmword ptr [edi+20h]
|
||||
mulps xmm4,xmmword ptr [edi+30h]
|
||||
cmp ebp,ebx
|
||||
mulps xmm1,xmmword ptr [edi+30h]
|
||||
lea edi,[edi+60h]
|
||||
jl _lStartAlign2
|
||||
movaps xmmword ptr [ebp+20h],xmm5
|
||||
addps xmm3,xmm1
|
||||
subps xmm7,xmm4
|
||||
movaps xmmword ptr [edx+20h],xmm0
|
||||
movaps xmmword ptr [edx],xmm3
|
||||
movaps xmmword ptr [ebp],xmm7
|
||||
mov ebp,[esp]
|
||||
mov edx,[esp+4]
|
||||
add ebp,40h
|
||||
add edx,40h
|
||||
mov [esp],ebp
|
||||
mov [esp+4],edx
|
||||
cmp ebp,[esp+10h]
|
||||
lea ebx,[ebp+10h]
|
||||
mov [esp+8],ebx
|
||||
lea edi,_tabCoef64_2
|
||||
jl _lAlign2
|
||||
|
||||
mov ebp, [esp+18h]
|
||||
mov edx, [esp+1ch]
|
||||
mov [esp], ebp
|
||||
mov [esp+4], edx
|
||||
mov ebx, [esp+10h]
|
||||
fld dword ptr [ebp]
|
||||
fld st(0)
|
||||
fld dword ptr [ebp+8]
|
||||
fsub st(1),st
|
||||
faddp st(2),st
|
||||
fld dword ptr [ebp+4]
|
||||
fxch st(2)
|
||||
fld st(2)
|
||||
fld dword ptr [ebp+0Ch]
|
||||
fadd st(1),st
|
||||
fsubp st(4),st
|
||||
jmp _lEnd3
|
||||
align 4
|
||||
_lCicle:
|
||||
fstp dword ptr [ebp-4]
|
||||
fld dword ptr [ebp]
|
||||
fxch st(1)
|
||||
fstp dword ptr [ebp-8]
|
||||
fld st(0)
|
||||
fld dword ptr [ebp+8]
|
||||
fadd st(2),st
|
||||
fxch st(3)
|
||||
fstp dword ptr [edx-10h]
|
||||
fsubrp st(2),st
|
||||
fld dword ptr [ebp+4]
|
||||
fld st(0)
|
||||
fld dword ptr [ebp+0Ch]
|
||||
fadd st(2),st
|
||||
fxch st(5)
|
||||
fstp dword ptr [edx-4]
|
||||
fsubrp st(4),st
|
||||
_lEnd3:
|
||||
fld dword ptr [edx]
|
||||
fld dword ptr [edx]
|
||||
fld st(3)
|
||||
fadd st,st(3)
|
||||
fld dword ptr [edx+8]
|
||||
fadd st(3),st
|
||||
fxch st(5)
|
||||
fsubrp st(4),st
|
||||
fld dword ptr [edx+4]
|
||||
fxch st(2)
|
||||
fsubrp st(5),st
|
||||
fstp dword ptr [ebp]
|
||||
fld st(0)
|
||||
fld dword ptr [edx+0Ch]
|
||||
fadd st(2),st
|
||||
fxch st(4)
|
||||
fstp dword ptr [ebp+4]
|
||||
fsubrp st(3),st
|
||||
fst [esp+10h]
|
||||
fadd st,st(1)
|
||||
fxch st(4)
|
||||
fst [esp+14h]
|
||||
fadd st,st(2)
|
||||
fxch st(3)
|
||||
fst [esp+18h]
|
||||
fsub st,st(5)
|
||||
fld [esp+10h]
|
||||
fsubp st(2),st
|
||||
fld [esp+14h]
|
||||
fsubrp st(3),st
|
||||
fld [esp+18h]
|
||||
faddp st(6),st
|
||||
add ebp,10h
|
||||
add edx,10h
|
||||
fstp dword ptr [edx-8]
|
||||
cmp ebp,ebx
|
||||
fstp dword ptr [edx-0Ch]
|
||||
jl _lCicle
|
||||
fstp dword ptr [ebp-4]
|
||||
fstp dword ptr [ebp-8]
|
||||
fstp dword ptr [edx-10h]
|
||||
fstp dword ptr [edx-4]
|
||||
mov ebp, [esp+0ch]
|
||||
add esp, 20h
|
||||
}
|
||||
}
|
||||
|
||||
void bittabc(int *p, int sn)
|
||||
{
|
||||
int i2 = sn;
|
||||
int j = 1;
|
||||
int i, k;
|
||||
int ind = 0;
|
||||
i2 >>= 1;
|
||||
for (i=1; i<=sn-1; i++)
|
||||
{
|
||||
if (i < j)
|
||||
{
|
||||
ind += 2;
|
||||
p[ind] = i-1;
|
||||
p[ind+1] = j-1;
|
||||
}
|
||||
k = i2;
|
||||
while (j > k)
|
||||
{
|
||||
j -= k;
|
||||
k >>= 1;
|
||||
}
|
||||
j += k;
|
||||
}
|
||||
p[0] = 0;
|
||||
p[1] = ind >> 1;
|
||||
}
|
||||
|
||||
void coef4r22c(int *ptr, int nm)
|
||||
{
|
||||
int sn = 1<<nm;
|
||||
bittabc(ptr, sn);
|
||||
}
|
||||
|
||||
|
||||
void cbitrevc(float* ar, float* ai, int *p)
|
||||
{
|
||||
int nCount = p[1];
|
||||
int *pInd = &p[2];
|
||||
int nC = nCount >> 2;
|
||||
while (nC)
|
||||
{
|
||||
Exchange(ar[pInd[0]], ar[pInd[1]]);
|
||||
Exchange(ar[pInd[2]], ar[pInd[3]]);
|
||||
Exchange(ar[pInd[4]], ar[pInd[5]]);
|
||||
Exchange(ar[pInd[6]], ar[pInd[7]]);
|
||||
pInd += 8;
|
||||
nC--;
|
||||
}
|
||||
pInd = &p[2];
|
||||
nC = nCount >> 2;
|
||||
while (nC)
|
||||
{
|
||||
Exchange(ai[pInd[0]], ai[pInd[1]]);
|
||||
Exchange(ai[pInd[2]], ai[pInd[3]]);
|
||||
Exchange(ai[pInd[4]], ai[pInd[5]]);
|
||||
Exchange(ai[pInd[6]], ai[pInd[7]]);
|
||||
pInd += 8;
|
||||
nC--;
|
||||
}
|
||||
}
|
||||
|
||||
void xcfft1dc(float* ar, float* ai, int *p, int nm)
|
||||
{
|
||||
cradix4c_64(ar, ai, nm);
|
||||
cbitrevc(ar, ai, p);
|
||||
}
|
||||
|
||||
void FFTSSE_64(float* ar, float* ai)
|
||||
{
|
||||
int i, j;
|
||||
const int nm = 6;
|
||||
|
||||
_declspec(align(16)) int p0[OCEANGRID*8];
|
||||
coef4r22c(p0, nm);
|
||||
for (i=0; i<OCEANGRID; i++)
|
||||
{
|
||||
xcfft1dc(&ar[OCEANGRID*i], &ai[OCEANGRID*i], p0, nm);
|
||||
}
|
||||
|
||||
coef4r22c(p0, nm);
|
||||
|
||||
_declspec(align(16)) float p1[4][OCEANGRID];
|
||||
_declspec(align(16)) float p2[4][OCEANGRID];
|
||||
|
||||
float *src, *dst;
|
||||
for (j=0; j<OCEANGRID; j+=4)
|
||||
{
|
||||
src = &ar[j];
|
||||
for (i=0; i<OCEANGRID; i++, src+=OCEANGRID)
|
||||
{
|
||||
p1[0][i] = src[0];
|
||||
p1[1][i] = src[1];
|
||||
p1[2][i] = src[2];
|
||||
p1[3][i] = src[3];
|
||||
}
|
||||
src = &ai[j];
|
||||
for (i=0; i<OCEANGRID; i++, src+=OCEANGRID)
|
||||
{
|
||||
p2[0][i] = src[0];
|
||||
p2[1][i] = src[1];
|
||||
p2[2][i] = src[2];
|
||||
p2[3][i] = src[3];
|
||||
}
|
||||
|
||||
xcfft1dc(&p1[0][0], &p2[0][0], p0, nm);
|
||||
xcfft1dc(&p1[1][0], &p2[1][0], p0, nm);
|
||||
xcfft1dc(&p1[2][0], &p2[2][0], p0, nm);
|
||||
xcfft1dc(&p1[3][0], &p2[3][0], p0, nm);
|
||||
|
||||
dst = &ar[j];
|
||||
for (i=0; i<OCEANGRID; i++, dst+=OCEANGRID)
|
||||
{
|
||||
dst[0] = p1[0][i];
|
||||
dst[1] = p1[1][i];
|
||||
dst[2] = p1[2][i];
|
||||
dst[3] = p1[3][i];
|
||||
}
|
||||
dst = &ai[j];
|
||||
for (i=0; i<OCEANGRID; i++, dst+=OCEANGRID)
|
||||
{
|
||||
dst[0] = p2[0][i];
|
||||
dst[1] = p2[1][i];
|
||||
dst[2] = p2[2][i];
|
||||
dst[3] = p2[3][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
#endif // !defined(WIN64)
|
||||
1523
RenderDll/Common/RendElements/RendElement.cpp
Normal file
1523
RenderDll/Common/RendElements/RendElement.cpp
Normal file
File diff suppressed because it is too large
Load Diff
931
RenderDll/Common/RenderPipeline.h
Normal file
931
RenderDll/Common/RenderPipeline.h
Normal file
@@ -0,0 +1,931 @@
|
||||
|
||||
/*=============================================================================
|
||||
RenderPipeline.h : Shaders pipeline declarations.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Honitch Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
|
||||
#ifndef __RENDERPIPELINE_H__
|
||||
#define __RENDERPIPELINE_H__
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define PIPE_USE_INSTANCING
|
||||
|
||||
#define NUMRI_LISTS 6
|
||||
#define MAX_HWINST_PARAMS 16384
|
||||
|
||||
typedef union UnINT64
|
||||
{
|
||||
uint64 SortVal;
|
||||
struct
|
||||
{
|
||||
uint Low;
|
||||
uint High;
|
||||
}i;
|
||||
} UnINT64;
|
||||
|
||||
struct SRendItemPre
|
||||
{
|
||||
UnINT64 SortVal;
|
||||
CRendElement *Item;
|
||||
union
|
||||
{
|
||||
uint ObjSort;
|
||||
float fDist;
|
||||
};
|
||||
uint DynLMask;
|
||||
};
|
||||
|
||||
struct SRendItemLight : SRendItemPre
|
||||
{
|
||||
};
|
||||
|
||||
struct SRendItemStenc : SRendItemPre
|
||||
{
|
||||
};
|
||||
|
||||
struct SRendItem : SRendItemPre
|
||||
{
|
||||
static void mfCalcRefractVectors(int Type, byte *Dst, int StrDst);
|
||||
static void mfCalcLightAttenuation(int type, byte *Dst, int StrideDst);
|
||||
static void mfCalcProjectVectors(int Type, float *Mat, float RefractIndex, byte *Dst, int StrDst);
|
||||
|
||||
static void mfCalcLightVectors(byte *lv, int Stride);
|
||||
static void mfCalcNormLightVectors(byte *lv, int Stride, int Type);
|
||||
static void mfCalcHalfAngles(int type, byte *ha, int StrHA);
|
||||
|
||||
static void mfCalcProjectAttenFromCamera(byte *dst, int Str);
|
||||
|
||||
static void mfCalcLAttenuationSpec0(byte *dst, int StrDst, byte *lv, int StrLV, int type);
|
||||
static void mfCalcLAttenuationSpec1(byte *dst, int StrDst, byte *lv, int StrLV, int type);
|
||||
|
||||
static void mfCalcLightVectors_Terrain(byte *lv, int Stride);
|
||||
static void mfCalcLAttenuationSpec0_Terrain(byte *dst, int StrDst, byte *lv, int StrLV, int type);
|
||||
static void mfCalcLAttenuationSpec1_Terrain(byte *dst, int StrDst, byte *lv, int StrLV, int type);
|
||||
static void mfCalcHalfAngles_Terrain(int type, byte *ha, int StrHA);
|
||||
|
||||
static void mfCalcTangentSpaceVectors();
|
||||
static void mfComputeTangent(const Vec3d& v0, const Vec3d& v1, const Vec3d& v2, const float t0[2], const float t1[2], const float t2[2], Vec3d &tangent, Vec3d& binormal, float& sign, Vec3d& face_normal);
|
||||
|
||||
//==================================================
|
||||
static void *mfGetPointerCommon(ESrcPointer ePT, int *Stride, int Type, ESrcPointer Dst, int Flags);
|
||||
|
||||
|
||||
#ifdef PIPE_USE_INSTANCING
|
||||
static _inline void mfAdd(CRendElement *Item, CCObject *pObj, SShader *Shader, int ResId, SShader *EfState, int numFog, int nTempl, int nSort=0)
|
||||
{
|
||||
int nList = nSort>>28;
|
||||
nSort &= 0xffff;
|
||||
int n = m_RendItems[nList].Num();
|
||||
m_RendItems[nList].AddIndex(1);
|
||||
SRendItemPre *ri = &m_RendItems[nList][n];
|
||||
int IdState = EfState ? EfState->m_Id : 0;
|
||||
nSort = (nSort > 0) ? nSort : Shader->m_eSort;
|
||||
int ObjNum;
|
||||
if (pObj)
|
||||
{
|
||||
ObjNum = pObj->m_VisId;
|
||||
ri->ObjSort = (pObj->m_ObjFlags & 0xffff0000) | pObj->m_nLMId;
|
||||
ri->DynLMask = pObj->m_DynLMMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjNum = 0;
|
||||
ri->ObjSort = 0;
|
||||
ri->DynLMask = 0;
|
||||
}
|
||||
ri->SortVal.i.Low = (ObjNum<<20) | (IdState<<8) | (numFog);
|
||||
ri->SortVal.i.High = (nSort<<26) | (Shader->m_Id<<14) | (ResId);
|
||||
ri->Item = Item;
|
||||
}
|
||||
static _inline void mfGet(UnINT64 flag, int *nObject, SShader **Shader, SShader **ShaderState, int *numFog, SRenderShaderResources **Res)
|
||||
{
|
||||
*numFog = flag.i.Low & 0x3f;
|
||||
*Shader = SShader::m_Shaders_known[(flag.i.High>>14) & 0xfff];
|
||||
int n = (flag.i.Low>>8) & 0xfff;
|
||||
*ShaderState = n ? SShader::m_Shaders_known[n] : NULL;
|
||||
*nObject = (flag.i.Low>>20) & 0xfff;
|
||||
n = flag.i.High & 0x3fff;
|
||||
*Res = (n) ? SShader::m_ShaderResources_known[n] : NULL;
|
||||
}
|
||||
static _inline void mfGetObj(UnINT64 flag, int *nObject)
|
||||
{
|
||||
*nObject = (flag.i.Low>>20) & 0xfff;
|
||||
}
|
||||
static _inline void mfGet(UnINT64 flag, SShader **Shader, SShader **ShaderState, SRenderShaderResources **Res)
|
||||
{
|
||||
*Shader = SShader::m_Shaders_known[(flag.i.High>>14) & 0xfff];
|
||||
int n = (flag.i.Low>>8) & 0xfff;
|
||||
*ShaderState = n ? SShader::m_Shaders_known[n] : NULL;
|
||||
n = flag.i.High & 0x3fff;
|
||||
*Res = (n) ? SShader::m_ShaderResources_known[n] : NULL;
|
||||
}
|
||||
static _inline SShader *mfGetShader(UnINT64 flag)
|
||||
{
|
||||
return SShader::m_Shaders_known[(flag.i.High>>14) & 0xfff];
|
||||
}
|
||||
#else
|
||||
static _inline void mfAdd(CRendElement *Item, CCObject *pObj, SShader *Shader, int ResId, SShader *EfState, int numFog, int nTempl, int nSort=0)
|
||||
{
|
||||
int nList = nSort>>28;
|
||||
nSort &= 0xffff;
|
||||
int n = m_RendItems[nList].Num();
|
||||
m_RendItems[nList].AddIndex(1);
|
||||
SRendItemPre *ri = &m_RendItems[nList][n];
|
||||
int IdState = EfState ? EfState->m_Id : 0;
|
||||
nSort = (nSort > 0) ? nSort : Shader->m_eSort;
|
||||
int ObjNum = pObj ? pObj->m_VisId : 0;
|
||||
ri->SortVal.i.Low = (Shader->m_Id<<20) | (IdState<<8) | (numFog);
|
||||
ri->SortVal.i.High = (nSort<<26) | (ObjNum<<15) | (ResId);
|
||||
ri->Item = Item;
|
||||
}
|
||||
static _inline void mfGet(UnINT64 flag, int *nObject, SShader **Shader, SShader **ShaderState, int *numFog, SRenderShaderResources **Res)
|
||||
{
|
||||
*numFog = flag.i.Low & 0x3f;
|
||||
*Shader = SShader::m_Shaders_known[(flag.i.Low>>20) & 0xfff];
|
||||
int n = (flag.i.Low>>8) & 0xfff;
|
||||
*ShaderState = n ? SShader::m_Shaders_known[n] : NULL;
|
||||
*nObject = (flag.i.High>>15) & 0x7ff;
|
||||
n = flag.i.High & 0x3fff;
|
||||
*Res = (n) ? SShader::m_ShaderResources_known[n] : NULL;
|
||||
}
|
||||
static _inline void mfGet(UnINT64 flag, SShader **Shader, SShader **ShaderState, SRenderShaderResources **Res)
|
||||
{
|
||||
*Shader = SShader::m_Shaders_known[(flag.i.Low>>20) & 0xfff];
|
||||
int n = (flag.i.Low>>8) & 0xfff;
|
||||
*ShaderState = n ? SShader::m_Shaders_known[n] : NULL;
|
||||
n = flag.i.High & 0x3fff;
|
||||
*Res = (n) ? SShader::m_ShaderResources_known[n] : NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sort by SortVal member of RI
|
||||
static void mfSort(SRendItemPre *First, int Num);
|
||||
// Special Sorting ignoring shadow maps
|
||||
static void mfSortForStencil(SRendItemPre *First, int Num);
|
||||
// Sort by distance
|
||||
static void mfSortByDist(SRendItemPre *First, int Num);
|
||||
// Sort by light
|
||||
static void mfSortByLight(SRendItemPre *First, int Num);
|
||||
|
||||
static int m_RecurseLevel;
|
||||
static int m_StartRI[8][NUMRI_LISTS];
|
||||
static int m_EndRI[8][NUMRI_LISTS];
|
||||
static TArray<SRendItemPre> m_RendItems[];
|
||||
};
|
||||
|
||||
struct SRendItemPreprocess : public SRendItem
|
||||
{
|
||||
CCObject *m_Object;
|
||||
|
||||
static void mfSort(SRendItemPreprocess *First, int Num);
|
||||
};
|
||||
|
||||
struct SRefSprite
|
||||
{
|
||||
CCObject *m_pObj;
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
|
||||
#define RNF_NOSHINE 0x1000
|
||||
|
||||
struct SMRendVert;
|
||||
struct SMRendTexVert;
|
||||
struct SShaderPass;
|
||||
struct SEvalFuncs;
|
||||
|
||||
union UPipeVertex
|
||||
{
|
||||
void *Ptr;
|
||||
byte *PtrB;
|
||||
float *PtrF;
|
||||
|
||||
Vec3d *VBPtr_0;
|
||||
struct_VERTEX_FORMAT_P3F *VBPtr_1;
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB *VBPtr_2;
|
||||
struct_VERTEX_FORMAT_P3F_TEX2F *VBPtr_3;
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *VBPtr_4;
|
||||
struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F *VBPtr_5;
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB_COL4UB *VBPtr_6;
|
||||
struct_VERTEX_FORMAT_P3F_N *VBPtr_7;
|
||||
struct_VERTEX_FORMAT_P3F_N_COL4UB *VBPtr_8;
|
||||
struct_VERTEX_FORMAT_P3F_N_TEX2F *VBPtr_9;
|
||||
struct_VERTEX_FORMAT_P3F_N_COL4UB_TEX2F *VBPtr_10;
|
||||
SPipTangents *VBPtr_11;
|
||||
struct_VERTEX_FORMAT_TEX2F *VBPtr_12;
|
||||
struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F_TEX2F *VBPtr_13;
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
|
||||
#define MAX_DYNVBS 8
|
||||
|
||||
struct SMFenceBufs
|
||||
{
|
||||
uint m_Fence;
|
||||
UPipeVertex Ptr;
|
||||
CVertexBuffer *m_pVBDyn;
|
||||
int m_nOffs;
|
||||
int m_nCount;
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
|
||||
#define MAX_PORTAL_RECURSES 4
|
||||
#define MAX_WARPSURFS 64
|
||||
#define MAX_WARPS 8
|
||||
|
||||
struct SWarpSurf
|
||||
{
|
||||
CRendElement *srf;
|
||||
int nobj;
|
||||
SShader *Shader;
|
||||
SRenderShaderResources *ShaderRes;
|
||||
};
|
||||
|
||||
struct STWarpZone
|
||||
{
|
||||
Plane plane;
|
||||
int numSrf;
|
||||
SWarpSurf Surfs[MAX_WARPSURFS];
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
// StencilStates
|
||||
|
||||
#define FSS_STENCFUNC_ALWAYS 0x0
|
||||
#define FSS_STENCFUNC_NEVER 0x1
|
||||
#define FSS_STENCFUNC_LESS 0x2
|
||||
#define FSS_STENCFUNC_LEQUAL 0x3
|
||||
#define FSS_STENCFUNC_GREATER 0x4
|
||||
#define FSS_STENCFUNC_GEQUAL 0x5
|
||||
#define FSS_STENCFUNC_EQUAL 0x6
|
||||
#define FSS_STENCFUNC_NOTEQUAL 0x7
|
||||
#define FSS_STENCFUNC_MASK 0x7
|
||||
|
||||
#define FSS_STENCIL_TWOSIDED 0x8
|
||||
|
||||
#define FSS_CCW_SHIFT 16
|
||||
|
||||
#define FSS_STENCOP_KEEP 0x0
|
||||
#define FSS_STENCOP_REPLACE 0x1
|
||||
#define FSS_STENCOP_INCR 0x2
|
||||
#define FSS_STENCOP_DECR 0x3
|
||||
#define FSS_STENCOP_ZERO 0x4
|
||||
#define FSS_STENCOP_INCR_WRAP 0x5
|
||||
#define FSS_STENCOP_DECR_WRAP 0x6
|
||||
|
||||
#define FSS_STENCFAIL_SHIFT 4
|
||||
#define FSS_STENCFAIL_MASK (0x7 << FSS_STENCFAIL_SHIFT)
|
||||
|
||||
#define FSS_STENCZFAIL_SHIFT 8
|
||||
#define FSS_STENCZFAIL_MASK (0x7 << FSS_STENCZFAIL_SHIFT)
|
||||
|
||||
#define FSS_STENCPASS_SHIFT 12
|
||||
#define FSS_STENCPASS_MASK (0x7 << FSS_STENCPASS_SHIFT)
|
||||
|
||||
#define STENC_FUNC(op) (op)
|
||||
#define STENC_CCW_FUNC(op) (op << FSS_CCW_SHIFT)
|
||||
#define STENCOP_FAIL(op) (op << FSS_STENCFAIL_SHIFT)
|
||||
#define STENCOP_ZFAIL(op) (op << FSS_STENCZFAIL_SHIFT)
|
||||
#define STENCOP_PASS(op) (op << FSS_STENCPASS_SHIFT)
|
||||
#define STENCOP_CCW_FAIL(op) (op << (FSS_STENCFAIL_SHIFT+FSS_CCW_SHIFT))
|
||||
#define STENCOP_CCW_ZFAIL(op) (op << (FSS_STENCZFAIL_SHIFT+FSS_CCW_SHIFT))
|
||||
#define STENCOP_CCW_PASS(op) (op << (FSS_STENCPASS_SHIFT+FSS_CCW_SHIFT))
|
||||
|
||||
//==================================================================
|
||||
|
||||
#ifdef DIRECT3D9
|
||||
#include <d3d9.h>
|
||||
#endif
|
||||
|
||||
#if defined (DIRECT3D8) || defined (DIRECT3D9)
|
||||
template <class IndexType> class DynamicIB;
|
||||
|
||||
struct SD3DFixedVShader
|
||||
{
|
||||
#ifdef DIRECT3D8
|
||||
TArray<DWORD> m_Declaration;
|
||||
#elif DIRECT3D9
|
||||
TArray<D3DVERTEXELEMENT9> m_Declaration;
|
||||
LPDIRECT3DVERTEXDECLARATION9 m_pDeclaration;
|
||||
#endif
|
||||
DWORD m_Handle;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (DIRECT3D8) || defined (DIRECT3D9)
|
||||
#define MAX_DYNVBS 8
|
||||
template < class VertexType > class DynamicVB;
|
||||
union UDynamicVB
|
||||
{
|
||||
DynamicVB <Vec3d> *VBPtr_0;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F> *VBPtr_1;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_COL4UB> *VBPtr_2;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_TEX2F> *VBPtr_3;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F> *VBPtr_4;
|
||||
DynamicVB <struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F> *VBPtr_5;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_COL4UB_COL4UB> *VBPtr_6;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_N> *VBPtr_7;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_N_COL4UB> *VBPtr_8;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_N_TEX2F> *VBPtr_9;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_N_COL4UB_TEX2F> *VBPtr_10;
|
||||
DynamicVB <SPipTangents> *VBPtr_11;
|
||||
DynamicVB <struct_VERTEX_FORMAT_TEX2F> *VBPtr_12;
|
||||
DynamicVB <struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F_TEX2F> *VBPtr_13;
|
||||
};
|
||||
struct SVertexDeclaration
|
||||
{
|
||||
int StreamMask;
|
||||
int VertFormat;
|
||||
int InstMask;
|
||||
TArray<D3DVERTEXELEMENT9> m_Declaration;
|
||||
LPDIRECT3DVERTEXDECLARATION9 m_pDeclaration;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct SProfInfo
|
||||
{
|
||||
int NumPolys;
|
||||
SShader *ef;
|
||||
double Time;
|
||||
int m_nItems;
|
||||
};
|
||||
|
||||
struct SVrect
|
||||
{
|
||||
int x,y,width,height;
|
||||
};
|
||||
|
||||
struct SPlane
|
||||
{
|
||||
byte m_Type;
|
||||
byte m_SignBits;
|
||||
Vec3d m_Normal;
|
||||
float m_Dist;
|
||||
void Init()
|
||||
{
|
||||
if ( m_Normal[0] == 1.0f )
|
||||
m_Type = PLANE_X;
|
||||
if ( m_Normal[1] == 1.0f )
|
||||
m_Type = PLANE_Y;
|
||||
if ( m_Normal[2] == 1.0f )
|
||||
m_Type = PLANE_Z;
|
||||
else
|
||||
m_Type = PLANE_NON_AXIAL;
|
||||
|
||||
// for fast box on planeside test
|
||||
int bits = 0;
|
||||
int j;
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
if (m_Normal[j] < 0)
|
||||
bits |= 1<<j;
|
||||
}
|
||||
m_SignBits = bits;
|
||||
}
|
||||
};
|
||||
|
||||
struct SStatItem
|
||||
{
|
||||
int m_Nums;
|
||||
double m_fTime;
|
||||
};
|
||||
|
||||
#define STARTPROFILE(Item) { ticks(Item.m_fTime); Item.m_Nums++; }
|
||||
#define ENDPROFILE(Item) { unticks(Item.m_fTime); }
|
||||
|
||||
struct SPipeStat
|
||||
{
|
||||
int m_NumRendBatches;
|
||||
int m_NumRendItems;
|
||||
int m_NumRendObjects;
|
||||
int m_NumDrawCalls;
|
||||
int m_NumTextChanges;
|
||||
int m_NumStateChanges;
|
||||
int m_NumRendSkinnedObjects;
|
||||
int m_NumLitShaders;
|
||||
int m_NumVShadChanges;
|
||||
int m_NumPShadChanges;
|
||||
int m_NumVShaders;
|
||||
int m_NumPShaders;
|
||||
int m_NumTextures;
|
||||
int m_TexturesSize;
|
||||
int m_MeshUpdateBytes;
|
||||
float m_fOverdraw;
|
||||
float m_fSkinningTime;
|
||||
float m_fPreprocessTime;
|
||||
float m_fFlushTime;
|
||||
float m_fTexUploadTime;
|
||||
float m_fOcclusionTime;
|
||||
int m_NumNotFinishFences;
|
||||
int m_NumFences;
|
||||
float m_fEnvCMapUpdateTime;
|
||||
};
|
||||
|
||||
struct STexStageInfo
|
||||
{
|
||||
int nMipFilter;
|
||||
byte Repeat;
|
||||
byte Projected;
|
||||
int MagFilter;
|
||||
int MinFilter;
|
||||
int Anisotropic;
|
||||
int TCIndex;
|
||||
// Per-stage color operations
|
||||
byte m_CO;
|
||||
byte m_CA;
|
||||
byte m_AO;
|
||||
byte m_AA;
|
||||
#ifndef _XBOX
|
||||
int Palette;
|
||||
#else
|
||||
void* Palette;
|
||||
#endif
|
||||
STexPic *Texture;
|
||||
STexStageInfo()
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
void Flush()
|
||||
{
|
||||
TCIndex = -1;
|
||||
nMipFilter = -1;
|
||||
Repeat = (bool)-1;
|
||||
Anisotropic = 255;
|
||||
Texture = NULL;
|
||||
#ifndef _XBOX
|
||||
Palette = -1;
|
||||
#else
|
||||
Palette = NULL;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct SSplash
|
||||
{
|
||||
int m_Id;
|
||||
Vec3d m_Pos;
|
||||
float m_fForce;
|
||||
eSplashType m_eType;
|
||||
float m_fStartTime;
|
||||
float m_fLastTime;
|
||||
float m_fCurRadius;
|
||||
};
|
||||
|
||||
// m_RP.m_Flags
|
||||
#define RBF_2D 0x10
|
||||
#define RBF_USEFENCES 0x100
|
||||
|
||||
#define RBF_MODIF_TC 0x1000
|
||||
#define RBF_MODIF_VERT 0x2000
|
||||
#define RBF_MODIF_COL 0x4000
|
||||
#define RBF_MODIF_MASK 0xf000
|
||||
|
||||
#define RBF_NEAREST 0x10000
|
||||
#define RBF_3D 0x40000
|
||||
#define RBF_SHOWLINES 0x80000
|
||||
|
||||
// m_RP.m_PersFlags
|
||||
#define RBPF_DONTDRAWSUN 1
|
||||
#define RBPF_SETCLIPPLANE 2
|
||||
#define RBPF_USESTREAM1 4
|
||||
#define RBPF_USESTREAM2 8
|
||||
#define RBPF_MEASUREOVERDRAW 0x10
|
||||
#define RBPF_DONTDRAWNEAREST 0x20
|
||||
#define RBPF_DRAWPORTAL 0x40
|
||||
#define RBPF_DRAWMIRROR 0x80
|
||||
#define RBPF_NOSHINE 0x100
|
||||
#define RBPF_NOCLEARBUF 0x400
|
||||
#define RBPF_DRAWNIGHTMAP 0x800
|
||||
#define RBPF_DRAWHEATMAP 0x1000
|
||||
#define RBPF_DRAWMOTIONMAP 0x2000
|
||||
#define RBPF_DRAWSCREENMAP 0x4000
|
||||
#define RBPF_MATRIXNOTLOADED 0x8000
|
||||
|
||||
#define RBPF_DRAWSCREENTEXMAP 0x10000 // tiago: added
|
||||
#define RBPF_ONLYREFRACTED 0x20000
|
||||
#define RBPF_IGNORERENDERING 0x40000
|
||||
#define RBPF_IGNOREREFRACTED 0x80000
|
||||
|
||||
#define RBPF_PS1WASSET 0x100000
|
||||
#define RBPF_PS2WASSET 0x200000
|
||||
#define RBPF_VSWASSET 0x400000
|
||||
#define RBPF_TSWASSET 0x800000
|
||||
|
||||
#define RBPF_PS1NEEDSET 0x1000000
|
||||
#define RBPF_PS2NEEDSET 0x2000000
|
||||
#define RBPF_VSNEEDSET 0x4000000
|
||||
#define RBPF_TSNEEDSET 0x8000000
|
||||
|
||||
#define RBPF_WASWORLDSPACE 0x10000000
|
||||
#define RBPF_MAKESPRITE 0x20000000
|
||||
#define RBPF_MULTILIGHTS 0x40000000
|
||||
#define RBPF_HDR 0x80000000
|
||||
|
||||
// m_RP.m_FlagsModificators
|
||||
#define RBMF_TANGENTSUSED SHPF_TANGENTS
|
||||
#define RBMF_LMTCUSED SHPF_LMTC
|
||||
#define RBMF_BENDINFOUSED 4
|
||||
#define RBMF_OBJUSESROTATE 8
|
||||
|
||||
// Texture transform flags (4)
|
||||
#define RBMF_TCM0 0x100
|
||||
// Object linear texgen flags (4)
|
||||
#define RBMF_TCGOL0 0x1000
|
||||
// Reflection map texgen flags (4)
|
||||
#define RBMF_TCGRM0 0x10000
|
||||
// Normal map texgen flags (4)
|
||||
#define RBMF_TCGNM0 0x100000
|
||||
// Normal map texgen flags (4)
|
||||
#define RBMF_TCGSM0 0x1000000
|
||||
|
||||
#define RBMF_NOUPDATE 0x10000000
|
||||
|
||||
#define RBMF_TCG 0xffff000
|
||||
#define RBMF_TCM 0xf00
|
||||
|
||||
|
||||
// m_RP.m_FlagsPerFlush
|
||||
#define RBSI_BLEND 0x1
|
||||
#define RBSI_NOCULL 0x2
|
||||
#define RBSI_WASDEPTHWRITE 0x4
|
||||
#define RBSI_DRAWAS2D 0x8
|
||||
#define RBSI_ALPHABLEND 0x10
|
||||
#define RBSI_ALPHATEST 0x20
|
||||
#define RBSI_DEPTHWRITE 0x40
|
||||
#define RBSI_FOGVOLUME 0x80
|
||||
#define RBSI_TEXSTATE 0x100
|
||||
#define RBSI_ALPHAGEN 0x200
|
||||
#define RBSI_RGBGEN 0x400
|
||||
#define RBSI_COLORMASK 0x800
|
||||
#define RBSI_INDEXSTREAM 0x1000
|
||||
#define RBSI_USEVP 0x2000
|
||||
#define RBSI_DEPTHTEST 0x4000
|
||||
#define RBSI_DEPTHFUNC 0x8000
|
||||
#define RBSI_SHADOWPASS 0x10000
|
||||
#define RBSI_STENCIL 0x20000
|
||||
#define RBSI_GLOBALRGB 0x40000
|
||||
#define RBSI_GLOBALALPHA 0x80000
|
||||
#define RBSI_VERTSMERGED 0x100000
|
||||
#define RBSI_LMTCMERGED 0x200000
|
||||
#define RBSI_TANGSMERGED 0x400000
|
||||
#define RBSI_FURPASS 0x800000
|
||||
#define RBSI_MERGED 0x1000000
|
||||
#define RBSI_USE_LM 0x2000000
|
||||
#define RBSI_USE_HDRLM 0x4000000
|
||||
#define RBSI_USE_3DC 0x8000000
|
||||
#define RBSI_USE_3DC_A 0x10000000
|
||||
#define RBSI_USE_SPECANTIALIAS 0x20000000
|
||||
|
||||
// m_RP.m_HWCurState
|
||||
// m_RP.m_HWPrevState
|
||||
#define RPHW_VPROGRAM 1
|
||||
#define RPHW_RCOMBINER 2
|
||||
#define RPHW_PSHADER 4
|
||||
|
||||
// m_RP.m_ShaderLightMask
|
||||
#define SLMF_DIRECT 0
|
||||
#define SLMF_POINT 1
|
||||
#define SLMF_PROJECTED 2
|
||||
#define SLMF_TYPE_MASK (SLMF_POINT | SLMF_PROJECTED)
|
||||
#define SLMF_ONLYSPEC 4
|
||||
#define SLMF_SPECOCCLUSION 8
|
||||
#define SLMF_LTYPE_SHIFT 16
|
||||
|
||||
struct SLightPass
|
||||
{
|
||||
CDLight *pLights[4];
|
||||
int nLights;
|
||||
int nProjectors;
|
||||
};
|
||||
|
||||
// Render status structure
|
||||
struct SRenderPipeline
|
||||
{
|
||||
SShader *m_pShader;
|
||||
CCObject *m_pCurObject;
|
||||
SShader *m_pStateShader;
|
||||
CRendElement *m_pRE;
|
||||
SRenderShaderResources *m_pShaderResources;
|
||||
CCObject *m_pPrevObject;
|
||||
#ifdef PIPE_USE_INSTANCING
|
||||
TArray<CCObject *> m_MergedObjects;
|
||||
TArray<CCObject *> m_RotatedMergedObjects;
|
||||
TArray<CCObject *> m_NonRotatedMergedObjects;
|
||||
#endif
|
||||
int m_FrameGTC;
|
||||
SGenTC *m_pGTC[MAX_TMU];
|
||||
STexStageInfo m_TexStages[MAX_TMU];
|
||||
|
||||
short m_TransformFrame;
|
||||
UCol m_CurGlobalColor;
|
||||
UCol m_NeedGlobalColor;
|
||||
|
||||
SEvalFuncs *m_pCurFuncs;
|
||||
SEvalFuncs_RE m_EvalFuncs_RE;
|
||||
SEvalFuncs_C m_EvalFuncs_C;
|
||||
|
||||
float m_RealTime;
|
||||
|
||||
int m_ObjFlags;
|
||||
int m_Flags; // Reset on start pipeline
|
||||
int m_PersFlags; // Never reset
|
||||
int m_FlagsPerFlush;
|
||||
int m_FlagsModificators;
|
||||
int m_FrameObject;
|
||||
float m_fCurSpecShininess;
|
||||
CName m_Name_SpecularExp;
|
||||
int m_ClipPlaneEnabled;
|
||||
CCObject *m_pIgnoreObject;
|
||||
|
||||
bool m_bStartPipeline;
|
||||
bool m_bDrawToTexture;
|
||||
int m_MirrorClipSide;
|
||||
int m_RenderFrame;
|
||||
int m_RendPass;
|
||||
int m_ResourceState;
|
||||
|
||||
SEnvTexture *m_pCurEnvTexture;
|
||||
|
||||
int m_StatNumLights;
|
||||
int m_StatNumLightPasses;
|
||||
int m_StatNumPasses;
|
||||
int m_StatLightMask;
|
||||
char *m_ExcludeShader;
|
||||
char *m_ShowOnlyShader;
|
||||
|
||||
TArray<SProfInfo> m_Profile;
|
||||
|
||||
Vec3d m_ViewOrg;
|
||||
|
||||
int m_CurrentVLightFlags;
|
||||
int m_EnabledVLightFlags;
|
||||
int m_EnabledVLights;
|
||||
int m_CurrentVLights;
|
||||
|
||||
int m_ShaderLightMask;
|
||||
int m_DynLMask;
|
||||
CDLight *m_pCurLight;
|
||||
int m_nCurLight;
|
||||
int m_nCurLightPass;
|
||||
int m_NumActiveDLights;
|
||||
CDLight *m_pActiveDLights[16];
|
||||
int m_nCurLightParam;
|
||||
SLightPass m_LPasses[32];
|
||||
|
||||
SLightMaterial *m_pCurLightMaterial;
|
||||
SLightMaterial m_DefLightMaterial;
|
||||
|
||||
SLightIndicies *m_pCurLightIndices;
|
||||
SLightIndicies m_FakeLightIndices;
|
||||
|
||||
UPipeVertex m_Ptr;
|
||||
UPipeVertex m_NextPtr;
|
||||
int m_Stride;
|
||||
int m_OffsT;
|
||||
int m_OffsD;
|
||||
int m_OffsN;
|
||||
int m_CurVFormat;
|
||||
TArray<CREOcLeaf *> m_MergedREs;
|
||||
TArray<CCObject *> m_MergedObjs;
|
||||
|
||||
float m_fLastWaterFOVUpdate;
|
||||
Vec3d m_LastWaterAngleUpdate;
|
||||
Vec3d m_LastWaterPosUpdate;
|
||||
float m_fLastWaterUpdate;
|
||||
|
||||
#if defined (DIRECT3D8) || defined (DIRECT3D9)
|
||||
UDynamicVB m_VBs[MAX_DYNVBS];
|
||||
DynamicIB <ushort> *m_IndexBuf;
|
||||
UDynamicVB m_MergedStreams[3];
|
||||
int m_nStreamOffset[3];
|
||||
SD3DFixedVShader m_D3DFixedPipeline[8][VERTEX_FORMAT_NUMS];
|
||||
DynamicVB <vec4_t> *m_VB_Inst;
|
||||
TArray<SVertexDeclaration *>m_CustomVD;
|
||||
#endif
|
||||
ushort *m_RendIndices;
|
||||
ushort *m_SysRendIndices;
|
||||
int m_CurVB;
|
||||
#ifdef OPENGL
|
||||
int m_NumFences;
|
||||
int m_CurFence;
|
||||
int m_FenceCount;
|
||||
SMFenceBufs m_VidBufs[MAX_DYNVBS];
|
||||
SVertexStream m_IBDyn;
|
||||
int m_IBDynOffs;
|
||||
int m_IBDynSize;
|
||||
int m_MergedStreams[3];
|
||||
int m_nStreamOffset[3];
|
||||
#endif
|
||||
|
||||
int m_RendNumIndices;
|
||||
int m_RendNumVerts;
|
||||
int m_FirstIndex;
|
||||
int m_FirstVertex;
|
||||
int m_BaseVertex;
|
||||
|
||||
int m_VFormatsMerge[VERTEX_FORMAT_NUMS][VERTEX_FORMAT_NUMS];
|
||||
|
||||
ECull m_eCull;
|
||||
|
||||
void (*m_pRenderFunc)();
|
||||
|
||||
SMFog *m_pFogVolume;
|
||||
|
||||
bool m_bClipPlaneRefract;
|
||||
SPlane m_CurClipPlane;
|
||||
SPlane m_CurClipPlaneCull;
|
||||
int m_ClipPlaneWasOverrided;
|
||||
int m_nClipPlaneTMU;
|
||||
|
||||
int m_FT;
|
||||
|
||||
SEfResTexture *m_ShaderTexResources[MAX_TMU];
|
||||
|
||||
CVProgram *m_CurVP;
|
||||
CPShader *m_CurPS;
|
||||
CVProgram *m_LastVP;
|
||||
|
||||
CPShader *m_RCSun;
|
||||
CPShader *m_RCDetail;
|
||||
CPShader *m_RCSprites;
|
||||
CPShader *m_RCSprites_Heat;
|
||||
CPShader *m_RCSprites_FV;
|
||||
CVProgram *m_VPDetail;
|
||||
CVProgram *m_VPTransformTexture;
|
||||
CVProgram *m_VPTexShadow;
|
||||
CVProgram *m_VPFog;
|
||||
CPShader *m_RCFog;
|
||||
CPShader *m_RCTexShadow;
|
||||
CVProgram *m_VPPlantBendingSpr;
|
||||
CVProgram *m_VPPlantBendingSpr_FV;
|
||||
CPShader *m_RCBlur;
|
||||
CVProgram *m_VPBlur;
|
||||
CVProgram *m_VPSubSurfaceScatering;
|
||||
CPShader *m_RCSubSurfaceScatering;
|
||||
CVProgram *m_VPSubSurfaceScatering_pp;
|
||||
CPShader *m_RCSubSurfaceScatering_pp;
|
||||
CVProgram *m_VPFur_NormGen;
|
||||
CVProgram *m_VPFur_OffsGen;
|
||||
CPShader *m_RCFur_NormGen;
|
||||
CPShader *m_RCFur_OffsGen;
|
||||
|
||||
CVProgram *m_VP_BaseCol;
|
||||
|
||||
CPShader *m_PS_HDRTemp;
|
||||
CPShader *m_PS_HDRDownScale2x2;
|
||||
CPShader *m_PS_HDRDownScale4x4;
|
||||
CPShader *m_PS_HDRDownScale4x4_RG;
|
||||
CPShader *m_PS_HDRDownScale4x4_BA;
|
||||
CPShader *m_PS_HDRSampleAvgLum;
|
||||
CPShader *m_PS_HDRResampleAvgLum;
|
||||
CPShader *m_PS_HDRResampleAvgLumExp;
|
||||
CPShader *m_PS_HDRCalcAdaptedLum;
|
||||
CPShader *m_PS_HDRBrightPassFilter;
|
||||
CPShader *m_PS_HDRGaussBlur5x5;
|
||||
CPShader *m_PS_HDRGaussBlur5x5_Bilinear;
|
||||
CPShader *m_PS_HDRBloom;
|
||||
CPShader *m_PS_HDRStar;
|
||||
CPShader *m_PS_HDRStar_MRT;
|
||||
CPShader *m_PS_HDRFinalScene;
|
||||
CPShader *m_PS_HDRMergeTextures[8];
|
||||
CPShader *m_PS_HDR_ShowR;
|
||||
CPShader *m_PS_HDR_ShowRG_MRT;
|
||||
CPShader *m_PS_HDR_Base;
|
||||
CPShader *m_PS_HDR_BaseCol;
|
||||
CPShader *m_PS_HDR_BaseCol_FV;
|
||||
CPShader *m_PS_HDR_AmbBase;
|
||||
CPShader *m_PS_HDR_AmbBaseCol;
|
||||
CPShader *m_PS_HDR_AmbBaseConst;
|
||||
CPShader *m_PS_HDR_BaseConst;
|
||||
CPShader *m_PS_HDR_AmbBaseCol_FV;
|
||||
CPShader *m_PS_HDR_DrawFlare;
|
||||
CPShader *m_PS_HDR_SkyFake;
|
||||
CPShader *m_PS_HDR_Sky;
|
||||
CPShader *m_PS_HDR_ClearScreen;
|
||||
CPShader *m_PS_GaussBlurSep;
|
||||
CVProgram *m_VS_GaussBlurSep;
|
||||
|
||||
SShaderPass *m_CurrPass;
|
||||
|
||||
int m_nCurStartCaster;
|
||||
|
||||
int m_Frame;
|
||||
int m_FillFrame;
|
||||
|
||||
SShaderTechnique *m_pCurTechnique;
|
||||
float m_fDistanceToCameraSquared;
|
||||
float m_fCurOpacity;
|
||||
Matrix44 m_WaterProjMatrix;
|
||||
Vec3d m_CamVecs[3];
|
||||
Vec3d m_OSCameraPos;
|
||||
|
||||
SPipeStat m_PS;
|
||||
|
||||
Vec3d m_SunDir;
|
||||
CFColor m_SunColor;
|
||||
|
||||
int m_nLMStage;
|
||||
INT_PTR m_nCurBufferID; // For ATI vertex object support //AMD Port
|
||||
int m_nCurBufferOffset; // For ATI vertex object support
|
||||
|
||||
int m_MaxVerts;
|
||||
int m_MaxTris;
|
||||
|
||||
int m_RECustomTexBind[8];
|
||||
CFColor m_REColor;
|
||||
float m_RECustomData[64];
|
||||
|
||||
STexPic *m_AnimTexs[4][32];
|
||||
int m_CurLayerNum;
|
||||
|
||||
Vec3d m_Center;
|
||||
|
||||
CCamera m_PrevCamera;
|
||||
|
||||
//=========================================================================
|
||||
// Per vertex attributes
|
||||
Vec3d *m_pBinormals;
|
||||
Vec3d *m_pTangents;
|
||||
Vec3d *m_pTNormals;
|
||||
Vec3d *m_pLightVectors[4];
|
||||
Vec3d *m_pHalfAngleVectors[4];
|
||||
Vec3d *m_pAttenuation;
|
||||
Vec3d *m_pLAttenSpec0;
|
||||
Vec3d *m_pLAttenSpec1;
|
||||
|
||||
SMRendTexVert *m_pBaseTexCoordPointer;
|
||||
SMRendTexVert *m_pLMTexCoordPointer;
|
||||
float *m_pFogVertValues;
|
||||
bvec4 *m_pClientColors;
|
||||
|
||||
//===================================================================
|
||||
// Input render data
|
||||
TArray<SSplash> m_Splashes;
|
||||
int m_NumVisObjects;
|
||||
CCObject **m_VisObjects;
|
||||
TArray<CDLight *> m_DLights[8];
|
||||
TArray <CCObject *> m_RejectedObjects;
|
||||
TArray <CCObject *> m_Objects;
|
||||
TArray <CCObject *> m_TempObjects;
|
||||
TArray<SMFog> m_FogVolumes;
|
||||
CCObject *m_ObjectsPool;
|
||||
int m_nNumObjectsInPool;
|
||||
|
||||
//================================================================
|
||||
// Portals support
|
||||
float m_fMinDepthRange;
|
||||
float m_fMaxDepthRange;
|
||||
|
||||
int m_RecurseLevel;
|
||||
int m_WasPortals;
|
||||
int m_CurPortal;
|
||||
STWarpZone *m_CurWarp;
|
||||
|
||||
//================================================================
|
||||
// Sprites
|
||||
TArray<SRefSprite> m_Sprites;
|
||||
|
||||
//================================================================
|
||||
// Temporary mesh
|
||||
TArray<class CRETempMesh *> m_TempMeshes[2];
|
||||
TArray<class CRETempMesh *> *m_CurTempMeshes;
|
||||
|
||||
//================================================================
|
||||
// Glare Heat and Night
|
||||
class CREGlare *m_pREGlare;
|
||||
class CREHDRProcess *m_pREHDR;
|
||||
int m_HeatSize;
|
||||
int m_NightSize;
|
||||
int m_GlareSize;
|
||||
int m_RainMapSize;
|
||||
int m_FlashBangSize;
|
||||
|
||||
//=================================================================
|
||||
// WaveForm tables
|
||||
float m_tSinTable[1024];
|
||||
float m_tHalfSinTable[1024];
|
||||
float m_tCosTable[1024];
|
||||
float m_tSquareTable[1024];
|
||||
float m_tTriTable[1024];
|
||||
float m_tSawtoothTable[1024];
|
||||
float m_tInvSawtoothTable[1024];
|
||||
float m_tHillTable[1024];
|
||||
|
||||
float m_tRandFloats[256];
|
||||
byte m_tRandBytes[256];
|
||||
};
|
||||
|
||||
#define MAX_REND_OBJECTS 4096
|
||||
|
||||
#endif // __RENDERPIPELINE_H__
|
||||
4395
RenderDll/Common/Renderer.cpp
Normal file
4395
RenderDll/Common/Renderer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1264
RenderDll/Common/Renderer.h
Normal file
1264
RenderDll/Common/Renderer.h
Normal file
File diff suppressed because it is too large
Load Diff
1099
RenderDll/Common/ResFile.cpp
Normal file
1099
RenderDll/Common/ResFile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
245
RenderDll/Common/ResFile.h
Normal file
245
RenderDll/Common/ResFile.h
Normal file
@@ -0,0 +1,245 @@
|
||||
#ifndef __RESFILE_H__
|
||||
#define __RESFILE_H__
|
||||
|
||||
#define IDRESHEADER (('K'<<24)+('C'<<16)+('P'<<8)+'C')
|
||||
#define RESVERSION 1
|
||||
|
||||
enum EResId
|
||||
{
|
||||
eRI_UNKNOWN = -1,
|
||||
eRI_BIN = 0,
|
||||
eRI_IMAGE = 1,
|
||||
eRI_MIPTEX = 2,
|
||||
eRI_SOUND = 3,
|
||||
eRI_MODEL = 4,
|
||||
eRI_PALETTE = 5
|
||||
};
|
||||
|
||||
enum EArc
|
||||
{
|
||||
eARC_NONE = 0,
|
||||
eARC_RLE = 1,
|
||||
eARC_LZSS = 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Resource header
|
||||
struct SFileResHeader
|
||||
{
|
||||
uint hid;
|
||||
int ver;
|
||||
uint optimize_mode;
|
||||
int num_files;
|
||||
#ifdef PS2
|
||||
int ofs_first;
|
||||
#else
|
||||
long ofs_first;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum EFS_DirType
|
||||
{
|
||||
eFSD_name,
|
||||
eFSD_id,
|
||||
};
|
||||
|
||||
// Each file entry in resource
|
||||
struct SFileDirEntry_0
|
||||
{
|
||||
char name[256-6*4];
|
||||
int size;
|
||||
int offset;
|
||||
int offnext;
|
||||
int offprev;
|
||||
EResId eid; // eRI_
|
||||
EArc earc; // eARC_
|
||||
};
|
||||
|
||||
// Each file entry in resource
|
||||
struct SFileDirEntry_1
|
||||
{
|
||||
int ID;
|
||||
int size;
|
||||
int offset;
|
||||
int offnext;
|
||||
int offprev;
|
||||
EResId eid; // eRI_
|
||||
EArc earc; // eARC_
|
||||
};
|
||||
|
||||
struct SCacheUser
|
||||
{
|
||||
void *data;
|
||||
};
|
||||
|
||||
// Intrinsic file entry
|
||||
struct SDirEntry
|
||||
{
|
||||
uint ID;
|
||||
int size;
|
||||
#ifdef PS2
|
||||
long offset;
|
||||
long offsetHeader;
|
||||
long curseek;
|
||||
#else
|
||||
int offset;
|
||||
int offsetHeader;
|
||||
int curseek;
|
||||
#endif
|
||||
EResId eid; // eRI_
|
||||
EArc earc; // eARC_
|
||||
SCacheUser user;
|
||||
uint flags;
|
||||
|
||||
SDirEntry()
|
||||
{
|
||||
memset(this, 0, sizeof(SDirEntry));
|
||||
}
|
||||
const char *Name()
|
||||
{
|
||||
return CName(ID).c_str();
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint,SDirEntry*> ResFilesMap;
|
||||
typedef ResFilesMap::iterator ResFilesMapItor;
|
||||
|
||||
// Resource access types
|
||||
#define RA_READ 1
|
||||
#define RA_WRITE 2
|
||||
#define RA_CREATE 4
|
||||
|
||||
|
||||
// Resource files flags
|
||||
#define RF_NOTSAVED 1
|
||||
#define RF_DELETED 2
|
||||
#define RF_INTRINSIC 4
|
||||
#define RF_CACHED 8
|
||||
#define RF_BIG 0x10
|
||||
#define RF_TEMPDATA 0x20
|
||||
|
||||
// Resource optimize flags
|
||||
#define RO_HEADERS_IN_BEGIN 1
|
||||
#define RO_HEADERS_IN_END 2
|
||||
#define RO_HEADER_FILE 4
|
||||
#define RO_SORT_ALPHA_ASC 8
|
||||
#define RO_SORT_ALPHA_DESC 0x10
|
||||
|
||||
#define MAX_OPEN_RESFILES 40
|
||||
|
||||
class CResFile
|
||||
{
|
||||
private:
|
||||
char m_name[1024];
|
||||
char *m_szAccess;
|
||||
FILE* m_handle;
|
||||
EFS_DirType m_eDT;
|
||||
ResFilesMap m_dir;
|
||||
int m_typeaccess;
|
||||
uint m_optimize;
|
||||
char m_ermes[1024];
|
||||
int m_version;
|
||||
int m_holesSize;
|
||||
|
||||
static CResFile m_Root;
|
||||
static int m_nNumOpenResources;
|
||||
CResFile *m_Next;
|
||||
CResFile *m_Prev;
|
||||
|
||||
bool mfActivate(bool bFirstTime);
|
||||
void mfDeactivate();
|
||||
|
||||
_inline void Relink(CResFile* Before)
|
||||
{
|
||||
if (m_Next && m_Prev)
|
||||
{
|
||||
m_Next->m_Prev = m_Prev;
|
||||
m_Prev->m_Next = m_Next;
|
||||
}
|
||||
m_Next = Before->m_Next;
|
||||
Before->m_Next->m_Prev = this;
|
||||
Before->m_Next = this;
|
||||
m_Prev = Before;
|
||||
}
|
||||
_inline void Unlink()
|
||||
{
|
||||
if (!m_Next || !m_Prev)
|
||||
return;
|
||||
m_Next->m_Prev = m_Prev;
|
||||
m_Prev->m_Next = m_Next;
|
||||
m_Next = m_Prev = NULL;
|
||||
}
|
||||
_inline void Link(CResFile* Before)
|
||||
{
|
||||
if (m_Next || m_Prev)
|
||||
return;
|
||||
m_Next = Before->m_Next;
|
||||
Before->m_Next->m_Prev = this;
|
||||
Before->m_Next = this;
|
||||
m_Prev = Before;
|
||||
}
|
||||
|
||||
public:
|
||||
CResFile(const char* name, EFS_DirType eDT);
|
||||
CResFile();
|
||||
~CResFile();
|
||||
|
||||
char* mfGetError(void);
|
||||
void mfSetError(const char *er);
|
||||
const char *mfGetFileName() {return m_name;}
|
||||
bool mfGetDir(TArray<SDirEntry *>& Dir);
|
||||
|
||||
bool mfOpen(int type);
|
||||
bool mfClose();
|
||||
bool mfFlush();
|
||||
bool mfOptimize(uint type);
|
||||
|
||||
int mfGetNumFiles() { return m_dir.size(); }
|
||||
|
||||
int mfFileGetNum(const char* name);
|
||||
|
||||
int mfFileRead(SDirEntry *de);
|
||||
int mfFileRead(const char* name);
|
||||
int mfFileRead(int num);
|
||||
|
||||
int mfFileRead(SDirEntry *de, void* data);
|
||||
int mfFileRead(int num, void* data);
|
||||
int mfFileRead(const char* name, void* data);
|
||||
|
||||
void* mfFileRead2(SDirEntry *de, int size);
|
||||
void* mfFileRead2(int num, int size);
|
||||
void* mfFileRead2(const char* name, int size);
|
||||
|
||||
void mfFileRead2(SDirEntry *de, int size, void *buf);
|
||||
void mfFileRead2(int num, int size, void *buf);
|
||||
|
||||
void* mfFileGetBuf(SDirEntry *de);
|
||||
void* mfFileGetBuf(int num);
|
||||
void* mfFileGetBuf(char* name);
|
||||
|
||||
int mfFileSeek(SDirEntry *de, int offs, int type);
|
||||
int mfFileSeek(int num, int offs, int type);
|
||||
int mfFileSeek(char* name, int offs, int type);
|
||||
|
||||
int mfFileLength(SDirEntry *de);
|
||||
int mfFileLength(int num);
|
||||
int mfFileLength(char* name);
|
||||
|
||||
int mfFileAdd(SDirEntry* de);
|
||||
|
||||
int mfFileDelete(SDirEntry *de);
|
||||
int mfFileDelete(int num);
|
||||
int mfFileDelete(char* name);
|
||||
|
||||
int mfFileExist(int ID);
|
||||
int mfFileExist(const char* name);
|
||||
|
||||
SDirEntry *mfGetEntry(int num);
|
||||
|
||||
FILE *mfGetHandle() { return m_handle; }
|
||||
int mfGetResourceSize();
|
||||
int mfGetHolesSize();
|
||||
};
|
||||
|
||||
#endif // __RESFILE_H__
|
||||
408
RenderDll/Common/Shaders/CShader.h
Normal file
408
RenderDll/Common/Shaders/CShader.h
Normal file
@@ -0,0 +1,408 @@
|
||||
|
||||
#ifndef __CSHADER_H__
|
||||
#define __CSHADER_H__
|
||||
|
||||
#include <map>
|
||||
|
||||
struct SRenderBuf;
|
||||
class CRendElement;
|
||||
struct SEmitter;
|
||||
struct SParticleInfo;
|
||||
struct SPartMoveStage;
|
||||
struct SSunFlare;
|
||||
|
||||
//===================================================================
|
||||
|
||||
#define MAX_ENVLIGHTCUBEMAPS 16
|
||||
#define ENVLIGHTCUBEMAP_SIZE 16
|
||||
#define MAX_ENVLIGHTCUBEMAPSCANDIST_UPDATE 16
|
||||
#define MAX_ENVLIGHTCUBEMAPSCANDIST_THRESHOLD 2
|
||||
|
||||
#define MAX_ENVCUBEMAPS 4
|
||||
#define MAX_ENVCUBEMAPSCANDIST_THRESHOLD 1
|
||||
|
||||
#define MAX_ENVTEXTURES 4
|
||||
#define MAX_ENVTEXSCANDIST 0.1f
|
||||
|
||||
struct SNameAlias
|
||||
{
|
||||
CName m_Alias;
|
||||
CName m_Name;
|
||||
};
|
||||
|
||||
struct SEnvTexture
|
||||
{
|
||||
bool m_bInprogress;
|
||||
bool m_bReady;
|
||||
bool m_bWater;
|
||||
bool m_bReflected;
|
||||
int m_MaskReady;
|
||||
int m_Id;
|
||||
int m_TexSize;
|
||||
// Result Cube-Map or 2D RT texture
|
||||
STexPic *m_Tex;
|
||||
// Temporary 2D texture
|
||||
STexPic *m_TexTemp;
|
||||
float m_TimeLastUsed;
|
||||
Vec3d m_CamPos;
|
||||
Vec3d m_ObjPos;
|
||||
Vec3d m_Angle;
|
||||
int m_nFrameReset;
|
||||
// Cube maps average colors (used for RT radiosity)
|
||||
int m_nFrameCreated[6];
|
||||
UCol m_EnvColors[6];
|
||||
void *m_RenderTargets[6];
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
|
||||
#define MAX_EF_FILES 256
|
||||
|
||||
struct SRegTemplate
|
||||
{
|
||||
char m_Name[64];
|
||||
SShader *m_pShader;
|
||||
};
|
||||
|
||||
|
||||
#define SF_RELOAD 1
|
||||
|
||||
class CShader
|
||||
{
|
||||
friend struct SShader;
|
||||
|
||||
private:
|
||||
|
||||
void mfStartScriptPreprocess();
|
||||
int mfRemoveScript_ifdef(char *posStart, char *posEnd, bool bRemoveAll, int nPos, char *buf, const char *fileName);
|
||||
char *mfPreprCheckMacros (char *buf, const char *nameFile);
|
||||
char *mfPreprCheckConditions (char *buf, const char *nameFile);
|
||||
char *mfPreprCheckIncludes (char *buf, const char *drn, const char *name);
|
||||
int mfLoadSubdir (char *drn, int n);
|
||||
|
||||
int mfReadTexSequence(SShader *ef, TArray<STexPic *>& txs, const char *name, byte eTT, int Flags, int Flags2, float fAmount1=-1.0f, float fAmount2=-1.0f);
|
||||
|
||||
SShader *mfNewShader(EShClass Class, int num);
|
||||
|
||||
char *mfRescanScript(int type, int nInd, SShader *pSHOrg, uint64 nMaskGen);
|
||||
void mfScanScript (char *scr, int n);
|
||||
bool mfCompileShaderGen(SShader *ef, SShaderGen *shg, char *scr);
|
||||
SShaderGenBit *mfCompileShaderGenProperty(SShader *ef, char *scr);
|
||||
SShader *mfCompileShader(SShader *ef, char *scr);
|
||||
|
||||
void mfCompileFogParms(SShader *ef, char *scr);
|
||||
void mfCompileDeform(SShader *ef, SDeform *df, char *dname, char *scr);
|
||||
bool mfCompileSunFlares(SShader *ef, char *name, char *scr);
|
||||
bool mfCompileFlare(SShader *ef, SSunFlare *fl, char *scr);
|
||||
bool mfCompileParams(SShader *ef, char *scr);
|
||||
bool mfCompileRenderParams(SShader *ef, char *scr);
|
||||
bool mfCompilePublic(SShader *ef, char *scr);
|
||||
void mfParseLightStyle(CLightStyle *ls, char *lstr);
|
||||
bool mfCompileLightStyle(SShader *ef, int num, char *scr);
|
||||
void mfCompileParamComps(SParam *pr, char *scr, SShader *ef);
|
||||
uint mfCompileRendState(SShader *ef, SShaderPass *sm, char *scr);
|
||||
bool mfCompileSequence(SShader *ef, SShaderTexUnit *tl, int nLayer, char *scr, ETexType eTT, int Flags, int Flags2, float fBumpAmount);
|
||||
void mfCompileOrient(SShader *ef, int num, char *scr);
|
||||
|
||||
void mfCompileLightMove(SShader *ef, char *nameMove, SLightEval *le, char *scr);
|
||||
void mfCompileEvalLight(SShader *ef, char *scr);
|
||||
void mfCompileStencil(SShader *ef, char *params);
|
||||
void mfCompileState(SShader *ef, char *params);
|
||||
|
||||
STexPic *mfTryToLoadTexture(const char *nameTex, int Flags, int Flags2, byte eTT, SShader *sh, float fAmount1=-1.0f, float fAmount2=-1.0f);
|
||||
STexPic *mfLoadResourceTexture(const char *nameTex, const char *path, int Flags, int Flags2, byte eTT, SShader *sh, SEfResTexture *Tex, float fAmount1=-1.0f, float fAmount2=-1.0f);
|
||||
bool mfCheckAnimatedSequence(SShaderTexUnit *tl, STexPic *tx);
|
||||
STexPic *mfCheckTemplateTexName(char *mapname, ETexType eTT, short &nFlags);
|
||||
void mfCheckShaderResTextures(TArray<SShaderPass> &Dst, SShader *ef, SRenderShaderResources *Res);
|
||||
void mfCheckShaderResTexturesHW(TArray<SShaderPassHW> &Dst, SShader *ef, SRenderShaderResources *Res);
|
||||
int mfTemplateNameToId(char *name);
|
||||
void mfCompileTemplate(SShader *ef, char *scr);
|
||||
bool mfCompileTexGen(char *name, char *params, SShader *ef, SShaderTexUnit *ml);
|
||||
|
||||
SShader *mfCompile(SShader *ef, char *scr);
|
||||
|
||||
void mfCompileLayers(SShader *ef, char *scr, TArray<SShaderPassHW>& Layers, EShaderPassType eType);
|
||||
void mfCompileVarsPak(char *scr, TArray<CVarCond>& Vars, SShader *ef);
|
||||
void mfCompileHWConditions(SShader *ef, char *scr, SShaderTechnique *hs, int Id);
|
||||
SShaderTechnique *mfCompileHW(SShader *ef, char *scr, int Id);
|
||||
bool mfUpdateMergeStatus(SShaderTechnique *hs, TArray<SCGParam4f> *p);
|
||||
bool mfCompileHWShadeLayer(SShader *ef, char *scr, TArray<SShaderPassHW>& Layers);
|
||||
|
||||
void mfClEfCompile(SShader *ef, char *scr, char *name);
|
||||
|
||||
bool mfReloadShaderScript(const char *szShaderName, int nFlags, SShader *pSH);
|
||||
void mfRefreshResources(SShader *eft, SRenderShaderResources *Res);
|
||||
bool mfAddTemplate(SRenderShaderResources *Res, SShader *ef, int IdTempl, const char *Name=NULL, uint64 nMaskGen=0);
|
||||
void mfRegisterDefaultTemplates();
|
||||
void mfUnregisterDefaultTemplates();
|
||||
bool mfSetOpacity (SShaderPass *Layer, float Opa, SShader *ef, int Mode);
|
||||
void mfRefreshLayer(SShaderPass *sl, SShader *sh);
|
||||
bool mfReloadShader(const char *szName, int nFlags);
|
||||
bool mfReloadShaderFile(const char *szName, int nFlags);
|
||||
void mfCheckAffectedFiles(const char *ShadersPath, int nCheckFile, TArray<char *>& CheckNames, TArray<char *>& AffectedFiles);
|
||||
|
||||
public:
|
||||
char *m_pCurScript;
|
||||
ShaderMacro m_Macros;
|
||||
TArray<SLocalMacros> m_LocalMacros;
|
||||
|
||||
bool PackCache();
|
||||
SShaderCacheHeaderItem *GetCacheItem(SShaderCache *pCache, int nMask);
|
||||
bool FreeCacheItem(SShaderCache *pCache, int nMask);
|
||||
bool AddCacheItem(SShaderCache *pCache, SShaderCacheHeaderItem *pItem, byte *pData, int nLen, bool bFlush);
|
||||
SShaderCache *OpenCacheFile(const char *szName, float fVersion);
|
||||
bool FlushCacheFile(SShaderCache *pCache);
|
||||
bool CloseCacheFile(SShaderCache *pCache);
|
||||
|
||||
char *mfScriptPreprocessor (char *buf, const char *drn, const char *name);
|
||||
uint64 mfScriptPreprocessorMask(SShader *pSH, int nOffset);
|
||||
bool mfReloadAllShaders(int nFlags);
|
||||
bool mfReloadFile(const char *szPath, const char *szName, int nFlags);
|
||||
const char *mfTemplateTexIdToName(int Id);
|
||||
bool mfGetParmComps(int comp, SParam *vpp, char *name, char *params, SShader *ef);
|
||||
bool mfCompilePlantsTMoving(char *scr, SShader *ef, TArray<SParam>* Params, int reg);
|
||||
void mfCompileParamMatrix(char *scr, SShader *ef, SParamComp_Matrix *pcm);
|
||||
bool mfCompileParam(char *scr, SShader *ef, TArray<SParam>* Params);
|
||||
bool mfCompileCGParam(char *scr, SShader *ef, TArray<SCGParam4f>* Params);
|
||||
void mfCheckObjectDependParams(TArray<SParam>* PNoObj, TArray<SParam>* PObj);
|
||||
void mfCheckObjectDependParams(TArray<SCGParam4f>* PNoObj, TArray<SCGParam4f>* PObj);
|
||||
void mfCompileArrayPointer(TArray<SArrayPointer *>& Pointers, char *scr, SShader *ef);
|
||||
ESrcPointer mfParseSrcPointer(char *type, SShader *ef);
|
||||
bool mfCompileLayer(SShader *ef, int num, char *scr, SShaderPass *sm);
|
||||
|
||||
bool mfRegisterTemplate(int nTemplId, char *Name, bool bReplace, bool bDefault=false);
|
||||
void mfLoadFromFiles(int num);
|
||||
|
||||
void mfBeginFrame();
|
||||
|
||||
void mfCompileMatrixOp(TArray<SMatrixTransform>* MatrixOps, char *scr, char *name, SShader *ef);
|
||||
|
||||
SEnvTexture *mfFindSuitableEnvLCMap(Vec3d& Pos, bool bMustExist, int RendFlags, float fDistToCam, CCObject *pObj=NULL);
|
||||
SEnvTexture *mfFindSuitableEnvCMap(Vec3d& Pos, bool bMustExist, int RendFlags, float fDistToCam);
|
||||
SEnvTexture *mfFindSuitableEnvTex(Vec3d& Pos, Vec3d& Angs, bool bMustExist, int RendFlags, bool bUseExistingREs, SShader *pSH, SRenderShaderResources *pRes, CCObject *pObj, bool bReflect, CRendElement *pRE);
|
||||
|
||||
private:
|
||||
|
||||
ShaderFilesMap *m_RefEfs[2];
|
||||
LoadedShadersMap m_RefEfsLoaded;
|
||||
|
||||
public:
|
||||
bool m_bInitialized;
|
||||
|
||||
char m_ShadersPath[2][128];
|
||||
char m_ShadersCache[128];
|
||||
char *m_ModelsPath;
|
||||
char *m_TexturesPath;
|
||||
char *m_SystemPath;
|
||||
|
||||
char m_HWPath[128];
|
||||
|
||||
SOrient m_Orients[MAX_ORIENTS];
|
||||
int m_NumOrients;
|
||||
|
||||
string m_FileNames[2][MAX_EF_FILES];
|
||||
short m_nFrameReload[2][MAX_EF_FILES];
|
||||
FILETIME m_WriteTime[2][MAX_EF_FILES];
|
||||
int m_NumFiles[2];
|
||||
int m_nFrameForceReload;
|
||||
|
||||
int m_NightMapReady;
|
||||
int m_nCountNightMap;
|
||||
|
||||
int m_CurEfsNum;
|
||||
SShader *m_CurShader;
|
||||
|
||||
TArray<SNameAlias> m_AliasNames;
|
||||
TArray<SNameAlias> m_CustomAliasNames;
|
||||
|
||||
static SShader *m_DefaultShader;
|
||||
|
||||
#ifndef NULL_RENDERER
|
||||
static SShader *m_ShaderVFog;
|
||||
static SShader *m_ShaderVFogCaust;
|
||||
static SShader *m_ShaderFog;
|
||||
static SShader *m_ShaderFogCaust;
|
||||
static SShader *m_ShaderFog_FP;
|
||||
static SShader *m_ShaderFogCaust_FP;
|
||||
static SShader *m_ShaderStateNoCull;
|
||||
static SShader *m_ZBuffPassShader;
|
||||
static SShader *m_ShadowMapShader;
|
||||
static SShader *m_ShaderHDRProcess;
|
||||
static SShader *m_GlareShader;
|
||||
static SShader *m_ShaderSunFlares;
|
||||
static SShader *m_ShaderLightStyles;
|
||||
static SShader *m_ShaderCGPShaders;
|
||||
static SShader *m_ShaderCGVProgramms;
|
||||
|
||||
#else
|
||||
static SShaderItem m_DefaultShaderItem;
|
||||
#endif
|
||||
|
||||
TArray<SRegTemplate> m_KnownTemplates;
|
||||
|
||||
int m_Frame;
|
||||
SRenderShaderResources *m_pCurResources;
|
||||
|
||||
Matrix44 m_TempMatrices[4][8];
|
||||
|
||||
bool m_bReload;
|
||||
|
||||
int m_Nums;
|
||||
int m_MaxNums;
|
||||
int m_FirstCopyNum;
|
||||
|
||||
bool m_bNeedSysBuf;
|
||||
bool m_bNeedCol;
|
||||
bool m_bNeedSecCol;
|
||||
bool m_bNeedNormal;
|
||||
bool m_bNeedTangents;
|
||||
int m_nTC;
|
||||
|
||||
|
||||
public:
|
||||
CShader()
|
||||
{
|
||||
m_bInitialized = false;
|
||||
m_CurEfsNum = 0;
|
||||
m_NumFiles[0] = m_NumFiles[1] = 0;
|
||||
m_DefaultShader = NULL;
|
||||
}
|
||||
|
||||
void mfShutdown (void);
|
||||
void mfClearAll (void);
|
||||
void mfClearShaders (TArray<SShader *> &Efs, int *Nums);
|
||||
|
||||
SShader *mfCopyShader(SShader *ef);
|
||||
void mfCompileWaveForm(SWaveForm *wf, char *scr);
|
||||
void mfCompileRGBAStyle(char *scr, SShader *ef, SShaderPass *sp, bool bRGB);
|
||||
void mfCompileRGBNoise(SRGBGenNoise *cn, char *scr, SShader *ef);
|
||||
void mfCompileAlphaNoise(SAlphaGenNoise *cn, char *scr, SShader *ef);
|
||||
void mfAddToHash (char *Name, SShader *ef);
|
||||
void mfAddToHashLwr (char *Name, SShader *ef);
|
||||
void mfRemoveFromHash (SShader *ef);
|
||||
//STexPic *mfLoadCubeTex(const char *mapname, uint flags, uint flags2, int State, ETexType eTT, int RState, int Id, int BindId=0);
|
||||
|
||||
int mfReadAllImgFiles(SShader *ef, SShaderTexUnit *tl, STexAnim *ta, char *name);
|
||||
|
||||
void mfInit(void);
|
||||
void mfShaderNameForAlias(const char *nameAlias, char *nameEf, int nSize);
|
||||
SRenderShaderResources *mfCreateShaderResources(const SInputShaderResources *Res, bool bShare);
|
||||
SShaderItem mfShaderItemForName (const char *name, EShClass Class, bool bShare, const char *templName, int flags, const SInputShaderResources *Res=NULL, uint64 nMaskGen=0);
|
||||
SShader *mfForName (const char *name, EShClass Class, int flags, const SInputShaderResources *Res=NULL, uint64 nMaskGen=0);
|
||||
SShader *mfSpawn (char *name, SShader *ef, SShader *efGen, uint64 nMaskGen);
|
||||
|
||||
bool mfParseFXTechnique_MergeParameters (std::vector<SFXStruct>& Structs, std::vector<SFXParam>& Params, int nNum, SShader *ef, bool bPixelShader, const char *szShaderName);
|
||||
bool mfParseFXTechnique_LoadShaderTexture (SFXSampler *smp, SFXTexture *tx, SShaderPassHW *pShPass, SShader *ef, int nIndex, byte ColorOp, byte AlphaOp, byte ColorArg, byte AlphaArg);
|
||||
bool mfParseFXTechnique_LoadShader (const char *szShaderCom, SShaderPassHW *pShPass, SShader *ef, std::vector<SFXSampler>& Samplers, std::vector<SFXTexture>& Textures, std::vector<SFXStruct>& Structs, std::vector<SFXParam>& Params, std::vector<SPair>& Macros, bool bPixelShader);
|
||||
bool mfParseFXTechniquePass (char *buf, char *annotations, SShaderTechnique *pShTech, SShader *ef, std::vector<SFXSampler>& Samplers, std::vector<SFXTexture>& Textures, std::vector<SFXStruct>& Structs, std::vector<SFXParam>& Params);
|
||||
bool mfParseFXTechnique (char *buf, char *annotations, SShader *ef, std::vector<SFXSampler>& Samplers, std::vector<SFXTexture>& Textures, std::vector<SFXStruct>& Structs, std::vector<SFXParam>& Params);
|
||||
bool mfParseFXSampler(char *buf, char *name, SShader *ef, std::vector<SFXSampler>& Samplers, std::vector<SFXTexture>& Textures);
|
||||
SShader *mfParseFX (char *buf, SShader *ef, SShader *efGen, uint64 nMaskGen);
|
||||
|
||||
char *mfFindInAllText (char *name, char *&pBuf, SShader *shGen, uint64 nMaskGen);
|
||||
char **mfListInScript (char *scr);
|
||||
char *mfScriptForFileName(const char *name, SShader *shGen, uint64 nMaskGen);
|
||||
|
||||
void mfSetDefaults(void);
|
||||
void mfOptimizeShader(SShader *ef, TArray<SShaderPass>& Layers, int Stage);
|
||||
void mfOptimizeShaderHW(SShader *ef, TArray<SShaderPassHW>& Layers, int Stage);
|
||||
void mfConstruct(SShader *ef);
|
||||
|
||||
#ifdef WIN64
|
||||
#pragma warning( push ) //AMD Port
|
||||
#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'XXX', possible loss of data
|
||||
#endif
|
||||
|
||||
int Size()
|
||||
{
|
||||
int i, j;
|
||||
int nSize = sizeof(*this);
|
||||
|
||||
nSize += m_KnownTemplates.GetMemoryUsage();
|
||||
nSize += m_AliasNames.GetMemoryUsage();
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
for (j=0; j<MAX_EF_FILES; j++)
|
||||
{
|
||||
if (!m_FileNames[i][j].empty())
|
||||
nSize += m_FileNames[i][j].capacity();
|
||||
}
|
||||
}
|
||||
|
||||
return nSize;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef WIN64
|
||||
#pragma warning( pop ) //AMD Port
|
||||
#endif
|
||||
|
||||
//=====================================================================
|
||||
|
||||
struct SSunFlare
|
||||
{
|
||||
float m_Scale;
|
||||
float m_Loc; // position offset on axis
|
||||
CFColor m_Color;
|
||||
STexPic *m_Tex;
|
||||
Vec3d m_Position;
|
||||
float m_RenderSize;
|
||||
|
||||
int Size()
|
||||
{
|
||||
int nSize = sizeof(SSunFlare);
|
||||
return nSize;
|
||||
}
|
||||
SSunFlare()
|
||||
{
|
||||
m_Tex = NULL;
|
||||
m_Scale = 1.0f;
|
||||
m_Loc = 0;
|
||||
m_Color = Col_White;
|
||||
}
|
||||
~SSunFlare();
|
||||
};
|
||||
|
||||
class CSunFlares
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
static TArray<CSunFlares *> m_SunFlares;
|
||||
static CSunFlares *m_CurFlares;
|
||||
|
||||
char m_Name[32];
|
||||
int m_NumFlares;
|
||||
SSunFlare *m_Flares;
|
||||
|
||||
//==================================================================
|
||||
|
||||
int Size()
|
||||
{
|
||||
int nSize = sizeof(CSunFlares);
|
||||
for (int i=0; i<m_NumFlares; i++)
|
||||
{
|
||||
nSize += m_Flares[i].Size();
|
||||
}
|
||||
return nSize;
|
||||
}
|
||||
|
||||
static CSunFlares *mfForName(char *name);
|
||||
|
||||
CSunFlares()
|
||||
{
|
||||
m_NumFlares = 0;
|
||||
m_Flares = NULL;
|
||||
}
|
||||
~CSunFlares()
|
||||
{
|
||||
if (m_Flares)
|
||||
delete [] m_Flares;
|
||||
m_NumFlares = 0;
|
||||
}
|
||||
};
|
||||
|
||||
//=====================================================================
|
||||
|
||||
#endif // __CSHADER_H__
|
||||
1587
RenderDll/Common/Shaders/Parser.cpp
Normal file
1587
RenderDll/Common/Shaders/Parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
80
RenderDll/Common/Shaders/Parser.h
Normal file
80
RenderDll/Common/Shaders/Parser.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*=============================================================================
|
||||
Parser.h : Script parser declarations.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
extern char *pCurCommand;
|
||||
|
||||
/**
|
||||
* Structure to describe a single token
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/// value returned when token is matched
|
||||
long id;
|
||||
/// token to match
|
||||
char *token;
|
||||
} tokenDesc;
|
||||
|
||||
struct SFXTokenDesc
|
||||
{
|
||||
int id;
|
||||
char *token;
|
||||
};
|
||||
|
||||
|
||||
extern const char *kWhiteSpace;
|
||||
|
||||
|
||||
/// Get an object from the buffer.
|
||||
long shGetObject(char **buf, tokenDesc *tokens, char **name, char **data);
|
||||
/// Get a command from the buffer.
|
||||
long shGetCommand(char **buf, tokenDesc *tokens, char **params);
|
||||
|
||||
extern std::vector<SPair> g_Macros;
|
||||
|
||||
long fxGetObject(char **buf, tokenDesc *tokens, char **name, char **data, int &nIndex);
|
||||
long fxGetObject(char **buf, SFXTokenDesc *tokens, char **name, char **value, char **data, char **assign, char **annotations, std::vector<SFXStruct>& Structs);
|
||||
void fxGetParams(char *annot, std::vector<SFXParam>& prms);
|
||||
void fxParserInit(void);
|
||||
void fxStart(void);
|
||||
void fxIncrLevel();
|
||||
void fxDecrLevel();
|
||||
int fxFill(char **buf, char *dst);
|
||||
|
||||
void fxTranslate(char **buf);
|
||||
char *fxGetAssignmentText(char **buf);
|
||||
char *fxGetAssignmentText2(char **buf);
|
||||
|
||||
char *GetSubText(char **buf, char open, char close);
|
||||
void SkipCharacters(char **buf, const char *toSkip);
|
||||
char *GetAssignmentText(char **buf);
|
||||
void SkipComments(char **buf, bool bSkipWhiteSpace);
|
||||
char *RemoveComments(char *buf);
|
||||
void RemoveCR(char *buf);
|
||||
|
||||
bool shGetBool(char *buf);
|
||||
float shGetFloat(char *buf);
|
||||
void shGetFloat(char *buf, float *v1, float *v2);
|
||||
int shGetInt(char *buf);
|
||||
int shGetHex(const char *buf);
|
||||
uint64 shGetHex64(const char *buf);
|
||||
void shGetVector(char *buf, Vec3d& v);
|
||||
void shGetVector(char *buf, float v[3]);
|
||||
void shGetVector4(char *buf, vec4_t& v);
|
||||
void shGetColor(char *buf, CFColor& v);
|
||||
void shGetColor(char *buf, float v[4]);
|
||||
int shGetVar (char **buf, char **vr, char **val);
|
||||
|
||||
char *fxReplaceInText(char *pText, const char *pSubStr, const char *pReplace);
|
||||
char *fxReplaceInText2(char *pText, const char *pSubStr, const char *pReplace);
|
||||
|
||||
#endif
|
||||
|
||||
4302
RenderDll/Common/Shaders/Shader.h
Normal file
4302
RenderDll/Common/Shaders/Shader.h
Normal file
File diff suppressed because it is too large
Load Diff
4063
RenderDll/Common/Shaders/ShaderComponents.cpp
Normal file
4063
RenderDll/Common/Shaders/ShaderComponents.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2753
RenderDll/Common/Shaders/ShaderCore.cpp
Normal file
2753
RenderDll/Common/Shaders/ShaderCore.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3782
RenderDll/Common/Shaders/ShaderParse.cpp
Normal file
3782
RenderDll/Common/Shaders/ShaderParse.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2753
RenderDll/Common/Shaders/ShaderScript.cpp
Normal file
2753
RenderDll/Common/Shaders/ShaderScript.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1815
RenderDll/Common/Shaders/ShaderTemplate.cpp
Normal file
1815
RenderDll/Common/Shaders/ShaderTemplate.cpp
Normal file
File diff suppressed because it is too large
Load Diff
230
RenderDll/Common/Shadow_Renderer.h
Normal file
230
RenderDll/Common/Shadow_Renderer.h
Normal file
@@ -0,0 +1,230 @@
|
||||
#ifndef SHADOWMAP_H
|
||||
#define SHADOWMAP_H
|
||||
|
||||
enum EShadowType
|
||||
{
|
||||
EST_DEPTH_BUFFER,
|
||||
EST_2D_BUFFER,
|
||||
EST_PENUMBRA
|
||||
};
|
||||
|
||||
#include "IRenderer.h"
|
||||
|
||||
#define SMFF_ACTIVE_SHADOW_MAP 1
|
||||
|
||||
struct ShadowMapFrustum
|
||||
{
|
||||
float debugLightFrustumMatrix[16];
|
||||
float debugLightViewMatrix[16];
|
||||
unsigned int depth_tex_id;
|
||||
struct ShadowMapLightSource * pLs;
|
||||
EShadowType shadow_type;
|
||||
float FOV;
|
||||
float min_dist;
|
||||
float max_dist;
|
||||
Vec3d target;
|
||||
bool bUpdateRequested;
|
||||
int nDLightId;
|
||||
int nTexSize;
|
||||
ShadowMapFrustum * pPenumbra;
|
||||
struct IEntityRender * pOwner;
|
||||
IStatObj * pOwnerGroup;
|
||||
int nTexIdSlot;
|
||||
int nResetID;
|
||||
int dwFlags;
|
||||
float fAlpha;
|
||||
float ProjRatio;
|
||||
float fOffsetScale;
|
||||
|
||||
list2<struct IStatObj*> * pModelsList;
|
||||
list2<struct IEntityRender*> * pEntityList;
|
||||
|
||||
Plane arrFrusrumPlanes[4];
|
||||
|
||||
float m_fCeachedFrustumScale;
|
||||
int m_nCeachedFrustumFrameId;
|
||||
float m_fBending;
|
||||
|
||||
ShadowMapFrustum()
|
||||
{
|
||||
ZeroStruct(*this);
|
||||
nTexIdSlot = -1;
|
||||
fAlpha = 1.f;
|
||||
ProjRatio = 1.f;
|
||||
nDLightId = -1;
|
||||
fOffsetScale = 1.f;
|
||||
}
|
||||
|
||||
~ShadowMapFrustum()
|
||||
{
|
||||
delete pModelsList;
|
||||
delete pEntityList;
|
||||
delete pPenumbra;
|
||||
}
|
||||
|
||||
void UnProject(float sx, float sy, float sz, float *px, float *py, float *pz, IRenderer * pRend )
|
||||
{
|
||||
const int shadowViewport[4] = {0,0,1,1};
|
||||
|
||||
|
||||
pRend->UnProject(sx,sy,sz,
|
||||
px,py,pz,
|
||||
debugLightViewMatrix,
|
||||
debugLightFrustumMatrix,
|
||||
shadowViewport);
|
||||
}
|
||||
|
||||
Vec3d & UnProjectVertex3d(int sx, int sy, int sz, Vec3d & vert, IRenderer * pRend)
|
||||
{
|
||||
float px;
|
||||
float py;
|
||||
float pz;
|
||||
UnProject((float)sx, (float)sy, (float)sz, &px, &py, &pz, pRend);
|
||||
vert.x=(float)px;
|
||||
vert.y=(float)py;
|
||||
vert.z=(float)pz;
|
||||
|
||||
// pRend->DrawBall(vert,10);
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
void DrawFrustum(IRenderer * pRend, Vec3d vPos, float fScale)
|
||||
{
|
||||
|
||||
Vec3d vert1,vert2;
|
||||
{
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(0,0,0,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(0,0,1,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(1,0,0,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(1,0,1,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(1,1,0,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(1,1,1,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(0,1,0,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(0,1,1,vert2,pRend), true);
|
||||
}
|
||||
|
||||
for(int i=0; i<=1; i++)
|
||||
{
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(0,0,i,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(1,0,i,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(1,0,i,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(1,1,i,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(1,1,i,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(0,1,i,vert2,pRend), true);
|
||||
|
||||
pRend->Draw3dBBox(
|
||||
vPos+fScale*UnProjectVertex3d(0,1,i,vert1,pRend),
|
||||
vPos+fScale*UnProjectVertex3d(0,0,i,vert2,pRend), true);
|
||||
}
|
||||
}
|
||||
|
||||
void InitFrustum(float fFrustumScale, IRenderer * pRend)
|
||||
{
|
||||
Vec3d v1,v2,v3;
|
||||
|
||||
// top
|
||||
UnProjectVertex3d(0,0,0,v1,pRend),
|
||||
UnProjectVertex3d(0,0,1,v2,pRend);
|
||||
UnProjectVertex3d(1,0,1,v3,pRend);
|
||||
arrFrusrumPlanes[0].Init(v1*fFrustumScale, v2*fFrustumScale, v3*fFrustumScale);
|
||||
|
||||
// left
|
||||
UnProjectVertex3d(0,1,0,v1,pRend),
|
||||
UnProjectVertex3d(0,1,1,v2,pRend);
|
||||
UnProjectVertex3d(0,0,1,v3,pRend);
|
||||
arrFrusrumPlanes[1].Init(v1*fFrustumScale, v2*fFrustumScale, v3*fFrustumScale);
|
||||
|
||||
// bottom
|
||||
UnProjectVertex3d(1,1,0,v1,pRend),
|
||||
UnProjectVertex3d(1,1,1,v2,pRend);
|
||||
UnProjectVertex3d(0,1,1,v3,pRend);
|
||||
arrFrusrumPlanes[2].Init(v1*fFrustumScale, v2*fFrustumScale, v3*fFrustumScale);
|
||||
|
||||
// right
|
||||
UnProjectVertex3d(1,0,0,v1,pRend),
|
||||
UnProjectVertex3d(1,0,1,v2,pRend);
|
||||
UnProjectVertex3d(1,1,1,v3,pRend);
|
||||
arrFrusrumPlanes[3].Init(v1*fFrustumScale, v2*fFrustumScale, v3*fFrustumScale);
|
||||
}
|
||||
|
||||
bool IsSphereInsideFrustum(Vec3d vSphereCenter, float fSphereRadius, float fFrustumScale, IRenderer * pRend)
|
||||
{
|
||||
// todo: optimize this
|
||||
static int a=0, b=0;
|
||||
if(/*debugLightFrustumMatrix[0] && */m_fCeachedFrustumScale != fFrustumScale || m_nCeachedFrustumFrameId != pRend->GetFrameID())
|
||||
{
|
||||
InitFrustum(fFrustumScale, pRend);
|
||||
m_fCeachedFrustumScale = fFrustumScale;
|
||||
m_nCeachedFrustumFrameId = pRend->GetFrameID();
|
||||
a++;
|
||||
}
|
||||
else
|
||||
{
|
||||
b++;
|
||||
}
|
||||
|
||||
float fDistance0 = arrFrusrumPlanes[0].DistFromPlane(vSphereCenter);
|
||||
float fDistance1 = arrFrusrumPlanes[1].DistFromPlane(vSphereCenter);
|
||||
float fDistance2 = arrFrusrumPlanes[2].DistFromPlane(vSphereCenter);
|
||||
float fDistance3 = arrFrusrumPlanes[3].DistFromPlane(vSphereCenter);
|
||||
|
||||
bool bRes = fDistance0>-fSphereRadius && fDistance1>-fSphereRadius && fDistance2>-fSphereRadius && fDistance3>-fSphereRadius;
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
InitFrustum(fFrustumScale, pRend);
|
||||
float fDistance0 = arrFrusrumPlanes[0].DistFromPlane(vSphereCenter);
|
||||
float fDistance1 = arrFrusrumPlanes[1].DistFromPlane(vSphereCenter);
|
||||
float fDistance2 = arrFrusrumPlanes[2].DistFromPlane(vSphereCenter);
|
||||
float fDistance3 = arrFrusrumPlanes[3].DistFromPlane(vSphereCenter);
|
||||
bool bResTest = fDistance0>-fSphereRadius && fDistance1>-fSphereRadius && fDistance2>-fSphereRadius && fDistance3>-fSphereRadius;
|
||||
assert(bResTest == bRes);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
return bRes;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShadowMapLightSource
|
||||
{
|
||||
ShadowMapLightSource(){ ZeroStruct(*this); nDLightId = -1; }
|
||||
Vec3 vSrcPos; // relative world space
|
||||
Vec3 vObjSpaceSrcPos; // objects space
|
||||
float fRadius;
|
||||
list2<ShadowMapFrustum> m_LightFrustums;
|
||||
int nDLightId;
|
||||
int SizeOf();
|
||||
ShadowMapFrustum * GetShadowMapFrustum(int nId=0)
|
||||
{
|
||||
if(nId<m_LightFrustums.Count())
|
||||
return &m_LightFrustums[nId];
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShadowMapLightSourceInstance
|
||||
{
|
||||
ShadowMapLightSourceInstance() { ZeroStruct(*this); }
|
||||
ShadowMapLightSource * m_pLS;
|
||||
Vec3 m_vProjTranslation;
|
||||
float m_fProjScale;
|
||||
float m_fDistance;
|
||||
struct IEntityRender * m_pReceiver;
|
||||
bool m_bNoDepthTest;
|
||||
};
|
||||
|
||||
#endif
|
||||
184
RenderDll/Common/SimpleFrameProfiler.cpp
Normal file
184
RenderDll/Common/SimpleFrameProfiler.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
#if !defined(LINUX)
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "SimpleFrameProfiler.h"
|
||||
|
||||
CRecursiveFrameProfiler* CRecursiveFrameProfiler::g_arrStack[CRecursiveFrameProfiler::nStackDepth];
|
||||
int CRecursiveFrameProfiler::g_nStackTop = 0;
|
||||
|
||||
CProfilerTimer g_ProfilerTimer;
|
||||
CSimpleFrameProfilerInfo *CSimpleFrameProfilerInfo::g_arrProfiles[64];
|
||||
|
||||
CSimpleFrameProfilerInfo::CSimpleFrameProfilerInfo (const char* szName):
|
||||
m_szName (szName),
|
||||
m_nTickTimer (0)
|
||||
{
|
||||
m_nIndex = g_nCount * 2;
|
||||
assert(g_nCount < 64);
|
||||
g_arrProfiles[g_nCount] = this;
|
||||
|
||||
m_bExpanded = false;
|
||||
m_bExpandable = false;
|
||||
m_bActive = false;
|
||||
m_pParent = NULL;
|
||||
m_nLevel = 0;
|
||||
|
||||
++g_nCount;
|
||||
}
|
||||
|
||||
int CSimpleFrameProfilerInfo::g_nCount = 0;
|
||||
|
||||
// this is called when the monitored interval starts
|
||||
void CSimpleFrameProfilerInfo::startInterval()
|
||||
{
|
||||
flush();
|
||||
m_nTickTimer -= g_ProfilerTimer.getTicks();
|
||||
++m_nCounter;
|
||||
}
|
||||
|
||||
void CSimpleFrameProfilerInfo::flush()
|
||||
{
|
||||
int nCurrentFrame = gRenDev->GetFrameID();
|
||||
if (nCurrentFrame != m_nFrame)
|
||||
{
|
||||
// clean up statistics if the frames didn't go in sequence,
|
||||
// or add to statistics if they did
|
||||
if (nCurrentFrame - m_nFrame > 16)
|
||||
{
|
||||
m_HistTime.clear();
|
||||
m_HistCount.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HistTime.add(g_ProfilerTimer.ticksToMilliseconds(m_nTickTimer));
|
||||
m_HistCount.add((float)m_nCounter);
|
||||
}
|
||||
|
||||
m_nTickTimer = 0;
|
||||
m_nFrame = nCurrentFrame;
|
||||
m_nCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSimpleFrameProfilerInfo::endInterval()
|
||||
{
|
||||
m_nTickTimer += g_ProfilerTimer.getTicks();
|
||||
}
|
||||
|
||||
void CSimpleFrameProfilerInfo::startDelay()
|
||||
{
|
||||
m_nTickTimer += g_ProfilerTimer.getTicks();
|
||||
}
|
||||
void CSimpleFrameProfilerInfo::endDelay()
|
||||
{
|
||||
m_nTickTimer -= g_ProfilerTimer.getTicks();
|
||||
}
|
||||
|
||||
|
||||
void CSimpleFrameProfilerInfo::drawLabel (float fRow, float* fColor, const char* szText)
|
||||
{
|
||||
gRenDev->Draw2dLabel (1+(float)m_nLevel*24.0f, fRow*13+50, 1.4f, fColor, false, "%s", szText);
|
||||
}
|
||||
|
||||
static float g_fColorHeader[4] = {0.5f,0.9f,1,0.75f};
|
||||
|
||||
void CSimpleFrameProfilerInfo::drawHeaderLabel()
|
||||
{
|
||||
drawLabel (-1.25f, g_fColorHeader, " max ave now min");
|
||||
}
|
||||
|
||||
void CSimpleFrameProfilerInfo::drawStatistics (float fRow, float* fColor, const char* szLabel, CProfilerTimerHistory<float,64>& rProfiler)
|
||||
{
|
||||
// draw the profiler statistics gathered on the previous frame
|
||||
char szBuf[128];
|
||||
sprintf (szBuf, "%22s %7.2f%7.2f%7.2f%7.2f",
|
||||
szLabel,
|
||||
rProfiler.getMax (),
|
||||
rProfiler.getAve (),
|
||||
rProfiler.getLast(),
|
||||
rProfiler.getMin()
|
||||
);
|
||||
drawLabel (fRow, fColor, szBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__int64 CProfilerTimer::g_nTicksPerSecond = 1000000000;
|
||||
double CProfilerTimer::g_fSecondsPerTick = 1e-9;
|
||||
double CProfilerTimer::g_fMilliSecondsPerTick = 1e-6;
|
||||
unsigned CProfilerTimer::g_nCPUHerz = 1000000000;
|
||||
void CProfilerTimer::init() // called once
|
||||
{
|
||||
#ifdef WIN32
|
||||
QueryPerformanceFrequency ((LARGE_INTEGER*)&g_nTicksPerSecond);
|
||||
#endif //WIN32
|
||||
|
||||
#ifdef GAMECUBE
|
||||
g_nTicksPerSecond = OS_CORE_CLOCK; //its a simple define on GC: 486.000.000
|
||||
g_nCPUHerz = OS_CORE_CLOCK;
|
||||
#endif
|
||||
|
||||
g_fSecondsPerTick = 1.0 / (double)g_nTicksPerSecond;
|
||||
g_fMilliSecondsPerTick = 1000.0 / (double)g_nTicksPerSecond;
|
||||
|
||||
#ifdef WIN32
|
||||
HKEY hKey;
|
||||
DWORD dwSize = sizeof(g_nCPUHerz);
|
||||
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey)
|
||||
&&ERROR_SUCCESS == RegQueryValueEx (hKey, "~MHz", NULL, NULL, (LPBYTE)&g_nCPUHerz, &dwSize))
|
||||
{
|
||||
g_nCPUHerz *= 1000000;
|
||||
g_fSecondsPerTick = 1.0/(double)g_nCPUHerz;
|
||||
g_fMilliSecondsPerTick = 1000.0/(double)g_nCPUHerz;
|
||||
}
|
||||
else
|
||||
g_nCPUHerz = 1000000000;
|
||||
#endif //WIN32
|
||||
|
||||
#ifdef _XBOX
|
||||
//@FIXME: Hack for XBOX
|
||||
g_nCPUHerz = 800*1000*1000; // 800 Mhz
|
||||
g_fSecondsPerTick = 1.0/(double)g_nCPUHerz;
|
||||
g_fMilliSecondsPerTick = 1000.0/(double)g_nCPUHerz;
|
||||
#endif //XBOX
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CProfilerTimer::getTicks(__int64* pnTime)
|
||||
{
|
||||
#ifdef WIN64
|
||||
*pnTime = __rdtsc();
|
||||
#elif defined(_CPU_X86)
|
||||
__asm {
|
||||
mov ebx, pnTime
|
||||
rdtsc
|
||||
mov [ebx], eax
|
||||
mov [ebx+4], edx
|
||||
}
|
||||
#else
|
||||
//#error Please provide a precise value or zero for pnTime
|
||||
#ifdef GAMECUBE
|
||||
//I know it looks strange, but this are the cycles!
|
||||
pnTime = (s64*)(OSGetTime()*12);
|
||||
#elif defined(WIN64)
|
||||
*pnTime = __rdtsc();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
float CProfilerTimer::ticksToSeconds (__int64 nTime)
|
||||
{
|
||||
return float(g_fSecondsPerTick * nTime);
|
||||
}
|
||||
|
||||
float CProfilerTimer::ticksToMilliseconds (__int64 nTime)
|
||||
{
|
||||
return float(g_fMilliSecondsPerTick * nTime);
|
||||
}
|
||||
|
||||
#endif // !defined(LINUX)
|
||||
19
RenderDll/Common/SimpleFrameProfiler.h
Normal file
19
RenderDll/Common/SimpleFrameProfiler.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// A simple profiler useful for collecting multiple call times per frame
|
||||
// and displaying their different average statistics.
|
||||
// For usage, see the bottom of the file
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef _SIMPLE_FRAME_PROFILER_
|
||||
#define _SIMPLE_FRAME_PROFILER_
|
||||
|
||||
// set #if 0 here if you don't want profiling to be compiled in the code
|
||||
#if ENABLE_FRAME_PROFILER
|
||||
#define PROFILE_FRAME(id) FRAME_PROFILER_FAST( "Renderer:" #id,iSystem,PROFILE_RENDERER,g_bProfilerEnabled )
|
||||
#else
|
||||
#define PROFILE_FRAME(id)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
615
RenderDll/Common/TangentSpaceCalculation.h
Normal file
615
RenderDll/Common/TangentSpaceCalculation.h
Normal file
@@ -0,0 +1,615 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek SuperFramework Source code
|
||||
//
|
||||
// (c) by Crytek GmbH 2003. All rights reserved.
|
||||
// Used with permission to distribute for non-commercial purposes.
|
||||
//
|
||||
//
|
||||
// File:TangentSpaceCalculation.h
|
||||
// Description: calculated the tangent space base vector for a given mesh
|
||||
// Dependencies: none
|
||||
// Documentation: "How to calculate tangent base vectors.doc"
|
||||
//
|
||||
// Usage:
|
||||
// implement the proxy class: CTriangleInputProxy
|
||||
// instance the proxy class: CTriangleInputProxy MyProxy(MyData);
|
||||
// instance the calculation helper: CTangentSpaceCalculation<MyProxy> MyTangent;
|
||||
// do the calculation: MyTangent.CalculateTangentSpace(MyProxy);
|
||||
// get the data back: MyTangent.GetTriangleIndices(), MyTangent.GetBase()
|
||||
//
|
||||
// History:
|
||||
// - 12/07/2002: Created by Martin Mittring as part of CryEngine
|
||||
// - 08/18/2003: MM improved stability (no illegal floats) with bad input data
|
||||
// - 08/19/2003: MM added check for input data problems (DebugMesh() is deactivated by default)
|
||||
// - 10/02/2003: MM removed rundundant code
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector> // STL vector<>
|
||||
#include <map> // STL map<,,> multimap<>
|
||||
|
||||
#define BASEMATRIXMERGEBIAS 0.9f
|
||||
|
||||
/* // use this as reference
|
||||
class CTriangleInputProxy
|
||||
{
|
||||
public:
|
||||
|
||||
//! /return 0..
|
||||
DWORD GetTriangleCount( void ) const;
|
||||
|
||||
//! /param indwTriNo 0..
|
||||
//! /param outdwPos
|
||||
//! /param outdwNorm
|
||||
//! /param outdwUV
|
||||
void GetTriangleIndices( const DWORD indwTriNo, DWORD outdwPos[3], DWORD outdwNorm[3], DWORD outdwUV[3] ) const;
|
||||
|
||||
//! /param indwPos 0..
|
||||
//! /param outfPos
|
||||
void GetPos( const DWORD indwPos, float outfPos[3] ) const;
|
||||
|
||||
//! /param indwPos 0..
|
||||
//! /param outfUV
|
||||
void GetUV( const DWORD indwPos, float outfUV[2] ) const;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// InputProxy - use CTriangleInputProxy as reference
|
||||
template <class InputProxy>
|
||||
class CTangentSpaceCalculation
|
||||
{
|
||||
public:
|
||||
|
||||
// IN ------------------------------------------------
|
||||
|
||||
//! /param inInput - the normals are only used as smoothing input - we calculate the normals ourself
|
||||
void CalculateTangentSpace( const InputProxy &inInput );
|
||||
|
||||
// OUT -----------------------------------------------
|
||||
|
||||
//! /return the number of base vectors that are stored 0..
|
||||
size_t GetBaseCount( void );
|
||||
|
||||
//!
|
||||
//! /param indwTriNo 0..
|
||||
//! /param outdwBase
|
||||
void GetTriangleBaseIndices( const DWORD indwTriNo, DWORD outdwBase[3] );
|
||||
|
||||
//! returns a orthogonal base (perpendicular and normalized)
|
||||
//! /param indwPos 0..
|
||||
//! /param outU in object/worldspace
|
||||
//! /param outV in object/worldspace
|
||||
//! /param outN in object/worldspace
|
||||
void GetBase( const DWORD indwPos, float *outU, float *outV, float *outN );
|
||||
|
||||
private: // -----------------------------------------------------------------
|
||||
|
||||
class CVec2
|
||||
{
|
||||
public:
|
||||
float x,y;
|
||||
|
||||
CVec2(){}
|
||||
CVec2(float fXval, float fYval) { x=fXval; y=fYval; }
|
||||
friend CVec2 operator - (const CVec2 &vec1, const CVec2 &vec2) { return CVec2(vec1.x-vec2.x, vec1.y-vec2.y); }
|
||||
operator float * () { return((float *)this); }
|
||||
};
|
||||
|
||||
class CVec3
|
||||
{
|
||||
public:
|
||||
float x,y,z;
|
||||
|
||||
CVec3(){}
|
||||
CVec3(float fXval, float fYval, float fZval) { x=fXval; y=fYval; z=fZval; }
|
||||
friend CVec3 operator - (const CVec3 &vec1, const CVec3 &vec2) { return CVec3(vec1.x-vec2.x, vec1.y-vec2.y, vec1.z-vec2.z); }
|
||||
friend CVec3 operator - (const CVec3 &vec1) { return CVec3(-vec1.x, -vec1.y, -vec1.z); }
|
||||
friend CVec3 operator + (const CVec3 &vec1, const CVec3 &vec2) { return CVec3(vec1.x+vec2.x, vec1.y+vec2.y, vec1.z+vec2.z); }
|
||||
friend CVec3 operator * (const CVec3 &vec1, const float fVal) { return CVec3(vec1.x*fVal, vec1.y*fVal, vec1.z*fVal); }
|
||||
friend float operator * (const CVec3 &vec1, const CVec3 &vec2) { return( vec1.x*vec2.x + vec1.y*vec2.y + vec1.z*vec2.z); }
|
||||
operator float * () { return((float *)this); }
|
||||
void Negate() { x=-x;y=-y;z=-z; }
|
||||
friend CVec3 normalize( const CVec3 &vec ) { CVec3 ret; float fLen=length(vec); if(fLen<0.00001f)return(vec); fLen=1.0f/fLen;ret.x=vec.x*fLen;ret.y=vec.y*fLen;ret.z=vec.z*fLen;return(ret); }
|
||||
friend CVec3 cross( const CVec3 &vec1, const CVec3 &vec2 ) { return CVec3(vec1.y*vec2.z-vec1.z*vec2.y, vec1.z*vec2.x-vec1.x*vec2.z, vec1.x*vec2.y-vec1.y*vec2.x); }
|
||||
friend float length( const CVec3 &invA ) { return (float)sqrt(invA.x*invA.x+invA.y*invA.y+invA.z*invA.z); }
|
||||
friend float CalcAngleBetween( const CVec3 &invA, const CVec3 &invB )
|
||||
{
|
||||
float LengthQ=length(invA)*length(invB);
|
||||
|
||||
if(LengthQ<0.0001f)LengthQ=0.0001f; // to prevent division by zero
|
||||
|
||||
float f=(invA*invB)/LengthQ;
|
||||
|
||||
if(f>1.0f)f=1.0f; // acos need input in the range [-1..1]
|
||||
else if(f<-1.0f)f=-1.0f; //
|
||||
|
||||
float fRet=(float)acos(f); // cosf is not avaiable on every plattform
|
||||
|
||||
return(fRet);
|
||||
}
|
||||
friend bool IsZero( const CVec3 &invA ) { return(invA.x==0.0f && invA.y==0.0f && invA.z==0.0f); }
|
||||
friend bool IsNormalized( const CVec3 &invA ) { float f=length(invA);return(f>=0.95f && f<=1.05f); }
|
||||
};
|
||||
|
||||
class CBaseIndex
|
||||
{
|
||||
public:
|
||||
DWORD m_dwPosNo; //!< 0..
|
||||
DWORD m_dwNormNo; //!< 0..
|
||||
};
|
||||
|
||||
// helper to get order for CVertexLoadHelper
|
||||
struct CBaseIndexOrder: public std::binary_function< CBaseIndex, CBaseIndex, bool>
|
||||
{
|
||||
bool operator() ( const CBaseIndex &a, const CBaseIndex &b ) const
|
||||
{
|
||||
// first sort by position
|
||||
if(a.m_dwPosNo<b.m_dwPosNo)return(true);
|
||||
if(a.m_dwPosNo>b.m_dwPosNo)return(false);
|
||||
|
||||
// then by normal
|
||||
if(a.m_dwNormNo<b.m_dwNormNo)return(true);
|
||||
if(a.m_dwNormNo>b.m_dwNormNo)return(false);
|
||||
|
||||
return(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CBase33
|
||||
{
|
||||
public:
|
||||
|
||||
CBase33() { }
|
||||
CBase33(CVec3 Uval, CVec3 Vval, CVec3 Nval) { u=Uval; v=Vval; n=Nval; }
|
||||
|
||||
CVec3 u; //!<
|
||||
CVec3 v; //!<
|
||||
CVec3 n; //!< is part of the tangent base but can be used also as vertex normal
|
||||
};
|
||||
|
||||
class CTriBaseIndex
|
||||
{
|
||||
public:
|
||||
DWORD p[3]; //!< index in m_BaseVectors
|
||||
};
|
||||
|
||||
// output data -----------------------------------------------------------------------------------
|
||||
|
||||
std::vector<CTriBaseIndex> m_TriBaseAssigment; //!< [0..dwTriangleCount]
|
||||
std::vector<CBase33> m_BaseVectors; //!< [0..] generated output data
|
||||
|
||||
//! /param indwPosNo
|
||||
//! /param indwNormNo
|
||||
CBase33 &GetBase( std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> &inMap, const DWORD indwPosNo, const DWORD indwNormNo );
|
||||
|
||||
private:
|
||||
//! creates, copies or returns a reference
|
||||
//! /param inMap
|
||||
//! /param indwPosNo
|
||||
//! /param indwNormNo
|
||||
//! /param inU weighted
|
||||
//! /param inV weighted
|
||||
//! /param inN normalized
|
||||
DWORD AddUV2Base( std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> &inMap, const DWORD indwPosNo, const DWORD indwNormNo, const CVec3 &inU, const CVec3 &inV, const CVec3 &inNormN );
|
||||
|
||||
//! /param inMap
|
||||
//! /param indwPosNo
|
||||
//! /param indwNormNo
|
||||
//! /param inNormal weighted normal
|
||||
void AddNormal2Base( std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> &inMap, const DWORD indwPosNo, const DWORD indwNormNo, const CVec3 &inNormal );
|
||||
|
||||
//! this code was heavly tested with external test app by SergiyM and MartinM
|
||||
//! rotates the input vector with the rotation to-from
|
||||
//! /param vFrom has to be normalized
|
||||
//! /param vTo has to be normalized
|
||||
//! /param vInput
|
||||
static CVec3 Rotate( const CVec3 &vFrom, const CVec3 &vTo, const CVec3 &vInput )
|
||||
{
|
||||
// no mesh is perfect
|
||||
// assert(IsNormalized(vFrom));
|
||||
// no mesh is perfect
|
||||
// assert(IsNormalized(vTo));
|
||||
|
||||
CVec3 vRotAxis=cross(vFrom,vTo); // rotation axis
|
||||
|
||||
float fSin=length(vRotAxis);
|
||||
float fCos=vFrom*vTo;
|
||||
|
||||
if(fSin<0.00001f) // no rotation
|
||||
return(vInput);
|
||||
|
||||
vRotAxis=vRotAxis*(1.0f/fSin); // normalize
|
||||
|
||||
CVec3 vFrom90deg=normalize(cross(vRotAxis,vFrom)); // perpendicular to vRotAxis and vFrom90deg
|
||||
|
||||
// Base is vFrom,vFrom90deg,vRotAxis
|
||||
|
||||
float fXInPlane=vFrom*vInput;
|
||||
float fYInPlane=vFrom90deg*vInput;
|
||||
|
||||
CVec3 a=vFrom*(fXInPlane*fCos-fYInPlane*fSin);
|
||||
CVec3 b=vFrom90deg*(fXInPlane*fSin+fYInPlane*fCos);
|
||||
CVec3 c=vRotAxis*(vRotAxis*vInput);
|
||||
|
||||
return( a + b + c );
|
||||
}
|
||||
|
||||
void DebugMesh( const InputProxy &inInput ) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class InputProxy>
|
||||
void CTangentSpaceCalculation<InputProxy>::DebugMesh( const InputProxy &inInput ) const
|
||||
{
|
||||
DWORD dwTriCount=inInput.GetTriangleCount();
|
||||
|
||||
// search for polygons that use the same indices (input data problems)
|
||||
for(DWORD a=0;a<dwTriCount;a++)
|
||||
{
|
||||
DWORD dwAPos[3],dwANorm[3],dwAUV[3];
|
||||
|
||||
inInput.GetTriangleIndices(a,dwAPos,dwANorm,dwAUV);
|
||||
|
||||
for(DWORD b=a+1;b<dwTriCount;b++)
|
||||
{
|
||||
DWORD dwBPos[3],dwBNorm[3],dwBUV[3];
|
||||
|
||||
inInput.GetTriangleIndices(b,dwBPos,dwBNorm,dwBUV);
|
||||
|
||||
assert(!( dwAPos[0]==dwBPos[0] && dwAPos[1]==dwBPos[1] && dwAPos[2]==dwBPos[2] ));
|
||||
assert(!( dwAPos[1]==dwBPos[0] && dwAPos[2]==dwBPos[1] && dwAPos[0]==dwBPos[2] ));
|
||||
assert(!( dwAPos[2]==dwBPos[0] && dwAPos[0]==dwBPos[1] && dwAPos[1]==dwBPos[2] ));
|
||||
|
||||
assert(!( dwAPos[1]==dwBPos[0] && dwAPos[0]==dwBPos[1] && dwAPos[2]==dwBPos[2] ));
|
||||
assert(!( dwAPos[2]==dwBPos[0] && dwAPos[1]==dwBPos[1] && dwAPos[0]==dwBPos[2] ));
|
||||
assert(!( dwAPos[0]==dwBPos[0] && dwAPos[2]==dwBPos[1] && dwAPos[1]==dwBPos[2] ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
void CTangentSpaceCalculation<InputProxy>::CalculateTangentSpace( const InputProxy &inInput )
|
||||
{
|
||||
DWORD dwTriCount=inInput.GetTriangleCount();
|
||||
|
||||
// clear result
|
||||
m_BaseVectors.clear();
|
||||
m_TriBaseAssigment.clear();
|
||||
m_TriBaseAssigment.reserve(dwTriCount);
|
||||
assert(m_BaseVectors.size()==0);
|
||||
assert(m_TriBaseAssigment.size()==0);
|
||||
|
||||
std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> mBaseMap; // second=index into m_BaseVectors, generated output data
|
||||
std::vector<CBase33> vTriangleBase; // base vectors per triangle
|
||||
|
||||
// DebugMesh(inInput); // only for debugging - slow
|
||||
|
||||
// calculate the base vectors per triangle -------------------------------------------
|
||||
{
|
||||
for(DWORD i=0;i<dwTriCount;i++)
|
||||
{
|
||||
// get data from caller ---------------------------
|
||||
DWORD dwPos[3],dwNorm[3],dwUV[3];
|
||||
|
||||
inInput.GetTriangleIndices(i,dwPos,dwNorm,dwUV);
|
||||
|
||||
CVec3 vPos[3];
|
||||
CVec2 vUV[3];
|
||||
|
||||
for(int e=0;e<3;e++)
|
||||
{
|
||||
inInput.GetPos(dwPos[e],vPos[e]);
|
||||
inInput.GetUV(dwUV[e],vUV[e]);
|
||||
}
|
||||
|
||||
// calculate tangent vectors ---------------------------
|
||||
|
||||
CVec3 vA=vPos[1]-vPos[0];
|
||||
CVec3 vB=vPos[2]-vPos[0];
|
||||
|
||||
/*
|
||||
char str[2024];
|
||||
|
||||
sprintf(str,"in: vA=(%.3f %.3f %.3f) vB=(%.3f %.3f %.3f)\n",vA.x,vA.y,vA.z,vA.x,vA.y,vA.z);
|
||||
OutputDebugString(str);
|
||||
*/
|
||||
|
||||
float fDeltaU1=vUV[1].x-vUV[0].x;
|
||||
float fDeltaU2=vUV[2].x-vUV[0].x;
|
||||
float fDeltaV1=vUV[1].y-vUV[0].y;
|
||||
float fDeltaV2=vUV[2].y-vUV[0].y;
|
||||
|
||||
float div =(fDeltaU1*fDeltaV2-fDeltaU2*fDeltaV1);
|
||||
|
||||
CVec3 vU,vV,vN=normalize(cross(vA,vB));
|
||||
|
||||
|
||||
if(div!=0.0)
|
||||
{
|
||||
// area(u1*v2-u2*v1)/2
|
||||
float fAreaMul2=fabsf(fDeltaU1*fDeltaV2-fDeltaU2*fDeltaV1); // weight the tangent vectors by the UV triangles area size (fix problems with base UV assignment)
|
||||
|
||||
float a = fDeltaV2/div;
|
||||
float b = -fDeltaV1/div;
|
||||
float c = -fDeltaU2/div;
|
||||
float d = fDeltaU1/div;
|
||||
|
||||
vU=normalize(vA*a+vB*b)*fAreaMul2;
|
||||
vV=normalize(vA*c+vB*d)*fAreaMul2;
|
||||
}
|
||||
else
|
||||
{
|
||||
vU=CVec3(1,0,0);vV=CVec3(0,1,0);
|
||||
}
|
||||
|
||||
vTriangleBase.push_back(CBase33(vU,vV,vN));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// distribute the normals to the vertices
|
||||
{
|
||||
// we create a new tangent base for every vertex index that has a different normal (later we split further for mirrored use)
|
||||
// and sum the base vectors (weighted by angle and mirrored if necessary)
|
||||
for(DWORD i=0;i<dwTriCount;i++)
|
||||
{
|
||||
DWORD e;
|
||||
|
||||
// get data from caller ---------------------------
|
||||
DWORD dwPos[3],dwNorm[3],dwUV[3];
|
||||
|
||||
inInput.GetTriangleIndices(i,dwPos,dwNorm,dwUV);
|
||||
CBase33 TriBase=vTriangleBase[i];
|
||||
CVec3 vPos[3];
|
||||
|
||||
for(e=0;e<3;e++) inInput.GetPos(dwPos[e],vPos[e]);
|
||||
|
||||
// for each triangle vertex
|
||||
for(e=0;e<3;e++)
|
||||
{
|
||||
float fWeight=CalcAngleBetween( vPos[(e+2)%3]-vPos[e],vPos[(e+1)%3]-vPos[e] ); // weight by angle to fix the L-Shape problem
|
||||
// float fWeight=length(cross( vPos[(e+2)%3]-vPos[e],vPos[(e+1)%3]-vPos[e] )); // weight by area, that does not fix the L-Shape problem 100%
|
||||
|
||||
if(fWeight<=0.0f)
|
||||
fWeight=0.0001f;
|
||||
|
||||
AddNormal2Base(mBaseMap,dwPos[e],dwNorm[e],TriBase.n*fWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// distribute the uv vectors to the vertices
|
||||
{
|
||||
// we create a new tangent base for every vertex index that has a different normal
|
||||
// if the base vectors does'nt fit we split as well
|
||||
for(DWORD i=0;i<dwTriCount;i++)
|
||||
{
|
||||
DWORD e;
|
||||
|
||||
// get data from caller ---------------------------
|
||||
DWORD dwPos[3],dwNorm[3],dwUV[3];
|
||||
|
||||
CTriBaseIndex Indx;
|
||||
inInput.GetTriangleIndices(i,dwPos,dwNorm,dwUV);
|
||||
CBase33 TriBase=vTriangleBase[i];
|
||||
CVec3 vPos[3];
|
||||
|
||||
for(e=0;e<3;e++) inInput.GetPos(dwPos[e],vPos[e]);
|
||||
|
||||
// for each triangle vertex
|
||||
for(e=0;e<3;e++)
|
||||
{
|
||||
float fWeight=CalcAngleBetween( vPos[(e+2)%3]-vPos[e],vPos[(e+1)%3]-vPos[e] ); // weight by angle to fix the L-Shape problem
|
||||
// float fWeight=length(cross( vPos[(e+2)%3]-vPos[e],vPos[(e+1)%3]-vPos[e] )); // weight by area, that does not fix the L-Shape problem 100%
|
||||
|
||||
Indx.p[e]=AddUV2Base(mBaseMap,dwPos[e],dwNorm[e],TriBase.u*fWeight,TriBase.v*fWeight,normalize(TriBase.n));
|
||||
}
|
||||
|
||||
m_TriBaseAssigment.push_back(Indx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// orthogonalize the base vectors per vertex -------------------------------------------
|
||||
{
|
||||
typename std::vector<CBase33>::iterator it;
|
||||
|
||||
for(it=m_BaseVectors.begin();it!=m_BaseVectors.end();++it)
|
||||
{
|
||||
CBase33 &ref=(*it);
|
||||
|
||||
// rotate u and v in n plane
|
||||
{
|
||||
// (N is dominating, U and V equal weighted)
|
||||
CVec3 vUout,vVout,vNout;
|
||||
|
||||
vNout=normalize(ref.n);
|
||||
|
||||
vUout = ref.u - vNout * (vNout*ref.u); // project u in n plane
|
||||
vVout = ref.v - vNout * (vNout*ref.v); // project v in n plane
|
||||
|
||||
ref.u=normalize(vUout);ref.v=normalize(vVout);ref.n=vNout;
|
||||
|
||||
//assert(ref.u.x>=-1 && ref.u.x<=1);
|
||||
//assert(ref.u.y>=-1 && ref.u.y<=1);
|
||||
//assert(ref.u.z>=-1 && ref.u.z<=1);
|
||||
//assert(ref.v.x>=-1 && ref.v.x<=1);
|
||||
//assert(ref.v.y>=-1 && ref.v.y<=1);
|
||||
//assert(ref.v.z>=-1 && ref.v.z<=1);
|
||||
//assert(ref.n.x>=-1 && ref.n.x<=1);
|
||||
//assert(ref.n.y>=-1 && ref.n.y<=1);
|
||||
//assert(ref.n.z>=-1 && ref.n.z<=1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
DWORD CTangentSpaceCalculation<InputProxy>::AddUV2Base( std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> &inMap,
|
||||
const DWORD indwPosNo, const DWORD indwNormNo, const CVec3 &inU, const CVec3 &inV, const CVec3 &inNormN )
|
||||
{
|
||||
// no mesh is perfect
|
||||
// assert(IsNormalized(inNormN));
|
||||
|
||||
CBaseIndex Indx;
|
||||
|
||||
Indx.m_dwPosNo=indwPosNo;
|
||||
Indx.m_dwNormNo=indwNormNo;
|
||||
|
||||
typename std::multimap<CBaseIndex,DWORD,CBaseIndexOrder>::iterator iFind,iFindEnd;
|
||||
|
||||
iFind = inMap.lower_bound(Indx);
|
||||
|
||||
assert(iFind!=inMap.end());
|
||||
|
||||
CVec3 vNormal=m_BaseVectors[(*iFind).second].n;
|
||||
|
||||
iFindEnd = inMap.upper_bound(Indx);
|
||||
|
||||
DWORD dwBaseUVIndex=0xffffffff; // init with not found
|
||||
|
||||
bool bParity=(cross(inU,inV)*inNormN>0.0f);
|
||||
|
||||
for(;iFind!=iFindEnd;++iFind)
|
||||
{
|
||||
CBase33 &refFound=m_BaseVectors[(*iFind).second];
|
||||
|
||||
if(!IsZero(refFound.u))
|
||||
{
|
||||
bool bParityRef=(cross(refFound.u,refFound.v)*refFound.n>0.0f);
|
||||
bool bParityCheck=(bParityRef==bParity);
|
||||
|
||||
if(!bParityCheck)continue;
|
||||
|
||||
// bool bHalfAngleCheck=normalize(inU+inV) * normalize(refFound.u+refFound.v) > 0.0f;
|
||||
|
||||
|
||||
CVec3 vRotHalf=Rotate(normalize(refFound.n),inNormN,normalize(refFound.u+refFound.v));
|
||||
|
||||
bool bHalfAngleCheck=normalize(inU+inV) * vRotHalf > 0.0f;
|
||||
// // bool bHalfAngleCheck=normalize(normalize(inU)+normalize(inV)) * normalize(normalize(refFound.u)+normalize(refFound.v)) > 0.0f;
|
||||
|
||||
if(!bHalfAngleCheck)continue;
|
||||
}
|
||||
|
||||
dwBaseUVIndex=(*iFind).second;break;
|
||||
}
|
||||
|
||||
if(dwBaseUVIndex==0xffffffff) // not found
|
||||
{
|
||||
// otherwise create a new base
|
||||
|
||||
CBase33 Base( CVec3(0,0,0), CVec3(0,0,0), vNormal );
|
||||
|
||||
dwBaseUVIndex = m_BaseVectors.size();
|
||||
|
||||
inMap.insert( std::pair<CBaseIndex,DWORD>(Indx,dwBaseUVIndex) );
|
||||
m_BaseVectors.push_back(Base);
|
||||
}
|
||||
|
||||
CBase33 &refBaseUV=m_BaseVectors[dwBaseUVIndex];
|
||||
|
||||
refBaseUV.u=refBaseUV.u+inU;
|
||||
refBaseUV.v=refBaseUV.v+inV;
|
||||
|
||||
//no mesh is perfect
|
||||
if(inU.x!=0.0f || inU.y!=0.0f || inU.z!=0.0f)
|
||||
assert(refBaseUV.u.x!=0.0f || refBaseUV.u.y!=0.0f || refBaseUV.u.z!=0.0f);
|
||||
// no mesh is perfect
|
||||
if(inV.x!=0.0f || inV.y!=0.0f || inV.z!=0.0f)
|
||||
assert(refBaseUV.v.x!=0.0f || refBaseUV.v.y!=0.0f || refBaseUV.v.z!=0.0f);
|
||||
|
||||
return(dwBaseUVIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
void CTangentSpaceCalculation<InputProxy>::AddNormal2Base( std::multimap<CBaseIndex,DWORD,CBaseIndexOrder> &inMap,
|
||||
const DWORD indwPosNo, const DWORD indwNormNo, const CVec3 &inNormal )
|
||||
{
|
||||
CBaseIndex Indx;
|
||||
|
||||
Indx.m_dwPosNo=indwPosNo;
|
||||
Indx.m_dwNormNo=indwNormNo;
|
||||
|
||||
typename std::multimap<CBaseIndex,DWORD,CBaseIndexOrder>::iterator iFind = inMap.find(Indx);
|
||||
|
||||
DWORD dwBaseNIndex;
|
||||
|
||||
if(iFind!=inMap.end()) // found
|
||||
{
|
||||
// resuse the existing one
|
||||
|
||||
dwBaseNIndex=(*iFind).second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise create a new base
|
||||
|
||||
CBase33 Base( CVec3(0,0,0), CVec3(0,0,0), CVec3(0,0,0) );
|
||||
|
||||
dwBaseNIndex=m_BaseVectors.size();
|
||||
inMap.insert( std::pair<CBaseIndex,DWORD>(Indx,dwBaseNIndex) );
|
||||
m_BaseVectors.push_back(Base);
|
||||
}
|
||||
|
||||
CBase33 &refBaseN=m_BaseVectors[dwBaseNIndex];
|
||||
|
||||
refBaseN.n=refBaseN.n+inNormal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
void CTangentSpaceCalculation<InputProxy>::GetBase( const DWORD indwPos, float *outU, float *outV, float *outN )
|
||||
{
|
||||
CBase33 &base=m_BaseVectors[indwPos];
|
||||
|
||||
outU[0]=base.u.x;
|
||||
outV[0]=base.v.x;
|
||||
outN[0]=base.n.x;
|
||||
outU[1]=base.u.y;
|
||||
outV[1]=base.v.y;
|
||||
outN[1]=base.n.y;
|
||||
outU[2]=base.u.z;
|
||||
outV[2]=base.v.z;
|
||||
outN[2]=base.n.z;
|
||||
}
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
void CTangentSpaceCalculation<InputProxy>::GetTriangleBaseIndices( const DWORD indwTriNo, DWORD outdwBase[3] )
|
||||
{
|
||||
assert(indwTriNo<m_TriBaseAssigment.size());
|
||||
CTriBaseIndex &indx=m_TriBaseAssigment[indwTriNo];
|
||||
|
||||
for(DWORD i=0;i<3;i++) outdwBase[i]=indx.p[i];
|
||||
}
|
||||
|
||||
|
||||
template <class InputProxy>
|
||||
size_t CTangentSpaceCalculation<InputProxy>::GetBaseCount( void )
|
||||
{
|
||||
return(m_BaseVectors.size());
|
||||
}
|
||||
258
RenderDll/Common/Textures/Image/BmpImage.cpp
Normal file
258
RenderDll/Common/Textures/Image/BmpImage.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*=============================================================================
|
||||
BmpImage.cpp : BMP image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
#include "BmpImage.h"
|
||||
|
||||
#include "SHEndian.h"
|
||||
|
||||
//===========================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Some platforms require strict-alignment, which means that values of
|
||||
// primitive types must be accessed at memory locations which are multiples
|
||||
// of the size of those types. For instance, a 'long' can only be accessed
|
||||
// at a memory location which is a multiple of four. Consequently, the
|
||||
// following endian-conversion functions first copy the raw data into a
|
||||
// variable of the proper data type using memcpy() prior to attempting to
|
||||
// access it as the given type.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static inline ushort us_endian (const byte* ptr)
|
||||
{
|
||||
short n;
|
||||
memcpy(&n, ptr, sizeof(n));
|
||||
return convert_endian(n);
|
||||
}
|
||||
|
||||
static inline unsigned long ul_endian (const byte* ptr)
|
||||
{
|
||||
long n;
|
||||
memcpy(&n, ptr, sizeof(n));
|
||||
return convert_endian(n);
|
||||
}
|
||||
|
||||
static inline long l_endian (const byte* ptr)
|
||||
{
|
||||
long n;
|
||||
memcpy(&n, ptr, sizeof(n));
|
||||
return convert_endian(n);
|
||||
}
|
||||
|
||||
#define BFTYPE(x) us_endian((x) + 0)
|
||||
#define BFSIZE(x) ul_endian((x) + 2)
|
||||
#define BFOFFBITS(x) ul_endian((x) + 10)
|
||||
#define BISIZE(x) ul_endian((x) + 14)
|
||||
#define BIWIDTH(x) l_endian ((x) + 18)
|
||||
#define BIHEIGHT(x) l_endian ((x) + 22)
|
||||
#define BITCOUNT(x) us_endian((x) + 28)
|
||||
#define BICOMP(x) ul_endian((x) + 30)
|
||||
#define IMAGESIZE(x) ul_endian((x) + 34)
|
||||
#define BICLRUSED(x) ul_endian((x) + 46)
|
||||
#define BICLRIMP(x) ul_endian((x) + 50)
|
||||
#define BIPALETTE(x) ((x) + 54)
|
||||
|
||||
// Type ID
|
||||
#define BM "BM" // Windows 3.1x, 95, NT, ...
|
||||
#define BA "BA" // OS/2 Bitmap Array
|
||||
#define CI "CI" // OS/2 Color Icon
|
||||
#define CP "CP" // OS/2 Color Pointer
|
||||
#define IC "IC" // OS/2 Icon
|
||||
#define PT "PT" // OS/2 Pointer
|
||||
|
||||
// Possible values for the header size
|
||||
#define WinHSize 0x28
|
||||
#define OS21xHSize 0x0C
|
||||
#define OS22xHSize 0xF0
|
||||
|
||||
// Possible values for the BPP setting
|
||||
#define Mono 1 // Monochrome bitmap
|
||||
#define _16Color 4 // 16 color bitmap
|
||||
#define _256Color 8 // 256 color bitmap
|
||||
#define HIGHCOLOR 16 // 16bit (high color) bitmap
|
||||
#define TRUECOLOR24 24 // 24bit (true color) bitmap
|
||||
#define TRUECOLOR32 32 // 32bit (true color) bitmap
|
||||
|
||||
// Compression Types
|
||||
#ifndef BI_RGB
|
||||
#define BI_RGB 0 // none
|
||||
#define BI_RLE8 1 // RLE 8-bit / pixel
|
||||
#define BI_RLE4 2 // RLE 4-bit / pixel
|
||||
#define BI_BITFIELDS 3 // Bitfields
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void CImageBmpFile::mfLoadWindowsBitmap (byte* iBuffer, long iSize)
|
||||
{
|
||||
mfSet_dimensions (BIWIDTH(iBuffer), BIHEIGHT(iBuffer));
|
||||
const int bmp_size = m_Width * m_Height;
|
||||
m_eFormat = eIF_Bmp;
|
||||
|
||||
byte *iPtr = iBuffer + BFOFFBITS(iBuffer);
|
||||
|
||||
// The last scanline in BMP corresponds to the top line in the image
|
||||
int buffer_y = m_Width * (m_Height - 1);
|
||||
bool blip = false;
|
||||
|
||||
if (BITCOUNT(iBuffer) == _256Color && BICLRUSED(iBuffer))
|
||||
{
|
||||
mfSet_ImageSize(m_Width * m_Height);
|
||||
byte *buffer = mfGet_image();
|
||||
m_pPal = new SRGBPixel [256];
|
||||
SRGBPixel *pwork = m_pPal;
|
||||
byte *inpal = BIPALETTE(iBuffer);
|
||||
mfSet_bps(8);
|
||||
|
||||
for (int color=0; color<256; color++, pwork++)
|
||||
{
|
||||
// Whacky BMP palette is in BGR order.
|
||||
pwork->blue = *inpal++;
|
||||
pwork->green = *inpal++;
|
||||
pwork->red = *inpal++;
|
||||
pwork->alpha = 255;
|
||||
inpal++; // Skip unused byte.
|
||||
}
|
||||
|
||||
if (BICOMP(iBuffer) == BI_RGB)
|
||||
{
|
||||
// Read the pixels from "top" to "bottom"
|
||||
while (iPtr < iBuffer + iSize && buffer_y >= 0)
|
||||
{
|
||||
memcpy (buffer + buffer_y, iPtr, m_Width);
|
||||
iPtr += m_Width;
|
||||
buffer_y -= m_Width;
|
||||
} /* endwhile */
|
||||
}
|
||||
else
|
||||
if (BICOMP(iBuffer) == BI_RLE8)
|
||||
{
|
||||
// Decompress pixel data
|
||||
byte rl, rl1, i; // runlength
|
||||
byte clridx, clridx1; // colorindex
|
||||
int buffer_x = 0;
|
||||
while (iPtr < iBuffer + iSize && buffer_y >= 0)
|
||||
{
|
||||
rl = rl1 = *iPtr++;
|
||||
clridx = clridx1 = *iPtr++;
|
||||
if (rl == 0)
|
||||
if (clridx == 0)
|
||||
{
|
||||
// new scanline
|
||||
if (!blip)
|
||||
{
|
||||
// if we didnt already jumped to the new line, do it now
|
||||
buffer_x = 0;
|
||||
buffer_y -= m_Width;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (clridx == 1)
|
||||
// end of bitmap
|
||||
break;
|
||||
else
|
||||
if (clridx == 2)
|
||||
{
|
||||
// next 2 bytes mean column- and scanline- offset
|
||||
buffer_x += *iPtr++;
|
||||
buffer_y -= (m_Width * (*iPtr++));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (clridx > 2)
|
||||
rl1 = clridx;
|
||||
|
||||
for ( i = 0; i < rl1; i++ )
|
||||
{
|
||||
if (!rl)
|
||||
clridx1 = *iPtr++;
|
||||
buffer [buffer_y + buffer_x] = clridx1;
|
||||
|
||||
if (++buffer_x >= m_Width)
|
||||
{
|
||||
buffer_x = 0;
|
||||
buffer_y -= m_Width;
|
||||
blip = true;
|
||||
}
|
||||
else
|
||||
blip = false;
|
||||
}
|
||||
// pad in case rl == 0 and clridx in [3..255]
|
||||
if (rl == 0 && (clridx & 0x01))
|
||||
iPtr++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (!BICLRUSED(iBuffer) && BITCOUNT(iBuffer) == TRUECOLOR24)
|
||||
{
|
||||
mfSet_ImageSize(m_Width * m_Height * 4);
|
||||
mfSet_bps (24);
|
||||
SRGBPixel *buffer = (SRGBPixel *)mfGet_image();
|
||||
|
||||
while (iPtr < iBuffer + iSize && buffer_y >= 0)
|
||||
{
|
||||
SRGBPixel *d = buffer + buffer_y;
|
||||
for (int x = m_Width; x; x--)
|
||||
{
|
||||
d->blue = *iPtr++;
|
||||
d->green = *iPtr++;
|
||||
d->red = *iPtr++;
|
||||
d->alpha = 255;
|
||||
d++;
|
||||
} /* endfor */
|
||||
|
||||
buffer_y -= m_Width;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (!BICLRUSED(iBuffer) && BITCOUNT(iBuffer) == TRUECOLOR32)
|
||||
{
|
||||
mfSet_ImageSize(m_Width * m_Height * 4);
|
||||
mfSet_bps (32);
|
||||
SRGBPixel *buffer = (SRGBPixel *)mfGet_image();
|
||||
|
||||
while (iPtr < iBuffer + iSize && buffer_y >= 0)
|
||||
{
|
||||
SRGBPixel *d = buffer + buffer_y;
|
||||
for (int x = m_Width; x; x--)
|
||||
{
|
||||
d->blue = *iPtr++;
|
||||
d->green = *iPtr++;
|
||||
d->red = *iPtr++;
|
||||
d->alpha = *iPtr++;
|
||||
d++;
|
||||
} /* endfor */
|
||||
|
||||
buffer_y -= m_Width;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mfSet_error (eIFE_BadFormat, "Unknown BMP image format");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CImageBmpFile::CImageBmpFile (byte* ptr, long filesize) : CImageFile ()
|
||||
{
|
||||
if ((memcmp (ptr, BM, 2) == 0) && BISIZE(ptr) == WinHSize)
|
||||
mfLoadWindowsBitmap (ptr, filesize);
|
||||
else
|
||||
mfSet_error (eIFE_BadFormat, "Not a Windows BMP file");
|
||||
return;
|
||||
}
|
||||
|
||||
CImageBmpFile::~CImageBmpFile ()
|
||||
{
|
||||
}
|
||||
26
RenderDll/Common/Textures/Image/BmpImage.h
Normal file
26
RenderDll/Common/Textures/Image/BmpImage.h
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef BMPIMAGE_H
|
||||
#define BMPIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading BMP files.
|
||||
*/
|
||||
class CImageBmpFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
/// Read the BMP file from the buffer.
|
||||
CImageBmpFile (byte* buf, long size);
|
||||
void mfLoadWindowsBitmap (byte* ptr, long filesize);
|
||||
|
||||
public:
|
||||
///
|
||||
virtual ~CImageBmpFile ();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
186
RenderDll/Common/Textures/Image/CImage.cpp
Normal file
186
RenderDll/Common/Textures/Image/CImage.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/*=============================================================================
|
||||
CImage.cpp : Common Image class implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
|
||||
|
||||
#include "PcxImage.h"
|
||||
#include "DDSImage.h"
|
||||
#include "BmpImage.h"
|
||||
#include "TgaImage.h"
|
||||
#include "JpgImage.h"
|
||||
|
||||
#ifdef PS2
|
||||
#include "XtfImage.h"
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
EImFileError CImageFile::m_eError = eIFE_OK;
|
||||
char CImageFile::m_Error_detail[256];
|
||||
char CImageFile::m_CurFileName[128];
|
||||
|
||||
CImageFile::CImageFile ()
|
||||
{
|
||||
m_pByteImage = NULL;
|
||||
m_pPal = NULL;
|
||||
m_eError = eIFE_OK;
|
||||
m_Error_detail[0] = 0;
|
||||
m_eFormat = eIF_Unknown;
|
||||
m_NumMips = 0;
|
||||
m_Flags = 0;
|
||||
m_ImgSize = 0;
|
||||
m_Depth = 1;
|
||||
}
|
||||
|
||||
CImageFile::~CImageFile ()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(m_pByteImage);
|
||||
SAFE_DELETE_ARRAY(m_pPal)
|
||||
}
|
||||
|
||||
void CImageFile::mfSet_dimensions (int w, int h)
|
||||
{
|
||||
m_Width = w;
|
||||
m_Height = h;
|
||||
}
|
||||
|
||||
void CImageFile::mfSet_error (EImFileError error, char* detail)
|
||||
{
|
||||
CImageFile::m_eError = error;
|
||||
if (detail)
|
||||
strcpy (m_Error_detail, detail);
|
||||
m_Error_detail[0] = 0;
|
||||
}
|
||||
|
||||
void CImageFile::mfWrite_error (char* extra)
|
||||
{
|
||||
if (m_eError == eIFE_OK)
|
||||
return;
|
||||
char buf[1000];
|
||||
int idx = 0;
|
||||
if (extra)
|
||||
idx += sprintf (buf+idx, "'%s': ", extra);
|
||||
switch (m_eError)
|
||||
{
|
||||
case eIFE_OK:
|
||||
return;
|
||||
|
||||
case eIFE_IOerror:
|
||||
idx += sprintf (buf+idx, "IO error");
|
||||
break;
|
||||
|
||||
case eIFE_OutOfMemory:
|
||||
idx += sprintf (buf+idx, "Out of memory");
|
||||
break;
|
||||
|
||||
case eIFE_BadFormat:
|
||||
idx += sprintf (buf+idx, "Bad format");
|
||||
break;
|
||||
}
|
||||
if (m_Error_detail[0])
|
||||
sprintf (buf+idx, " (%s)!\n", m_Error_detail);
|
||||
else
|
||||
sprintf (buf+idx, "!\n");
|
||||
iConsole->Exit ("%s", buf);
|
||||
}
|
||||
|
||||
float gFOpenTime;
|
||||
int nRejectFOpen;
|
||||
int nAcceptFOpen;
|
||||
|
||||
CImageFile* CImageFile::mfLoad_file (char* szFileName)
|
||||
{
|
||||
double dTime0 = 0;
|
||||
ticks(dTime0);
|
||||
|
||||
FILE* pRawFile = iSystem->GetIPak()->FOpen (szFileName, "rb");
|
||||
|
||||
unticks(dTime0);
|
||||
gFOpenTime += (float)(dTime0*1000.0*g_SecondsPerCycle);
|
||||
|
||||
if (!pRawFile)
|
||||
{
|
||||
nRejectFOpen++;
|
||||
return NULL;
|
||||
}
|
||||
nAcceptFOpen++;
|
||||
|
||||
strcpy(m_CurFileName, szFileName);
|
||||
strlwr(m_CurFileName);
|
||||
CImageFile* pImageFile = mfLoad_file (pRawFile);
|
||||
if (pImageFile)
|
||||
{
|
||||
strcpy(pImageFile->m_FileName, m_CurFileName);
|
||||
iSystem->GetIPak()->FClose (pRawFile);
|
||||
}
|
||||
else
|
||||
iSystem->GetILog()->LogToFile("\002Warning: Cannot load texture %s, pImageFile format is invalid", szFileName);
|
||||
return pImageFile;
|
||||
}
|
||||
|
||||
CImageFile* CImageFile::mfLoad_file (FILE* fp)
|
||||
{
|
||||
iSystem->GetIPak()->FSeek (fp, 0, SEEK_END);
|
||||
long size = iSystem->GetIPak()->FTell (fp);
|
||||
iSystem->GetIPak()->FSeek (fp, 0, SEEK_SET);
|
||||
CHK (byte* buf = new byte [size+1]);
|
||||
iSystem->GetIPak()->FRead (buf, 1, size + 1, fp);
|
||||
CImageFile* file = mfLoad_file (buf, size);
|
||||
CHK (delete [] buf);
|
||||
return file;
|
||||
}
|
||||
|
||||
CImageFile* CImageFile::mfLoad_file (byte* buf, long size)
|
||||
{
|
||||
CImageFile* file = NULL;
|
||||
CImageFile::m_eError = eIFE_OK;
|
||||
|
||||
// Catch NULL pointers (for example, when ZIP file is corrupt)
|
||||
assert (buf);
|
||||
|
||||
const char *ext = GetExtension(m_CurFileName);
|
||||
|
||||
#ifdef PS2
|
||||
// Try XTF first
|
||||
if (!strcmp(ext, ".xtf"))
|
||||
CHK (file = (CImageFile *)new CImageXtfFile (buf, (int)size));
|
||||
#endif
|
||||
|
||||
// Try DDS first
|
||||
if (!strcmp(ext, ".dds") || !strcmp(ext, ".ddn") || !strcmp(ext, ".ddp") || !strcmp(ext, ".ddt"))
|
||||
CHK (file = (CImageFile *)new CImageDDSFile (buf, size));
|
||||
|
||||
// If failed, try BMP
|
||||
if (!strcmp(ext, ".bmp"))
|
||||
CHK (file = (CImageFile *)new CImageBmpFile (buf, size));
|
||||
|
||||
// If failed, try PCX
|
||||
if (!strcmp(ext, ".pcx"))
|
||||
CHK (file = (CImageFile *)new CImagePcxFile (buf, size));
|
||||
#if !defined(NULL_RENDERER)
|
||||
// Try JPG next
|
||||
if (!strcmp(ext, ".jpg") || !strcmp(ext, ".jpeg"))
|
||||
CHK (file = (CImageFile *)new CImageJpgFile (buf, size));
|
||||
#endif
|
||||
// As a last resort, try TGA
|
||||
if (!strcmp(ext, ".tga"))
|
||||
CHK (file = (CImageFile *)new CImageTgaFile (buf, size));
|
||||
|
||||
if (file && (CImageFile::mfGet_error () != eIFE_OK))
|
||||
{
|
||||
CHK (delete file);
|
||||
file = NULL;
|
||||
} /* endif */
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
203
RenderDll/Common/Textures/Image/CImage.h
Normal file
203
RenderDll/Common/Textures/Image/CImage.h
Normal file
@@ -0,0 +1,203 @@
|
||||
|
||||
#ifndef CIMAGE_H
|
||||
#define CIMAGE_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define CHK(x) x
|
||||
|
||||
#define SH_LITTLE_ENDIAN
|
||||
|
||||
// The mask for extracting just R/G/B from an ulong or SRGBPixel
|
||||
#ifdef SH_BIG_ENDIAN
|
||||
# define RGB_MASK 0xffffff00
|
||||
#else
|
||||
# define RGB_MASK 0x00ffffff
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An RGB pixel.
|
||||
*/
|
||||
struct SRGBPixel
|
||||
{
|
||||
uchar blue, green, red, alpha;
|
||||
SRGBPixel () /* : red(0), green(0), blue(0), alpha(255) {} */
|
||||
{ *(unsigned long *)this = (unsigned long)~RGB_MASK; }
|
||||
SRGBPixel (int r, int g, int b) : red (r), green (g), blue (b), alpha (255) {}
|
||||
bool eq (const SRGBPixel& p) const { return ((*(unsigned long *)this) & RGB_MASK) == ((*(unsigned long *)&p) & RGB_MASK); }
|
||||
/// Get the pixel intensity
|
||||
int Intensity () { return (red + green + blue) / 3; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An RGB palette entry with statistics information.
|
||||
*/
|
||||
struct SRGBPalEntry
|
||||
{
|
||||
uchar red, green, blue;
|
||||
long count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Possible errors for CImageFile::mfGet_error.
|
||||
*/
|
||||
enum EImFileError { eIFE_OK = 0, eIFE_IOerror, eIFE_OutOfMemory, eIFE_BadFormat };
|
||||
|
||||
/**
|
||||
* Eye sensivity to different color components, from NTSC grayscale equation.
|
||||
* The coefficients are multiplied by 100 and rounded towards nearest integer,
|
||||
* to facilitate integer math. The squared coefficients are also multiplied
|
||||
* by 100 and rounded to nearest integer (thus 173 == 1.73, 242 == 2.42 etc).
|
||||
*/
|
||||
/// Red component sensivity
|
||||
#define R_COEF 173
|
||||
/// Green component sensivity
|
||||
#define G_COEF 242
|
||||
/// Blue component sensivity
|
||||
#define B_COEF 107
|
||||
/// Eye sensivity to different color components, squared
|
||||
/// Red component sensivity, squared
|
||||
#define R_COEF_SQ 299
|
||||
/// Green component sensivity, squared
|
||||
#define G_COEF_SQ 587
|
||||
/// Blue component sensivity, squared
|
||||
#define B_COEF_SQ 114
|
||||
|
||||
#define FIM_NORMALMAP 1
|
||||
#define FIM_DSDT 2
|
||||
|
||||
/**
|
||||
* An abstract class implementing an image loader. For every image
|
||||
* type supported, a subclass should be created for loading that image
|
||||
* type and ImageFile::load_file should be extended to recognize that
|
||||
* image format.
|
||||
*/
|
||||
class CImageFile
|
||||
{
|
||||
friend class CImageDDSFile;
|
||||
friend class CImageCCTFile;
|
||||
friend class CImageBmpFile;
|
||||
friend class CImagePcxFile;
|
||||
friend class CImageJpgFile;
|
||||
friend class CTexMan;
|
||||
|
||||
private:
|
||||
/// Width of image.
|
||||
int m_Width;
|
||||
/// Height of image.
|
||||
int m_Height;
|
||||
/// Depth of image.
|
||||
int m_Depth;
|
||||
|
||||
int m_Bps;
|
||||
int m_ImgSize;
|
||||
|
||||
int m_NumMips;
|
||||
int m_Flags;
|
||||
|
||||
/// The image data.
|
||||
union
|
||||
{
|
||||
SRGBPixel* m_pPixImage;
|
||||
byte* m_pByteImage;
|
||||
};
|
||||
|
||||
/// Last error code.
|
||||
static EImFileError m_eError;
|
||||
/// Last error detail information.
|
||||
static char m_Error_detail[256];
|
||||
|
||||
protected:
|
||||
|
||||
EImFormat m_eFormat;
|
||||
SRGBPixel* m_pPal;
|
||||
|
||||
/**
|
||||
* Constructor is private since this object can only be
|
||||
* created by load_file.
|
||||
*/
|
||||
CImageFile ();
|
||||
|
||||
/**
|
||||
* Before failing, a ImageFile subclass should call set_error to
|
||||
* set the code and detail.
|
||||
*/
|
||||
static void mfSet_error (EImFileError error, char* detail = NULL);
|
||||
|
||||
/**
|
||||
* Set the width and height. This will also allocate the 'image'
|
||||
* buffer to hold the bitmap.
|
||||
*/
|
||||
void mfSet_dimensions (int w, int h);
|
||||
|
||||
public:
|
||||
static char m_CurFileName[128];
|
||||
char m_FileName[128];
|
||||
|
||||
///
|
||||
virtual ~CImageFile ();
|
||||
|
||||
///
|
||||
int mfGet_width () { return m_Width; }
|
||||
///
|
||||
int mfGet_height () { return m_Height; }
|
||||
///
|
||||
int mfGet_depth () { return m_Depth; }
|
||||
///
|
||||
byte* mfGet_image ()
|
||||
{
|
||||
if (!m_pByteImage)
|
||||
{
|
||||
if (m_ImgSize)
|
||||
m_pByteImage = new byte [m_ImgSize];
|
||||
}
|
||||
return m_pByteImage;
|
||||
}
|
||||
///
|
||||
SRGBPixel* mfGet_palette () { return m_pPal; }
|
||||
|
||||
int mfGet_bps () { return m_Bps; }
|
||||
void mfSet_bps(int b) { m_Bps = b; }
|
||||
void mfSet_ImageSize (int Size) {m_ImgSize = Size;}
|
||||
int mfGet_ImageSize () {return m_ImgSize;}
|
||||
|
||||
EImFormat mfGetFormat() { return m_eFormat; }
|
||||
|
||||
void mfSet_numMips (int num) { m_NumMips = num; }
|
||||
int mfGet_numMips (void) { return m_NumMips; }
|
||||
void mfSet_Flags (int Flags) { m_Flags |= Flags; }
|
||||
int mfGet_Flags () { return m_Flags; }
|
||||
|
||||
///
|
||||
static EImFileError mfGet_error () { return m_eError; }
|
||||
///
|
||||
static char* mfGet_error_detail () { return m_Error_detail ? m_Error_detail : (char *)""; }
|
||||
/// Write a message describing the error on screen.
|
||||
static void mfWrite_error (char* extra);
|
||||
|
||||
/**
|
||||
* Load the file given the filename.
|
||||
* This routine will open the file and call load_file (FILE*).
|
||||
*/
|
||||
static CImageFile* mfLoad_file (char* filename);
|
||||
|
||||
/**
|
||||
* Load the file given a file pointer.
|
||||
* This routine will read from the file pointer and call load_file (UByte*, long).
|
||||
*/
|
||||
static CImageFile* mfLoad_file (FILE* fp);
|
||||
|
||||
/**
|
||||
* Load the file from a buffer.
|
||||
* This routine will try to recognize the image file type and then
|
||||
* created an appropriate ImageFile subclass.
|
||||
*/
|
||||
static CImageFile* mfLoad_file (byte* buf, long size);
|
||||
};
|
||||
|
||||
#include "Quantize.h"
|
||||
#include "Inv_cmap.h"
|
||||
|
||||
#endif
|
||||
|
||||
339
RenderDll/Common/Textures/Image/DDSImage.cpp
Normal file
339
RenderDll/Common/Textures/Image/DDSImage.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
/*=============================================================================
|
||||
DDSImage.cpp : DDS image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
#include "DDSImage.h"
|
||||
|
||||
/* needed for DirectX's DDSURFACEDESC2 structure definition */
|
||||
#if !defined(_XBOX) && !defined(PS2) && !defined(LINUX)
|
||||
#include <ddraw.h>
|
||||
#else
|
||||
#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))
|
||||
#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))
|
||||
#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))
|
||||
#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))
|
||||
#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))
|
||||
#endif
|
||||
|
||||
#include "dds.h"
|
||||
#if defined(LINUX)
|
||||
#include "ILog.h"
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static int sDDSSize(int sx, int sy, EImFormat eF )
|
||||
{
|
||||
switch (eF)
|
||||
{
|
||||
case eIF_DXT1:
|
||||
case eIF_DXT3:
|
||||
case eIF_DXT5:
|
||||
{
|
||||
int blockSize = (eF == eIF_DXT1) ? 8 : 16;
|
||||
return ((sx+3)/4)*((sy+3)/4)*blockSize;
|
||||
}
|
||||
break;
|
||||
case eIF_DDS_LUMINANCE:
|
||||
return sx * sy;
|
||||
break;
|
||||
case eIF_DDS_RGB8:
|
||||
case eIF_DDS_SIGNED_RGB8:
|
||||
return sx*sy*3;
|
||||
break;
|
||||
case eIF_DDS_RGBA8:
|
||||
return sx*sy*4;
|
||||
break;
|
||||
case eIF_DDS_RGBA4:
|
||||
return sx*sy*2;
|
||||
break;
|
||||
case eIF_DDS_DSDT:
|
||||
return sx*sy*3;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CImageDDSFile::mfSizeWithMips(int filesize, int sx, int sy, int nMips)
|
||||
{
|
||||
int nSize = 0;
|
||||
for (int i=0; i<nMips; i++)
|
||||
{
|
||||
assert(sx || sy);
|
||||
if (!sx)
|
||||
sx = 1;
|
||||
if (!sy)
|
||||
sy = 1;
|
||||
nSize += sDDSSize(sx, sy, m_eFormat);
|
||||
sx >>= 1;
|
||||
sy >>= 1;
|
||||
}
|
||||
assert((int)(filesize-sizeof(DDS_HEADER)-4) >= nSize);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
static FILE *sFILELog;
|
||||
|
||||
CImageDDSFile::CImageDDSFile (byte* ptr, long filesize) : CImageFile ()
|
||||
{
|
||||
int sx, sy;
|
||||
int numMips;
|
||||
|
||||
DWORD dwMagic;
|
||||
DDS_HEADER *ddsh;
|
||||
|
||||
dwMagic = *(DWORD *)ptr;
|
||||
ptr += sizeof(DWORD);
|
||||
if (dwMagic != MAKEFOURCC('D','D','S',' '))
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "Not a DDS file");
|
||||
return;
|
||||
}
|
||||
ddsh = (DDS_HEADER *)ptr;
|
||||
ptr += sizeof(DDS_HEADER);
|
||||
if (ddsh->dwSize != sizeof(DDS_HEADER))
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "Unknown DDS file header");
|
||||
return;
|
||||
}
|
||||
sx = ddsh->dwWidth;
|
||||
sy = ddsh->dwHeight;
|
||||
numMips = ddsh->dwMipMapCount;
|
||||
if (numMips == 0)
|
||||
numMips = 1;
|
||||
|
||||
if (ddsh->ddspf.dwFourCC == FOURCC_DXT1)
|
||||
m_eFormat = eIF_DXT1;
|
||||
else
|
||||
if (ddsh->ddspf.dwFourCC == FOURCC_DXT3)
|
||||
m_eFormat = eIF_DXT3;
|
||||
else
|
||||
if (ddsh->ddspf.dwFourCC == FOURCC_DXT5)
|
||||
m_eFormat = eIF_DXT5;
|
||||
else
|
||||
if (ddsh->ddspf.dwFlags == DDS_RGBA && ddsh->ddspf.dwRGBBitCount == 32 && ddsh->ddspf.dwABitMask == 0xff000000)
|
||||
m_eFormat = eIF_DDS_RGBA8;
|
||||
else
|
||||
if (ddsh->ddspf.dwFlags == DDS_RGBA && ddsh->ddspf.dwRGBBitCount == 16)
|
||||
m_eFormat = eIF_DDS_RGBA4;
|
||||
else
|
||||
if (ddsh->ddspf.dwFlags == DDS_RGB && ddsh->ddspf.dwRGBBitCount == 24)
|
||||
m_eFormat = eIF_DDS_RGB8;
|
||||
else
|
||||
if (ddsh->ddspf.dwFlags == DDS_RGB && ddsh->ddspf.dwRGBBitCount == 32)
|
||||
m_eFormat = eIF_DDS_RGBA8;
|
||||
else
|
||||
if (ddsh->ddspf.dwFlags == DDS_LUMINANCE && ddsh->ddspf.dwRGBBitCount == 8)
|
||||
m_eFormat = eIF_DDS_LUMINANCE;
|
||||
else
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "Unknown DDS image format");
|
||||
return;
|
||||
}
|
||||
mfSet_numMips(numMips);
|
||||
const char *ext = GetExtension(m_CurFileName);
|
||||
if ((ddsh->dwReserved1[0] & DDS_RESF1_NORMALMAP) ||
|
||||
!stricmp(ext, ".ddn") || !stricmp(ext, ".ddp") ||
|
||||
(strlen(m_CurFileName)>4 && (strstr(m_CurFileName, "_ddn") || strstr(m_CurFileName, "_ddp"))))
|
||||
mfSet_Flags(FIM_NORMALMAP);
|
||||
else
|
||||
if ((ddsh->dwReserved1[0] & DDS_RESF1_DSDT) ||
|
||||
!stricmp(ext, ".ddt") ||
|
||||
(strlen(m_CurFileName)>4 && strstr(m_CurFileName, "_ddt")))
|
||||
{
|
||||
mfSet_Flags(FIM_DSDT);
|
||||
m_eFormat = eIF_DDS_DSDT;
|
||||
}
|
||||
int nDepth = ddsh->dwDepth;
|
||||
if (nDepth <= 0)
|
||||
nDepth = 1;
|
||||
m_Width = sx;
|
||||
m_Height = sy;
|
||||
m_Depth = nDepth;
|
||||
|
||||
SAFE_DELETE_ARRAY(m_pByteImage);
|
||||
int size = filesize - sizeof(DDS_HEADER) - 4;
|
||||
if (m_eFormat == eIF_DDS_DSDT || m_eFormat == eIF_DDS_RGB8)
|
||||
{
|
||||
size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
size = size/3*4*nDepth;
|
||||
}
|
||||
mfSet_ImageSize(size);
|
||||
mfGet_image();
|
||||
|
||||
int nOffsSrc = 0;
|
||||
int nOffsDst = 0;
|
||||
|
||||
for (int dpt=0; dpt<nDepth; dpt++)
|
||||
{
|
||||
if (m_eFormat == eIF_DXT1 || m_eFormat == eIF_DXT3 || m_eFormat == eIF_DXT5)
|
||||
{
|
||||
int size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
cryMemcpy(&m_pByteImage[nOffsDst], &ptr[nOffsSrc], size);
|
||||
nOffsSrc += size;
|
||||
nOffsDst += size;
|
||||
}
|
||||
else
|
||||
if (m_eFormat == eIF_DDS_LUMINANCE)
|
||||
{
|
||||
int size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
cryMemcpy(&m_pByteImage[nOffsDst], &ptr[nOffsSrc], size);
|
||||
nOffsSrc += size;
|
||||
nOffsDst += size;
|
||||
}
|
||||
else
|
||||
if (m_eFormat == eIF_DDS_RGBA8 || m_eFormat == eIF_DDS_RGBA4)
|
||||
{
|
||||
int size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
cryMemcpy(&m_pByteImage[nOffsDst], &ptr[nOffsSrc], size);
|
||||
nOffsSrc += size;
|
||||
nOffsDst += size;
|
||||
}
|
||||
else
|
||||
if (m_eFormat == eIF_DDS_RGB8)
|
||||
{
|
||||
int size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
int n = size/3;
|
||||
int sizeDst = n * 4;
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
m_pByteImage[i*4+nOffsDst+0] = ptr[i*3+nOffsSrc+0];
|
||||
m_pByteImage[i*4+nOffsDst+1] = ptr[i*3+nOffsSrc+1];
|
||||
m_pByteImage[i*4+nOffsDst+2] = ptr[i*3+nOffsSrc+2];
|
||||
m_pByteImage[i*4+nOffsDst+3] = 255;
|
||||
}
|
||||
nOffsSrc += size;
|
||||
nOffsDst += sizeDst;
|
||||
if (CRenderer::CV_r_logusedtextures == 10 && (m_Flags & FIM_NORMALMAP))
|
||||
{
|
||||
if (!sFILELog)
|
||||
sFILELog = fopen("LogBumpTexturesNoAlpha.txt", "w");
|
||||
if (sFILELog)
|
||||
{
|
||||
fprintf(sFILELog, "%s\n", m_CurFileName);
|
||||
fflush(sFILELog);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (m_eFormat == eIF_DDS_DSDT)
|
||||
{
|
||||
int size = mfSizeWithMips(filesize, sx, sy, numMips);
|
||||
int n = size/3;
|
||||
int sizeDst = n * 4;
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
m_pByteImage[i*4+nOffsDst+0] = ptr[i*3+nOffsSrc+2];
|
||||
m_pByteImage[i*4+nOffsDst+1] = ptr[i*3+nOffsSrc+1];
|
||||
m_pByteImage[i*4+nOffsDst+2] = ptr[i*3+nOffsSrc+0];
|
||||
m_pByteImage[i*4+nOffsDst+3] = 255;
|
||||
}
|
||||
nOffsSrc += size;
|
||||
nOffsDst += sizeDst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CImageDDSFile::~CImageDDSFile ()
|
||||
{
|
||||
}
|
||||
|
||||
void WriteDDS(byte *dat, int wdt, int hgt, int Size, const char *name, EImFormat eF, int NumMips)
|
||||
{
|
||||
DWORD dwMagic;
|
||||
DDS_HEADER ddsh;
|
||||
memset(&ddsh, 0, sizeof(ddsh));
|
||||
|
||||
FILE *fp = fxopen(name, "wb");
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
dwMagic = MAKEFOURCC('D','D','S',' ');
|
||||
fwrite(&dwMagic, 1, sizeof(DWORD), fp);
|
||||
|
||||
ddsh.dwSize = sizeof(DDS_HEADER);
|
||||
ddsh.dwWidth = wdt;
|
||||
ddsh.dwHeight = hgt;
|
||||
ddsh.dwMipMapCount = NumMips;
|
||||
if (!NumMips)
|
||||
ddsh.dwMipMapCount = 1;
|
||||
ddsh.dwHeaderFlags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP;
|
||||
ddsh.dwSurfaceFlags = DDS_SURFACE_FLAGS_TEXTURE | DDS_SURFACE_FLAGS_MIPMAP;
|
||||
size_t len = strlen(name);
|
||||
if (len > 4)
|
||||
{
|
||||
if (!stricmp(&name[len-4], ".ddn"))
|
||||
ddsh.dwReserved1[0] = DDS_RESF1_NORMALMAP;
|
||||
else
|
||||
if (!stricmp(&name[len-4], ".ddt"))
|
||||
ddsh.dwReserved1[0] = DDS_RESF1_DSDT;
|
||||
}
|
||||
|
||||
switch (eF)
|
||||
{
|
||||
case eIF_DXT1:
|
||||
ddsh.ddspf = DDSPF_DXT1;
|
||||
break;
|
||||
case eIF_DXT3:
|
||||
ddsh.ddspf = DDSPF_DXT3;
|
||||
break;
|
||||
case eIF_DXT5:
|
||||
ddsh.ddspf = DDSPF_DXT5;
|
||||
break;
|
||||
case eIF_DDS_RGB8:
|
||||
case eIF_DDS_SIGNED_RGB8:
|
||||
case eIF_DDS_DSDT:
|
||||
ddsh.ddspf = DDSPF_R8G8B8;
|
||||
break;
|
||||
case eIF_DDS_RGBA8:
|
||||
ddsh.ddspf = DDSPF_A8R8G8B8;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
fwrite(&ddsh, 1, sizeof(ddsh), fp);
|
||||
|
||||
byte *data = NULL;
|
||||
|
||||
if (eF == eIF_DDS_RGB8 || eF == eIF_DDS_SIGNED_RGB8 || eF == eIF_DDS_DSDT)
|
||||
{
|
||||
data = new byte[Size];
|
||||
int n = Size / 3;
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
data[i*3+0] = dat[i*3+2];
|
||||
data[i*3+1] = dat[i*3+1];
|
||||
data[i*3+2] = dat[i*3+0];
|
||||
}
|
||||
fwrite(data, 1, Size, fp);
|
||||
}
|
||||
else
|
||||
if (eF == eIF_DDS_RGBA8)
|
||||
{
|
||||
data = new byte[Size];
|
||||
int n = Size / 4;
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
data[i*4+0] = dat[i*4+2];
|
||||
data[i*4+1] = dat[i*4+1];
|
||||
data[i*4+2] = dat[i*4+0];
|
||||
data[i*4+3] = dat[i*4+3];
|
||||
}
|
||||
}
|
||||
else
|
||||
fwrite(dat, 1, Size, fp);
|
||||
|
||||
SAFE_DELETE_ARRAY(data);
|
||||
|
||||
fclose (fp);
|
||||
}
|
||||
27
RenderDll/Common/Textures/Image/DDSImage.h
Normal file
27
RenderDll/Common/Textures/Image/DDSImage.h
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
#ifndef DDSIMAGE_H
|
||||
#define DDSIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading DDS files.
|
||||
*/
|
||||
class CImageDDSFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
/// Read the DDS file from the buffer.
|
||||
CImageDDSFile (byte* buf, long size);
|
||||
int mfSizeWithMips(int filesize, int sx, int sy, int numMips);
|
||||
///
|
||||
virtual ~CImageDDSFile ();
|
||||
};
|
||||
|
||||
void WriteDDS(byte *dat, int wdt, int hgt, int Size, char *name, EImFormat eF, int NumMips);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
210
RenderDll/Common/Textures/Image/DXTCImage.h
Normal file
210
RenderDll/Common/Textures/Image/DXTCImage.h
Normal file
@@ -0,0 +1,210 @@
|
||||
/*********************************************************************NVMH2****
|
||||
File: Image_DXTC.h
|
||||
|
||||
Copyright (C) 1999, 2000 NVIDIA Corporation
|
||||
Copyright (C) 2002, Ubi Soft Milan
|
||||
Tiziano Sardone
|
||||
|
||||
|
||||
Comments:
|
||||
A class to load and decompress DXT textures to 32-bit raw image data format.
|
||||
.RAW output files can be loaded into photoshop by specifying the resolution
|
||||
and 4 color channels of 8-bit, interleaved.
|
||||
|
||||
A few approaches to block decompression are in place and a simple code timing
|
||||
function is called. Output of timing test is saved to a local .txt file.
|
||||
|
||||
TiZ: some modification to adapt the code to run under PS2.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
#if !defined(AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_)
|
||||
#define AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifdef WIN32
|
||||
#include <d3d.h>
|
||||
#endif
|
||||
|
||||
#ifdef PS2
|
||||
/////////////////////////////////////
|
||||
// should be in ddraw.h
|
||||
|
||||
#ifndef MAKEFOURCC
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
|
||||
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
|
||||
#endif //defined(MAKEFOURCC)
|
||||
|
||||
#endif
|
||||
|
||||
struct TimingInfo; // defined in Image_DXTC.cpp
|
||||
|
||||
#define byte unsigned char
|
||||
#define BYTE unsigned char
|
||||
//#ifndef PS2
|
||||
#define WORD unsigned short
|
||||
#define DWORD unsigned int
|
||||
#define LONG unsigned int
|
||||
#define LPVOID void*
|
||||
#define VOID void
|
||||
#define CHAR char
|
||||
#define LARGE_INTEGER int
|
||||
//#endif
|
||||
|
||||
enum PixFormat
|
||||
{
|
||||
PF_ARGB,
|
||||
PF_DXT1,
|
||||
PF_DXT2,
|
||||
PF_DXT3,
|
||||
PF_DXT4,
|
||||
PF_DXT5,
|
||||
PF_UNKNOWN,
|
||||
};
|
||||
|
||||
#define COMPRESSED_S3TC_DXT1 PF_DXT1
|
||||
|
||||
typedef struct _DDSCAPS2 {
|
||||
DWORD dwCaps;
|
||||
DWORD dwCaps2;
|
||||
DWORD dwCaps3;
|
||||
DWORD dwCaps4;
|
||||
} DDSCAPS2, *LPDDSCAPS2;
|
||||
|
||||
typedef struct _DDPIXELFORMAT {
|
||||
DWORD dwSize;
|
||||
DWORD dwFlags;
|
||||
DWORD dwFourCC;
|
||||
union {
|
||||
DWORD dwRGBBitCount;
|
||||
DWORD dwYUVBitCount;
|
||||
DWORD dwZBufferBitDepth;
|
||||
DWORD dwAlphaBitDepth;
|
||||
DWORD dwLuminanceBitCount;
|
||||
DWORD dwBumpBitCount;
|
||||
DWORD dwPrivateFormatBitCount;
|
||||
} ;
|
||||
union {
|
||||
DWORD dwRBitMask;
|
||||
DWORD dwYBitMask;
|
||||
DWORD dwStencilBitDepth;
|
||||
DWORD dwLuminanceBitMask;
|
||||
DWORD dwBumpDuBitMask;
|
||||
DWORD dwOperations;
|
||||
} ;
|
||||
union {
|
||||
DWORD dwGBitMask;
|
||||
DWORD dwUBitMask;
|
||||
DWORD dwZBitMask;
|
||||
DWORD dwBumpDvBitMask;
|
||||
struct {
|
||||
WORD wFlipMSTypes;
|
||||
WORD wBltMSTypes;
|
||||
} MultiSampleCaps;
|
||||
} ;
|
||||
union {
|
||||
DWORD dwBBitMask;
|
||||
DWORD dwVBitMask;
|
||||
DWORD dwStencilBitMask;
|
||||
DWORD dwBumpLuminanceBitMask;
|
||||
} ;
|
||||
union {
|
||||
DWORD dwRGBAlphaBitMask;
|
||||
DWORD dwYUVAlphaBitMask;
|
||||
DWORD dwLuminanceAlphaBitMask;
|
||||
DWORD dwRGBZBitMask;
|
||||
DWORD dwYUVZBitMask;
|
||||
} ;
|
||||
} DDPIXELFORMAT, *LPDDPIXELFORMAT;
|
||||
|
||||
typedef struct _DDCOLORKEY{
|
||||
DWORD dwColorSpaceLowValue;
|
||||
DWORD dwColorSpaceHighValue;
|
||||
} DDCOLORKEY, *LPDDCOLORKEY;
|
||||
|
||||
typedef struct _DDSURFACEDESC2 {
|
||||
DWORD dwSize;
|
||||
DWORD dwFlags;
|
||||
DWORD dwHeight;
|
||||
DWORD dwWidth;
|
||||
union
|
||||
{
|
||||
LONG lPitch;
|
||||
DWORD dwLinearSize;
|
||||
} DUMMYUNIONNAMEN_1;
|
||||
DWORD dwBackBufferCount;
|
||||
union
|
||||
{
|
||||
DWORD dwMipMapCount;
|
||||
DWORD dwRefreshRate;
|
||||
} DUMMYUNIONNAMEN_2;
|
||||
DWORD dwAlphaBitDepth;
|
||||
DWORD dwReserved;
|
||||
LPVOID lpSurface;
|
||||
DDCOLORKEY ddckCKDestOverlay;
|
||||
DDCOLORKEY ddckCKDestBlt;
|
||||
DDCOLORKEY ddckCKSrcOverlay;
|
||||
DDCOLORKEY ddckCKSrcBlt;
|
||||
DDPIXELFORMAT ddpfPixelFormat;
|
||||
DDSCAPS2 ddsCaps;
|
||||
DWORD dwTextureStage;
|
||||
} DDSURFACEDESC2, *LPDDSURFACEDESC2;
|
||||
|
||||
|
||||
class Image_DXTC
|
||||
{
|
||||
public:
|
||||
unsigned char * m_pCompBytes; // compressed image bytes
|
||||
unsigned char * m_pDecompBytes;
|
||||
|
||||
int m_nCompSize;
|
||||
int m_nCompLineSz;
|
||||
|
||||
|
||||
char m_strFormat[256];
|
||||
PixFormat m_CompFormat;
|
||||
|
||||
DDSURFACEDESC2 m_DDSD; // read from dds file
|
||||
bool m_bMipTexture; // texture has mipmaps?
|
||||
|
||||
|
||||
int m_nWidth; // in pixels of uncompressed image
|
||||
int m_nHeight;
|
||||
|
||||
bool LoadFromFile( char * filename ); // true if success
|
||||
|
||||
VOID DecodePixelFormat( CHAR* strPixelFormat, DDPIXELFORMAT* pddpf );
|
||||
|
||||
void AllocateDecompBytes();
|
||||
|
||||
void Decompress();
|
||||
|
||||
void DecompressDXT1();
|
||||
void DecompressDXT2();
|
||||
void DecompressDXT3();
|
||||
void DecompressDXT4();
|
||||
void DecompressDXT5();
|
||||
|
||||
void SaveAsRaw8888(const char *name); // save decompressed bits
|
||||
void SaveAsRaw888(const char *name); // save decompressed bits
|
||||
|
||||
void RunTimingSession(); // run a few methods & time the code
|
||||
// must use dxt5 texture
|
||||
void Time_Decomp5_01( int ntimes, TimingInfo * info );
|
||||
void Time_Decomp5_02( int ntimes, TimingInfo * info );
|
||||
void Time_Decomp5_03( int ntimes, TimingInfo * info );
|
||||
void Time_Decomp5_04( int ntimes, TimingInfo * info );
|
||||
|
||||
|
||||
Image_DXTC();
|
||||
virtual ~Image_DXTC();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_)
|
||||
24
RenderDll/Common/Textures/Image/GifImage.h
Normal file
24
RenderDll/Common/Textures/Image/GifImage.h
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef GIFIMAGE_H
|
||||
#define GIFIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading GIF files.
|
||||
*/
|
||||
class CImageGifFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
/// Read the GIF file from the buffer.
|
||||
CImageGifFile (byte* buf, long size);
|
||||
|
||||
public:
|
||||
///
|
||||
virtual ~CImageGifFile ();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
143
RenderDll/Common/Textures/Image/Jmemsrc.c
Normal file
143
RenderDll/Common/Textures/Image/Jmemsrc.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 1998 by Tor Andersson and Jorrit Tyberghein
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* !!! not standard... written by Tor Andersson !!!
|
||||
* get data from memory buffer instead of from file
|
||||
* assumes that the entire file is in one large block of memory
|
||||
*
|
||||
*/
|
||||
|
||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
||||
#include "Jpeg6/jinclude.h"
|
||||
#include "Jpeg6/jpeglib.h"
|
||||
#include "Jpeg6/jerror.h"
|
||||
|
||||
|
||||
/* Expanded data source object for stdio input */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub; /* public fields */
|
||||
|
||||
FILE * infile; /* source stream */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
boolean start_of_file; /* have we gotten any data yet? */
|
||||
} my_source_mgr;
|
||||
|
||||
typedef my_source_mgr * my_src_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
* before any data is actually read.
|
||||
*/
|
||||
|
||||
static void
|
||||
init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* We reset the empty-input-file flag for each image,
|
||||
* but we don't clear the input buffer.
|
||||
* This is correct behavior for reading a series of images from one source.
|
||||
*/
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
* should never happen :)
|
||||
*/
|
||||
|
||||
static boolean
|
||||
fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* no-op */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip data --- used to skip over a potentially large amount of
|
||||
* uninteresting data (such as an APPn marker).
|
||||
*/
|
||||
|
||||
static void
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
if (num_bytes > 0) {
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress
|
||||
* after all data has been read. Often a no-op.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
static void
|
||||
term_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from mem buffer.
|
||||
* Leaves buffer untouched.
|
||||
*/
|
||||
|
||||
void
|
||||
my_jpeg_memory_src (j_decompress_ptr cinfo, char * inbfr, int len)
|
||||
{
|
||||
my_src_ptr src;
|
||||
|
||||
/* The source object and input buffer are made permanent so that a series
|
||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
||||
* only before the first one. (If we discarded the buffer at the end of
|
||||
* one image, we'd likely lose the start of the next one.)
|
||||
* This makes it unsafe to use this manager and a different source
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *) inbfr;
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->pub.init_source = init_source;
|
||||
src->pub.fill_input_buffer = fill_input_buffer;
|
||||
src->pub.skip_input_data = skip_input_data;
|
||||
src->pub.resync_to_restart = my_jpeg_resync_to_restart; /* use default method */
|
||||
src->pub.term_source = term_source;
|
||||
src->infile = 0L;
|
||||
src->pub.bytes_in_buffer = len; /*!!! sets to entire file len */
|
||||
src->pub.next_input_byte = (JOCTET *)inbfr; /*!!! at start of buffer */
|
||||
}
|
||||
|
||||
430
RenderDll/Common/Textures/Image/JpgImage.cpp
Normal file
430
RenderDll/Common/Textures/Image/JpgImage.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
/*=============================================================================
|
||||
JpgImage.cpp : JPG image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
#include "JpgImage.h"
|
||||
|
||||
#if !defined(WIN64) && !defined(LINUX)
|
||||
|
||||
#if defined(PS2)
|
||||
|
||||
#include "jpeglib.h"
|
||||
#include "PS2GDriver.h"
|
||||
|
||||
#else
|
||||
extern "C" {
|
||||
#include "ijl.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* ==== Constructor ==== */
|
||||
CImageJpgFile::~CImageJpgFile () {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
CImageJpgFile::CImageJpgFile (byte* ptr, long filesize) : CImageFile ()
|
||||
{
|
||||
#ifdef PS2
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
u_char *pImage=NULL;
|
||||
|
||||
pImage=(u_char *)PS2GDRV_LoadJpegImage(mCurFileName, cinfo);
|
||||
if(pImage)
|
||||
{
|
||||
m_eFormat = eIF_Jpg;
|
||||
|
||||
mfSet_bps(32);
|
||||
|
||||
mfSet_dimensions (cinfo.image_width,cinfo.image_height);
|
||||
mfSet_ImageSize(m_Width * m_Height * 4);
|
||||
|
||||
SRGBPixel *pixels = mfGet_image ();
|
||||
u_char *pix=pImage;
|
||||
|
||||
for(int j=0; j<cinfo.image_height; j++)
|
||||
{
|
||||
for(int i=0; i<cinfo.image_width; i++)
|
||||
{
|
||||
pixels[0].red=*pix++;
|
||||
pixels[0].green=*pix++;
|
||||
pixels[0].blue=*pix++;
|
||||
pixels[0].alpha=255;
|
||||
|
||||
pixels++;
|
||||
}
|
||||
}
|
||||
|
||||
delete [] pImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat,"Cannot read JPEG file header");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
JPEG_CORE_PROPERTIES image;
|
||||
ZeroStruct( image );
|
||||
SRGBPixel *pixels;
|
||||
m_eFormat = eIF_Jpg;
|
||||
|
||||
if( ijlInit( &image ) != IJL_OK )
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat,"Cannot initialize Intel JPEG library");
|
||||
return;
|
||||
}
|
||||
image.JPGBytes = ptr;
|
||||
image.JPGSizeBytes = filesize;
|
||||
if( ijlRead( &image, IJL_JBUFF_READPARAMS ) != IJL_OK )
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat,"Cannot read JPEG file header");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the JPG color space ... this will always be
|
||||
// somewhat of an educated guess at best because JPEG
|
||||
// is "color blind" (i.e., nothing in the bit stream
|
||||
// tells you what color space the data was encoded from).
|
||||
// However, in this example we assume that we are
|
||||
// reading JFIF files which means that 3 channel images
|
||||
// are in the YCbCr color space and 1 channel images are
|
||||
// in the Y color space.
|
||||
switch(image.JPGChannels)
|
||||
{
|
||||
case 1:
|
||||
image.JPGColor = IJL_G;
|
||||
image.DIBChannels = 3;
|
||||
image.DIBColor = IJL_RGB;
|
||||
mfSet_bps(24);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
image.JPGColor = IJL_YCBCR;
|
||||
image.DIBChannels = 3;
|
||||
image.DIBColor = IJL_RGB;
|
||||
mfSet_bps(24);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
image.JPGColor = IJL_YCBCRA_FPX;
|
||||
image.DIBChannels = 4;
|
||||
image.DIBColor = IJL_RGBA_FPX;
|
||||
mfSet_bps(32);
|
||||
break;
|
||||
|
||||
default:
|
||||
// This catches everything else, but no
|
||||
// color twist will be performed by the IJL.
|
||||
image.DIBColor = (IJL_COLOR)IJL_OTHER;
|
||||
image.JPGColor = (IJL_COLOR)IJL_OTHER;
|
||||
image.DIBChannels = image.JPGChannels;
|
||||
break;
|
||||
}
|
||||
|
||||
image.DIBWidth = image.JPGWidth;
|
||||
image.DIBHeight = image.JPGHeight;
|
||||
image.DIBPadBytes = IJL_DIB_PAD_BYTES(image.DIBWidth,image.DIBChannels);
|
||||
|
||||
mfSet_dimensions (image.DIBWidth, image.DIBHeight);
|
||||
mfSet_ImageSize(m_Width * m_Height * 4);
|
||||
pixels = (SRGBPixel *)mfGet_image ();
|
||||
|
||||
int imageSize = (image.DIBWidth * image.DIBChannels + image.DIBPadBytes) * image.DIBHeight;
|
||||
|
||||
byte *imageData = new BYTE[ imageSize ];
|
||||
if( imageData == NULL )
|
||||
{
|
||||
mfSet_error (eIFE_OutOfMemory,"Cannot allocate memory for image");
|
||||
ijlFree( &image );
|
||||
return;
|
||||
}
|
||||
|
||||
image.DIBBytes = imageData;
|
||||
|
||||
if( ijlRead( &image, IJL_JBUFF_READWHOLEIMAGE ) != IJL_OK )
|
||||
{
|
||||
mfSet_error (eIFE_IOerror,"Cannot read image data");
|
||||
ijlFree( &image );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ijlFree( &image ) != IJL_OK )
|
||||
{
|
||||
mfSet_error (eIFE_IOerror,"Cannot free Intel(R) JPEG library");
|
||||
return;
|
||||
}
|
||||
|
||||
byte *src = imageData;
|
||||
int width = image.DIBWidth;
|
||||
int height = image.DIBHeight;
|
||||
int pad = IJL_DIB_PAD_BYTES(width,4);
|
||||
|
||||
if (image.DIBColor == IJL_RGBA_FPX)
|
||||
{
|
||||
int line_width = image.DIBWidth * 4 + pad;
|
||||
for(int i=0; i<height; i++)
|
||||
{
|
||||
src = imageData + line_width*i;
|
||||
for(int j=0; j<width; j++)
|
||||
{
|
||||
pixels->red = src[0];
|
||||
pixels->green = src[1];
|
||||
pixels->blue = src[2];
|
||||
pixels->alpha = src[3];
|
||||
pixels++;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SRGBPixel *pix = pixels;
|
||||
int line_width = image.DIBWidth * 3 + pad;
|
||||
for(int i=0; i<height; i++)
|
||||
{
|
||||
src = imageData + line_width*i;
|
||||
for(int j=0; j<width; j++)
|
||||
{
|
||||
pixels->red = src[0];
|
||||
pixels->green = src[1];
|
||||
pixels->blue = src[2];
|
||||
pixels->alpha = 255;
|
||||
pixels++;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete [] imageData;
|
||||
|
||||
/* And we're done! */
|
||||
#endif //PS2
|
||||
}
|
||||
|
||||
#endif // WIN64
|
||||
|
||||
#ifdef WIN64
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "Jpeg6/Jpeglib.h"
|
||||
#include "Jmemsrc.c" // include buffer source input code
|
||||
}
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
/* ==== Error mgmnt ==== */
|
||||
static char jpg_err_msg[256];
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
};
|
||||
typedef struct my_error_mgr *my_error_ptr;
|
||||
static void my_error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
char errmsg [256];
|
||||
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->format_message) (cinfo,errmsg);
|
||||
strcpy (jpg_err_msg,errmsg);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
/* ==== Constructor ==== */
|
||||
CImageJpgFile::~CImageJpgFile () {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
CImageJpgFile::CImageJpgFile (byte* ptr, long filesize) : CImageFile () {
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
JSAMPARRAY buffer; /* Output row buffer */
|
||||
int row_stride; /* physical row width in output buffer */
|
||||
|
||||
int bufp;
|
||||
int i;
|
||||
SRGBPixel *pixels;
|
||||
|
||||
m_eFormat = eIF_Jpg;
|
||||
|
||||
/* ==== Step 1: allocate and initialize JPEG decompression object */
|
||||
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||
cinfo.err = my_jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
my_jpeg_destroy_decompress(&cinfo);
|
||||
mfSet_error (eIFE_BadFormat,jpg_err_msg);
|
||||
return;
|
||||
}
|
||||
/* Now we can initialize the JPEG decompression object. */
|
||||
my_jpeg_create_decompress(&cinfo);
|
||||
|
||||
/* ==== Step 2: specify data source (memory buffer, in this case) */
|
||||
my_jpeg_memory_src(&cinfo, (char *)ptr, filesize);
|
||||
|
||||
/* ==== Step 3: read file parameters with jpeg_read_header() */
|
||||
(void) my_jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
/* ==== Step 4: set parameters for decompression */
|
||||
/* In this example, we don't need to change any of the defaults set by
|
||||
* jpeg_read_header(), so we do nothing here.
|
||||
*/
|
||||
|
||||
/* ==== Step 5: Start decompressor */
|
||||
|
||||
(void) my_jpeg_start_decompress(&cinfo);
|
||||
/* We may need to do some setup of our own at this point before reading
|
||||
* the data. After jpeg_start_decompress() we have the correct scaled
|
||||
* output image dimensions available, as well as the output colormap
|
||||
* if we asked for color quantization.
|
||||
* In this example, we need to make an output work buffer of the right size.
|
||||
*/
|
||||
|
||||
mfSet_dimensions (cinfo.output_width, cinfo.output_height);
|
||||
mfSet_ImageSize(cinfo.output_width * cinfo.output_height * 4);
|
||||
pixels = (SRGBPixel *)mfGet_image();
|
||||
bufp = 0;
|
||||
|
||||
/* JSAMPLEs per row in output buffer */
|
||||
row_stride = cinfo.output_width * cinfo.output_components;
|
||||
/* Make a one-row-high sample array that will go away when done with image */
|
||||
buffer = (*cinfo.mem->alloc_sarray)
|
||||
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||
|
||||
/* ==== Step 6: while (scan lines remain to be read) */
|
||||
/* jpeg_read_scanlines(...); */
|
||||
|
||||
/* Here we use the library's state variable cinfo.output_scanline as the
|
||||
* loop counter, so that we don't have to keep track ourselves.
|
||||
*/
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
/* jpeg_read_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could ask for
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
(void) my_jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
|
||||
/* Assume put_scanline_someplace wants a pointer and sample count. */
|
||||
/* put_scanline_someplace(buffer[0], row_stride); */
|
||||
if (cinfo.output_components == 1)
|
||||
{ /* grey scale */
|
||||
for (i=0;i<row_stride;i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i];
|
||||
pixels[bufp].green = buffer[0][i];
|
||||
pixels[bufp].blue = buffer[0][i];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cinfo.output_components == 3)
|
||||
{ /* rgb triplets */
|
||||
for (i = 0; i < (int)cinfo.output_width; i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i*3+0];
|
||||
pixels[bufp].green = buffer[0][i*3+1];
|
||||
pixels[bufp].blue = buffer[0][i*3+2];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < (int)cinfo.output_width; i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i*4+0];
|
||||
pixels[bufp].green = buffer[0][i*4+1];
|
||||
pixels[bufp].blue = buffer[0][i*4+2];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== Step 7: Finish decompression */
|
||||
|
||||
(void) my_jpeg_finish_decompress(&cinfo);
|
||||
/* We can ignore the return value since suspension is not possible
|
||||
* with the buffer data source.
|
||||
*/
|
||||
|
||||
/* ==== Step 8: Release JPEG decompression object */
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
my_jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
|
||||
/* At this point you may want to check to see whether any corrupt-data
|
||||
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
|
||||
*/
|
||||
|
||||
/* And we're done! */
|
||||
}
|
||||
#endif //WIN64
|
||||
|
||||
|
||||
|
||||
void WriteJPG(byte *dat, int wdt, int hgt, char *name)
|
||||
{
|
||||
#if !defined(PS2) && !defined(WIN64) && !defined(NULL_RENDERER)
|
||||
JPEG_CORE_PROPERTIES image;
|
||||
ZeroMemory( &image, sizeof( JPEG_CORE_PROPERTIES ) );
|
||||
|
||||
if( ijlInit( &image ) != IJL_OK )
|
||||
return;
|
||||
|
||||
byte *data = new byte [wdt*hgt*3];
|
||||
for (int i=0; i<wdt*hgt; i++)
|
||||
{
|
||||
data[i*3+0] = dat[i*4+0];
|
||||
data[i*3+1] = dat[i*4+1];
|
||||
data[i*3+2] = dat[i*4+2];
|
||||
}
|
||||
|
||||
// Setup DIB
|
||||
image.DIBWidth = wdt;
|
||||
image.DIBHeight = hgt;
|
||||
image.DIBBytes = data;
|
||||
image.DIBPadBytes = 0; //IJL_DIB_PAD_BYTES(image.DIBWidth,3);
|
||||
|
||||
// Setup JPEG
|
||||
image.JPGFile = name;
|
||||
image.JPGWidth = wdt;
|
||||
image.JPGHeight = hgt;
|
||||
|
||||
image.jquality = 100;
|
||||
|
||||
image.DIBColor = IJL_RGB;
|
||||
|
||||
if( ijlWrite( &image, IJL_JFILE_WRITEWHOLEIMAGE ) != IJL_OK )
|
||||
{
|
||||
delete [] data;
|
||||
return;
|
||||
}
|
||||
|
||||
if( ijlFree( &image ) != IJL_OK )
|
||||
{
|
||||
delete [] data;
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] data;
|
||||
#else
|
||||
OutputDebugString("Not Implemented");
|
||||
#endif //!defined(PS2) && !defined(WIN64)
|
||||
}
|
||||
24
RenderDll/Common/Textures/Image/JpgImage.h
Normal file
24
RenderDll/Common/Textures/Image/JpgImage.h
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef JPGIMAGE_H
|
||||
#define JPGIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading JPG files.<p>
|
||||
* This implementation needs libjpeg to read JFIF files.
|
||||
*/
|
||||
class CImageJpgFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
/// Read the JPG file from the buffer.
|
||||
CImageJpgFile (byte* buf, long size);
|
||||
|
||||
public:
|
||||
///
|
||||
virtual ~CImageJpgFile ();
|
||||
};
|
||||
|
||||
#endif //JPGIMAGE_H
|
||||
|
||||
179
RenderDll/Common/Textures/Image/JpgImage_XBox.cpp
Normal file
179
RenderDll/Common/Textures/Image/JpgImage_XBox.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/*=============================================================================
|
||||
JpgImage.cpp : JPG image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#if !defined(LINUX)
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CImage.h"
|
||||
#include "JpgImage.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "Jpeg6/Jpeglib.h"
|
||||
#include "Jmemsrc.c" // include buffer source input code
|
||||
}
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
/* ==== Error mgmnt ==== */
|
||||
static char jpg_err_msg[256];
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
};
|
||||
typedef struct my_error_mgr *my_error_ptr;
|
||||
static void my_error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
char errmsg [256];
|
||||
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->format_message) (cinfo,errmsg);
|
||||
strcpy (jpg_err_msg,errmsg);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
/* ==== Constructor ==== */
|
||||
CImageJpgFile::~CImageJpgFile () {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
CImageJpgFile::CImageJpgFile (byte* ptr, long filesize) : CImageFile () {
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
JSAMPARRAY buffer; /* Output row buffer */
|
||||
int row_stride; /* physical row width in output buffer */
|
||||
|
||||
int bufp;
|
||||
int i;
|
||||
SRGBPixel *pixels;
|
||||
|
||||
m_eFormat = eIF_Jpg;
|
||||
|
||||
/* ==== Step 1: allocate and initialize JPEG decompression object */
|
||||
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||
cinfo.err = my_jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
my_jpeg_destroy_decompress(&cinfo);
|
||||
mfSet_error (eIFE_BadFormat,jpg_err_msg);
|
||||
return;
|
||||
}
|
||||
/* Now we can initialize the JPEG decompression object. */
|
||||
my_jpeg_create_decompress(&cinfo);
|
||||
|
||||
/* ==== Step 2: specify data source (memory buffer, in this case) */
|
||||
my_jpeg_memory_src(&cinfo, (char *)ptr, filesize);
|
||||
|
||||
/* ==== Step 3: read file parameters with jpeg_read_header() */
|
||||
(void) my_jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
/* ==== Step 4: set parameters for decompression */
|
||||
/* In this example, we don't need to change any of the defaults set by
|
||||
* jpeg_read_header(), so we do nothing here.
|
||||
*/
|
||||
|
||||
/* ==== Step 5: Start decompressor */
|
||||
|
||||
(void) my_jpeg_start_decompress(&cinfo);
|
||||
/* We may need to do some setup of our own at this point before reading
|
||||
* the data. After jpeg_start_decompress() we have the correct scaled
|
||||
* output image dimensions available, as well as the output colormap
|
||||
* if we asked for color quantization.
|
||||
* In this example, we need to make an output work buffer of the right size.
|
||||
*/
|
||||
|
||||
mfSet_dimensions (cinfo.output_width, cinfo.output_height);
|
||||
mfSet_ImageSize(cinfo.output_width * cinfo.output_height * 4);
|
||||
pixels = (SRGBPixel *)mfGet_image();
|
||||
bufp = 0;
|
||||
|
||||
/* JSAMPLEs per row in output buffer */
|
||||
row_stride = cinfo.output_width * cinfo.output_components;
|
||||
/* Make a one-row-high sample array that will go away when done with image */
|
||||
buffer = (*cinfo.mem->alloc_sarray)
|
||||
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||
|
||||
/* ==== Step 6: while (scan lines remain to be read) */
|
||||
/* jpeg_read_scanlines(...); */
|
||||
|
||||
/* Here we use the library's state variable cinfo.output_scanline as the
|
||||
* loop counter, so that we don't have to keep track ourselves.
|
||||
*/
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
/* jpeg_read_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could ask for
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
(void) my_jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
|
||||
/* Assume put_scanline_someplace wants a pointer and sample count. */
|
||||
/* put_scanline_someplace(buffer[0], row_stride); */
|
||||
if (cinfo.output_components == 1)
|
||||
{ /* grey scale */
|
||||
for (i=0;i<row_stride;i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i];
|
||||
pixels[bufp].green = buffer[0][i];
|
||||
pixels[bufp].blue = buffer[0][i];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cinfo.output_components == 3)
|
||||
{ /* rgb triplets */
|
||||
for (i = 0; i < (int)cinfo.output_width; i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i*3+0];
|
||||
pixels[bufp].green = buffer[0][i*3+1];
|
||||
pixels[bufp].blue = buffer[0][i*3+2];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < (int)cinfo.output_width; i++)
|
||||
{
|
||||
pixels[bufp].red = buffer[0][i*4+0];
|
||||
pixels[bufp].green = buffer[0][i*4+1];
|
||||
pixels[bufp].blue = buffer[0][i*4+2];
|
||||
pixels[bufp].alpha = 255;
|
||||
bufp ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== Step 7: Finish decompression */
|
||||
|
||||
(void) my_jpeg_finish_decompress(&cinfo);
|
||||
/* We can ignore the return value since suspension is not possible
|
||||
* with the buffer data source.
|
||||
*/
|
||||
|
||||
/* ==== Step 8: Release JPEG decompression object */
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
my_jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
|
||||
/* At this point you may want to check to see whether any corrupt-data
|
||||
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
|
||||
*/
|
||||
|
||||
/* And we're done! */
|
||||
}
|
||||
|
||||
#endif
|
||||
166
RenderDll/Common/Textures/Image/PcxImage.cpp
Normal file
166
RenderDll/Common/Textures/Image/PcxImage.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*=============================================================================
|
||||
PcxImage.cpp : PCX image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
#include "PcxImage.h"
|
||||
#if defined(LINUX)
|
||||
#include "ILog.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
short xmin;
|
||||
short ymin;
|
||||
short xmax;
|
||||
short ymax;
|
||||
short hres;
|
||||
short vres;
|
||||
byte palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
short bytes_per_line;
|
||||
short palette_type;
|
||||
char filler[58];
|
||||
byte data;
|
||||
} pcx_header;
|
||||
|
||||
CImagePcxFile::~CImagePcxFile ()
|
||||
{
|
||||
}
|
||||
|
||||
CImagePcxFile::CImagePcxFile (byte* ptr, long filesize) : CImageFile ()
|
||||
{
|
||||
pcx_header *pcx;
|
||||
byte* raw, *p, dat;
|
||||
int x, y, runLength;
|
||||
int sx, sy;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
pcx = (pcx_header *)ptr;
|
||||
raw = &pcx->data;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 640
|
||||
|| pcx->ymax >= 480)
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "not a PCX file");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sx=pcx->xmax+1;
|
||||
sy=pcx->ymax+1;
|
||||
|
||||
m_eFormat = eIF_Pcx;
|
||||
|
||||
/* Read in global colormap. */
|
||||
CHK (m_pPal = new SRGBPixel [256]);
|
||||
|
||||
p = (byte *)pcx + filesize - 768;
|
||||
int i;
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
m_pPal[i].red = p[0];
|
||||
m_pPal[i].green = p[1];
|
||||
m_pPal[i].blue = p[2];
|
||||
m_pPal[i].alpha = 255;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
// Set the dimensions which will also allocate the image data
|
||||
// buffer.
|
||||
mfSet_dimensions (sx, sy);
|
||||
mfSet_ImageSize(m_Width * m_Height);
|
||||
byte *IndexImage = mfGet_image ();
|
||||
p = IndexImage;
|
||||
|
||||
i = 0;
|
||||
for (y=0 ; y<=pcx->ymax ; y++, p += pcx->xmax+1)
|
||||
{
|
||||
for (x=0 ; x<=pcx->xmax ; )
|
||||
{
|
||||
dat = *raw++;
|
||||
|
||||
if((dat & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dat & 0x3F;
|
||||
dat = *raw++;
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
{
|
||||
p[x++] = dat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WritePCX (char *name, byte *data, byte *pal, int width, int height)
|
||||
{
|
||||
int i, j, len;
|
||||
pcx_header *pcx;
|
||||
byte *pack;
|
||||
FILE *fp;
|
||||
|
||||
pcx = (pcx_header*)malloc (width*height*2+1000);
|
||||
pcx->manufacturer = 10; // Some programs complains if this is 0
|
||||
pcx->version = 5;
|
||||
pcx->encoding = 1;
|
||||
pcx->bits_per_pixel = 8;
|
||||
pcx->xmin = 0;
|
||||
pcx->ymin = 0;
|
||||
pcx->xmax = width - 1;
|
||||
pcx->ymax = height - 1;
|
||||
pcx->hres = width;
|
||||
pcx->vres = height;
|
||||
memset (pcx->palette, 0, sizeof(pcx->palette));
|
||||
pcx->color_planes = 1;
|
||||
pcx->bytes_per_line = width;
|
||||
pcx->palette_type = 2;
|
||||
memset (pcx->filler, 0, sizeof(pcx->filler));
|
||||
pack = &(pcx->data);
|
||||
|
||||
for (i=0; i<height; i++)
|
||||
{
|
||||
for (j=0; j<width; j++)
|
||||
{
|
||||
if ((*data & 0xc0) != 0xc0)
|
||||
*pack++ = *data++;
|
||||
else
|
||||
{
|
||||
*pack++ = 0xc1;
|
||||
*pack++ = *data++;
|
||||
}
|
||||
}
|
||||
// data += width;
|
||||
}
|
||||
*pack++ = 0x0c;
|
||||
for (i=0; i<768; i++)
|
||||
*pack++ = *pal++;
|
||||
len = pack - (byte *)pcx;
|
||||
fp = fxopen (name, "wb");
|
||||
if (!fp)
|
||||
return;
|
||||
fwrite (pcx, len, 1, fp);
|
||||
fclose (fp);
|
||||
free (pcx);
|
||||
}
|
||||
25
RenderDll/Common/Textures/Image/PcxImage.h
Normal file
25
RenderDll/Common/Textures/Image/PcxImage.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef PCXIMAGE_H
|
||||
#define PCXIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading PCX files.
|
||||
*/
|
||||
class CImagePcxFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
/// Read the PCX file from the buffer.
|
||||
CImagePcxFile (byte* buf, long size);
|
||||
|
||||
public:
|
||||
///
|
||||
virtual ~CImagePcxFile ();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
737
RenderDll/Common/Textures/Image/Quantize.cpp
Normal file
737
RenderDll/Common/Textures/Image/Quantize.cpp
Normal file
@@ -0,0 +1,737 @@
|
||||
/*=============================================================================
|
||||
PcxImage.cpp : PCX image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
|
||||
#define HIST_R_BITS 5
|
||||
#define HIST_G_BITS 6
|
||||
#define HIST_B_BITS 5
|
||||
|
||||
// Amount to shift left R value to get max (hist_r, hist_g, hist_b)
|
||||
#define HIST_SHIFT_R 1
|
||||
#define HIST_SHIFT_G 0
|
||||
#define HIST_SHIFT_B 1
|
||||
|
||||
#define HIST_R_MAX (1 << HIST_R_BITS)
|
||||
#define HIST_G_MAX (1 << HIST_G_BITS)
|
||||
#define HIST_B_MAX (1 << HIST_B_BITS)
|
||||
|
||||
#ifdef SH_LITTLE_ENDIAN
|
||||
# define R_BIT 0
|
||||
# define G_BIT 8
|
||||
# define B_BIT 16
|
||||
#else
|
||||
# define R_BIT 24
|
||||
# define G_BIT 16
|
||||
# define B_BIT 8
|
||||
#endif
|
||||
|
||||
|
||||
// Compute masks for effectively separating R,G and B components from a unsigned long.
|
||||
// For a little-endian machine they are respectively
|
||||
// 0x000000f8, 0x0000fc00 and 0x00f80000
|
||||
// For a big-endian machine they are respectively
|
||||
// 0xf8000000, 0x00fc0000 and 0x0000f800
|
||||
#define R_MASK ((HIST_R_MAX - 1) << (R_BIT + 8 - HIST_R_BITS))
|
||||
#define G_MASK ((HIST_G_MAX - 1) << (G_BIT + 8 - HIST_G_BITS))
|
||||
#define B_MASK ((HIST_B_MAX - 1) << (B_BIT + 8 - HIST_B_BITS))
|
||||
// The following macro extract the respective color components from a unsigned long
|
||||
// and transform them into a index in the histogram.
|
||||
#define INDEX_R(l) ((l & R_MASK) >> (R_BIT + 8 - HIST_R_BITS))
|
||||
#define INDEX_G(l) ((l & G_MASK) >> (G_BIT + 8 - HIST_G_BITS - HIST_R_BITS))
|
||||
#define INDEX_B(l) ((l & B_MASK) >> (B_BIT + 8 - HIST_B_BITS - HIST_G_BITS - HIST_R_BITS))
|
||||
// Calculate index into histogram for given R,G,B components
|
||||
#define INDEX(r,g,b) (r + (g << HIST_R_BITS) + (b << (HIST_R_BITS + HIST_G_BITS)))
|
||||
|
||||
// The storage for color usage histogram
|
||||
static ushort *hist = NULL;
|
||||
// Total number of colors that were used to create the histogram
|
||||
static unsigned hist_pixels;
|
||||
|
||||
/*
|
||||
* A box in color space.
|
||||
* Both minimal and maximal component bounds are inclusive, that is, the bounds
|
||||
* Rm = 0, Rx = 255 means the box covers the entire R component range.
|
||||
* <p>
|
||||
* This structure is meant to be highly fast, thus only atomic operations
|
||||
* are implemented for it. After some operations the box may be left in a
|
||||
* invalid state, thus take care.
|
||||
*/
|
||||
struct shColorBox
|
||||
{
|
||||
// The minimal and maximal R
|
||||
byte Rm,Rx;
|
||||
// The minimal and maximal G
|
||||
byte Gm,Gx;
|
||||
// The minimal and maximal B
|
||||
byte Bm,Bx;
|
||||
// Color box volume
|
||||
unsigned Volume;
|
||||
// Number of pixels in this box
|
||||
unsigned PixelCount;
|
||||
// Number of non-zero different color values in this box
|
||||
unsigned ColorCount;
|
||||
|
||||
// Useful function
|
||||
static inline unsigned Sqr (int x)
|
||||
{ return x * x; }
|
||||
// Set box to given bounds
|
||||
void Set (byte rm, byte rx, byte gm, byte gx, byte bm, byte bx)
|
||||
{ Rm = rm; Rx = rx; Gm = gm; Gx = gx; Bm = bm; Bx = bx; }
|
||||
// Compute the volume of box
|
||||
void ComputeVolume ()
|
||||
{
|
||||
// We compute the length of the diagonal of the box rather than the
|
||||
// proper volume. This also has the side effect that a long narrow
|
||||
// box looks more "voluminous" thus its more probably that it will
|
||||
// be split rather than a relatively cubic one.
|
||||
Volume = Sqr (Rx - Rm) * (R_COEF_SQ << HIST_SHIFT_R) +
|
||||
Sqr (Gx - Gm) * (G_COEF_SQ << HIST_SHIFT_G) +
|
||||
Sqr (Bx - Bm) * (B_COEF_SQ << HIST_SHIFT_B);
|
||||
}
|
||||
// Count number of non-zero colors within this box
|
||||
void CountPixels ()
|
||||
{
|
||||
PixelCount = ColorCount = 0;
|
||||
for (int b = Bm; b <= Bx; b++)
|
||||
for (int g = Gm; g <= Gx; g++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, g, b)];
|
||||
for (int r = Rx - Rm; r >= 0; r--, hp++)
|
||||
if (*hp)
|
||||
{
|
||||
PixelCount += *hp;
|
||||
ColorCount++;
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
}
|
||||
// Move Rm up until we find pixels that contain this value
|
||||
bool ShrinkRm ()
|
||||
{
|
||||
byte iRm = Rm;
|
||||
for (; Rm <= Rx; Rm++)
|
||||
for (byte b = Bm; b <= Bx; b++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, Gm, b)];
|
||||
for (int g = Gx - Gm; g >= 0; g--, hp += HIST_R_MAX)
|
||||
if (*hp) return (Rm != iRm);
|
||||
}
|
||||
return (Rm != iRm);
|
||||
}
|
||||
// Move Rx down until we find pixels that contain this value
|
||||
bool ShrinkRx ()
|
||||
{
|
||||
byte iRx = Rx;
|
||||
for (; Rx >= Rm; Rx--)
|
||||
for (byte b = Bm; b <= Bx; b++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rx, Gm, b)];
|
||||
for (int g = Gx - Gm; g >= 0; g--, hp += HIST_R_MAX)
|
||||
if (*hp) return (Rx != iRx);
|
||||
}
|
||||
return (Rx != iRx);
|
||||
}
|
||||
// Move Gm up until we find pixels that contain this value
|
||||
bool ShrinkGm ()
|
||||
{
|
||||
byte iGm = Gm;
|
||||
for (; Gm <= Gx; Gm++)
|
||||
for (byte b = Bm; b <= Bx; b++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, Gm, b)];
|
||||
for (int r = Rx - Rm; r >= 0; r--, hp++)
|
||||
if (*hp) return (Gm != iGm);
|
||||
}
|
||||
return (Gm != iGm);
|
||||
}
|
||||
// Move Gx down until we find pixels that contain this value
|
||||
bool ShrinkGx ()
|
||||
{
|
||||
byte iGx = Gx;
|
||||
for (; Gx >= Gm; Gx--)
|
||||
for (byte b = Bm; b <= Bx; b++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, Gx, b)];
|
||||
for (int r = Rx - Rm; r >= 0; r--, hp++)
|
||||
if (*hp) return (Gx != iGx);
|
||||
}
|
||||
return (Gx != iGx);
|
||||
}
|
||||
// Move Bm up until we find pixels that contain this value
|
||||
bool ShrinkBm ()
|
||||
{
|
||||
byte iBm = Bm;
|
||||
for (; Bm <= Bx; Bm++)
|
||||
for (byte g = Gm; g <= Gx; g++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, g, Bm)];
|
||||
for (int r = Rx - Rm; r >= 0; r--, hp++)
|
||||
if (*hp) return (Bm != iBm);
|
||||
}
|
||||
return (Bm != iBm);
|
||||
}
|
||||
// Move Bx down until we find pixels that contain this value
|
||||
bool ShrinkBx ()
|
||||
{
|
||||
byte iBx = Bx;
|
||||
for (; Bx >= Bm; Bx--)
|
||||
for (byte g = Gm; g <= Gx; g++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, g, Bx)];
|
||||
for (int r = Rx - Rm; r >= 0; r--, hp++)
|
||||
if (*hp) return (Bx != iBx);
|
||||
}
|
||||
return (Bx != iBx);
|
||||
}
|
||||
// Shrink box: move min/max bounds until we hit an existing color
|
||||
void Shrink ()
|
||||
{
|
||||
ShrinkRm (); ShrinkRx ();
|
||||
ShrinkGm (); ShrinkGx ();
|
||||
ShrinkBm (); ShrinkBx ();
|
||||
}
|
||||
/**
|
||||
* Compute the mean color for this box.
|
||||
* The computation is performed by taking into account each color's
|
||||
* weight, i.e. number of pixels with this color. Thus resulting palette
|
||||
* is biased towards most often used colors.
|
||||
*/
|
||||
void GetMeanColor (SRGBPixel &color)
|
||||
{
|
||||
unsigned rs = 0, gs = 0, bs = 0;
|
||||
unsigned count = 0;
|
||||
for (int b = Bm; b <= Bx; b++)
|
||||
for (int g = Gm; g <= Gx; g++)
|
||||
{
|
||||
ushort *hp = &hist [INDEX (Rm, g, b)];
|
||||
for (int r = Rm; r <= Rx; r++, hp++)
|
||||
if (*hp)
|
||||
{
|
||||
unsigned pixc = *hp;
|
||||
count += pixc;
|
||||
rs += pixc * r;
|
||||
gs += pixc * g;
|
||||
bs += pixc * b;
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
// In some extreme cases (textures with zero pixels or
|
||||
// single-color textures with 1 transparent color)
|
||||
// we can end here with count == 0; avoid division by zero
|
||||
if (!count)
|
||||
{
|
||||
color = SRGBPixel (0, 0, 0);
|
||||
return;
|
||||
}
|
||||
color.red = ((rs + count / 2) << (8 - HIST_R_BITS)) / count;
|
||||
color.green = ((gs + count / 2) << (8 - HIST_G_BITS)) / count;
|
||||
color.blue = ((bs + count / 2) << (8 - HIST_B_BITS)) / count;
|
||||
}
|
||||
void FillInverseCMap (byte *icmap, byte index)
|
||||
{
|
||||
int Rcount = Rx - Rm + 1;
|
||||
for (int b = Bm; b <= Bx; b++)
|
||||
for (int g = Gm; g <= Gx; g++)
|
||||
memset (&icmap [INDEX (Rm, g, b)], index, Rcount);
|
||||
}
|
||||
};
|
||||
|
||||
// The storage for color space boxes
|
||||
static shColorBox *box = NULL;
|
||||
// Number of valid color boxes
|
||||
static int boxcount;
|
||||
// The storage for color indices
|
||||
static byte *color_index = NULL;
|
||||
|
||||
static int __cdecl compare_boxes (const void *i1, const void *i2)
|
||||
{
|
||||
int count1 = box [*(byte *)i1].PixelCount;
|
||||
int count2 = box [*(byte *)i2].PixelCount;
|
||||
return (count1 > count2) ? -1 : (count1 == count2) ? 0 : +1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------- The API ------//
|
||||
|
||||
// The state of quantization variables
|
||||
static enum
|
||||
{
|
||||
// Uninitialized: initial state
|
||||
qsNone,
|
||||
// Counting color frequencies
|
||||
qsCount,
|
||||
// Remapping input images to output
|
||||
qsRemap
|
||||
} qState = qsNone;
|
||||
|
||||
void shQuantizeBegin ()
|
||||
{
|
||||
// Clean up, if previous quantization sequence was not finished
|
||||
shQuantizeEnd ();
|
||||
|
||||
// First, allocate the histogram
|
||||
hist = new ushort [HIST_R_MAX * HIST_G_MAX * HIST_B_MAX];
|
||||
memset (hist, 0, HIST_R_MAX * HIST_G_MAX * HIST_B_MAX * sizeof (ushort));
|
||||
|
||||
hist_pixels = 0;
|
||||
qState = qsCount;
|
||||
}
|
||||
|
||||
void shQuantizeEnd ()
|
||||
{
|
||||
delete [] color_index; color_index = NULL;
|
||||
delete [] box; box = NULL;
|
||||
delete [] hist; hist = NULL;
|
||||
}
|
||||
|
||||
void shQuantizeCount (SRGBPixel *image, int pixels, SRGBPixel *transp)
|
||||
{
|
||||
// Sanity check
|
||||
if (!pixels || qState != qsCount)
|
||||
return;
|
||||
|
||||
hist_pixels += pixels;
|
||||
|
||||
// Now, count all colors in image
|
||||
unsigned long *src = (unsigned long *)image;
|
||||
if (transp)
|
||||
{
|
||||
unsigned long tc = (*(unsigned long *)transp) & RGB_MASK;
|
||||
while (pixels--)
|
||||
{
|
||||
unsigned long pix = *src++;
|
||||
if (tc != (pix & RGB_MASK))
|
||||
{
|
||||
ushort &pa = hist [INDEX_R (pix) + INDEX_G (pix) + INDEX_B (pix)];
|
||||
// do not permit overflow here; stick to MAX_ushort
|
||||
if (!++pa) --pa;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
while (pixels--)
|
||||
{
|
||||
unsigned long pix = *src++;
|
||||
ushort &pa = hist [INDEX_R (pix) + INDEX_G (pix) + INDEX_B (pix)];
|
||||
// do not permit overflow here; stick to MAX_ushort
|
||||
if (!++pa) --pa;
|
||||
}
|
||||
}
|
||||
|
||||
void shQuantizeBias (SRGBPixel *colors, int count, int weight)
|
||||
{
|
||||
// Sanity check
|
||||
if (!count || qState != qsCount)
|
||||
return;
|
||||
|
||||
unsigned delta;
|
||||
if (hist_pixels < (0xffffffff / 100))
|
||||
delta = ((hist_pixels + 1) * weight / (100 * count));
|
||||
else
|
||||
delta = ((hist_pixels / count + 1) * weight) / 100;
|
||||
if (delta > 0xffff)
|
||||
delta = 0xffff;
|
||||
else if (!delta)
|
||||
return;
|
||||
|
||||
// Now, count all colors in image
|
||||
unsigned long *src = (unsigned long *)colors;
|
||||
while (count--)
|
||||
{
|
||||
unsigned long pix = *src++;
|
||||
ushort &pa = hist [INDEX_R (pix) + INDEX_G (pix) + INDEX_B (pix)];
|
||||
// do not permit overflow here; stick to MAX_ushort
|
||||
if (unsigned (pa) + delta > 0xffff) pa = 0xffff; else pa += delta;
|
||||
}
|
||||
}
|
||||
|
||||
void shQuantizePalette (SRGBPixel *&outpalette, int &maxcolors, SRGBPixel *transp)
|
||||
{
|
||||
// Sanity check
|
||||
if (qState != qsCount || !maxcolors)
|
||||
return;
|
||||
|
||||
// Good. Now we create the array of color space boxes.
|
||||
box = new shColorBox [maxcolors];
|
||||
box [0].Set (0, HIST_R_MAX - 1, 0, HIST_G_MAX - 1, 0, HIST_B_MAX - 1);
|
||||
box [0].Shrink ();
|
||||
box [0].ComputeVolume ();
|
||||
box [0].CountPixels ();
|
||||
boxcount = 1;
|
||||
|
||||
if (transp)
|
||||
maxcolors--;
|
||||
|
||||
// Loop until we have enough boxes (or we're out of pixels)
|
||||
while (boxcount < maxcolors)
|
||||
{
|
||||
// Find the box that should be split
|
||||
// We're making this decision the following way:
|
||||
// - first half of palette we prefer to split boxes that are
|
||||
// most populated with different colors.
|
||||
// - the rest of palette we prefer to split largest boxes.
|
||||
int bi, bestbox = -1;
|
||||
unsigned bestrating = 0;
|
||||
if (boxcount < maxcolors / 2)
|
||||
{
|
||||
for (bi = 0; bi < boxcount; bi++)
|
||||
if (bestrating < box [bi].ColorCount)
|
||||
{
|
||||
bestrating = box [bi].ColorCount;
|
||||
bestbox = bi;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (bi = 0; bi < boxcount; bi++)
|
||||
if (bestrating < box [bi].Volume)
|
||||
{
|
||||
bestrating = box [bi].Volume;
|
||||
bestbox = bi;
|
||||
}
|
||||
}
|
||||
// Out of splittable boxes?
|
||||
if (bestrating <= 1)
|
||||
break;
|
||||
|
||||
shColorBox &srcbox = box [bestbox];
|
||||
shColorBox &dstbox = box [boxcount++];
|
||||
dstbox = srcbox;
|
||||
|
||||
// Decide along which of R/G/B axis to split the box
|
||||
int rlen = (dstbox.Rx - dstbox.Rm) * (R_COEF << HIST_SHIFT_R);
|
||||
int glen = (dstbox.Gx - dstbox.Gm) * (G_COEF << HIST_SHIFT_G);
|
||||
int blen = (dstbox.Bx - dstbox.Bm) * (B_COEF << HIST_SHIFT_B);
|
||||
|
||||
enum { axisR, axisG, axisB } axis =
|
||||
(glen < rlen) ?
|
||||
((rlen < blen) ? axisB : axisR) :
|
||||
((glen < blen) ? axisB : axisG);
|
||||
|
||||
//
|
||||
// We split each box into two by the plane that goes through given color
|
||||
// component (one of R,G,B as choosen above). Any of resulting split boxes
|
||||
// possibly can become smaller if we move one of the five its faces (the
|
||||
// sixth face sure can't move because it was checked before - the one that
|
||||
// is opposed to the just-created new face, in the place of split).
|
||||
// Here goes some ASCII art:
|
||||
//
|
||||
// C G K The initial color box ABCD-IJKL was split by a
|
||||
// *-------*-------* plane and two boxes ABCD-EFGH and EFGH-IJKL
|
||||
// /| /| /| were created. The boxes cannot be shrinked
|
||||
// B/ | F/ | J/ | by moving faces ABCD and IJKL (because the
|
||||
// *-------*-------* | boxes were previously adjusted and any surface
|
||||
// | *----|--*----|--* passes through at least one used color).
|
||||
// | /D | /H | /L Now we also see that if the left box
|
||||
// |/ |/ |/ can be shrinked by moving face, say, ABFE
|
||||
// *-------*-------* towards DCGH, it is impossible for the right
|
||||
// A E I box to be shrinked by moving EFJI towards HGKL,
|
||||
// because the previous whole face ABJI is known
|
||||
// to pass through at least one used color (and if it is not in the ABFE
|
||||
// are, then it is surely in the EFJI area). We can say the same about
|
||||
// the DCGH/HGKL, BCGF/FGKJ and ADHE/EHLI pairs.
|
||||
//
|
||||
switch (axis)
|
||||
{
|
||||
case axisR:
|
||||
srcbox.Rx = (srcbox.Rm + srcbox.Rx) / 2;
|
||||
dstbox.Rm = srcbox.Rx + 1;
|
||||
srcbox.ShrinkRx ();
|
||||
dstbox.ShrinkRm ();
|
||||
if (!srcbox.ShrinkGm ())
|
||||
dstbox.ShrinkGm ();
|
||||
if (!srcbox.ShrinkGx ())
|
||||
dstbox.ShrinkGx ();
|
||||
if (!srcbox.ShrinkBm ())
|
||||
dstbox.ShrinkBm ();
|
||||
if (!srcbox.ShrinkBx ())
|
||||
dstbox.ShrinkBx ();
|
||||
break;
|
||||
case axisG:
|
||||
srcbox.Gx = (srcbox.Gm + srcbox.Gx) / 2;
|
||||
dstbox.Gm = srcbox.Gx + 1;
|
||||
srcbox.ShrinkGx ();
|
||||
dstbox.ShrinkGm ();
|
||||
if (!srcbox.ShrinkRm ())
|
||||
dstbox.ShrinkRm ();
|
||||
if (!srcbox.ShrinkRx ())
|
||||
dstbox.ShrinkRx ();
|
||||
if (!srcbox.ShrinkBm ())
|
||||
dstbox.ShrinkBm ();
|
||||
if (!srcbox.ShrinkBx ())
|
||||
dstbox.ShrinkBx ();
|
||||
break;
|
||||
case axisB:
|
||||
srcbox.Bx = (srcbox.Bm + srcbox.Bx) / 2;
|
||||
dstbox.Bm = srcbox.Bx + 1;
|
||||
srcbox.ShrinkBx ();
|
||||
dstbox.ShrinkBm ();
|
||||
if (!srcbox.ShrinkRm ())
|
||||
dstbox.ShrinkRm ();
|
||||
if (!srcbox.ShrinkRx ())
|
||||
dstbox.ShrinkRx ();
|
||||
if (!srcbox.ShrinkGm ())
|
||||
dstbox.ShrinkGm ();
|
||||
if (!srcbox.ShrinkGx ())
|
||||
dstbox.ShrinkGx ();
|
||||
break;
|
||||
} /* endswitch */
|
||||
|
||||
dstbox.CountPixels ();
|
||||
srcbox.PixelCount -= dstbox.PixelCount;
|
||||
srcbox.ColorCount -= dstbox.ColorCount;
|
||||
srcbox.ComputeVolume ();
|
||||
dstbox.ComputeVolume ();
|
||||
} /* endwhile */
|
||||
|
||||
// Either we're out of splittable boxes, or we have palsize boxes.
|
||||
|
||||
// Assign successive palette indices to all boxes
|
||||
int count, delta = transp ? 1 : 0;
|
||||
color_index = new byte [boxcount + delta];
|
||||
for (count = 0; count < boxcount; count++)
|
||||
color_index [count] = count;
|
||||
// Sort palette indices by usage (a side bonus to quantization)
|
||||
qsort (color_index, boxcount, sizeof (byte), compare_boxes);
|
||||
|
||||
// Allocate the palette, if not already allocated
|
||||
if (!outpalette)
|
||||
outpalette = new SRGBPixel [maxcolors + delta];
|
||||
|
||||
// Fill the unused colormap entries with zeros
|
||||
memset (&outpalette [boxcount + delta], 0,
|
||||
(maxcolors - boxcount) * sizeof (SRGBPixel));
|
||||
|
||||
// Now compute the mean color for each box
|
||||
for (count = 0; count < boxcount; count++)
|
||||
box [color_index [count]].GetMeanColor (outpalette [count + delta]);
|
||||
|
||||
// If we have a transparent color, set colormap entry 0 to it
|
||||
if (delta)
|
||||
{
|
||||
for (count = boxcount; count; count--)
|
||||
color_index [count] = color_index [count - 1] + 1;
|
||||
color_index [0] = 0;
|
||||
outpalette [0] = SRGBPixel (0, 0, 0);
|
||||
}
|
||||
|
||||
maxcolors = boxcount + delta;
|
||||
}
|
||||
|
||||
void shQuantizeRemap (SRGBPixel *image, int pixels,
|
||||
byte *&outimage, SRGBPixel *transp)
|
||||
{
|
||||
// Sanity check
|
||||
if (qState != qsCount && qState != qsRemap)
|
||||
return;
|
||||
|
||||
int count;
|
||||
|
||||
// We will re-use the histogram memory for a inverse colormap. However, we
|
||||
// will need just a byte per element, so we'll assign the address of
|
||||
// histogram memory block to a pointer of suitable type, and the second
|
||||
// half of histogram storage remains unused.
|
||||
byte *icmap = (byte *)hist;
|
||||
|
||||
int delta = transp ? 1 : 0;
|
||||
if (qState == qsCount)
|
||||
{
|
||||
// Now, fill inverse colormap with color indices
|
||||
for (count = 0; count < boxcount; count++)
|
||||
box [color_index [count + delta] - delta].FillInverseCMap (icmap, count + delta);
|
||||
qState = qsRemap;
|
||||
}
|
||||
|
||||
// Allocate the picture and the palette
|
||||
if (!outimage) outimage = new byte [pixels];
|
||||
|
||||
unsigned long *src = (unsigned long *)image;
|
||||
byte *dst = outimage;
|
||||
count = pixels;
|
||||
|
||||
if (transp)
|
||||
{
|
||||
unsigned long tc = (*(unsigned long *)transp) & RGB_MASK;
|
||||
while (count--)
|
||||
{
|
||||
unsigned long pix = *src++;
|
||||
if (tc == (pix & RGB_MASK))
|
||||
*dst++ = 0;
|
||||
else
|
||||
*dst++ = icmap [INDEX_R (pix) + INDEX_G (pix) + INDEX_B (pix)];
|
||||
}
|
||||
}
|
||||
else
|
||||
while (count--)
|
||||
{
|
||||
unsigned long pix = *src++;
|
||||
*dst++ = icmap [INDEX_R (pix) + INDEX_G (pix) + INDEX_B (pix)];
|
||||
}
|
||||
}
|
||||
|
||||
void shQuantizeRemapDither (SRGBPixel *image, int pixels, int pixperline,
|
||||
SRGBPixel *palette, int colors, byte *&outimage, SRGBPixel *transp)
|
||||
{
|
||||
// Sanity check
|
||||
if (qState != qsCount && qState != qsRemap)
|
||||
return;
|
||||
|
||||
int count;
|
||||
|
||||
// We will re-use the histogram memory for a inverse colormap. However, we
|
||||
// will need just a byte per element, so we'll assign the address of
|
||||
// histogram memory block to a pointer of suitable type, and the second
|
||||
// half of histogram storage remains unused.
|
||||
byte *icmap = (byte *)hist;
|
||||
|
||||
int delta = transp ? 1 : 0;
|
||||
if (qState == qsCount)
|
||||
{
|
||||
// Build an inverse colormap (since during dithering we can get color
|
||||
// indices that did not existed in the original image)
|
||||
shInverseColormap (colors - delta, palette + delta,
|
||||
HIST_R_BITS, HIST_G_BITS, HIST_B_BITS, icmap);
|
||||
if (transp)
|
||||
for (int i = 0; i < HIST_R_MAX * HIST_G_MAX * HIST_B_MAX; i++)
|
||||
icmap [i]++;
|
||||
qState = qsRemap;
|
||||
}
|
||||
|
||||
// Allocate the picture and the palette
|
||||
if (!outimage) outimage = new byte [pixels];
|
||||
|
||||
SRGBPixel *src = image;
|
||||
byte *dst = outimage;
|
||||
count = pixels;
|
||||
|
||||
int *fserr = (int *)malloc (2 * 3 * (pixperline + 2) * sizeof (int));
|
||||
memset (fserr, 0, 3 * (pixperline + 2) * sizeof (int));
|
||||
// odd/even row
|
||||
unsigned char odd = 0;
|
||||
while (count > 0)
|
||||
{
|
||||
// The alogorithm implements the widely-known and used Floyd-Steinberg
|
||||
// error distribution - based dithering. The errors are distributed with
|
||||
// the following weights to the surrounding pixels:
|
||||
//
|
||||
// (here) 7/16
|
||||
// 3/16 5/16 1/16
|
||||
//
|
||||
// Even lines are traversed left to right, odd lines backwards.
|
||||
|
||||
SRGBPixel *cursrc;
|
||||
byte *curdst;
|
||||
int *curerr, *nexterr;
|
||||
int dir;
|
||||
|
||||
if (odd)
|
||||
{
|
||||
cursrc = src + pixperline - 1;
|
||||
curdst = dst + pixperline - 1;
|
||||
curerr = fserr + 2 * 3 * (pixperline + 2) - 6;
|
||||
nexterr = fserr + 3 * (pixperline + 2) - 3;
|
||||
dir = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursrc = src;
|
||||
curdst = dst;
|
||||
curerr = fserr + 3;
|
||||
nexterr = fserr + 3 * (pixperline + 2);
|
||||
dir = 1;
|
||||
}
|
||||
int dir3 = dir * 3;
|
||||
|
||||
// We will keep the errors for pixels (x+1, y) in the variable "err10",
|
||||
// the error for the pixel right below us (x, y + 1) in "err01", and
|
||||
// the error at (x + 1, y + 1) in "err11". The error for the pixel at
|
||||
// (x - 1, y + 1) will be flushed into the errors array. This way, we
|
||||
// will have just one memory read and one memory write per pixel.
|
||||
// Well, in fact we have much more (x86 is terribly lacking registers)
|
||||
// but anyway they go through the cache.
|
||||
int err10r = 0, err01r = 0, err11r = 0;
|
||||
int err10g = 0, err01g = 0, err11g = 0;
|
||||
int err10b = 0, err01b = 0, err11b = 0;
|
||||
|
||||
for (int fspix = pixperline; fspix; fspix--,
|
||||
cursrc += dir, curdst += dir,
|
||||
curerr += dir3, nexterr += dir3)
|
||||
{
|
||||
SRGBPixel srcpix = *cursrc;
|
||||
|
||||
if (transp && transp->eq (srcpix))
|
||||
{
|
||||
*curdst = 0;
|
||||
err10r = err10g = err10b = 0;
|
||||
nexterr [0] = err01r; nexterr [1] = err01g; nexterr [2] = err01b;
|
||||
err01r = err11r; err01g = err11g; err01b = err11b;
|
||||
err11r = err11g = err11b = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
int r = srcpix.red + ((err10r + curerr [0]) / 16);
|
||||
if (r < 0) r = 0; if (r > 255) r = 255;
|
||||
|
||||
int g = srcpix.green + ((err10g + curerr [1]) / 16);
|
||||
if (g < 0) g = 0; if (g > 255) g = 255;
|
||||
|
||||
int b = srcpix.blue + ((err10b + curerr [2]) / 16);
|
||||
if (b < 0) b = 0; if (b > 255) b = 255;
|
||||
|
||||
byte pix = icmap [((r >> (8 - HIST_R_BITS)) << (HIST_G_BITS + HIST_B_BITS)) |
|
||||
((g >> (8 - HIST_G_BITS)) << HIST_B_BITS) |
|
||||
((b >> (8 - HIST_B_BITS)))];
|
||||
*curdst = pix;
|
||||
|
||||
SRGBPixel realcolor = palette [pix];
|
||||
|
||||
err10r = r - realcolor.red;
|
||||
nexterr [0] = err01r + err10r * 3; // * 3
|
||||
err01r = err11r + err10r * 5; // * 5
|
||||
err11r = err10r; // * 1
|
||||
err10r *= 7; // * 7
|
||||
|
||||
err10g = g - realcolor.green;
|
||||
nexterr [1] = err01g + err10g * 3; // * 3
|
||||
err01g = err11g + err10g * 5; // * 5
|
||||
err11g = err10g; // * 1
|
||||
err10g *= 7; // * 7
|
||||
|
||||
err10b = b - realcolor.blue;
|
||||
nexterr [2] = err01b + err10b * 3; // * 3
|
||||
err01b = err11b + err10b * 5; // * 5
|
||||
err11b = err10b; // * 1
|
||||
err10b *= 7; // * 7
|
||||
}
|
||||
// flush cached errors into error array
|
||||
nexterr [0] = err01r;
|
||||
nexterr [1] = err01g;
|
||||
nexterr [2] = err01b;
|
||||
|
||||
src += pixperline;
|
||||
dst += pixperline;
|
||||
odd ^= 1;
|
||||
count -= pixperline;
|
||||
}
|
||||
free(fserr);
|
||||
}
|
||||
|
||||
void shQuantizeRGB (SRGBPixel *image, int pixels, int pixperline,
|
||||
byte *&outimage, SRGBPixel *&outpalette, int &maxcolors, bool dither)
|
||||
{
|
||||
shQuantizeBegin ();
|
||||
|
||||
shQuantizeCount (image, pixels);
|
||||
shQuantizePalette (outpalette, maxcolors);
|
||||
if (dither)
|
||||
shQuantizeRemapDither (image, pixels, pixperline, outpalette, maxcolors, outimage);
|
||||
else
|
||||
shQuantizeRemap (image, pixels, outimage);
|
||||
|
||||
shQuantizeEnd ();
|
||||
}
|
||||
28
RenderDll/Common/Textures/Image/Quantize.h
Normal file
28
RenderDll/Common/Textures/Image/Quantize.h
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
#ifndef __QUANTIZE_H__
|
||||
#define __QUANTIZE_H__
|
||||
|
||||
extern void shQuantizeRGB (SRGBPixel *image, int pixels, int pixperline,
|
||||
byte *&outimage, SRGBPixel *&outpalette, int &maxcolors, bool dither);
|
||||
|
||||
|
||||
/// Begin quantization
|
||||
extern void shQuantizeBegin ();
|
||||
/// Finish quantization
|
||||
extern void shQuantizeEnd ();
|
||||
/// Count the colors in a image and update the color histogram
|
||||
extern void shQuantizeCount (SRGBPixel *image, int pixels,
|
||||
SRGBPixel *transp = NULL);
|
||||
/// Bias the color histogram towards given colors (weight = 0..100)
|
||||
extern void shQuantizeBias (SRGBPixel *colors, int count, int weight);
|
||||
/// Compute the optimal palette for all images passed to QuantizeCount()
|
||||
extern void shQuantizePalette (SRGBPixel *&outpalette, int &maxcolors,
|
||||
SRGBPixel *transp = NULL);
|
||||
/// Remap a image to the palette computed by shQuantizePalette()
|
||||
extern void shQuantizeRemap (SRGBPixel *image, int pixels,
|
||||
byte *&outimage, SRGBPixel *transp = NULL);
|
||||
/// Same but apply Floyd-Steinberg dithering for nicer (but slower) results
|
||||
extern void shQuantizeRemapDither (SRGBPixel *image, int pixels, int pixperline,
|
||||
SRGBPixel *palette, int colors, byte *&outimage, SRGBPixel *transp = NULL);
|
||||
|
||||
#endif // __QUANTIZE_H__
|
||||
216
RenderDll/Common/Textures/Image/SHendian.h
Normal file
216
RenderDll/Common/Textures/Image/SHendian.h
Normal file
@@ -0,0 +1,216 @@
|
||||
#ifndef __SHENDIAN_H__
|
||||
#define __SHENDIAN_H__
|
||||
|
||||
#define CS_LITTLE_ENDIAN
|
||||
/*
|
||||
* This is a bit of overkill but if you're sure your CPU doesn't require
|
||||
* strict alignment add your CPU to the !defined below to get slightly
|
||||
* smaller and faster code in some cases.
|
||||
*/
|
||||
#if !defined (PROC_INTEL)
|
||||
# define PROC_NEEDS_STRICT_ALIGNMENT
|
||||
#endif
|
||||
|
||||
struct swap_4
|
||||
{
|
||||
unsigned char b1, b2, b3, b4;
|
||||
};
|
||||
|
||||
#ifdef CS_BIG_ENDIAN
|
||||
# define big_endian_long(x) x
|
||||
# define big_endian_short(x) x
|
||||
# define big_endian_float(x) x
|
||||
#else
|
||||
|
||||
/// Convert a long from big-endian to machine format
|
||||
static inline unsigned long big_endian_long (unsigned long l)
|
||||
{ return (l >> 24) | ((l >> 8) & 0xff00) | ((l << 8) & 0xff0000) | (l << 24); }
|
||||
|
||||
/// Convert a short from big-endian to machine format
|
||||
static inline ushort big_endian_short (ushort s)
|
||||
{ return (s >> 8) | (s << 8); }
|
||||
|
||||
/// Convert a big-endian floating-point number to machine format
|
||||
//@@WARNING: Should be removed -- use float2long instead
|
||||
static inline float big_endian_float (float f)
|
||||
{
|
||||
unsigned char tmp;
|
||||
swap_4 *pf = (swap_4 *)&f;
|
||||
tmp = pf->b1; pf->b1 = pf->b4; pf->b4 = tmp;
|
||||
tmp = pf->b2; pf->b2 = pf->b3; pf->b3 = tmp;
|
||||
return f;
|
||||
}
|
||||
|
||||
#endif // CS_BIG_ENDIAN
|
||||
|
||||
#ifdef CS_LITTLE_ENDIAN
|
||||
# define little_endian_long(x) x
|
||||
# define little_endian_short(x) x
|
||||
# define little_endian_float(x) x
|
||||
#else
|
||||
|
||||
/// Convert a long from little-endian to machine format
|
||||
static inline unsigned long little_endian_long (unsigned long l)
|
||||
{ return (l >> 24) | ((l >> 8) & 0xff00) | ((l << 8) & 0xff0000) | (l << 24); }
|
||||
|
||||
/// Convert a short from little-endian to machine format
|
||||
static inline ushort little_endian_short (ushort s)
|
||||
{ return (s >> 8) | (s << 8); }
|
||||
|
||||
/// Convert a little-endian floating-point number to machine format
|
||||
static inline float little_endian_float (float f)
|
||||
{
|
||||
unsigned char tmp;
|
||||
swap_4 *pf = (swap_4 *)&f;
|
||||
tmp = pf->b1; pf->b1 = pf->b4; pf->b4 = tmp;
|
||||
tmp = pf->b2; pf->b2 = pf->b3; pf->b3 = tmp;
|
||||
return f;
|
||||
}
|
||||
|
||||
#endif // CS_LITTLE_ENDIAN
|
||||
|
||||
/*
|
||||
To be able to painlessly transfer files betwen platforms, we should
|
||||
avoid using native floating-point format. Here are a couple of routines
|
||||
that are guaranteed to work on all platforms.
|
||||
|
||||
The floating point is converted to a fixed 1.7.25 bits format
|
||||
(one bit sign, 7 bits exponent, 25 bits mantissa) and back,
|
||||
so that we can binary store floating-point number without
|
||||
cross-platform problems. If you wonder why 1+7+25 = 33 while we
|
||||
only have 32 bits, we'll ommit the most significant bit of mantissa
|
||||
since it is always 1 (we use normalized numbers). This increases the
|
||||
precision twice.
|
||||
*/
|
||||
|
||||
/// Convert a float to a cross-platform 32-bit format (no endianess adjustments!)
|
||||
static inline long float2long (float f)
|
||||
{
|
||||
int exp;
|
||||
long mant = QRound ((float)frexp (f, &exp) * (float)0x1000000);
|
||||
long sign = mant & 0x80000000;
|
||||
if (mant < 0) mant = -mant;
|
||||
if (exp > 63) exp = 63; else if (exp < -64) exp = -64;
|
||||
return sign | ((exp & 0x7f) << 24) | (mant & 0xffffff);
|
||||
}
|
||||
|
||||
/// Convert a 32-bit cross-platform float to native format (no endianess adjustments!)
|
||||
static inline float long2float (long l)
|
||||
{
|
||||
int exp = (l >> 24) & 0x7f;
|
||||
if (exp & 0x40) exp = exp | ~0x7f;
|
||||
float mant = float (l & 0x00ffffff) / 0x1000000;
|
||||
if (l & 0x80000000) mant = -mant;
|
||||
return (float)ldexp (mant, exp);
|
||||
}
|
||||
|
||||
/**
|
||||
* The following routines are used for converting floating-point numbers
|
||||
* into 16-bit shorts and back. This is useful for low-precision data.
|
||||
* They use the 1.4.12 format. The range of numbers that can be represented
|
||||
* in this format is from 2^-8 to 2^7. The precision for numbers near to
|
||||
* 2^-8 (0.00390625) is near 0.000001, for numbers near 2^7 (128) is near 0.03.
|
||||
*/
|
||||
|
||||
/// Convert a float to a cross-platform 16-bit format (no endianess adjustments!)
|
||||
static inline short float2short (float f)
|
||||
{
|
||||
int exp;
|
||||
long mant = QRound ((float)frexp (f, &exp) * (float)0x1000);
|
||||
long sign = mant & 0x8000;
|
||||
if (mant < 0) mant = -mant;
|
||||
if (exp > 7) mant = 0x7ff, exp = 7; else if (exp < -8) mant = 0, exp = -8;
|
||||
return (short)(sign | ((exp & 0xf) << 11) | (mant & 0x7ff));
|
||||
}
|
||||
|
||||
/// Convert a 16-bit cross-platform float to native format (no endianess adjustments!)
|
||||
static inline float short2float (short s)
|
||||
{
|
||||
int exp = (s >> 11) & 0xf;
|
||||
if (exp & 0x8) exp = exp | ~0xf;
|
||||
float mant = float ((s & 0x07ff) | 0x0800) / 0x1000;
|
||||
if (s & 0x8000) mant = -mant;
|
||||
return (float)ldexp (mant, exp);
|
||||
}
|
||||
|
||||
/// Swap the bytes in a unsigned long value.
|
||||
static inline unsigned long convert_endian (unsigned long l)
|
||||
{ return little_endian_long (l); }
|
||||
|
||||
/// Swap the bytes in a long value.
|
||||
static inline long convert_endian (long l)
|
||||
{ return little_endian_long (l); }
|
||||
|
||||
/// Swap the bytes in a int value.
|
||||
static inline int convert_endian (int i)
|
||||
{ return little_endian_long (i); }
|
||||
|
||||
/// Swap the bytes in a short value.
|
||||
static inline ushort convert_endian (ushort s)
|
||||
{ return little_endian_short (s); }
|
||||
|
||||
/// Swap the bytes in a float value.
|
||||
static inline float convert_endian (float f)
|
||||
{ return little_endian_float (f); }
|
||||
|
||||
/// Read a little-endian short from address
|
||||
inline ushort get_le_short (void *buff)
|
||||
{
|
||||
#ifdef PROC_NEEDS_STRICT_ALIGNMENT
|
||||
ushort s; memcpy (&s, buff, sizeof (s));
|
||||
return little_endian_short (s);
|
||||
#else
|
||||
return little_endian_short (*(ushort *)buff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Read a little-endian long from address
|
||||
inline unsigned long get_le_long (void *buff)
|
||||
{
|
||||
#ifdef PROC_NEEDS_STRICT_ALIGNMENT
|
||||
unsigned long l; memcpy (&l, buff, sizeof (l));
|
||||
return little_endian_long (l);
|
||||
#else
|
||||
return little_endian_long (*(unsigned long *)buff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Read a little-endian 32-bit float from address
|
||||
inline float get_le_float32 (void *buff)
|
||||
{ unsigned long l = get_le_long (buff); return long2float (l); }
|
||||
|
||||
/// Read a little-endian 16-bit float from address
|
||||
inline float get_le_float16 (void *buff)
|
||||
{ ushort s = get_le_short (buff); return short2float (s); }
|
||||
|
||||
/// Set a little-endian short on a address
|
||||
inline void set_le_short (void *buff, ushort s)
|
||||
{
|
||||
#ifdef PROC_NEEDS_STRICT_ALIGNMENT
|
||||
s = little_endian_short (s);
|
||||
memcpy (buff, &s, sizeof (s));
|
||||
#else
|
||||
*((ushort *)buff) = little_endian_short (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set a little-endian long on a address
|
||||
inline void set_le_long (void *buff, unsigned long l)
|
||||
{
|
||||
#ifdef PROC_NEEDS_STRICT_ALIGNMENT
|
||||
l = little_endian_long (l);
|
||||
memcpy (buff, &l, sizeof (l));
|
||||
#else
|
||||
*((unsigned long *)buff) = little_endian_long (l);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set a little-endian 32-bit float on a address
|
||||
inline void set_le_float32 (void *buff, float f)
|
||||
{ set_le_long (buff, float2long (f)); }
|
||||
|
||||
/// Set a little-endian 16-bit float on a address
|
||||
inline void set_le_float16 (void *buff, float f)
|
||||
{ set_le_short (buff, float2short (f)); }
|
||||
|
||||
#endif // __SHENDIAN_H__
|
||||
553
RenderDll/Common/Textures/Image/TgaImage.cpp
Normal file
553
RenderDll/Common/Textures/Image/TgaImage.cpp
Normal file
@@ -0,0 +1,553 @@
|
||||
/*=============================================================================
|
||||
TgaImage.cpp : TGA image file format implementation.
|
||||
Copyright (c) 2001 Crytek Studios. All Rights Reserved.
|
||||
|
||||
Revision history:
|
||||
* Created by Khonich Andrey
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "RenderPCH.h"
|
||||
#include "CImage.h"
|
||||
#include "TgaImage.h"
|
||||
|
||||
|
||||
|
||||
#define MAXCOLORS 16384
|
||||
|
||||
static int mapped, rlencoded;
|
||||
|
||||
static SRGBPixel ColorMap[MAXCOLORS];
|
||||
static int RLE_count = 0, RLE_flag = 0;
|
||||
|
||||
static void readtga ( byte*& ptr, struct SImageHeader* tgaP );
|
||||
static void get_map_entry ( byte*& ptr, SRGBPixel* Value, int Size );
|
||||
static void get_pixel ( byte*& ptr, SRGBPixel* dest, int Size );
|
||||
static byte getbyte ( byte*& ptr );
|
||||
|
||||
CImageTgaFile::~CImageTgaFile ()
|
||||
{
|
||||
}
|
||||
|
||||
CImageTgaFile::CImageTgaFile (byte* ptr, long filesize) : CImageFile ()
|
||||
{
|
||||
(void)filesize;
|
||||
struct SImageHeader tga_head;
|
||||
int i;
|
||||
unsigned int temp1, temp2;
|
||||
int rows, cols, row, col, realrow, truerow, baserow;
|
||||
int maxval;
|
||||
SRGBPixel *pixels;
|
||||
|
||||
/* @@@ to do: Add TGA format detection */
|
||||
|
||||
/* Read the Targa file header. */
|
||||
readtga (ptr, &tga_head);
|
||||
|
||||
rows = ( (int) tga_head.Height_lo ) + ( (int) tga_head.Height_hi ) * 256;
|
||||
cols = ( (int) tga_head.Width_lo ) + ( (int) tga_head.Width_hi ) * 256;
|
||||
|
||||
m_eFormat = eIF_Tga;
|
||||
|
||||
switch ( tga_head.ImgType )
|
||||
{
|
||||
case TGA_Map:
|
||||
case TGA_RGB:
|
||||
case TGA_Mono:
|
||||
case TGA_RLEMap:
|
||||
case TGA_RLERGB:
|
||||
case TGA_RLEMono:
|
||||
break;
|
||||
|
||||
default:
|
||||
mfSet_error (eIFE_BadFormat, "Unknown Targa image type");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( tga_head.ImgType == TGA_Map ||
|
||||
tga_head.ImgType == TGA_RLEMap ||
|
||||
tga_head.ImgType == TGA_CompMap ||
|
||||
tga_head.ImgType == TGA_CompMap4 )
|
||||
{ /* Color-mapped image */
|
||||
if ( tga_head.CoMapType != 1 )
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "Mapped image with bad color map type");
|
||||
return;
|
||||
}
|
||||
mapped = 1;
|
||||
/* Figure maxval from CoSize. */
|
||||
switch ( tga_head.CoSize )
|
||||
{
|
||||
case 8:
|
||||
case 24:
|
||||
case 32:
|
||||
maxval = 255;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
maxval = 31;
|
||||
break;
|
||||
|
||||
default:
|
||||
mfSet_error (eIFE_BadFormat, "Unknown colormap pixel size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* Not colormap, so figure maxval from PixelSize. */
|
||||
mapped = 0;
|
||||
switch ( tga_head.PixelSize )
|
||||
{
|
||||
case 8:
|
||||
case 24:
|
||||
case 32:
|
||||
maxval = 255;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
maxval = 31;
|
||||
break;
|
||||
|
||||
default:
|
||||
mfSet_error (eIFE_BadFormat, "Unknown pixel size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mfSet_bps(tga_head.PixelSize);
|
||||
|
||||
/* If required, read the color map information. */
|
||||
if ( tga_head.CoMapType != 0 )
|
||||
{
|
||||
temp1 = tga_head.Index_lo + tga_head.Index_hi * 256;
|
||||
temp2 = tga_head.Length_lo + tga_head.Length_hi * 256;
|
||||
if ( ( temp1 + temp2 + 1 ) >= MAXCOLORS )
|
||||
{
|
||||
mfSet_error (eIFE_BadFormat, "Too many colors in colormap");
|
||||
return;
|
||||
}
|
||||
for ( i = temp1; i < (int)( temp1 + temp2 ); ++i )
|
||||
get_map_entry( ptr, &ColorMap[i], (int) tga_head.CoSize );
|
||||
}
|
||||
|
||||
/* Check run-length encoding. */
|
||||
if ( tga_head.ImgType == TGA_RLEMap || tga_head.ImgType == TGA_RLERGB || tga_head.ImgType == TGA_RLEMono )
|
||||
rlencoded = 1;
|
||||
else
|
||||
rlencoded = 0;
|
||||
|
||||
/* Read the Targa file body and convert to portable format. */
|
||||
mfSet_dimensions (cols, rows);
|
||||
mfSet_ImageSize(cols * rows * 4);
|
||||
pixels = (SRGBPixel *)mfGet_image();
|
||||
|
||||
truerow = 0;
|
||||
baserow = 0;
|
||||
for ( row = 0; row < rows; ++row )
|
||||
{
|
||||
realrow = truerow;
|
||||
if ( tga_head.OrgBit == 0 )
|
||||
realrow = rows - realrow - 1;
|
||||
|
||||
for ( col = 0; col < cols; ++col )
|
||||
get_pixel( ptr, &(pixels[realrow*cols+col]), (int) tga_head.PixelSize );
|
||||
if ( tga_head.IntrLve == TGA_IL_Four )
|
||||
truerow += 4;
|
||||
else
|
||||
if ( tga_head.IntrLve == TGA_IL_Two )
|
||||
truerow += 2;
|
||||
else
|
||||
++truerow;
|
||||
if ( truerow >= rows )
|
||||
truerow = ++baserow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void readtga (byte*& ptr, SImageHeader* tgaP)
|
||||
{
|
||||
byte flags;
|
||||
|
||||
tgaP->IDLength = getbyte( ptr );
|
||||
tgaP->CoMapType = getbyte( ptr );
|
||||
tgaP->ImgType = getbyte( ptr );
|
||||
tgaP->Index_lo = getbyte( ptr );
|
||||
tgaP->Index_hi = getbyte( ptr );
|
||||
tgaP->Length_lo = getbyte( ptr );
|
||||
tgaP->Length_hi = getbyte( ptr );
|
||||
tgaP->CoSize = getbyte( ptr );
|
||||
tgaP->X_org_lo = getbyte( ptr );
|
||||
tgaP->X_org_hi = getbyte( ptr );
|
||||
tgaP->Y_org_lo = getbyte( ptr );
|
||||
tgaP->Y_org_hi = getbyte( ptr );
|
||||
tgaP->Width_lo = getbyte( ptr );
|
||||
tgaP->Width_hi = getbyte( ptr );
|
||||
tgaP->Height_lo = getbyte( ptr );
|
||||
tgaP->Height_hi = getbyte( ptr );
|
||||
tgaP->PixelSize = getbyte( ptr );
|
||||
flags = getbyte( ptr );
|
||||
tgaP->AttBits = flags & 0xf;
|
||||
tgaP->Rsrvd = ( flags & 0x10 ) >> 4;
|
||||
tgaP->OrgBit = ( flags & 0x20 ) >> 5;
|
||||
tgaP->IntrLve = ( flags & 0xc0 ) >> 6;
|
||||
|
||||
if ( tgaP->IDLength != 0 )
|
||||
ptr += tgaP->IDLength;
|
||||
}
|
||||
|
||||
static void get_map_entry (byte*& ptr, SRGBPixel* Value, int Size)
|
||||
{
|
||||
byte j, k, r, g, b;
|
||||
r=g=b=0; /* get rid of 'might be used uninited' warning */
|
||||
|
||||
/* Read appropriate number of bytes, break into rgb & put in map. */
|
||||
switch ( Size )
|
||||
{
|
||||
case 8: /* Grey scale, read and triplicate. */
|
||||
r = g = b = getbyte( ptr );
|
||||
break;
|
||||
|
||||
case 16: /* 5 bits each of red green and blue. */
|
||||
case 15: /* Watch for byte order. */
|
||||
j = getbyte( ptr );
|
||||
k = getbyte( ptr );
|
||||
r = ( k & 0x7C ) >> 2;
|
||||
g = ( ( k & 0x03 ) << 3 ) + ( ( j & 0xE0 ) >> 5 );
|
||||
b = j & 0x1F;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case 24: /* 8 bits each of blue green and red. */
|
||||
b = getbyte( ptr );
|
||||
g = getbyte( ptr );
|
||||
r = getbyte( ptr );
|
||||
if ( Size == 32 )
|
||||
(void) getbyte( ptr ); /* Read alpha byte & throw away. */
|
||||
break;
|
||||
|
||||
default:
|
||||
//mfSet_error (eIFE_BadFormat, "Unknown colormap pixel size");
|
||||
return;
|
||||
}
|
||||
Value->red=r; Value->green=g; Value->blue=b;
|
||||
}
|
||||
|
||||
static void get_pixel (byte*& ptr, SRGBPixel* dest, int Size)
|
||||
{
|
||||
static int Red, Grn, Blu, Alpha;
|
||||
byte j, k;
|
||||
static unsigned int l;
|
||||
|
||||
if (Size != 32)
|
||||
Alpha = 255;
|
||||
/* Check if run length encoded. */
|
||||
if ( rlencoded )
|
||||
{
|
||||
if ( RLE_count == 0 )
|
||||
{ /* Have to restart run. */
|
||||
byte i;
|
||||
i = getbyte( ptr );
|
||||
RLE_flag = ( i & 0x80 );
|
||||
if ( RLE_flag == 0 )
|
||||
/* Stream of unencoded pixels. */
|
||||
RLE_count = i + 1;
|
||||
else
|
||||
/* Single pixel replicated. */
|
||||
RLE_count = i - 127;
|
||||
/* Decrement count & get pixel. */
|
||||
--RLE_count;
|
||||
}
|
||||
else
|
||||
{ /* Have already read count & (at least) first pixel. */
|
||||
--RLE_count;
|
||||
if ( RLE_flag != 0 )
|
||||
/* Replicated pixels. */
|
||||
goto PixEncode;
|
||||
}
|
||||
}
|
||||
/* Read appropriate number of bytes, break into RGB. */
|
||||
switch ( Size )
|
||||
{
|
||||
case 8: /* Grey scale, read and triplicate. */
|
||||
Red = Grn = Blu = l = getbyte( ptr );
|
||||
break;
|
||||
|
||||
case 16: /* 5 bits each of red green and blue. */
|
||||
case 15: /* Watch byte order. */
|
||||
j = getbyte( ptr );
|
||||
k = getbyte( ptr );
|
||||
l = ( (unsigned int) k << 8 ) + j;
|
||||
Red = ( k & 0x7C ) >> 2;
|
||||
Grn = ( ( k & 0x03 ) << 3 ) + ( ( j & 0xE0 ) >> 5 );
|
||||
Blu = j & 0x1F;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
case 24: /* 8 bits each of blue green and red. */
|
||||
Blu = getbyte( ptr );
|
||||
Grn = getbyte( ptr );
|
||||
Red = getbyte( ptr );
|
||||
if ( Size == 32 )
|
||||
Alpha = getbyte( ptr ); /* Read alpha byte & throw away. */
|
||||
l = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
//mfSet_error (eIFE_BadFormat, "Unknown pixel size");
|
||||
return;
|
||||
}
|
||||
|
||||
PixEncode:
|
||||
if ( mapped )
|
||||
*dest = ColorMap[l];
|
||||
else
|
||||
{
|
||||
dest->red=Red;dest->green=Grn;dest->blue=Blu;
|
||||
dest->alpha = Alpha;
|
||||
}
|
||||
}
|
||||
|
||||
static byte getbyte (byte*& ptr)
|
||||
{
|
||||
byte c = *ptr++;
|
||||
return c;
|
||||
}
|
||||
|
||||
//=============================================================
|
||||
|
||||
#if !defined(LINUX)
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
static FILE *sFileData;
|
||||
static int src_bits_per_pixel;
|
||||
|
||||
static void bwrite(unsigned char data)
|
||||
{
|
||||
fputc(data, sFileData);
|
||||
}
|
||||
|
||||
void wwrite(unsigned short data)
|
||||
{
|
||||
unsigned char h, l;
|
||||
|
||||
l = data & 0xFF;
|
||||
h = data >> 8;
|
||||
bwrite(l);
|
||||
bwrite(h);
|
||||
}
|
||||
|
||||
|
||||
static void WritePixel(int depth, unsigned long a, unsigned long r, unsigned long g, unsigned long b)
|
||||
{
|
||||
DWORD color16;
|
||||
|
||||
switch(depth)
|
||||
{
|
||||
case 32:
|
||||
bwrite((byte)b); // b
|
||||
bwrite((byte)g); // g
|
||||
bwrite((byte)r); // r
|
||||
bwrite((byte)a); // a
|
||||
break;
|
||||
|
||||
case 24:
|
||||
bwrite((byte)b); // b
|
||||
bwrite((byte)g); // g
|
||||
bwrite((byte)r); // r
|
||||
break;
|
||||
|
||||
case 16:
|
||||
r >>= 3;
|
||||
g >>= 3;
|
||||
b >>= 3;
|
||||
|
||||
r &= 0x1F;
|
||||
g &= 0x1F;
|
||||
b &= 0x1F;
|
||||
|
||||
color16 = (r << 10) | (g << 5) | b;
|
||||
|
||||
wwrite((unsigned short)color16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetPixel(unsigned char * data, int depth, unsigned long &a, unsigned long &r, unsigned long &g, unsigned long &b)
|
||||
{
|
||||
switch(depth)
|
||||
{
|
||||
case 32:
|
||||
r = *data++;
|
||||
g = *data++;
|
||||
b = *data++;
|
||||
a = *data++;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
r = *data++;
|
||||
g = *data++;
|
||||
b = *data++;
|
||||
a = 0xFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WriteTGA8(byte *data8, int width, int height, char *filename)
|
||||
{
|
||||
unsigned char * data32 = new unsigned char [width*height*4];
|
||||
for(int i=0; i<width*height; i++)
|
||||
{
|
||||
data32[i*4+0] = data8[i];
|
||||
data32[i*4+1] = data8[i];
|
||||
data32[i*4+2] = data8[i];
|
||||
data32[i*4+3] = 255;
|
||||
}
|
||||
|
||||
WriteTGA(data32, width, height, filename, 32);
|
||||
delete [] data32;
|
||||
}
|
||||
|
||||
void WriteTGA(byte *data, int width, int height, char *filename, int dest_bits_per_pixel)
|
||||
{
|
||||
#ifndef PS2
|
||||
int i;
|
||||
unsigned long r,g,b,a;
|
||||
|
||||
src_bits_per_pixel = 32;
|
||||
|
||||
if ((sFileData = fopen(filename, "wb")) == NULL)
|
||||
return;
|
||||
|
||||
//mdesc |= LR; // left right
|
||||
//m_desc |= UL_TGA_BT; // top
|
||||
|
||||
int id_length = 0;
|
||||
int x_org = 0;
|
||||
int y_org = 0;
|
||||
int desc = 0;
|
||||
|
||||
// 32 bpp
|
||||
|
||||
int cm_index = 0;
|
||||
int cm_length = 0;
|
||||
int cm_entry_size = 0;
|
||||
int color_map_type = 0;
|
||||
|
||||
int type = 2;
|
||||
|
||||
bwrite(id_length);
|
||||
bwrite(color_map_type);
|
||||
bwrite(type);
|
||||
|
||||
wwrite(cm_index);
|
||||
wwrite(cm_length);
|
||||
|
||||
bwrite(cm_entry_size);
|
||||
|
||||
wwrite(x_org);
|
||||
wwrite(y_org);
|
||||
wwrite((unsigned short) width);
|
||||
wwrite((unsigned short) height);
|
||||
|
||||
bwrite( dest_bits_per_pixel );
|
||||
|
||||
bwrite(desc);
|
||||
|
||||
int hxw = height * width;
|
||||
|
||||
int right = 0;
|
||||
int top = 1;
|
||||
|
||||
DWORD * temp_dp = (DWORD*) data; // data = input pointer
|
||||
|
||||
DWORD * swap = 0;
|
||||
|
||||
|
||||
if( !top )
|
||||
{
|
||||
assert( src_bits_per_pixel == 32 );
|
||||
|
||||
swap = (DWORD *) new DWORD[ hxw ];
|
||||
|
||||
// copy whole image data to swap buffer
|
||||
cryMemcpy(swap, temp_dp, hxw * sizeof( DWORD ));
|
||||
|
||||
DWORD * src, * dest;
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
// copy lines from old into new buffer
|
||||
|
||||
src = & temp_dp[ ( height - i - 1) * width ];
|
||||
|
||||
dest = & swap[ i * width ];
|
||||
|
||||
cryMemcpy(dest, src, width * sizeof(DWORD) );
|
||||
}
|
||||
// use the swapped area in further processing & to write out the data
|
||||
data = (unsigned char *)swap;
|
||||
}
|
||||
|
||||
UINT src_bytes_per_pixel = src_bits_per_pixel / 8;
|
||||
|
||||
UINT size_in_bytes = hxw * src_bytes_per_pixel;
|
||||
|
||||
if( src_bits_per_pixel == dest_bits_per_pixel)
|
||||
{
|
||||
fwrite(data, hxw, src_bytes_per_pixel, sFileData);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < hxw; i++)
|
||||
{
|
||||
GetPixel( data, src_bits_per_pixel, a, b, g, r);
|
||||
WritePixel( dest_bits_per_pixel, a, b, g, r);
|
||||
data += src_bytes_per_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(sFileData);
|
||||
|
||||
SAFE_DELETE_ARRAY(swap);
|
||||
#else
|
||||
OutputDebugString("Not Implemented");
|
||||
#endif
|
||||
}
|
||||
|
||||
void BlurImage8(byte * pImage, int nSize, int nPassesNum)
|
||||
{
|
||||
#define DATA_TMP(_x,_y) (pTemp [(_x)+nSize*(_y)])
|
||||
#define DATA_IMG(_x,_y) (pImage[(_x)+nSize*(_y)])
|
||||
|
||||
byte * pTemp = new byte [nSize*nSize];
|
||||
|
||||
for(int nPass=0; nPass<nPassesNum; nPass++)
|
||||
{
|
||||
cryMemcpy(pTemp,pImage,nSize*nSize);
|
||||
|
||||
for(int x=1; x<nSize-1; x++)
|
||||
for(int y=1; y<nSize-1; y++)
|
||||
{
|
||||
float fVal = 0;
|
||||
fVal += DATA_TMP(x,y);
|
||||
fVal += DATA_TMP(x+1,y+1);
|
||||
fVal += DATA_TMP(x-1,y+1);
|
||||
fVal += DATA_TMP(x+1,y-1);
|
||||
fVal += DATA_TMP(x-1,y-1);
|
||||
DATA_IMG(x,y) = uchar(fVal*0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] pTemp;
|
||||
|
||||
#undef DATA_IMG
|
||||
#undef DATA_TMP
|
||||
}
|
||||
60
RenderDll/Common/Textures/Image/TgaImage.h
Normal file
60
RenderDll/Common/Textures/Image/TgaImage.h
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
#ifndef TGAIMAGE_H
|
||||
#define TGAIMAGE_H
|
||||
|
||||
/**
|
||||
* An ImageFile subclass for reading TGA files.
|
||||
*/
|
||||
class CImageTgaFile : public CImageFile
|
||||
{
|
||||
///
|
||||
friend class CImageFile; // For constructor
|
||||
|
||||
private:
|
||||
/// Read the TGA file from the buffer.
|
||||
CImageTgaFile (byte* buf, long size);
|
||||
|
||||
public:
|
||||
///
|
||||
virtual ~CImageTgaFile ();
|
||||
};
|
||||
|
||||
/* Header definition. */
|
||||
struct SImageHeader {
|
||||
unsigned char IDLength; /* length of Identifier String */
|
||||
unsigned char CoMapType; /* 0 = no map */
|
||||
unsigned char ImgType; /* image type (see below for values) */
|
||||
unsigned char Index_lo, Index_hi; /* index of first color map entry */
|
||||
unsigned char Length_lo, Length_hi; /* number of entries in color map */
|
||||
unsigned char CoSize; /* size of color map entry (15,16,24,32) */
|
||||
unsigned char X_org_lo, X_org_hi; /* x origin of image */
|
||||
unsigned char Y_org_lo, Y_org_hi; /* y origin of image */
|
||||
unsigned char Width_lo, Width_hi; /* width of image */
|
||||
unsigned char Height_lo, Height_hi; /* height of image */
|
||||
unsigned char PixelSize; /* pixel size (8,16,24,32) */
|
||||
unsigned char AttBits; /* 4 bits, number of attribute bits per pixel */
|
||||
unsigned char Rsrvd; /* 1 bit, reserved */
|
||||
unsigned char OrgBit; /* 1 bit, origin: 0=lower left, 1=upper left */
|
||||
unsigned char IntrLve; /* 2 bits, interleaving flag */
|
||||
};
|
||||
|
||||
typedef char ImageIDField[256];
|
||||
|
||||
/* Definitions for image types. */
|
||||
#define TGA_Null 0
|
||||
#define TGA_Map 1
|
||||
#define TGA_RGB 2
|
||||
#define TGA_Mono 3
|
||||
#define TGA_RLEMap 9
|
||||
#define TGA_RLERGB 10
|
||||
#define TGA_RLEMono 11
|
||||
#define TGA_CompMap 32
|
||||
#define TGA_CompMap4 33
|
||||
|
||||
/* Definitions for interleave flag. */
|
||||
#define TGA_IL_None 0
|
||||
#define TGA_IL_Two 1
|
||||
#define TGA_IL_Four 2
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user