gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Help! 3DS loader[SOLVED for now]

#137587 - yellowstar - Mon Aug 13, 2007 7:42 pm

I am trying to write a 3DS loader.

But it won't work.

I am doing an tutorial,
which this is based on.

Here's my problem:

My loader isn't detecting the EDIT3DS chunk.(This chunk contains
sub-chunks which contains the actual model data.)

Like that tutorial,(at the point I am at)
it only sends output to a text file,
not data structures.

Here's the output from it:(from the text file it writes to)
(Updated. Now it isn't detecting all of the chunks.
It started doing this since I fixed the SkipChunk function.)
Code:

ChunkID: 0x 4d4d Length: 693
ChunkID: 0x 0002 Length: 10
ChunkID: 0x 0000 Length: 671038



Here's how I am doing it:(source code)

Here's the important code:
Code:

//See the below piece of code(the whole thing) for
//the structures.
void ReadChunk(FILE *f, ChunkHeader *header)
{
     
     unsigned short ID = 0;
     unsigned int  bytesRead = 0;
     unsigned int bChunkLength = 0;
     
     bytesRead = fread(&ID,2,1,f);
     
     bytesRead += fread(&bChunkLength,4,1,f);
     
     header->ChunkID = ID;
     header->Length = bChunkLength;
     header->bytesRead = bytesRead;
     
}

void SkipChunk(FILE *f, ChunkHeader *header)
{
     //Updated. Was wrong. Since
//I updated this it won't detect all the chunks.
     fseek(f, ((long)header->Length - (long)header->bytesRead), SEEK_CUR);
     
}

void ReadEDIT3DS(FILE *f, ChunkHeader *header)
{
     fprintf(debug,"\n");
     
     fprintf(debug,"EDIT3DS Chunk\n");
     
     while(header->bytesRead < header->Length)
     {
     ChunkHeader temp;
     ReadChunk(f, &temp);
     DisplayChunkInfo(&temp);
     
                             switch(temp.ChunkID)
                             {
     
                             case NAMED_OBJECT:
                                  ReadNAMED_OBJECT(f,&temp);
                                  break;
                                 
                             default:
                                  SkipChunk(f,&temp);
                             }
     
     header->bytesRead+= temp.Length;
     }
}

//The code below is the while loop which reads in the 3DS file.

     while(chunk.header.bytesRead < chunk.header.Length)
     {
     
     ChunkHeader temp;
     
     ReadChunk(f,&temp);
     DisplayChunkInfo(&temp);
     
     unsigned int bytesRead = 0;
     
              switch(temp.ChunkID)
              {
             
              case EDIT3DS:
                   ReadEDIT3DS(f,&temp);
                   bytesRead = temp.Length;
                   break;
                   
              default:
                      SkipChunk(f,&temp);
                      bytesRead = temp.Length;
                      break;
             
              }
             
              chunk.header.bytesRead += bytesRead;
     
     }
     



This is the whole thing,
with some parts removed:
Code:

#include <stdio.h>
#include <string.h>

#include "3DSloaderChunkDefs.h"

bool Load3DS(char *filename);
bool Load3DS(char *filename, unsigned char *ErrorCode);

struct ChunkHeader
{
       unsigned short ChunkID;
       unsigned int Length;
       
       unsigned int bytesRead;//NOT a real field in an 3DS Chunk header.
       //This keeps track of how many bytes were read from this chunk.
};

struct Chunk
{
       ChunkHeader header;
       unsigned char *data;
};

FILE *debug = fopen("Debug.txt","w");

unsigned int GetFileLength(FILE *file)
{
        int l_iSavPos, l_iEnd;
   
            l_iSavPos = ftell(file);
        fseek(file, 0, SEEK_END);
        l_iEnd = ftell(file);
        fseek(file, l_iSavPos, SEEK_SET);
   
            return (unsigned int)l_iEnd;
}

void DisplayChunkInfo(ChunkHeader *ptr)
{
     fprintf(debug,"ChunkID: 0x %04x Length: %u\n",ptr->ChunkID,ptr->Length);
}

void ReadChunk(FILE *f, ChunkHeader *header)
{
     
     unsigned short ID = 0;
     unsigned int  bytesRead = 0;
     unsigned int bChunkLength = 0;
     
     bytesRead = fread(&ID,2,1,f);
     
     bytesRead += fread(&bChunkLength,4,1,f);
     
     header->ChunkID = ID;
     header->Length = bChunkLength;
     header->bytesRead = bytesRead;
     
}

void SkipChunk(FILE *f, ChunkHeader *header)
{
     
     fseek(f, ((long)header->Length - (long)header->bytesRead), SEEK_CUR);
     
}

