- Deprecating r_shadeMode and r_envMode

- Added lightingSpecularDiffuse which is like diffuse, but clamps and does a specular calc for the overbrights, and this is also disableable with the new r_shadeSpecular cvar
- Added tcGen environmentWater which is more suitable for water
- Faster bulge code from JK2
- Shutting up TGA loading fatal errors for warnings instead (to hunt down bad TGAs easier)
This commit is contained in:
leilei-
2014-09-06 09:23:10 -04:00
parent 2c07195887
commit f619c08fd9
6 changed files with 133 additions and 391 deletions

View File

@@ -56,6 +56,7 @@ cvar_t *r_verbose;
cvar_t *r_ignore;
cvar_t *r_detailTextures;
cvar_t *r_shadeSpecular;
cvar_t *r_znear;
cvar_t *r_zproj;
@@ -1281,6 +1282,7 @@ void R_Register( void )
r_texdump = ri.Cvar_Get( "r_texdump", "0", CVAR_CHEAT ); // leilei - debug - texture dumping
r_shadeSpecular = ri.Cvar_Get( "r_shadeSpecular", "1", CVAR_ARCHIVE | CVAR_LATCH ); // leilei - our models look best with these
// make sure all the commands added here are also
// removed in R_Shutdown

View File

@@ -185,7 +185,8 @@ typedef enum {
CGEN_LIGHTING_FLAT_DIRECT,
CGEN_FOG, // standard fog
CGEN_CONST, // fixed color
CGEN_VERTEX_LIT // leilei - tess.vertexColors * tr.identityLight * ambientlight*directlight
CGEN_VERTEX_LIT, // leilei - tess.vertexColors * tr.identityLight * ambientlight*directlight
CGEN_LIGHTING_DIFFUSE_SPECULAR // leilei - LIGHTING_DIFFUSE, capped by specular exponent
} colorGen_t;
typedef enum {
@@ -196,6 +197,7 @@ typedef enum {
TCGEN_ENVIRONMENT_MAPPED,
TCGEN_ENVIRONMENT_CELSHADE_MAPPED,
TCGEN_ENVIRONMENT_CELSHADE_LEILEI, // leilei - cel hack
TCGEN_ENVIRONMENT_MAPPED_WATER, // leilei - fake water reflection
TCGEN_EYE_LEFT, // eyes
TCGEN_EYE_RIGHT, // eyes
TCGEN_FOG,
@@ -745,9 +747,12 @@ typedef struct {
vec3_t lightGridSize;
vec3_t lightGridInverseSize;
int lightGridBounds[3];
byte *lightGridData;
int numClusters;
int clusterBytes;
const byte *vis; // may be passed in by CM_LoadMap to save space
@@ -1303,8 +1308,9 @@ extern cvar_t *r_lensReflection2;
extern cvar_t *r_lensReflectionBrightness;
extern cvar_t *r_ext_paletted_texture; // leilei - Paletted Texture
extern cvar_t *r_envMode;
//extern cvar_t *r_envMode;
extern cvar_t *r_specMode;
extern cvar_t *r_shadeSpecular; // leilei - allows the special specular diffuse shading
//extern cvar_t *r_waveMode;
extern cvar_t *r_flaresDlight;
@@ -2077,7 +2083,7 @@ void RB_CalcSpecularAlphaNew( unsigned char *alphas );
void RB_CalcDiffuseColor( unsigned char *colors );
void RB_CalcUniformColor( unsigned char *colors );
void RB_CalcDynamicColor( unsigned char *colors );
void RB_CalcDiffuseColor_Specular( unsigned char *colors ); // leilei - specular hack
void RB_CalcFlatAmbient( unsigned char *colors ); // leilei - cel hack
void RB_CalcFlatDirect( unsigned char *colors ); // leilei - cel hack

View File

@@ -809,6 +809,8 @@ static void ProjectDlightTexture( void ) {
}
/*
===================
RB_FogPass
@@ -1003,6 +1005,18 @@ static void ComputeColors( shaderStage_t *pStage )
case CGEN_ONE_MINUS_ENTITY:
RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
break;
case CGEN_LIGHTING_DIFFUSE_SPECULAR: // leilei - specular hack
RB_CalcDiffuseColor_Specular( ( unsigned char * ) tess.svars.colors );
if(r_monolightmaps->integer)
{
int scale;
for(i = 0; i < tess.numVertexes; i++)
{
scale = LUMA(tess.svars.colors[i][0], tess.svars.colors[i][1], tess.svars.colors[i][2]);
tess.svars.colors[i][0] = tess.svars.colors[i][1] = tess.svars.colors[i][2] = scale;
}
}
break;
}
//
@@ -1177,18 +1191,10 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_ENVIRONMENT_MAPPED:
if ( r_envMode->integer == 1 ) {
RB_CalcEnvironmentTexCoordsNew( ( float * ) tess.svars.texcoords[b] );
} // new dancing one
else if ( r_envMode->integer == 2 ) {
RB_CalcEnvironmentTexCoordsJO( ( float * ) tess.svars.texcoords[b] );
} // JO's
else if ( r_envMode->integer == 3 ) {
RB_CalcEnvironmentTexCoordsR( ( float * ) tess.svars.texcoords[b] );
} // Q3R's
else {
RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
} // old one
RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_ENVIRONMENT_MAPPED_WATER:
RB_CalcEnvironmentTexCoordsJO( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_ENVIRONMENT_CELSHADE_MAPPED:
RB_CalcEnvironmentCelShadeTexCoords( ( float * ) tess.svars.texcoords[b] );
@@ -1544,14 +1550,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
R_DrawElements( input->numIndexes, input->indexes );
}
// odin's patch adapted
if ( r_envMode->integer == 2) {
if ( pStage->bundle[0].tcGen == TCGEN_ENVIRONMENT_MAPPED ) {
qglDisable(GL_TEXTURE_GEN_S);
qglDisable(GL_TEXTURE_GEN_T);
qglDisable(GL_TEXTURE_GEN_R);
}
}
}
// allow skipping out to show just lightmaps during development

View File

@@ -268,7 +268,7 @@ RB_CalcBulgeVertexes
========================
*/
void RB_CalcBulgeVertexes( deformStage_t *ds ) {
void OldRB_CalcBulgeVertexes( deformStage_t *ds ) {
int i;
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
@@ -292,6 +292,46 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
}
// leilei - adapted a bit from the jk2 source, for performance
void RB_CalcBulgeVertexes( deformStage_t *ds ) {
int i;
float *xyz = ( float * ) tess.xyz;
float *normal = ( float * ) tess.normal;
if ( ds->bulgeSpeed == 0.0f && ds->bulgeWidth == 0.0f )
{
// We don't have a speed and width, so just use height to expand uniformly
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
{
xyz[0] += normal[0] * ds->bulgeHeight;
xyz[1] += normal[1] * ds->bulgeHeight;
xyz[2] += normal[2] * ds->bulgeHeight;
}
}
else
{
const float *st = ( const float * ) tess.texCoords[0];
float now;
now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
int off;
float scale;
off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight;
xyz[0] += normal[0] * scale;
xyz[1] += normal[1] * scale;
xyz[2] += normal[2] * scale;
}
}
}
/*
======================
RB_CalcMoveVertexes
@@ -1573,318 +1613,54 @@ static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
}
// leilei - use FIVE (!) lighting points. Very expensive!
static void RB_CalcDiffuseColor_crazy( unsigned char *colors )
{
int i, j, k;
float *v, *normal;
float incoming, incomingA;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir, lightDirA;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->lightDirA, lightDirA );
ambientLight[0] *= 0.5f;
ambientLight[1] *= 0.5f;
ambientLight[2] *= 0.5f;
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
incomingA = DotProduct (normal, lightDirA);
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
k = ri.ftol(ambientLight[0] + incomingA * directedLightA[0]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1] + incoming * directedLight[1]);
k = ri.ftol(ambientLight[1] + incomingA * directedLightA[1]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2] + incoming * directedLight[2]);
k = ri.ftol(ambientLight[2] + incomingA * directedLightA[2]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
/*
static void RB_CalcDiffuseColor_crafzy( unsigned char *colors )
{
int i, j, jA;
float *v, *normal;
float incoming, incomingA, incomingB, incomingC, incomingD;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir, lightDirA;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDirA, lightDirA );
// Actually, in reality, I disabled B, C and D as I figured out a more sane way to do things.
// debug light positions
{
vec3_t temp;
vec3_t temp2;
AnglesToAxis(lightDirA, temp);
AnglesToAxis(lightDir, temp2);
GL_Bind( tr.whiteImage );
qglColor3f (1,1,1);
qglDepthRange( 0, 0 ); // never occluded
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglBegin (GL_LINES);
qglVertex3fv (temp);
qglVertex3fv (temp2);
qglEnd ();
qglDepthRange( 0, 1 );
}
if (lightDirA[0] == 666){
VectorCopy( ent->directedLight, directedLightA );
VectorCopy( ent->lightDir, lightDirA );
}
int eg;
for (eg=0; eg<3;eg++){
//ambientLight[eg] /= 3;
directedLight[eg] *= 0.5f;
directedLightA[eg] *= 0.5f;
}
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
incomingA = DotProduct (normal, lightDirA);
if ( incomingA <= 0 ) { VectorCopy(directedLight, directedLightA); incomingA = incoming; }
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
j = ri.ftol(ambientLight[0] + (incoming * directedLight[0]));
jA = ri.ftol(ambientLight[0] + (incomingA * directedLightA[0]));
if ( j > 255 ) { j = 255; }
if ( jA > 255 ) { jA = 255; }
colors[i*4+0] = (j + jA) /2;
j = ri.ftol(ambientLight[1] + (incoming * directedLight[1]));
jA = ri.ftol(ambientLight[1] + (incomingA * directedLightA[1]));
if ( j > 255 ) {
j = 255;
}
if ( jA > 255 ) { jA = 255; }
colors[i*4+1] = (j + jA) /2;
j = ri.ftol(ambientLight[2] + (incoming * directedLight[2]));
jA = ri.ftol(ambientLight[2] + (incomingA * directedLightA[2]));
if ( j > 255 ) {
j = 255;
}
if ( jA > 255 ) { jA = 255; }
colors[i*4+2] = (j + jA) /2;
colors[i*4+3] = 255;
}
}
*/
// leilei - some slower, but bolder way of lighting
// i sure hope gcc unrolls this.
static void RB_CalcDiffuseColor_alternative( unsigned char *colors )
void RB_CalcDiffuseColor_Specular( unsigned char *colors )
{
int i, j;
int speccap = 0;
float spec;
float *v, *normal;
float incoming;
float incoming2;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t ambDir;
vec3_t lightDir;
vec3_t directedLight;
int numVertexes;
int shadecap = 200; // was 127
ent = backEnd.currentEntity;
float ilength;
int d, l, b;
vec3_t viewer, reflected;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->lightDir, ambDir );
VectorCopy( lightOrigin, ambDir );
VectorNormalizeFast( ambDir );
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir) * 0.6;
incoming2 = DotProduct (normal, ambDir) * 2;
if (incoming < 0) incoming = 0;
if (incoming2 < 0) incoming2 *= -0.7; // invert for fake rim effect
if (incoming2 < 0.9f) incoming2 = 0.9f; // clamp out black
incoming = DotProduct (normal, lightDir);
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
// Specular
// add specular to ambient incoming
{
VectorSubtract( lightOrigin, v, ambDir );
ilength = Q_rsqrt( DotProduct( ambDir, ambDir ) );
VectorNormalizeFast( ambDir );
// calculate the specular color
d = DotProduct (normal, ambDir);
// d *= ilength;
// we don't optimize for the d < 0 case since this tends to
// cause visual artifacts such as faceted "snapping"
reflected[0] = normal[0]*2*d - ambDir[0];
reflected[1] = normal[1]*2*d - ambDir[1];
reflected[2] = normal[2]*2*d - ambDir[2];
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
//ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
l = DotProduct (reflected, viewer);
l *= ilength;
if (l < 0) {
b = 0;
l = 0;
} else {
l = l*l;
l = l*l;
}
}
incoming2 *= l;
j = ri.ftol(ambientLight[0] * incoming2) + ri.ftol(incoming * directedLight[0]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1] * incoming2) + ri.ftol(incoming * directedLight[1]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2] * incoming2) + ri.ftol(incoming * directedLight[2]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
static void RB_CalcDiffuseColor_crazyew( unsigned char *colors )
{
int i, j;
float *v, *normal;
float incoming;
float incoming2;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t ambDir;
vec3_t lightDir, lightDirA, lightDirB;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
float ilength;
int d, l, b;
vec3_t viewer, reflected;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->lightDirA, lightDirA );
//VectorCopy( lightOrigin, lightDirB );
VectorNormalizeFast( lightDirB );
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir) * 0.8;
// incoming2 = DotProduct (normal, lightDirA) * 2;
if (incoming < 0) incoming = 0;
// if (incoming2 < 0) incoming2 *= -0.7; // invert for fake rim effect
// if (incoming2 < 0.9f) incoming2 = 0.9f; // clamp out black
// add specular to ambient incoming
{
float ilength;
int b;
vec3_t viewer, reflected;
float l, d;
// int b;
VectorCopy( backEnd.currentEntity->lightDir, lightDir );
//ilength = Q_rsqrt( DotProduct( ambDir, ambDir ) );
VectorNormalizeFast( ambDir );
VectorNormalizeFast( lightDir );
// calculate the specular color
d = DotProduct (normal, ambDir);
// d *= ilength;
d = DotProduct (normal, lightDir);
// we don't optimize for the d < 0 case since this tends to
// cause visual artifacts such as faceted "snapping"
@@ -1898,97 +1674,45 @@ static void RB_CalcDiffuseColor_crazyew( unsigned char *colors )
l *= ilength;
if (l < 0) {
b = 0;
l = 0;
spec = 0;
} else {
l = l*l;
l = l*l;
spec = l * 0.2f;
if (spec > 1) {
spec = 1;
}
}
}
incoming2 += l;
j = ri.ftol(ambientLight[0]) + ri.ftol(incoming * directedLight[0]) + ri.ftol(incoming2 * directedLightA[0]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1]) + ri.ftol(incoming * directedLight[1]) + ri.ftol(incoming2 * directedLightA[1]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2]) + ri.ftol(incoming * directedLight[2]) + ri.ftol(incoming2 * directedLightA[2]);
if ( j > 255 ) {
j = 255;
}
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
// simple faster one without a direction of any kind, should be similar to q2/hl
static void RB_CalcDiffuseColor_lame( unsigned char *colors )
{
int i, j;
float *v, *normal;
float incoming;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir;
vec3_t directedLight;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
lightDir[0] = 0;
lightDir[1] = 0;
lightDir[2] = 1;
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
if ( j > 255 ) {
j = 255;
}
if ( j > shadecap ) j = shadecap ;
j += ri.ftol(spec * directedLight[0]);
if ( j > 255) j = 255;
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1] + incoming * directedLight[1]);
if ( j > 255 ) {
j = 255;
}
if ( j > shadecap ) j = shadecap ;
j += ri.ftol(spec * directedLight[1]);
if ( j > 255) j = 255;
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2] + incoming * directedLight[2]);
if ( j > 255 ) {
j = 255;
}
if ( j > shadecap ) j = shadecap ;
j += ri.ftol(spec * directedLight[2]);
if ( j > 255) j = 255;
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
void RB_CalcDiffuseColor( unsigned char *colors )
{
#if idppc_altivec
@@ -1999,15 +1723,11 @@ void RB_CalcDiffuseColor( unsigned char *colors )
}
#endif
if (r_shadeMode->integer == 2)
RB_CalcDiffuseColor_alternative( colors );
else if (r_shadeMode->integer == 3)
RB_CalcDiffuseColor_lame( colors );
else if (r_shadeMode->integer == 6)
RB_CalcDiffuseColor_crazy( colors );
else
// leilei - reduced it to just this, r_shadeMode deprecated. :(
RB_CalcDiffuseColor_scalar( colors );
}
/*

View File

@@ -2617,6 +2617,13 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{
stage->rgbGen = CGEN_ONE_MINUS_VERTEX;
}
else if ( !Q_stricmp( token, "lightingSpecularDiffuse" ) ) // leilei - use special specular calculation if overbrights and r_shadeSpecular is enabled
{
if ( r_shadeSpecular->integer && tr.overbrightBits )
stage->rgbGen = CGEN_LIGHTING_DIFFUSE_SPECULAR;
else
stage->rgbGen = CGEN_LIGHTING_DIFFUSE;
}
else
{
ri.Printf( PRINT_WARNING, "WARNING: unknown rgbGen parameter '%s' in shader '%s'\n", token, shader.name );
@@ -2722,6 +2729,10 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{
stage->bundle[0].tcGen = TCGEN_EYE_RIGHT;
}
else if ( !Q_stricmp( token, "environmentWater" ) )
{
stage->bundle[0].tcGen = TCGEN_ENVIRONMENT_MAPPED_WATER; // leilei - water's envmaps
}
else if ( !Q_stricmp( token, "lightmap" ) )
{
stage->bundle[0].tcGen = TCGEN_LIGHTMAP;

View File

@@ -103,17 +103,22 @@ void R_LoadTGA ( const char *name, byte **pic, int *width, int *height)
&& targa_header.image_type!=10
&& targa_header.image_type != 3 )
{
ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported");
// leilei - made these far less fatal and more informative
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name);
//ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported");
}
if ( targa_header.colormap_type != 0 )
{
ri.Error( ERR_DROP, "LoadTGA: colormaps not supported" );
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' colormaps not supported\n", name);
//ri.Error( ERR_DROP, "LoadTGA: colormaps not supported" );
}
if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
{
ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)");
ri.Printf( PRINT_WARNING, "LoadTGA: '%s' Only 32 or 24 bit images supported (no colormaps)\n", name);
// ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)");
}
columns = targa_header.width;