.obj loader

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

.obj loader

Post by ttotto »

i have been working on a .obj loader but im having problems:

here's a pic:
www.freewebs.com/ttotto/snap037.bmp


heres the code:

Code: Select all

EZ_model* EZ_3d::Load_obj(char *fname)
{
  	
		FILE* fp;	
		  fp=fopen(fname,"rb");
   if (fp==NULL) return NULL;	
int t_verts=0, t_faces=-1;
bool normals=false;// if they are defined on the file or not
bool textures=false;
char buffer[256];
int t_norms=0;


EZ_model* model =(EZ_model*)malloc( sizeof(EZ_model));

model->verts=0;
model->t_verts=0;
model->t_faces=0;


   while(!feof(fp))
	   {
         fgets(buffer, sizeof(buffer), fp);
         
          if(buffer[0] == 'v' && buffer[1] == ' ')
            {
			     t_verts++;
            }
		   else if(buffer[0] == 'f' && buffer[1] == ' ')
            {
			      t_faces++;
            }
            else if(buffer[0] == 'v' && buffer[1] == 'n')
            {
			normals=true;
			t_norms++;
            }
             else if(buffer[0] == 'v' && buffer[1] == 't')
            {
			textures=true;
            }
         
	   }
	  fseek ( fp , 0 , SEEK_SET );
	  

allVertex tverts[t_verts];

model->t_verts=t_verts;
model->t_faces=t_faces;

model->list = (unsigned int *) malloc(t_faces*3*10);

model->indices=(short*) memalign(16, t_faces * 3 * sizeof(short));


model->verts = (allVertex*) memalign(16, t_faces * 3 * sizeof(allVertex));

short index[t_faces*3];
	 
	  char tu[4][32];
	  float tempv[3];
	  float tempn[3];
	  int tempf[4];
	  int tn[3];
	  int v=0;
	  int r=0;
	  int h=0;
	  int i=0;

	   while(!feof(fp))
	   {
	 
	  fgets(buffer, sizeof(buffer), fp);
          
          if(buffer[0] == 'v' && buffer[1] == ' ')
            {   
		   sscanf(buffer,"%*s %s %s %s",tu[0],tu[1],tu[2]);
		   tempv[0]=atof(tu[0]);
		   tempv[1]=atof(tu[1]);
		   tempv[2]=atof(tu[2]);
		
		model->verts[v].x=tempv[0];
		model->verts[v].y=tempv[1]; 
		model->verts[v].z=tempv[2];
		
		model->verts[v].color=WHITE(255);
		
	   	v++;
            }
             else if(buffer[0] == 'v' && buffer[1] == 'n')
            {
		  sscanf(buffer,"%*s %s %s %s",tu[0],tu[1],tu[2]);
		   tempn[0]=atof(tu[0]);
		   tempn[1]=atof(tu[1]);
		   tempn[2]=atof(tu[2]);
		
		model->verts[h].nx=tempn[0];
		model->verts[h].ny=tempn[1]; 
		model->verts[h].nz=tempn[2];
	
		
   h++;
           }	
		   else if(buffer[0] == 'f' && buffer[1] == ' ')
            {
            	if &#40;r<t_faces&#41;&#123;
			if &#40;normals && !textures&#41;&#123;
		sscanf&#40;buffer,"%*s %d//%d %d//%d %d//%d",&tempf&#91;0&#93;,&tn&#91;0&#93;,&tempf&#91;1&#93;,&tn&#91;1&#93;,&tempf&#91;2&#93;,&tn&#91;2&#93;&#41;;

			
		i++;
			&#125; 
			else &#123;    
             sscanf&#40;buffer,"%*s %hd %hd %hd",&index&#91;i*3&#93;,&index&#91;i*3+1&#93;,&index&#91;i*3+2&#93;&#41;;
            
            model->indices&#91;i*3&#93;=index&#91;i*3&#93;-1;
            model->indices&#91;i*3+1&#93;=index&#91;i*3+1&#93;-1;
            model->indices&#91;i*3+2&#93;=index&#91;i*3+2&#93;-1;
            
      
		
		i++;
	   &#125;
	   
   	r++;
   	&#125;

&#125; 
               
	   &#125; 
	   
fclose&#40;fp&#41;;	

return model;
&#125;

void EZ_model&#58;&#58;Draw&#40;&#41;&#123;

sceGumDrawArray&#40; GU_TRIANGLES, GU_COLOR_8888|GU_INDEX_16BIT|GU_VERTEX_32BITF|GU_TRANSFORM_3D,
					3*t_faces, indices, verts &#41;;	
&#125;
thanks!
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

I already have made an .obj loader so I may be of service but what exactly is the problem you encounter?
JustChris
Posts: 21
Joined: Thu Nov 03, 2005 7:17 am

Post by JustChris »

I have an .obj loader myself and it's almost 100% done, but I could never make a proper file parser the C way :P Vectors, StringStream and FileStream were my tools of choice.

First of all, what kind of shape are you trying to render in the example? Do the number of vertices and faces on the array correspond to the ones on the obj file? Maybe the indices are done out of order, or instead of drawing the set of vertices by index, you are just trying to connect all the unique vertices at once.
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

Post by ttotto »

heres my obj file sorry.

Code: Select all

# Blender3D v244 OBJ File&#58; <memory>
# www.blender3d.org
mtllib ssdatled.mtl
o Cube_Material
v 2.152884 -2.118817 -2.272749
v 2.158488 -2.118576 2.160933
v -2.275183 -2.128670 2.166537
v -2.280786 -2.128911 -2.267145
v 2.142790 2.314857 -2.272976
v -2.290881 2.304763 -2.267373
v -2.285278 2.305004 2.166308
v 2.148391 2.315098 2.160706
usemtl Material.001
s 1
f 5 1 4
f 5 4 6
f 3 7 4
f 7 6 4
f 2 8 3
f 8 7 3
f 1 5 2
f 5 8 2
f 5 6 7
f 5 7 8
f 1 2 3
f 1 3 4
it's just a simple box

all of my verts and indices are loading correctly. Just by looking at it, it should work, but it doesn't.
tommydanger
Posts: 2
Joined: Mon Nov 26, 2007 5:48 am

Post by tommydanger »

I made one myself and I had strange glitches too but they were gone after I put a sceKernelDcacheWritebackAll() in front of my rendering code ;)
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Post by Ghoti »

few things:

1.) why start the faces with -1?
2.) It looks like that you save the vertices the same order that you read them in model->verts and try to render those, you do not seem to use the faces. You should save the vertexnumbers belong to the faces and those in order so the first three in verts should be the vertex 5, vertex 1 and vertex4 followed by vertex 5, vertex4 and vertex6.
3.) How is your graphics environment set up ?

