2048x2048 texture limit
Moderators: MR.D, Moderators
2048x2048 texture limit
When Spring compiles the textures for the units it places them all on a single 2048x2048 "plane" of a single bitmap.
If they won't fit, you'll receive an error.
I created a small program to resize the images being used to something that could be "compressed" better in that fashion. Worked well, I know have 2700 textures loaded. Some are 8x8, some are 64x64...
If someone used all 64x64 textures in their unit pack, Spring would only be able to use 1024 textures total. Even less when you take into account team colors, etc.
Creating texture packs in powers of 2 would maximize the number you can use. This is what I accomplished by resizing the textures from some odd 127x99 to something placeable in a generic 2^x scale.
</randomthoughts>
-Buggi
If they won't fit, you'll receive an error.
I created a small program to resize the images being used to something that could be "compressed" better in that fashion. Worked well, I know have 2700 textures loaded. Some are 8x8, some are 64x64...
If someone used all 64x64 textures in their unit pack, Spring would only be able to use 1024 textures total. Even less when you take into account team colors, etc.
Creating texture packs in powers of 2 would maximize the number you can use. This is what I accomplished by resizing the textures from some odd 127x99 to something placeable in a generic 2^x scale.
</randomthoughts>
-Buggi
Do you acctlly understand how it puts them into the bmp?
Only i was thinking... Does it use its space wizely?
You see, it may be putting the textures in in the order it reads them, witch means it would be leaving big gaps between small and large images, and thered be lots of wasted space.
Or does it actully just write down the raw byte data in a long line that gives you a 2048x2048 equivilent image in the end (which would not waste any space)
If it does it something like the first way, then it would be better overall if all the textures were resized to, say 32x32. That would give you room for 4096 textures...
Of course this would mean youd lose detail on the 64 x 64 textures... so maybe it needs to resize everything to both and then when its writeing its texture file, it can do all the 32 ones first and then all the 64 ones... thus minimizing the space wasted.
If thats unclear... dam. Ill have to rexplane
aGorm
Only i was thinking... Does it use its space wizely?
You see, it may be putting the textures in in the order it reads them, witch means it would be leaving big gaps between small and large images, and thered be lots of wasted space.
Or does it actully just write down the raw byte data in a long line that gives you a 2048x2048 equivilent image in the end (which would not waste any space)
If it does it something like the first way, then it would be better overall if all the textures were resized to, say 32x32. That would give you room for 4096 textures...
Of course this would mean youd lose detail on the 64 x 64 textures... so maybe it needs to resize everything to both and then when its writeing its texture file, it can do all the 32 ones first and then all the 64 ones... thus minimizing the space wasted.
If thats unclear... dam. Ill have to rexplane
aGorm
actually the algorithm is quite brilliant, it writes images of like-heights. So if there is a slew of 32x32 images, it writes them all on one "line" saving a vast amount of space. However if there is an odd height texture, say 125 high, that wouldn't be placed in the 64 high strip and the 128 high images can't go in that strip so lots of space is waisted.
The WORST files that are guilty of this are tank "wheel" side shots. such odd sizes. The next version of the my resizer I'm going to specificy the size something should be resized to rather than just reducing it by half.
-Buggi
The WORST files that are guilty of this are tank "wheel" side shots. such odd sizes. The next version of the my resizer I'm going to specificy the size something should be resized to rather than just reducing it by half.
-Buggi
YES!!!
Or just all normalized. You can have odd shaped textures, just make sure they fit into a "category" of textures.
"Category 1" - 8x8, 16x16 24x24, 32x32, 48x48, 64x64. (Square) And 64 should really be the max size (width or depth) any one texture needs to be...
"Category 2" - 8x16, 24x16, 32x16, 48x16, 64x16... (Rectangular, same height)
Every texture should fit into one of those categories. Then you'd have almost no wasted space on the single texture plane and maximize the number of textures you have to choose from.
And with MiniSpring becoming so popular, there is even less need for uber high sized textures. A 32x32 stunning texture is far more beneficial than a 64x64 crappy one. When the game strinks/stretches them, high quality will win over when the user sees it.
*edit*
Be careful when messing with the limits of the texture allotment. I experienced crashes with my full set of textures. Once I reduced the number of textures, the crashes stopped.
This, of course, is a problem, but something to watch out for until a resolution can be found.
*/edit*
-Buggi
Or just all normalized. You can have odd shaped textures, just make sure they fit into a "category" of textures.
"Category 1" - 8x8, 16x16 24x24, 32x32, 48x48, 64x64. (Square) And 64 should really be the max size (width or depth) any one texture needs to be...
"Category 2" - 8x16, 24x16, 32x16, 48x16, 64x16... (Rectangular, same height)
Every texture should fit into one of those categories. Then you'd have almost no wasted space on the single texture plane and maximize the number of textures you have to choose from.
And with MiniSpring becoming so popular, there is even less need for uber high sized textures. A 32x32 stunning texture is far more beneficial than a 64x64 crappy one. When the game strinks/stretches them, high quality will win over when the user sees it.
*edit*
Be careful when messing with the limits of the texture allotment. I experienced crashes with my full set of textures. Once I reduced the number of textures, the crashes stopped.
This, of course, is a problem, but something to watch out for until a resolution can be found.
*/edit*
-Buggi
- RightField
- Posts: 110
- Joined: 11 Nov 2004, 21:29
- RightField
- Posts: 110
- Joined: 11 Nov 2004, 21:29
Half-Life is a FPS. FPS doesn't even come close to using as many animated characters on the screen at once. Ever fought against 200 aliens at once hmmm?
RTSes are different and do not require that big detail per unit. Check Warcraft 3 or Dawn of War for examples. You'll see they don't have THAT big texture maps.
RTSes are different and do not require that big detail per unit. Check Warcraft 3 or Dawn of War for examples. You'll see they don't have THAT big texture maps.
It seems there no link to the utility in here. :-\
http://www.epicedit.com/ImageResizer.zip
There it is :)
-Buggi
http://www.epicedit.com/ImageResizer.zip
There it is :)
-Buggi
hm but at least textures like 64-128px.. thats not very big compared to the REALY big textures in FPS like hlRightField wrote:Half-Life is a FPS. FPS doesn't even come close to using as many animated characters on the screen at once. Ever fought against 200 aliens at once hmmm?
RTSes are different and do not require that big detail per unit. Check Warcraft 3 or Dawn of War for examples. You'll see they don't have THAT big texture maps.
Springs code that places all the textures on the 2048x2048 super-texture could be made more efficient. The current code sorts all textures by height (biggest first) and fills up the super-texture in horizontal scanlines. If a texture gets smaller partway down a scanline, that space is wasted. As most textures are powers of 2 in height, this results in half the height wasted for the remainder of that scanline.
If instead you work in both horizontal scanlines across the whole width of the texture and then in vertical scanlines down the height of the first texture of that scanline, you wouldn't waste so much space. Indeed you can take it a step further so that when you work down a vertical scanline, you measure its starting width and ensure that textures are again spaced horizontally to fill that sub-scanline. The only space wasted would be where textures were not sized 2^n, or there was a gap at the end of a scanline.
Here's my implementation of this, first the compare function has to be modified to sort correctly:
Secondly a section of the CTextureHandler constructor has to be modified:
I think that should work...
If instead you work in both horizontal scanlines across the whole width of the texture and then in vertical scanlines down the height of the first texture of that scanline, you wouldn't waste so much space. Indeed you can take it a step further so that when you work down a vertical scanline, you measure its starting width and ensure that textures are again spaced horizontally to fill that sub-scanline. The only space wasted would be where textures were not sized 2^n, or there was a gap at the end of a scanline.
Here's my implementation of this, first the compare function has to be modified to sort correctly:
Code: Select all
static int CompareTatex2( const void *arg1, const void *arg2 ){
if((*(TexFile**)arg1)->tex.ysize > (*(TexFile**)arg2)->tex.ysize ||
(*(TexFile**)arg1)->tex.ysize == (*(TexFile**)arg2)->tex.ysize &&
(*(TexFile**)arg1)->tex.xsize > (*(TexFile**)arg2)->tex.xsize)
return -1;
return 1;
}
Code: Select all
CTextureHandler::CTextureHandler()
...
int currentOffsetY=0;
int currentOffsetX=0;
int scanLineOffsetY=0;
int scanLineOffsetX=0;
int scanLineHeight=0;
int subScanLineWidth=bigTexX;
int subScanLineHeight = 0;
for(int a=0;a<numfiles;++a){
CBitmap* curtex=&texfiles[a]->tex;
// reset horizontal sub-scanline when width exceeded
if( currentOffsetX + curtex->xsize > subScanLineWidth )
{
currentOffsetX = 0;
currentOffsetY += subScanLineHeight;
subScanLineHeight = curtex->ysize;
}
// reset vertical sub-scanline when height or maximum width exceeded
if( curtex->xsize > subScanLineWidth ||
currentOffsetY + curtex->ysize > scanLineHeight )
{
scanLineOffsetX += subScanLineWidth;
subScanLineWidth = curtex->xsize;
subScanLineHeight = curtex->ysize;
currentOffsetY = 0;
}
// reset horizontal scanline when image width exceeded
if( scanLineOffsetX + subScanLineWidth > bigTexX )
{
scanLineOffsetX = 0;
scanLineOffsetY += scanLineHeight;
scanLineHeight = curtex->ysize;
}
// break when no more space left
if( scanLineOffsetY + scanLineHeight > bigTexY )
{
MessageBox(0,"To many/large unit textures","Error",0);
break;
}
for(int y=0;y<curtex->ysize;y++){
for(int x=0;x<curtex->xsize;x++){
// if(curtex->mem[(y*curtex->xsize+x)*4]==254 && curtex->mem[(y*curtex->xsize+x)*4+1]==0 && curtex->mem[(y*curtex->xsize+x)*4+2]==254){
// tex[((currentOffsetY+y)*bigTexX+(currentOffsetX+x))*4+3]=0;
// } else {
for(int col=0;col<4;col++){
tex[((currentOffsetY+y)*bigTexX+(currentOffsetX+x))*4+col]=curtex->mem[(y*curtex->xsize+x)*4+col];
// }
}
}
}
UnitTexture* unittex=new UnitTexture;
unittex->xstart=(currentOffsetX+0.5f)/(float)bigTexX;
unittex->ystart=(currentOffsetY+0.5f)/(float)bigTexY;
unittex->xend=(currentOffsetX+curtex->xsize-0.5f)/(float)bigTexX;
unittex->yend=(currentOffsetY+curtex->ysize-0.5f)/(float)bigTexY;
textures[texfiles[a]->name]=unittex;
currentOffsetX+=curtex->xsize;
delete texfiles[a];
}
...
}
- RightField
- Posts: 110
- Joined: 11 Nov 2004, 21:29
The first thing you've got to remember is that the animation for every object in a model can be turned on/off by the unit's script (by caching). This is what adds the greatest complexity to animation. It would be "relatively" simple to just animate all textures on all models in sync by one of the following:
1) For all animated textures update all the vertexes u-v coordinates of every model to point to a different region of the super-texture every 0.3 seconds. You would have to do something clever by distinguishing animated from non-animated vertexes.
2) For all animated textures have 1 additional frame allocated on the super-textures, point all u-v coordinates to it permanently and just paste the section of animated texture over this frame buffer every 0.3 seconds.
3) For all different animation durations have an additional set of smaller super-textures, so that for the animated textures you can switch the texture being painted every 0.3 seconds. This would probably be slow because you're changing the current textures frequently for each animation length, hence this is my number 3 idea.
Trying to add caching on/off would require one of the above, in addition to which, for every object that is turned off on a unit, you would have to render a separate pass that points to a non animated model/texture.
I don't want to think about how you would go about actually implementing this in Spring. Really though it should be an extension of the team colour system. I can attest to (1) working as I've managed my own implementation of this elsewhere, but not been tested for hundreds of models.
My 2p...
1) For all animated textures update all the vertexes u-v coordinates of every model to point to a different region of the super-texture every 0.3 seconds. You would have to do something clever by distinguishing animated from non-animated vertexes.
2) For all animated textures have 1 additional frame allocated on the super-textures, point all u-v coordinates to it permanently and just paste the section of animated texture over this frame buffer every 0.3 seconds.
3) For all different animation durations have an additional set of smaller super-textures, so that for the animated textures you can switch the texture being painted every 0.3 seconds. This would probably be slow because you're changing the current textures frequently for each animation length, hence this is my number 3 idea.
Trying to add caching on/off would require one of the above, in addition to which, for every object that is turned off on a unit, you would have to render a separate pass that points to a non animated model/texture.
I don't want to think about how you would go about actually implementing this in Spring. Really though it should be an extension of the team colour system. I can attest to (1) working as I've managed my own implementation of this elsewhere, but not been tested for hundreds of models.
My 2p...
- RightField
- Posts: 110
- Joined: 11 Nov 2004, 21:29