Wierd nitroEngine texture glitch.

Discussion in 'NDS - Emulation and Homebrew' started by FuzzyQuills, Jul 24, 2014.

  1. FuzzyQuills
    OP

    FuzzyQuills Advanced Member

    Newcomer
    51
    4
    Aug 28, 2013
    Hi guys!

    I am a new member (well, I joined in 2012 or 2013, but I totally forgot i did!) and basically, I need help trying to iron out a texturing glitch in a nitroEngine-powered game. My problem is how the textures are mapped to the model in the DS ROM.

    Here is what it looks like in Blender (using an MD2 viewer shows this as well) :
    https://drive.google.com/file/d/0B2tqYgzg1_lWZkxkOEp0MFRiNE0/edit?usp=sharing

    But, when I export to NDS display list, and then load it in NitroEngine, this is what happens:
    https://drive.google.com/file/d/0B2tqYgzg1_lWQUY2aEhtTlpPeEE/edit?usp=sharing

    Any ideas? the only thing I can think of, among the many problems it could be, is that the mesh exported quads instead... but would that affect texturing? By looking closely, you will notice that the textures look right in some places, but in others, they are squished into one corner.
     
  2. ethanpet113

    ethanpet113 Member

    Newcomer
    12
    0
    Sep 13, 2009
    Canada
    Looks like your UV coordinates overflow remember you have to send them in
    t16 12.4 fixed point , so if your float values are too big to fit in a short they'll wrap around.
     
  3. FuzzyQuills
    OP

    FuzzyQuills Advanced Member

    Newcomer
    51
    4
    Aug 28, 2013
    Overflow? I looked at the link, it seems to only apply to if you hard-code the 3D yourself. I use Nitroengine.

    If I'm wrong, then some help on this would be great! it is one of the only things stopping me. BTW, would having faces stacked on top of each other in the UV map do it?

    EDIT: Actually, a guide on how to reduce to 12.4 fixed point in blender would be nice. could also be the MD2 converter... ;)

    EDIT2: anywhere in blender to convert to 12.4 coordinate space? I can't find it... :(

    EDIT3: Ok... oddly, the NDS model exporter works fine. must be the MD2 converter... ;) Any way of building an NEA file from an X file?

    BTW, every time I convert an MD2 model, it always says: "invalid texture size. converting anyway..." could this be the problem?
     
  4. FuzzyQuills
    OP

    FuzzyQuills Advanced Member

    Newcomer
    51
    4
    Aug 28, 2013
    Would "snap pixels" in blender help solve the problem? i am thinking this might fix it, as my UV's could be using 30-digit floats... ;)
     
  5. ethanpet113

    ethanpet113 Member

    Newcomer
    12
    0
    Sep 13, 2009
    Canada
    Textures must be power's of 2 according to the 3D API, so insure that your input textures are 2^n x 2^n in size.
    In your favourite image processing tool(gimp or photoshop), expand the canvas so that the image dimensions are square, then shrink the image to your preferred resolution (max 2049x2049, though you should keep them small due to memory limitations). You will need to squish you UV coordinates to accommodate the now rectangular aspect ratio of your texture.

    To make best use of your texture memory you should atlas non-repeating textures,http://www.gamasutra.com/view/feature/130940/practical_texture_atlases.php?print=1

    While I'm thinking on it, the problem may be that your UV extents exceed the texture, which causes the rendering to appear as wrapped in 3D tools, textures may be wrapped or clamped. Make sure your code wraps U and V.
     
  6. ethanpet113

    ethanpet113 Member

    Newcomer
    12
    0
    Sep 13, 2009
    Canada
    I also wrote a little test program for the conversion, if your UV values are in the range listed at the bottom, you're fine, ideally the should be close to the <1.0, 1.0> range that is 0<x<(1<<4).

    Note that fractional information can only be such that x ± .16, so that doesn't give you a lot of freedom before wrapping.

    Code:
    float fixedToFloat(int fi, int n, int precisionShift)
    {
        float f = fi;
        f/= precisionShift;
        f /= 1<<n;
        return f;
    }
    /**
    Convert a floating point number to a fixed point number
     
    @param f the floating point number
    @param n The n value for the floating point number(fixed point is of the form m.n)
    @param precisionShift This value must be the same for all your fixed point calls, it allows you
    to use more fractional more decimal points.  It should be a power of 10 e.g. 1000 would mean
    accurate up to the thousandths place.
    */
    int32_t floatToFixed32(float f, int n, int precisionShift)
    {
    int64_t i= round(f*precisionShift*(1<<n));
     
            if(i >INT32_MAX || i<INT32_MIN)
            {
                errno = EOVERFLOW;
                perror("fixedPointOverflow");
            }
     
        return (int32_t)i;
    }
     
    int16_t floatToFixed16(float f, int n, int precisionShift)
    {
    int32_t i= round(f*precisionShift*(1<<n));
        if(i > INT16_MAX || i < INT16_MIN)
        {
            errno = EOVERFLOW;
            perror("fixedPointOverflow");
            fflush(stderr);
        }
     
        return i;
    }
     
    ///False  means fidelity loss
    bool checkFidelity(float orig, int fixed, int n, int precisionShift)
    {
        return orig == fixedToFloat(fixed, n, precisionShift);
    }
    === n=4 precision=1 ===

    1000 => 16000
    16000 => 1000

    Fidelity loss
    204.79 => 3277
    3277 => 204.812

    Fidelity loss
    204.8 => 3277
    3277 => 204.812

    10 => 160
    160 => 10

    5 => 80
    80 => 5

    2 => 32
    32 => 2

    1 => 16
    16 => 1

    -1 => -16
    -16 => -1

    -2 => -32
    -32 => -2

    1.5 => 24
    24 => 1.5

    1.25 => 20
    20 => 1.25

    Fidelity loss
    1.333 => 21
    21 => 1.3125

    Fidelity loss
    10.1111 => 162
    162 => 10.125

    Fidelity loss
    100.111 => 1602
    1602 => 100.125

    Fidelity loss
    1000.11 => 16002
    16002 => 1000.12

    fixedPointOverflow: Value too large to be stored in data type
    Fidelity loss
    10000.1 => 28930
    28930 => 1808.12


    Fixed 12.4.1 MAX 2047.9
    Fixed 12.4.1 MIN -2048.0

    -------------------------------------------------------------------------------
    http://problemkaputt.de/gbatek.htm#ds3dtextureattributes

    DS 3D Texture Attributes

    4000488h - Cmd 22h - TEXCOORD - Set Texture Coordinates (W)
    Specifies the texture source coordinates within the texture bitmap which are to be associated with the next vertex.

    Parameter 1, Bit 0-15 S-Coordinate (X-Coordinate in Texture Source)
    Parameter 1, Bit 16-31 T-Coordinate (Y-Coordinate in Texture Source)
    Both values are 1bit sign + 11bit integer + 4bit fractional part.
    A value of 1.0 (=1 SHL 4) equals to one Texel.

    With Position 0.0 , 0.0 drawing starts from upperleft of the Texture.
    With positive offsets, drawing origin starts more "within" the texture.
    With negative offsets, drawing starts "before" the texture.
    "When texture mapping, the Geometry Engine works faster if you issue commands in the order TexCoord -> Normal -> Vertex."

    40004A8h - Cmd 2Ah - TEXIMAGE_PARAM - Set Texture Parameters (W)

    0-15 Texture VRAM Offset div 8 (0..FFFFh -> 512K RAM in Slot 0,1,2,3)
    (VRAM must be allocated as Texture data, see Memory Control chapter)
    16 Repeat in S Direction (0=Clamp Texture, 1=Repeat Texture)
    17 Repeat in T Direction (0=Clamp Texture, 1=Repeat Texture)
    18 Flip in S Direction (0=No, 1=Flip each 2nd Texture) (requires Repeat)
    19 Flip in T Direction (0=No, 1=Flip each 2nd Texture) (requires Repeat)
    20-22 Texture S-Size (for N=0..7: Size=(8 SHL N); ie. 8..1024 texels)
    23-25 Texture T-Size (for N=0..7: Size=(8 SHL N); ie. 8..1024 texels)
    26-28 Texture Format (0..7, see below)
    29 Color 0 of 4/16/256-Color Palettes (0=Displayed, 1=Made Transparent)
    30-31 Texture Coordinates Transformation Mode (0..3, see below)

     
  7. FuzzyQuills
    OP

    FuzzyQuills Advanced Member

    Newcomer
    51
    4
    Aug 28, 2013
    So where do I put this test program? is it a console app?

    BTW, I found that using NDS_model_exporter instead worked fine, yet using MD2_2_bin does the glitch. could the tool have something wrong? it does come with source, so if you can fix it for me, that would be great! :)

    Of course it could also be blender's MD2 exporter (probably exporting direct floats instead of shorts... :P)

    and in case you forgot, (or actually didn't know in the first place) I am using NitroEngine, a 3D api for DS that aims to make 3D easier to do. and except for this annoying glitch, (means animated models are messed up... :() it works really smoothly! :)