greet ghoti

PS mine .obj works but has no strange glitches and does not need the sceKernelDcacheWritebackAll.
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

Post by ttotto »

i tried adding sceKernelDcacheWritebackAll(); to my draw code and it didn't help. Thanks anyway. Is it posible to see one of your guys code so i can learn what im doing wrong. Thanks for all the help!
tommydanger
Posts: 2
Joined: Mon Nov 26, 2007 5:48 am

Post by tommydanger »

hmm if you have double checked your imported obj values then the error lies in your rendering code.
when i first executed my obj loader on the psp the output was like this:
simple box
but after I added sceKernelDcacheWritebackAll all was working as expected
well I don't know if it really was sceKernelDcacheWritebackAll but something very simple and my loading code was fine
well it's been 1h year and my code says sceKernelDcacheWritebackAll, I could be reading from an outdated version :/
you clearing the depth buffer?
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

Re

Post by ttotto »

tommydanger:

Yes i am clearing the depthbuffer.
is it posible you could upload or post your code, It would be a major help.


Ghoti:
1: i use -1 because when i was counting the number of faces, I would always get one more than their really is. so i set it to -1 and its worked fine.

2:i dont need to because i use indices.
3. here is my gu set up:

Code: Select all





void InitGU&#40; void &#41;&#123;



	fbp0  = 0;	

	

	// Init GU

	sceGuInit&#40;&#41;;

        sceGuStart&#40; GU_DIRECT, list &#41;;