void ReadEDIT3DS(FILE *f, ChunkHeader *header)
{
     fprintf(debug,"\n");
     
     fprintf(debug,"EDIT3DS Chunk\n");
     
     while(header->bytesRead < header->Length)
     {
     ChunkHeader temp;
     ReadChunk(f, &temp);
     DisplayChunkInfo(&temp);
     
                             switch(temp.ChunkID)
                             {
     
                             case NAMED_OBJECT:
                                  ReadNAMED_OBJECT(f,&temp);
                                  break;
                                 
                             default:
                                  SkipChunk(f,&temp);
                             }
     
     header->bytesRead+= temp.Length;
     }
}
bool Load3DS(char *filename)
{
     Load3DS(filename,NULL);
}

bool Load3DS(char *filename, unsigned char *ErrorCode)
     
     FILE *f = fopen(filename,"rb");
     
     Chunk chunk;
     
     unsigned int FileSize;
     
     bool do_errors = false;
         if(ErrorCode!=NULL)
         do_errors = true;
            if(ErrorCode==NULL)
            do_errors = false;
     
     if(do_errors)
     {
     *ErrorCode = 0;//For success.
     }
     
     if(f==NULL)
     {
        if(do_errors)
        *ErrorCode = 1;//Failed to open 3DS file.
       
        fprintf(debug,"ERROR: Failed to open 3DS file!\n\n");
     
     return 0;
     }
     
     memset(&chunk,0,sizeof(Chunk));
     
     FileSize = GetFileLength(f);
     
     ReadChunk(f,&chunk.header);
     
     DisplayChunkInfo(&chunk.header);
     
     if(chunk.header.ChunkID != PRIMARY ||
     chunk.header.Length != FileSize)
     {
                         
                         fprintf(debug,"ERROR: Bad 3DS file!\n\n");
                         
                         fclose(debug);
                         fclose(f);
                         
                         if(do_errors)
                         *ErrorCode = 2;//Bad 3DS file!
                         
                         return 0;
                         
     }
     
     while(chunk.header.bytesRead < chunk.header.Length)
     {
     
     ChunkHeader temp;
     
     ReadChunk(f,&temp);
     DisplayChunkInfo(&temp);
     
     unsigned int bytesRead = 0;
     
              switch(temp.ChunkID)
              {
             
              case EDIT3DS:
                   ReadEDIT3DS(f,&temp);
                   bytesRead = temp.Length;
                   break;
                   
              default:
                      SkipChunk(f,&temp);
                      bytesRead = temp.Length;
                      break;
             
              }
             
              chunk.header.bytesRead += bytesRead;
     
     }
     
     
     
     fclose(debug);
     fclose(f);
     
     return 1;
     
}



Last edited by yellowstar on Sat Sep 01, 2007 2:37 am; edited 4 times in total

#137597 - yellowstar - Mon Aug 13, 2007 9:17 pm

I have another question.

Is there a Google SketchUp plugin SDK,
for the free version?

If so,
would somebody post a link to a download link?

EDIT:
I don't need it now,
but I would like to know this.

I have found a Blender plugin
which can import Google Earth files.(Which Google SketchUp
can export to.)

Now that I can import models(After being converted to Google Earth)
from Google SketchUp, into Blender,
I can now convert them to 3ds, obj and md2,
and others.(Any format Blender can export to,
and others via plugins)

#137607 - dantheman - Mon Aug 13, 2007 11:10 pm

The MD2 loader by payk found at http://payk.drunkencoders.com/ might be of interest to you.

#137730 - yellowstar - Wed Aug 15, 2007 2:53 am

I have tried to compile and run the example which
came with that MD2 loader.

But, when I try to compile it,
I get compile errors.

I tried to fix them.
It compiles fine,
but it won't display anything

Here's the errors I recieved,
and what I did to try to fix them.

Code:

c:/ConsoleStuff/Simple_MD2/source/main.cpp: In function 'int main()':
c:/ConsoleStuff/Simple_MD2/source/main.cpp:69: error: 'glInit' was not declared in this scope
c:/devkitPro/libnds/include/nds/arm9/videoGL.inl:17: error: too many arguments to function 'void glClearColor(uint8, uint8, uint8)'
c:/ConsoleStuff/Simple_MD2/source/main.cpp:74: error: at this point in file
c:/ConsoleStuff/Simple_MD2/source/main.cpp:75: error: 'glClearPolyID' was not declared in this scope
c:/devkitPro/libnds/include/nds/arm9/videoGL.inl:112: error: too many arguments
to function 'void glFlush()'
c:/ConsoleStuff/Simple_MD2/source/main.cpp:158: error: at this point in file
make[1]: *** [main.o] Error 1
MAKE: *** [build] Error 2



I also got a warning:
Code:

c:/ConsoleStuff/Simple_MD2/include/MD2Load.cpp: In function 'void LoadMode
lTexture(char*, int*, int*, int, int*)':
c:/ConsoleStuff/Simple_MD2/include/MD2Load.cpp:175: warning: 'buffer8' may
 be used uninitialized in this function



