Homebrew Textures block format

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
For a few days I have been trying to load textures into memory without luck

Looking into the code of 3dscraft I found a script named texconv.py which seems to do the job. I have translated that into C++ code and it seems to work, but there are a few issues:
- Textures are upside down
- Only square textures seems to be loaded properly

Could anyone explain how textures are supposed to be stored into memory?
Also just for curiosity I'd like to understand why the orders of pixels in the GPU is this weird...

Thanks!
 
  • Like
Reactions: Margen67

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,029
Country
United States
For a few days I have been trying to load textures into memory without luck

Looking into the code of 3dscraft I found a script named texconv.py which seems to do the job. I have translated that into C++ code and it seems to work, but there are a few issues:
- Textures are upside down
- Only square textures seems to be loaded properly

Could anyone explain how textures are supposed to be stored into memory?
Also just for curiosity I'd like to understand why the orders of pixels in the GPU is this weird...

Thanks!
the width and height appear to be reversed in libctru. That still leaves stuff upside down. I was wondering if that has something to do with the rotated frame buffer.
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
Thanks, that almost did the job... I am still having issues with some resolutions
Does anyone know why the 3ds uses this format? I imagine it adds some kind of optimization but cannot image what...
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,029
Country
United States
Thanks, that almost did the job... I am still having issues with some resolutions
Does anyone know why the 3ds uses this format? I imagine it adds some kind of optimization but cannot image what...
The dimensions need to be powers of two. I have not had issues within those constraints. If you are referring to the block format I think I saw something somewhere about increasing cache hits when reading the texture.
 

themperror

Well-Known Member
Member
Joined
Aug 12, 2009
Messages
181
Trophies
0
XP
367
Country
Netherlands
For a few days I have been trying to load textures into memory without luck

Looking into the code of 3dscraft I found a script named texconv.py which seems to do the job. I have translated that into C++ code and it seems to work, but there are a few issues:
- Textures are upside down
- Only square textures seems to be loaded properly

Could anyone explain how textures are supposed to be stored into memory?
Also just for curiosity I'd like to understand why the orders of pixels in the GPU is this weird...

Thanks!