// Set Buffers

	sceGuDrawBuffer&#40; GU_PSM_8888, fbp0, BUF_WIDTH &#41;;

	sceGuDispBuffer&#40; SCR_WIDTH, SCR_HEIGHT, &#40;void*&#41;0x88000, BUF_WIDTH&#41;;

	sceGuDepthBuffer&#40; &#40;void*&#41;0x110000, BUF_WIDTH&#41;;

 

	sceGuOffset&#40; 2048 - &#40;SCR_WIDTH/2&#41;, 2048 - &#40;SCR_HEIGHT/2&#41;&#41;;

	sceGuViewport&#40; 2048, 2048, SCR_WIDTH, SCR_HEIGHT&#41;;

	sceGuDepthRange&#40; 65535, 0&#41;;

	

	// Set Render States

	sceGuScissor&#40; 0, 0, SCR_WIDTH, SCR_HEIGHT&#41;;

	sceGuEnable&#40; GU_SCISSOR_TEST &#41;;

	sceGuDepthFunc&#40; GU_GEQUAL &#41;;

	sceGuEnable&#40; GU_DEPTH_TEST &#41;;

	sceGuFrontFace&#40; GU_CW &#41;;

	sceGuShadeModel&#40; GU_SMOOTH &#41;;

	//sceGuEnable&#40; GU_CULL_FACE &#41;;

	sceGuEnable&#40; GU_CLIP_PLANES &#41;;

	sceGuEnable&#40;GU_TEXTURE_2D&#41;;

	

		sceGuTexMode&#40; GU_PSM_8888, 3, 0, GU_TRUE&#41;;	

	sceGuTexFunc&#40;GU_TFX_REPLACE, GU_TCC_RGBA&#41;;	// Modulate the color of the image

	sceGuTexFilter&#40;GU_NEAREST, GU_NEAREST&#41;;		// Linear filtering

	sceGuTexScale&#40; 1.0f, 1.0f &#41;;				// No scaling

	sceGuTexOffset&#40; 0.0f, 0.0f &#41;;

	

	sceGuAmbientColor&#40;0xffffffff&#41;;

	sceGuEnable&#40;GU_BLEND&#41;;

	sceGuBlendFunc&#40;GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0&#41;;

	gumInit&#40;&#41;;

	

        sceGuFinish&#40;&#41;;

	sceGuSync&#40;0,0&#41;;

 

	sceDisplayWaitVblankStart&#40;&#41;;

	sceGuDisplay&#40;GU_TRUE&#41;;

	// finish



	sceGuStart&#40;GU_CALL,list&#91;listNum&1&#93;&#41;;

&#125;;

ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

Post by ttotto »

b
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

u

Post by ttotto »

Solved:
It was my vertex struct.
Ghoti
Posts: 288
Joined: Sat Dec 31, 2005 11:06 pm

Re: Re

Post by Ghoti »

ttotto wrote: Ghoti:
1: i use -1 because when i was counting the number of faces, I would always get one more than their really is. so i set it to -1 and its worked fine.
This will probebly be due to that the last line in the file will be read twice.
I had this problem also. I first solved it by including another line with just crazy text like: This line does nothing. because it does not include one of the start letters you search for. I am busy with a object loader tutorial at the moment and there I am trying to solve it :)

nice to hear it works !
flynn_nrg
Posts: 4
Joined: Sat Sep 29, 2007 3:59 am
Location: Madrid, Spain
Contact:

Post by flynn_nrg »

Since this is a .obj converter thread I might as well put a link to my work-in-progress one. It's BSD licensed and free to use by anybody. It's not 100% done yet as it still doesn't grasp the concept of groups, but works fine with every .obj I've thrown at it.

It's designed to work with Softimage|3D's wavefront exporter output (long story) and thus assumes objects are textured. I didn't bother implementing the negative vertex referencing but, as I said, the code might be useful to others. The generated .h file can be trivially included into the cube.c example.

The code with some samples: obj2psp-0.1.tar.gz
ttotto
Posts: 8
Joined: Mon Nov 26, 2007 2:39 am

Post by ttotto »

thx for your contribution this will help many of those in need. Including ME!
Post Reply