Author Topic: 3D Textured Mesh Sample  (Read 557 times)

SkimmingSanshiro

  • Newbie
  • *
  • Posts: 21
  • Karma: +3/-0
    • View Profile
3D Textured Mesh Sample
« on: March 15, 2018, 06:39:05 pm »
Ive really been struggling trying to figure out how to get a textured 3D mesh running in Jo. Ive been following http://www.rockin-b.de/saturn/saturngametutorial/SaturnGameTutorial.htm#spanTexture to make a SG3 and SGT Texture table. Then http://www.rockin-b.de/saturn/saturngametutorial/SaturnGameTutorial.htm#usePolygons to use textured Polygons. But how do I implement this in Jo? Be nice to have a sample with 1 multi textured 3D mesh to take a look at how its called and the files it uses. 

XL2

  • Sr. Member
  • ****
  • Posts: 341
  • Karma: +72/-1
    • View Profile
Re: 3D Textured Mesh Sample
« Reply #1 on: March 16, 2018, 01:04:06 am »
I'm (slowly) working on a tool to do just that.
I'm not fully done yet, so maybe in 2 or 3 weeks I could try to release it with a small demo.
It just converts the model and textures to either c file or a binary file and you will just need to use the demo functions with it to load the model.
Sadly, I couldn't think of a way to include animations (I'm not that great with 3D modeling software, so even there I'm bad at animating).

SkimmingSanshiro

  • Newbie
  • *
  • Posts: 21
  • Karma: +3/-0
    • View Profile
Re: 3D Textured Mesh Sample
« Reply #2 on: March 20, 2018, 07:52:47 pm »
Sounds awesome thanks for your work. So should I make a texture table with that tutorial? Or will you program make a table from the texture from the .obj? Sounds to good to be true)

XL2

  • Sr. Member
  • ****
  • Posts: 341
  • Karma: +72/-1
    • View Profile
Re: 3D Textured Mesh Sample
« Reply #3 on: March 21, 2018, 03:30:10 pm »
It will do it all for you, as long as your model has material names that fit the TGA file's name. All textures should be 32 bits per pixel BUT should have no more than 16 colors (if not the program will compress the colors and you will loose details ).
I'm not supporting 32 bpp textures anymore as it just wastes VRAM.
It won't read the mtl file, so I will have to figure a way to support flat shaded quads, but I guess the easy way would be to use a 1x1 texture and I could just retrieve the color and put it on the quad.
We'll see.

XL2

  • Sr. Member
  • ****
  • Posts: 341
  • Karma: +72/-1
    • View Profile
Re: 3D Textured Mesh Sample
« Reply #4 on: April 16, 2018, 10:50:24 pm »
No demo yet, so make sure you follow the explanations (text I posted earlier today at Segaxtreme) :

I got the model converter I promised you working at pretty much 70-80%, but I didn't have time to test it nor write a demo.
It seems to be ok, but since I didn't test it, I can't guarantee it.
IT'S ALSO REALLY QUICKLY CODED! I made it in like 2 hours and only did small tests, so it might not work properly.

I'm sharing it with you now, but I guess without a demo it might be a bit hard to use.
The file starts with a header portion of 36 bytes, then writes the texture data, then the polygon data.
I added the header and the code to know how I write to the binary file so that you know what to load.
You can use the image converter I posted elsewhere to know how to load the paletted textures.
The program also outputs a text file including all the PDATA, but no textures, so you can also play with that.
Please note that it only supports textures, so if you want to load a flat shaded polygon, you can use something such as a 8x1 texture with 1 color. I guess it would be a bit slower than using a real flat shaded quad, but I don't think I will have time to modify my code to allow it for now.

Code: [Select]
//HEADER
typedef struct
{
    unsigned short  TOTAL_MESH; //total amount of PDATA
    short            TOT_TEXT;  //total amount of textures
    unsigned int    TEXT_SIZE;  //to quickly load from disk, that's the size of the textures in bytes
    unsigned int    PDATA_SIZE; //to quickly load from disk, total size of pdata in bytes
    vector3 Origin; //Origin point used to "center" the culling/collision data and your model's position. Should be 0,0,0 unless you have an offset
    vector3 Length;  //Lenght along the x,y z axis. Together with the origin, that gives you the bounding box for quick broad collision testing
} _MOD_DATA;

//TEXTURE DATA
unsigned short convert_to_4bpp(unsigned short a, unsigned short b){    return (((a&0xffff)<<4) | (b));}

