28 #include "../idlib/precompiled.h"
47 for (pot = 1 ; (pot*2) <= num ; pot<<=1) {
57 static byte colors[8][4] = {
65 { 255, 255, 255, 255 }
69 int c = MAX_LEVEL_WIDTH * MAX_LEVEL_WIDTH;
72 for (
int i = 0 ;
i <
c ;
i++ ) {
73 ((
int *)data)[
i] = fillColor.intVal;
123 level->
parms[0] = -1;
126 level->
parms[3] = (
float)width / TILE_PER_LEVEL;
135 for (
int i = 0 ;
i < 4 ;
i++ ) {
142 if ( width <= TILE_PER_LEVEL && height <= TILE_PER_LEVEL ) {
145 width = ( width + 1 ) >> 1;
146 height = ( height + 1 ) >> 1;
189 if ( v->
st[0] <= origin.
st[0] && v->
st[1] <= origin.
st[1] ) {
192 if ( v->
st[0] >= axis[0].
st[0] && v->
st[1] <= axis[0].
st[1] ) {
195 if ( v->
st[0] <= axis[1].
st[0] && v->
st[1] >= axis[1].
st[1] ) {
200 for (
int i = 0 ;
i < 2 ;
i++ ) {
202 float texLen = axis[
i].
st[
i] - origin.
st[
i];
203 float spaceLen = (axis[
i].
xyz - origin.
xyz).Length();
205 float scale = texLen / (spaceLen*spaceLen);
208 float c = origin.
xyz * dir - origin.
st[
i];
231 for (
int i = 0 ;
i < 7 ;
i++ ) {
237 static float parms[4] = { -2, -2, 0, 1 };
312 for (
int i = 0 ;
i < 2 ;
i++ ) {
336 if ( tile->
x == globalX && tile->
y == globalY ) {
339 if ( (globalX & (TILE_PER_LEVEL-1)) != localX || (globalY & (TILE_PER_LEVEL-1)) != localY ) {
340 common->
Error(
"idTextureLevel::UpdateTile: bad coordinate mod" );
346 byte data[ TILE_SIZE * TILE_SIZE * 4 ];
350 memset( data, 0,
sizeof( data ) );
355 int tileSize = TILE_SIZE * TILE_SIZE * 4;
358 memset( data, 128,
sizeof( data ) );
364 byte color[4] = { 255 * localX / TILE_PER_LEVEL, 255 * localY / TILE_PER_LEVEL, 0, 0 };
365 for (
int x = 0 ;
x < 8 ;
x++ ) {
366 for (
int y = 0 ;
y < 8 ;
y++ ) {
367 *(
int *)&data[ ( (
y + TILE_SIZE/2 - 4 ) * TILE_SIZE +
x + TILE_SIZE/2 - 4 ) * 4 ] = *(
int *)
color;
374 int size = TILE_SIZE;
376 qglTexSubImage2D( GL_TEXTURE_2D, level, localX * size, localY * size, size, size, GL_RGBA, GL_UNSIGNED_BYTE, data );
384 int byteSize = size * 4;
386 for (
int y = 0 ;
y <
size ;
y++ ) {
388 in = data +
y * size * 16;
390 out = data +
y * size * 4;
391 for (
int x = 0 ;
x <
size ;
x++ ) {
392 out[
x*4+0] = ( in[
x*8+0] + in[
x*8+4+0] + in2[
x*8+0] + in2[
x*8+4+0] ) >> 2;
393 out[
x*4+1] = ( in[
x*8+1] + in[
x*8+4+1] + in2[
x*8+1] + in2[
x*8+4+1] ) >> 2;
394 out[
x*4+2] = ( in[
x*8+2] + in[
x*8+4+2] + in2[
x*8+2] + in2[
x*8+4+2] ) >> 2;
395 out[
x*4+3] = ( in[
x*8+3] + in[
x*8+4+3] + in2[
x*8+3] + in2[
x*8+4+3] ) >> 2;
409 int globalTileCorner[2];
410 int localTileOffset[2];
413 globalTileCorner[0] = 0;
414 globalTileCorner[1] = 0;
415 localTileOffset[0] = 0;
416 localTileOffset[1] = 0;
422 for (
int i = 0 ;
i < 2 ;
i++ ) {
427 global[
i] = ( center[
i] *
parms[3] - 0.5 ) * TILE_PER_LEVEL;
429 globalTileCorner[
i] = (
int)( global[
i] + 0.5 );
431 localTileOffset[
i] = globalTileCorner[
i] & (TILE_PER_LEVEL-1);
435 parms[
i] = -globalTileCorner[
i] / (
float)TILE_PER_LEVEL;
441 for (
int x = 0 ;
x < TILE_PER_LEVEL ;
x++ ) {
442 for (
int y = 0 ;
y < TILE_PER_LEVEL ;
y++ ) {
445 globalTile[0] = globalTileCorner[0] + ( (
x - localTileOffset[0] ) & (TILE_PER_LEVEL-1) );
446 globalTile[1] = globalTileCorner[1] + ( (
y - localTileOffset[1] ) & (TILE_PER_LEVEL-1) );
461 for (
int x = 0 ;
x < TILE_PER_LEVEL ;
x++ ) {
462 for (
int y = 0 ;
y < TILE_PER_LEVEL ;
y++ ) {
488 static short ReadShort(
idFile *f ) {
493 return b[0] + ( b[1] << 8 );
513 byte *oldBlock = (
byte *)_alloca( tileSize );
514 byte *newBlock = (
byte *)_alloca( tileSize );
516 while ( width > 1 || height > 1 ) {
517 int newHeight = (height+1) >> 1;
518 if ( newHeight < 1 ) {
521 int newWidth = (width+1) >> 1;
525 common->
Printf(
"generating %i x %i block mip level\n", newWidth, newHeight );
529 for (
int y = 0 ;
y < newHeight ;
y++ ) {
533 for (
int x = 0 ;
x < newWidth ;
x++ ) {
535 for (
int yy = 0 ; yy < 2 ; yy++ ) {
536 for (
int xx = 0 ; xx< 2 ; xx++ ) {
540 if ( tx > width || ty > height ) {
542 memset( newBlock, 0,
sizeof( newBlock ) );
544 tileNum = tileOffset + ty * width + tx;
546 inFile->
Read( oldBlock, tileSize );
549 for (
int yyy = 0 ; yyy < TILE_SIZE / 2 ; yyy++ ) {
550 for (
int xxx = 0 ; xxx < TILE_SIZE / 2 ; xxx++ ) {
551 byte *
in = &oldBlock[ ( yyy * 2 * TILE_SIZE + xxx * 2 ) * 4 ];
552 byte *out = &newBlock[ ( ( ( TILE_SIZE/2 * yy ) + yyy ) * TILE_SIZE + ( TILE_SIZE/2 * xx ) + xxx ) * 4 ];
553 out[0] = ( in[0] + in[4] + in[0+TILE_SIZE*4] + in[4+TILE_SIZE*4] ) >> 2;
554 out[1] = ( in[1] + in[5] + in[1+TILE_SIZE*4] + in[5+TILE_SIZE*4] ) >> 2;
555 out[2] = ( in[2] + in[6] + in[2+TILE_SIZE*4] + in[6+TILE_SIZE*4] ) >> 2;
556 out[3] = ( in[3] + in[7] + in[3+TILE_SIZE*4] + in[7+TILE_SIZE*4] ) >> 2;
561 tileNum = tileOffset + width * height +
y * newWidth +
x;
563 outFile->
Write( newBlock, tileSize );
569 tileOffset += width *
height;
587 common->
Printf(
"idMegaTexture: failed to open %s\n", fileName );
591 idStr outName = fileName;
593 outName +=
"_preview.tga";
599 fileHandle->
Read( &header,
sizeof( header ) );
601 common->
Printf(
"idMegaTexture: bad header on %s\n", fileName );
609 int tileBytes = tileSize * tileSize * 4;
611 while ( width * tileSize > 2048 || height * tileSize > 2048 ) {
612 tileOffset += width *
height;
624 byte *oldBlock = (
byte *)_alloca( tileBytes );
626 for (
int x = 0 ;
x <
width ;
x++ ) {
627 int tileNum = tileOffset +
y * width +
x;
629 fileHandle->
Read( oldBlock, tileBytes );
631 for (
int yy = 0 ; yy < tileSize ; yy++ ) {
632 memcpy( pic + ( (
y * tileSize + yy ) * width * tileSize + x * tileSize ) * 4,
633 oldBlock + yy * tileSize * 4, tileSize * 4 );
638 R_WriteTGA( outName.
c_str(), pic, width * tileSize, height * tileSize, false );
654 int columns, rows, fileSize, numBytes;
659 if ( args.
Argc() != 2 ) {
660 common->
Printf(
"USAGE: makeMegaTexture <filebase>\n" );
664 idStr name_s =
"megaTextures/";
665 name_s += args.
Argv(1);
683 targa_header.
id_length = ReadByte( file );
690 targa_header.
x_origin = ReadShort( file );
691 targa_header.
y_origin = ReadShort( file );
692 targa_header.
width = ReadShort( file );
693 targa_header.
height = ReadShort( file );
698 common->
Error(
"LoadTGA( %s ): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name );
702 common->
Error(
"LoadTGA( %s ): colormaps not supported\n", name );
706 common->
Error(
"LoadTGA( %s ): Only 32 or 24 bit images supported (no colormaps)\n", name );
711 if ( numBytes > fileSize - 18 - targa_header.
id_length ) {
712 common->
Error(
"LoadTGA( %s ): incomplete file\n", name );
716 columns = targa_header.
width;
717 rows = targa_header.
height;
734 common->
Printf(
"Writing %i x %i size %i tiles to %s.\n",
740 out->
Write( &mtHeader,
sizeof( mtHeader ) );
747 int blockRowsRemaining = mtHeader.
tilesHigh;
748 while ( blockRowsRemaining-- ) {
749 common->
Printf(
"%i blockRowsRemaining\n", blockRowsRemaining );
754 for( row = 0 ; row < TILE_SIZE ; row++ ) {
755 pixbuf = targa_rgba + row*columns*4;
756 for( column = 0; column < columns; column++) {
760 blue = ReadByte( file );
770 blue = ReadByte( file );
771 green = ReadByte( file );
772 red = ReadByte( file );
779 blue = ReadByte( file );
780 green = ReadByte( file );
781 red = ReadByte( file );
782 alphabyte = ReadByte( file );
786 *pixbuf++ = alphabyte;
795 unsigned char red,
green,
blue,alphabyte,packetHeader,packetSize,
j;
802 for( row = 0 ; row < TILE_SIZE ; row++ ) {
803 pixbuf = targa_rgba + row*columns*4;
804 for( column = 0; column < columns; ) {
805 packetHeader= ReadByte( file );
806 packetSize = 1 + (packetHeader & 0x7f);
807 if ( packetHeader & 0x80 ) {
810 blue = ReadByte( file );
811 green = ReadByte( file );
812 red = ReadByte( file );
816 blue = ReadByte( file );
817 green = ReadByte( file );
818 red = ReadByte( file );
819 alphabyte = ReadByte( file );
826 for( j = 0; j < packetSize; j++ ) {
832 if ( column == columns ) {
833 common->
Error(
"TGA had RLE across columns, probably breaks block" );
841 pixbuf = targa_rgba + row*columns*4;
845 for( j = 0; j < packetSize; j++ ) {
848 blue = ReadByte( file );
849 green = ReadByte( file );
850 red = ReadByte( file );
857 blue = ReadByte( file );
858 green = ReadByte( file );
859 red = ReadByte( file );
860 alphabyte = ReadByte( file );
864 *pixbuf++ = alphabyte;
871 if ( column == columns ) {
879 pixbuf = targa_rgba + row*columns*4;
891 for (
int rowBlock = 0 ; rowBlock < mtHeader.
tilesWide ; rowBlock++ ) {
892 for (
int y = 0 ;
y < TILE_SIZE ;
y++ ) {
893 out->
Write( targa_rgba + (
y * targa_header.
width + rowBlock * TILE_SIZE ) * 4, TILE_SIZE * 4 );
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
void SetMappingForSurface(const srfTriangles_t *tri)
const srfTriangles_t * currentTriMapping
void GenerateImage(const byte *pic, int width, int height, textureFilter_t filter, bool allowDownSize, textureRepeat_t repeat, textureDepth_t depth)
float GetFloat(void) const
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
GLenum GLenum GLenum GLenum GLenum scale
struct _TargaHeader TargaHeader
void UpdateForCenter(float center[2])
megaTextureHeader_t header
idFileSystem * fileSystem
GLenum GLsizei GLenum GLenum const GLvoid * image
virtual const char * GetName(void)
idTextureLevel levels[MAX_LEVELS]
static void MakeMegaTexture_f(const idCmdArgs &args)
static idCVar r_megaTextureLevel
idStr & StripFileExtension(void)
void BindForViewOrigin(const idVec3 origin)
static void GenerateMegaMipMaps(megaTextureHeader_t *header, idFile *file)
static idCVar r_skipMegaTexture
GLsizei GLsizei GLenum GLenum const GLvoid * data
void SetViewOrigin(const idVec3 origin)
idImageManager * globalImages
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
virtual int Read(void *buffer, int len)
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical=false)
static idCVar r_showMegaTextureLabels
idImage * borderClampImage
idImage * ImageFromFunction(const char *name, void(*generatorFunction)(idImage *image))
virtual void UpdateScreen(bool outOfSequence=true)=0
virtual void Printf(const char *fmt,...) id_attribute((format(printf
virtual int Seek(long offset, fsOrigin_t origin)
GLenum GLsizei GLsizei height
static idCVar r_showMegaTexture
GLenum GLenum GLvoid * row
void UpdateTile(int localX, int localY, int globalX, int globalY)
float localViewToTextureCenter[2][4]
static idCVar r_terrainScale
void R_VerticalFlip(byte *data, int width, int height)
void * R_StaticAlloc(int bytes)
idTextureTile tileMap[TILE_PER_LEVEL][TILE_PER_LEVEL]
#define GL_VERTEX_PROGRAM_ARB
bool IsModified(void) const
virtual int Write(const void *buffer, int len)
PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB
const char * c_str(void) const
const char * Argv(int arg) const
bool InitFromMegaFile(const char *fileBase)
void GL_SelectTexture(int unit)
GLenum GLenum GLvoid GLvoid * column
void R_StaticFree(void *data)
int RoundDownToPowerOfTwo(int num)
virtual void Error(const char *fmt,...) id_attribute((format(printf
int sprintf(idStr &string, const char *fmt,...)
static void GenerateMegaPreview(const char *fileName)