53 #include "../idlib/precompiled.h"
88 for ( i = 0 ; i <
j ; i++ ) {
89 depth[
i] = ( data[i*4] + data[i*4+1] + data[i*4+2] ) / 3;
93 for ( i = 0 ; i <
height ; i++ ) {
94 for ( j = 0 ; j <
width ; j++ ) {
101 a1 = d1 = depth[ ( i * width +
j ) ];
102 a2 = d2 = depth[ ( i * width + ( ( j + 1 ) & ( width - 1 ) ) ) ];
103 a3 = d3 = depth[ ( ( ( i + 1 ) & ( height - 1 ) ) * width + j ) ];
104 a4 = d4 = depth[ ( ( ( i + 1 ) & ( height - 1 ) ) * width + ( ( j + 1 ) & ( width - 1 ) ) ) ];
109 dir[0] = -d2 *
scale;
110 dir[1] = -d3 *
scale;
117 dir2[0] = -a4 *
scale;
118 dir2[1] = a1 *
scale;
125 a1 = ( i * width +
j ) * 4;
126 data[ a1 + 0 ] = (
byte)(dir[0] * 127 + 128);
127 data[ a1 + 1 ] = (
byte)(dir[1] * 127 + 128);
128 data[ a1 + 2 ] = (
byte)(dir[2] * 127 + 128);
129 data[ a1 + 3 ] = 255;
143 static void R_ImageScale(
byte *data,
int width,
int height,
float scale[4] ) {
147 c = width * height * 4;
149 for ( i = 0 ; i <
c ; i++ ) {
150 j = (
byte)(data[i] * scale[i&3]);
153 }
else if ( j > 255 ) {
165 static void R_InvertAlpha(
byte *data,
int width,
int height ) {
169 c = width * height* 4;
171 for ( i = 0 ; i <
c ; i+=4 ) {
172 data[i+3] = 255 - data[i+3];
181 static void R_InvertColor(
byte *data,
int width,
int height ) {
185 c = width * height* 4;
187 for ( i = 0 ; i <
c ; i+=4 ) {
188 data[i+0] = 255 - data[i+0];
189 data[i+1] = 255 - data[i+1];
190 data[i+2] = 255 - data[i+2];
201 static void R_AddNormalMaps(
byte *data1,
int width1,
int height1,
byte *data2,
int width2,
int height2 ) {
206 if ( width2 != width1 || height2 != height1 ) {
207 newMap =
R_Dropsample( data2, width2, height2, width1, height1 );
214 for ( i = 0 ; i < height1 ; i++ ) {
215 for ( j = 0 ; j < width1 ; j++ ) {
220 d1 = data1 + ( i * width1 +
j ) * 4;
221 d2 = data2 + ( i * width1 +
j ) * 4;
223 n[0] = ( d1[0] - 128 ) / 127.0;
224 n[1] = ( d1[1] - 128 ) / 127.0;
225 n[2] = ( d1[2] - 128 ) / 127.0;
234 n[0] += ( d2[0] - 128 ) / 127.0;
235 n[1] += ( d2[1] - 128 ) / 127.0;
238 d1[0] = (
byte)(n[0] * 127 + 128);
239 d1[1] = (
byte)(n[1] * 127 + 128);
240 d1[2] = (
byte)(n[2] * 127 + 128);
255 static void R_SmoothNormalMap(
byte *data,
int width,
int height ) {
260 static float factors[3][3] = {
267 memcpy( orig, data, width * height * 4 );
269 for ( i = 0 ; i <
width ; i++ ) {
270 for ( j = 0 ; j <
height ; j++ ) {
272 for ( k = -1 ; k < 2 ; k++ ) {
273 for ( l = -1 ; l < 2 ; l++ ) {
276 in = orig + ( ((j+
l)&(height-1))*width + ((i+k)&(width-1)) ) * 4;
279 if ( in[0] == 0 && in[1] == 0 && in[2] == 0 ) {
282 if ( in[0] == 128 && in[1] == 128 && in[2] == 128 ) {
286 normal[0] += factors[k+1][l+1] * ( in[0] - 128 );
287 normal[1] += factors[k+1][l+1] * ( in[1] - 128 );
288 normal[2] += factors[k+1][l+1] * ( in[2] - 128 );
292 out = data + ( j * width +
i ) * 4;
293 out[0] = (
byte)(128 + 127 * normal[0]);
294 out[1] = (
byte)(128 + 127 * normal[1]);
295 out[2] = (
byte)(128 + 127 * normal[2]);
309 static void R_ImageAdd(
byte *data1,
int width1,
int height1,
byte *data2,
int width2,
int height2 ) {
315 if ( width2 != width1 || height2 != height1 ) {
316 newMap =
R_Dropsample( data2, width2, height2, width1, height1 );
323 c = width1 * height1 * 4;
325 for ( i = 0 ; i <
c ; i++ ) {
326 j = data1[
i] + data2[
i];
347 static void AppendToken(
idToken &token ) {
349 if ( parseBuffer[0] ) {
360 static void MatchAndAppendToken(
idLexer &
src,
const char *match ) {
377 static bool R_ParseImageProgram_r(
idLexer &src,
byte **pic,
int *width,
int *height,
384 AppendToken( token );
386 if ( !token.
Icmp(
"heightmap" ) ) {
387 MatchAndAppendToken( src,
"(" );
389 if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
393 MatchAndAppendToken( src,
"," );
396 AppendToken( token );
401 R_HeightmapToNormalMap( *pic, *width, *height, scale );
407 MatchAndAppendToken( src,
")" );
411 if ( !token.
Icmp(
"addnormals" ) ) {
415 MatchAndAppendToken( src,
"(" );
417 if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
421 MatchAndAppendToken( src,
"," );
423 if ( !R_ParseImageProgram_r( src, pic ? &pic2 :
NULL, &width2, &height2, timestamps, depth ) ) {
433 R_AddNormalMaps( *pic, *width, *height, pic2, width2, height2 );
440 MatchAndAppendToken( src,
")" );
444 if ( !token.
Icmp(
"smoothnormals" ) ) {
445 MatchAndAppendToken( src,
"(" );
447 if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
452 R_SmoothNormalMap( *pic, *width, *height );
458 MatchAndAppendToken( src,
")" );
462 if ( !token.
Icmp(
"add" ) ) {
466 MatchAndAppendToken( src,
"(" );
468 if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
472 MatchAndAppendToken( src,
"," );
474 if ( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, depth ) ) {
484 R_ImageAdd( *pic, *width, *height, pic2, width2, height2 );
488 MatchAndAppendToken( src,
")" );
492 if ( !token.
Icmp(
"scale" ) ) {
496 MatchAndAppendToken( src,
"(" );
498 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
500 for ( i = 0 ; i < 4 ; i++ ) {
501 MatchAndAppendToken( src,
"," );
503 AppendToken( token );
509 R_ImageScale( *pic, *width, *height, scale );
512 MatchAndAppendToken( src,
")" );
516 if ( !token.
Icmp(
"invertAlpha" ) ) {
517 MatchAndAppendToken( src,
"(" );
519 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
523 R_InvertAlpha( *pic, *width, *height );
526 MatchAndAppendToken( src,
")" );
530 if ( !token.
Icmp(
"invertColor" ) ) {
531 MatchAndAppendToken( src,
"(" );
533 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
537 R_InvertColor( *pic, *width, *height );
540 MatchAndAppendToken( src,
")" );
544 if ( !token.
Icmp(
"makeIntensity" ) ) {
547 MatchAndAppendToken( src,
"(" );
549 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
554 c = *width * *height * 4;
555 for ( i = 0 ; i <
c ; i+=4 ) {
558 (*pic)[i+3] = (*pic)[
i];
562 MatchAndAppendToken( src,
")" );
566 if ( !token.
Icmp(
"makeAlpha" ) ) {
569 MatchAndAppendToken( src,
"(" );
571 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
576 c = *width * *height * 4;
577 for ( i = 0 ; i <
c ; i+=4 ) {
578 (*pic)[i+3] = ( (*pic)[i+0] + (*pic)[i+1] + (*pic)[i+2] ) / 3;
585 MatchAndAppendToken( src,
")" );
591 if ( !timestamps && !pic ) {
598 if ( timestamp == -1 ) {
604 if ( timestamp > *timestamps ) {
605 *timestamps = timestamp;
629 R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
641 R_ParseImageProgram_r( src, NULL, NULL, NULL, NULL, NULL );
byte * R_Dropsample(const byte *in, int inwidth, int inheight, int outwidth, int outheight)
GLenum GLenum GLenum GLenum GLenum scale
void R_LoadImage(const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2)
float GetFloatValue(void)
GLint GLint GLsizei GLsizei GLsizei depth
static float Sqrt(float x)
int Icmp(const char *text) const
void R_LoadImageProgram(const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamps, textureDepth_t *depth)
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
GLsizei GLsizei GLenum GLenum const GLvoid * data
float NormalizeFast(void)
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
GLenum GLsizei GLsizei height
const char * R_ParsePastImageProgram(idLexer &src)
int ExpectTokenString(const char *string)
void Append(const char a)
void * R_StaticAlloc(int bytes)
const char * c_str(void) const
float LengthFast(void) const
void R_StaticFree(void *data)
int ReadToken(idToken *token)