void WRITES_TEXTURES(ofstream * binFile)
{
    cout << "Writing the textures to binary file...\n\n";
    unsigned short buf16;

    for (short i=0; i<MODEL_DATA.TOT_TEXT; i++)
    {
        unsigned short w = swap_endian_ushort(pimg[i].width);  //pimg == paletted image
        unsigned short h = swap_endian_ushort(pimg[i].height);
        binFile->write((char*)&w, sizeof(unsigned short));
        binFile->write((char*)&h, sizeof(unsigned short));
        binFile->write((char*)&MODEL_DATA.TEXT_SIZE, sizeof(int));

        for (short ii=0; ii< (pimg[i].width * pimg[i].height);)
        {
            unsigned char buf = 0;
            buf =  (unsigned char) convert_to_4bpp(pimg[i].palette_id[ii], pimg[i].palette_id[ii+1]);
            binFile->write((char*)&buf, sizeof(unsigned char));
            ii+=2;
        }

    }
    for (short i=0; i<MODEL_DATA.TOT_TEXT; i++)
    {
        for (unsigned int ii=0; ii<16; ii++)
        {
           buf16 = swap_endian_ushort(pimg[i].palette[ii]);
           binFile->write((char*)(&buf16), sizeof(unsigned short));
        }
    }
}


//PDATA
/*****
This writes all the PDATA in a sequential order
*****/
void WRITE_PDATA(ofstream * file)
{
    unsigned short bUint16;
    unsigned int bUint32;
    int bSint32;

    for (unsigned int i=0; i<MODEL_DATA.TOTAL_MESH; i++)
    {
        //PDATA, including buffers for the pointers
        bUint32 = 0;
            file->write((char*)&bUint32, sizeof(unsigned int));
        bUint32 = swap_endian_uint(mesh_array[i].nbPoint);
            file->write((char*)&bUint32, sizeof(unsigned int));
        bUint32 = 0;
            file->write((char*)&bUint32, sizeof(unsigned int));
        bUint32 = swap_endian_uint(mesh_array[i].nbPolygon);
            file->write((char*)&bUint32, sizeof(unsigned int));
        bUint32 = 0;
            file->write((char*)&bUint32, sizeof(unsigned int));

        //POINT (vertices), 12 bytes each
        for (unsigned int ii=0; ii<mesh_array[i].nbPoint; ii++)
        {
            for (unsigned int j=0; j<3; j++)
            {
                bSint32 = swap_endian_sint(mesh_array[i].pntbl[ii][j]);
                file->write((char*)&bSint32, sizeof(int));
            }
        }
        //POLYGON, 12 bytes for normals and 8 bytes for vertices
        for (unsigned int ii=0; ii<mesh_array[i].nbPolygon; ii++)
        {
            //Normals
            for (unsigned int j=0; j<3; j++)
            {
                bSint32 = swap_endian_sint(mesh_array[i].pltbl[ii].norm[j]);
                file->write((char*)&bSint32, sizeof(int));
            }
            //Vertices
            for (unsigned int j=0; j<4; j++)
            {
                bUint16 = swap_endian_ushort(mesh_array[i].pltbl[ii].Vertices[j]);
                file->write((char*)&bUint16, sizeof(unsigned short));
            }
        }
        //ATTRIBUTES, 12 bytes each
        for (unsigned int ii=0; ii<mesh_array[i].nbPolygon; ii++)
        {
            file->write((char*)&TextureAttributeArray[mesh_array[i].attbl[ii].texno].flag, sizeof(unsigned char));
            file->write((char*)&TextureAttributeArray[mesh_array[i].attbl[ii].texno].sorting, sizeof(unsigned char));
            bUint16=swap_endian_ushort(TextureAttributeArray[mesh_array[i].attbl[ii].texno].texno);
                file->write((char*)&bUint16, sizeof(unsigned short));
            bUint16=swap_endian_ushort(TextureAttributeArray[mesh_array[i].attbl[ii].texno].atrb);
                file->write((char*)&bUint16, sizeof(unsigned short));
            bUint16=swap_endian_ushort(TextureAttributeArray[mesh_array[i].attbl[ii].texno].colno);
                file->write((char*)&bUint16, sizeof(unsigned short));
            bUint16=swap_endian_ushort(TextureAttributeArray[mesh_array[i].attbl[ii].texno].gstb);
                file->write((char*)&bUint16, sizeof(unsigned short));
            bUint16=swap_endian_ushort(TextureAttributeArray[mesh_array[i].attbl[ii].texno].dir);
                file->write((char*)&bUint16, sizeof(unsigned short));
        }
    }
}

So, you can use something such as GFS_LOAD starting with 36 bytes to know what the file contains, then read the textures (just put it in low-work RAM), DMA everything to VRAM where it belongs and then overwrite the data in low-work RAM with the PDATA (since the textures are transfered, you don't need them in work-RAM, so just overwrite them).
For the textures, make sure you do it per face instead of using texture coordinates.
The converter I wrote only supports 16 colors per texture, but save your TGA files as 32 bits files. The alpha channel is treated as transparent.
I'll see what I can do for the demo, but I'm a bit busy with work so I might not have time. Let me know if you encounter bugs!
I added the title map from Quake as a demo, but this tool isn't meant for maps since it doesn't do map partition nor does it hold data for culling!


 

Sitemap 1 2 3 4 5 6 7 8 9 10 
SMF spam blocked by CleanTalk