Textures should always be a power of 2 in any dimension, 8x8, 16x16,32x32,64x64,128x128, 256x256, 512x512 (higher probably won't be needed on the 3ds (also considering speed)), in OpenGL and DirectX they CAN be rectangular, in the old days they had to be square though.. so 512x256 was allowed, But I don't know if it's allowed on the 3ds.

Textures are normally loaded in VRAM, in case of CPU rendering it's just a block of linear memory. so an array with all pixels in there will suffice.
 

neobrain

-
Member
Joined
Apr 25, 2014
Messages
306
Trophies
0
XP
730
Country
Textures are stored upside-down in memory indeed, i.e. the v=1 coordinate corresponds to the first data row in memory at the texture source address, whereas the v=0 coordinate corresponds to the last row in memory.

The same applies to framebuffers, fyi.
 

minexew

ayy lmao
Member
Joined
Mar 16, 2013
Messages
228
Trophies
0
XP
284
Country
Does anyone know why the 3ds uses this format? I imagine it adds some kind of optimization but cannot image what...

It's called the "native PICA format" and it either significantly simplifies the hardware design or helps a lot with cache utilization and thus performance (2nd possibility seems more likely IMO because the PICA uses some kind of block-based rendering).
Can't think of any other reason why they would use it.
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,029
Country
United States
Textures should always be a power of 2 in any dimension, 8x8, 16x16,32x32,64x64,128x128, 256x256, 512x512 (higher probably won't be needed on the 3ds (also considering speed)), in OpenGL and DirectX they CAN be rectangular, in the old days they had to be square though.. so 512x256 was allowed, But I don't know if it's allowed on the 3ds.

Textures are normally loaded in VRAM, in case of CPU rendering it's just a block of linear memory. so an array with all pixels in there will suffice.
Rectangle textures are allowed. My experience has been that GPU_SetTexture has the width and the height reversed.
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
Sorry I am still having problems with this... I can load square textures and rectangle textures but only if theis high is bigger then their width. When the width is bigger (64x32 for example) it doesn't look ok

Could anyone post the C++ code? That would be very helpful
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,029
Country
United States
I am sure this could be optimized but it take an 8 bit source and converts it to 16 bit. But it does show the proper tile ordering. It also flips the texture vertically. There is also a fair bit of dead code in there. Primarily for cross compiling for windows. I can confirm that it works with wide and narrow textures. There is a scale call but it just ensures power of 2 dimensions.

https://github.com/elhobbs/spectre3ds/blob/master/source/sys_textures.cpp#L329
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
I have been taking a look, but still the same problem. It doesn't seem to work with textures that are 32x64 or 64x32
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
Yes, I know... I was already swapping the width and height when calling GPU_SetTexture. The weird thing is that I also need to do it when calling parseTileTrans16 which is not what you had there
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,029
Country
United States
Yes, I know... I was already swapping the width and height when calling GPU_SetTexture. The weird thing is that I also need to do it when calling parseTileTrans16 which is not what you had there
That is bizarre. I do not do that and it works fine for me. I am curious. Do you have any code that I could look at to see how you are using this?
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
No, yeah... you were right... after cleaning my code a bit it turned out I was swapping width and height on a previous call and so I had to swap again
Now everything makes sense

Thanks a lot for your help elhobbs. Now I can continue working on this :)
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,496
Country
Sorry, I forgot to post the final code for this for anyone who can need it
Code:
void ReorderImageData(u8* src, u8* palette, u8* dst, int width, int height, void(copyFunc)(u8*, u8*, int, u8*, int))
{
    static int tile_order[] = {
         0,  1,  8,  9,  2,  3, 10, 11,
        16, 17, 24, 25, 18, 19, 26, 27,
         4,  5, 12, 13,  6,  7, 14, 15,
        20, 21, 28, 29, 22, 23, 30, 31,

        32, 33, 40, 41, 34, 35, 42, 43,
        48, 49, 56, 57, 50, 51, 58, 59,
        36, 37, 44, 45, 38, 39, 46, 47,
        52, 53, 60, 61, 54, 55, 62, 63
    };


    int idx = 0;
    int i, j;
    for(int y = 0; y < height; y += 8)
    {
        for(int x = 0; x < width; x += 8)
        {
            for(int k = 0; k < 64; ++ k)
            {
                i = (tile_order[k] % 8);
                j = (tile_order[k] - i) / 8;

                int src_idx = (height - (y + j) - 1) * width + (x + i);

                copyFunc(src, palette, src_idx, dst, idx);
       
                idx ++;
            }
        }
    }
}

where copyFunc is a pointer to a function similiar to these
Code:
void copyRGB(u8* src, u8* palette, int src_idx, u8* dst, int dst_idx)
{
    dst[dst_idx * 3 + 0] = src[src_idx * 3 + 2];
    dst[dst_idx * 3 + 1] = src[src_idx * 3 + 1];
    dst[dst_idx * 3 + 2] = src[src_idx * 3 + 0];
}

void copyRGBA(u8* src, u8* palette, int src_idx, u8* dst, int dst_idx)
{
    dst[dst_idx * 4 + 0] = src[src_idx * 4 + 3];
    dst[dst_idx * 4 + 1] = src[src_idx * 4 + 2];
    dst[dst_idx * 4 + 2] = src[src_idx * 4 + 1];
    dst[dst_idx * 4 + 3] = src[src_idx * 4 + 0];
}
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • SylverReZ @ SylverReZ:
    Loooooool :rofl2:
  • SylverReZ @ SylverReZ:
    So true
  • BigOnYa @ BigOnYa:
    @K3Nv2 Snow Day is pretty fun. My only bitch would be the camera controls, when you move around, say down, you have to move the right stick left or right to get camera to turn and get your view, other than that I like it so far.
  • K3Nv2 @ K3Nv2:
    From what people say pvp isn't even worth it
  • BigOnYa @ BigOnYa:
    I just been playing offline, and they give you a few bots here n there on your team to help battle. I don't think it's as funny as the other games tho, more battle oriented than humor, which kinda sucks, but I'm still early in it
  • Xdqwerty @ Xdqwerty:
    @BigOnYa, doesnt the game have a campaign mode?
  • BigOnYa @ BigOnYa:
    Yea, and co-op, but you can also start a pvp session and battle just with friends. You get special skill cards (powers) the more you play. And higher value cards, but you can only enable so many cards at a time.
  • K3Nv2 @ K3Nv2:
    If you can find enough for it
  • BigOnYa @ BigOnYa:
    Toilet paper is considered the money, you collect and buy stuff with TP, kinda funny. Graphics are def better than the other games tho, I think they used Unity 5 engine.
  • Psionic Roshambo @ Psionic Roshambo:
    Look if I zoom in enough I can see the herpes!!!
    +1
  • BigOnYa @ BigOnYa:
    In fact I'm gonna go make a drink, roll a fatty n play some, good night to all!
    +2
  • Xdqwerty @ Xdqwerty:
    I bet most people at the time still watched it in black and white
  • SylverReZ @ SylverReZ:
    @Xdqwerty, Many of them did before colour television was common.
  • SylverReZ @ SylverReZ:
    Likely because black and white TV was in-expensive.
    +1
  • K3Nv2 @ K3Nv2:
    It certainly wasn't inexpensive it cost the same as a new car back then
  • K3Nv2 @ K3Nv2:
    How much did a 1965 color TV cost?

    For example, a 21-inch (diagonal) GE color television in 1965 had an advertised price of $499, which is equal to $4,724 in today's dollars, according to the federal government's inflation calculator.
  • Xdqwerty @ Xdqwerty:
    @K3Nv2, take into consideration how economy was back then
  • K3Nv2 @ K3Nv2:
    Yeah that's why they listed inflation rates
  • Xdqwerty @ Xdqwerty:
    Sorry didnt read that part
  • BakerMan @ BakerMan:
    @LeoTCK don't worry i knew he was joking
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    My first color TV was like 1984 or something lol
    Psionic Roshambo @ Psionic Roshambo: My first color TV was like 1984 or something lol