glInit:
Since this was not declared,
I tried commenting it out.

glClearColor:
This function call has a fourth paramenter,
which seems to be the alpha.
But the compiler says that's to many parameters,
so I removed the last parameter.(fourth parameter)

glClearPolyID:
Since this was not declared,
I commented it out.

glFlush:
This call has 1 parameter,
with value 0.
Since that is too many,
I removed that parameter.

buffer8:
I tried setting it to NULL.(where it is declared)
When I do that, the above result happens.(only an black screen)
But when I let this var be,
I get a light-blue bar.(something similar to it)(its width is the screen width, and height is about 16 pixels, I'am not sure.)(This is the top screen)



Any other MD2 loaders?
EDIT:
Also, does anybody know of any MD2 tutorials?


Last edited by yellowstar on Thu Aug 16, 2007 4:47 pm; edited 1 time in total

#137774 - kalus - Wed Aug 15, 2007 5:29 pm

I converted a tutorial I found on some wiki to work on DS, used it for my DSLB game, but the example is broken at mo, will try and fix for you.

#137807 - yellowstar - Wed Aug 15, 2007 9:32 pm

I found a problem in the SkipChunk function.
I have fixed it, but now it dosen't detect
all of the chunks.

See my first post for details.

EDIT:
I have edited my above post,
with the following question:
yellowstar wrote:

Also, does anybody know of any MD2 tutorials?

#138030 - Rajveer - Sat Aug 18, 2007 8:50 pm

Not sure about an MD2 loader, but know of a great OBJ loader of which I'm using a modified version, if you don't want to use animation:

http://www.gamedev.net/community/forums/topic.asp?topic_id=312335

#138104 - yellowstar - Sun Aug 19, 2007 9:53 pm

I have written an MD2 loader,
based on an tutorial.
But lighting won't work like it is supposed
to when I won't want lighting.

I just need to edit it some.
Then I can add it to my game.



Does anybody know of any free modelers/converters
which have importer/exporter support for plugins,
via an SDK?

I know about Milkshape 3D,
but that is shareware.

#138119 - kusma - Mon Aug 20, 2007 12:55 am

yellowstar wrote:
Does anybody know of any free modelers/converters
which have importer/exporter support for plugins,
via an SDK?

Blender sounds like what you're looking for. Another option (and much more artist-friendly) is to use COLLADA as an interchange-format - that way your graphics artists can use whatever modeler they prefer.

#138175 - yellowstar - Mon Aug 20, 2007 7:51 pm

kusma wrote:

Blender sounds like what you're looking for.


I have Blender.
But the only way to write a importer/exporter
plugin in Blender,
is via the Python scripting language,
not an SDK.

There is an SDK,
but it is only for generating textures.

#138176 - kusma - Mon Aug 20, 2007 7:55 pm

yellowstar wrote:

I have Blender.
But the only way to write a importer/exporter
plugin in Blender,
is via the Python scripting language,
not an SDK.

Why do you need an SDK? Python is a really powerful and easy language, so it makes sense to write tools in that.

#138177 - yellowstar - Mon Aug 20, 2007 8:09 pm

kusma wrote:

Why do you need an SDK? Python is a really powerful and easy language, so it makes sense to write tools in that.


I'am reluctant to learn an new scripting language,
just to write importer/exporter plugins...

I guess I'll have to,
so I can write importer/exporter plugins.
And it seems that most modelers/converters
use a scripting language, not a SDK.

#138179 - kusma - Mon Aug 20, 2007 8:19 pm

yellowstar wrote:

I'am reluctant to learn an new scripting language,
just to write importer/exporter plugins...

The beauty of Python is that it's such an effective an versatile language, so you can use it for much more than just exporters. I use it for most of my mini-tools myself.

#138347 - calcprogrammer1 - Thu Aug 23, 2007 4:48 am

This might be a bit off topic, but I tried to open the test.md2 file from the MD2 library in Blender, but when I booted Blender and clicked the File menu, the screen messed up, the whole Blender window seemed to distort itself so that it was at an angle, and the menu didn't work. What's wrong with Blender?
_________________
DS Firmware 1, Datel Games n' Music card / Chism's FW hacked GBA MP v2 CF

There's no place like 127.0.0.1.

#139054 - yellowstar - Sat Sep 01, 2007 2:36 am

I have finally got it to work!

Apparently,
my SkipChunk function was skipping into the next chunk's data,
which caused problems.

So, the reason it wasn't working,
was because my SkipChunk function was broken.


Now I just need to finish my 3DS loader, and the tutorial.


I have finished learning Python.
Now I just need to figure out how to get the Mesh data in Blender.

As for converting 3D Models to my own formats,
once I finish this 3DS loader,(or maybe other formats)
maybe I could write a program which
loads a 3DS file,(or maybe a differen't format)
then exports to my own format.