3D Model Loading Problem

Problems with Canvas, OpenGL, etc...

3D Model Loading Problem

Postby souza » Mon Oct 11, 2010 6:22 pm

Hi everyone,
I'm developing an android application for my thesis and I need to load
a 3D model into it. I have decided to use the .obj file structure as
input. After some searching in the internet and also here in the
Android Developers group I found an object loader provided by the
project android-gl (http://code.google.com/p/android-gl). Its
ObjectLoader.java file provides the following load methods:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public Model load(InputStream in)
  2.         throws IOException
  3. public Model load(String file)
  4.         throws IOException
  5.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


My problem at the moment is to correctly load the model into my
application so that I can see it on the display. I have integrated the
loader call inside the onDrawFrame method:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public void onDrawFrame(GL10 gl) {
  2.                 gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  3.                 gl.glFrontFace(GL10.GL_CW);
  4.                 gl.glEnable(GL10.GL_CULL_FACE);
  5.                 gl.glCullFace(GL10.GL_BACK);
  6.                 for(int loop = 0; loop < 2; loop++) {
  7.                         if(loop==0) {
  8.                                 gl.glViewport(0, 0, w, h);
  9.                                 gl.glMatrixMode(GL10.GL_PROJECTION);
  10.                                 gl.glLoadIdentity();
  11.                                 gl.glOrthof(-1.0f, 1.0f, -1.0f * h / w, 1.0f * h / w, -2.0f, 10.0f);
  12.                         }
  13.                         if(loop==1) {
  14.                                 gl.glViewport(0, 65, w/2, w/2);
  15.                                 gl.glMatrixMode(GL10.GL_PROJECTION);
  16.                                 gl.glLoadIdentity();
  17.                                 GLU.gluPerspective(gl, 45.0f, (float) w / (float) h, -2.0f, 10.0f);
  18.                         }
  19.                         gl.glMatrixMode(GL10.GL_MODELVIEW);
  20.                         gl.glLoadIdentity();
  21.                         gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
  22.                         if(loop==0) {
  23.                                 gl.glPushMatrix();
  24.                                         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  25.                                         gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  26.                                         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
  27.                                         gl.glTranslatef(0.0f, 0.0f, 10.0f);
  28.                                         gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);
  29.                                         gl.glEnable(GL10.GL_TEXTURE_2D);
  30.                                         gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords);
  31.                                         gl.glDrawElements(GL10.GL_TRIANGLES, mIndices.length,
  32.                                                                     GL10.GL_UNSIGNED_SHORT, indices);
  33.                                 gl.glPopMatrix();
  34.                                 gl.glDisable(GL10.GL_TEXTURE_2D);
  35.                         }
  36.  
  37.                         // NOW THE PART WITH THE LOADER
  38.  
  39.                        if(loop==1) {
  40.                                 gl.glPushMatrix();
  41.                                         gl.glTranslatef(0.0f, 0.0f, 5.0f);
  42.                                         // loading 3D model
  43.                                         try {
  44.                 --------->              loader.load(new FileInputStream("sdcard/pixbag.obj"));
  45.                                         } catch (FileNotFoundException e) {
  46.                                            e.printStackTrace();
  47.                                         } catch (Exception e) {
  48.                                            e.printStackTrace();
  49.                                         }
  50.                                 gl.glPopMatrix();
  51.                         }
  52.                 }
  53.                 gl.glDisable(GL10.GL_CULL_FACE);
  54.                 gl.glFlush();
  55. }
  56.  
Parsed in 0.042 seconds, using GeSHi 1.0.8.4


Since I'm working with the android emulator I wanted to load the obj
file out of the emulated sdcard device. But when I'm trying to push a
file onto it using DDMS in eclipse the console returns the following
lines:

Failed to push the item(s).
(null)

I also tried to push the file using the command line tool without
result :( So for now without the model I'm even not sure if the loader
does what it's supposed to do.
Another way I tried was to have the obj file in the assets folder of
my eclipse project from where I also load my texture file. So I have
modified the above-mentioned lines concerning the loader to:

InputStream in = getAssets().open("pixbag.obj");
loader.load(in);

This revision neither worked. I still cannot see the 3d model. Any
help and advise on how I can load and display the 3d data in the
emulator is more than appreciated!

thanks in advance,
Sadi
souza
Freshman
Freshman
 
Posts: 3
Joined: Fri Aug 06, 2010 3:14 pm

Top

Re: 3D Model Loading Problem

Postby jonbonazza » Mon Oct 11, 2010 6:43 pm

The emulator has very very VERY poor OpenGL support. NEVER use the emulator to test applications/games using OpenGL...
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: 3D Model Loading Problem

Postby seed » Thu Oct 21, 2010 5:53 pm

souza wrote:InputStream in = getAssets().open("pixbag.obj");
loader.load(in);

This revision neither worked. I still cannot see the 3d model. Any
help and advise on how I can load and display the 3d data in the
emulator is more than appreciated!

thanks in advance,
Sadi


Loading it from assets should be easy. This code loads my map files from assets.

AssetManager assetManager = context.getAssets();
try {
InputStream in = assetManager.open("intro.lbm");
map.load_from_stream(in);
in.close();
}
catch ( IOException iox )
{
System.out.println("Problem reading file - " + iox);
}

First line of load_from_stream is:
DataInputStream in = new DataInputStream(stream);

Why are you loading the model every frame? Do you know that the sample code works? Can you display something else?

BTW, agree that this will run like a dog in the emulator.
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby jonbonazza » Thu Oct 21, 2010 8:30 pm

Seed, unfortunately, loading a 3D model isn't as simple as you implied. You have to read in the header file, then use the different parts of the header to read in each vertex and texture coordinate depending on the filetype used.
The only 3D Model file type I am really familiar with is MD2 and DAE. With this said, the only file type I have worked with internally is the MD2 file type. I am currently working on a Model loader for the MD2 file type, however, since I have it written already in C++ using immediate rendering, it's a pain in the ass converting the code to use vertex arrays.

@OP: Have you tried running it on an actual Device yet?
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: 3D Model Loading Problem

Postby benny! » Thu Oct 21, 2010 9:13 pm

@souza:
Did you have a look at this framework yet ?

http://code.google.com/p/min3d/

I played around with it some months ago and loading 3d models was really easy. Maybe this fits your needs?

Tutorial for loading obj files e.g.:

http://www.rozengain.com/blog/2010/05/17/loading-3d-models-with-the-min3d-framework-for-android/
User avatar
benny!
Experienced Developer
Experienced Developer
 
Posts: 69
Joined: Tue Nov 27, 2007 3:36 pm
Location: end of www

Re: 3D Model Loading Problem

Postby seed » Fri Oct 22, 2010 5:05 pm

jonbonazza wrote:Seed, unfortunately, loading a 3D model isn't as simple as you implied. You have to read in the header file, then use the different parts of the header to read in each vertex and texture coordinate depending on the filetype used.


I didn't say loading a 3D model was easy.

I said loading from assets is easy.

If you read the original post he was questioning the opening the input stream code. All my man was trying to do was open from assets and call object loader code in something he downloaded. I said that the load from assets was easy and asked whether he knew if the object loading code worked. I asked him to try to display something else too to check his GL code.

My post needed no correction, thank you.

jonbonazza wrote:The only 3D Model file type I am really familiar with is MD2 and DAE. With this said, the only file type I have worked with internally is the MD2 file type. I am currently working on a Model loader for the MD2 file type, however, since I have it written already in C++ using immediate rendering, it's a pain in the ass converting the code to use vertex arrays.


When loading an MD2 file, just duplicate the vertices that have split uv to make the frame buffers and correct your indices. Runs lightning fast that way. Oh, and don't even consider interpolation unless you are doing it at load time. Good luck with your project. I wrote my loader in about three hours. I had underlying mesh classes though, so it was only a parse and reorganize vertices problem. Again, good luck.

Check out this cool MD2 model from our upcoming game rendered in my model viewer.

Image
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Top

Re: 3D Model Loading Problem

Postby seed » Fri Oct 22, 2010 5:24 pm

souza wrote:This revision neither worked. I still cannot see the 3d model. Any
help and advise on how I can load and display the 3d data in the
emulator is more than appreciated!

Sadi


Maybe you are starting off too big. As a first step try to just display a cube or something first. When you have that working, then try to do the obj file load.

The way you describe your problem is that you can't see the model. It is really hard to know if that is because the model loading is wrong or because your GL code is just bad. Heck, for all we know the model may be loading properly but has vertices that are out of your view. I know I have done this plenty of times. Break the problem down some. Try something simple first.

Good Luck.
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby jonbonazza » Mon Oct 25, 2010 6:13 pm

Seed,
As you said, my largest problem is reorganizing the vertices... I still havent had a chance to try my idea, however, would it be better to sepearte the vertices into "groups" and render multiple vertex arrays, or load all of the vertices into one buffer and render it all at once?
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: 3D Model Loading Problem

Postby seed » Mon Oct 25, 2010 10:41 pm

jonbonazza wrote:Seed,
As you said, my largest problem is reorganizing the vertices... I still havent had a chance to try my idea, however, would it be better to sepearte the vertices into "groups" and render multiple vertex arrays, or load all of the vertices into one buffer and render it all at once?


Yes, I use one vertex buffer. Each frame has a vertex buffer and a normal buffer that are the same size. Each model also has a uv buffer that has the same number of elements as the vertex buffer and the normal buffer for each frame. The model also has the index buffer. Model contains frames.

I create a temp list of uv.

I then go through the triangles expanding my uv to match the vertex indexing. If a vertex index has been used before and has a different uv then used before, I create a new uv for it and change the triangle index. I also save to a temp structure where to copy that vertex from for when I unpack the frame vertices later.

I create the uv and index buffers.

Then when I go through each frame populating vertices and normals, I use the information saved in my temp structure to copy the vertices for the new indices that I had to create for the split UV in the steps above.

Don't know if that made sense. Read it a couple of times.

Hope this helps

Charlie
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby seed » Wed Oct 27, 2010 4:13 pm

Reading my post above, I really didn't do a good job of explaining how I did it. I hate making bad posts, so I will try again, this time with some pseudo code.

I have an existing Mesh class that has buffer references for vertices, texture vertices, normals, and indices. You can populate these buffers from arrays or you can just make them reference another buffer.

For models, I created two new classes both derived from Mesh - Model and Frame. Model contains Frames. Models have the buffers for UV and Indices. Frames contain the buffers for vertices and normals and reference buffers in the Model class for UV and indices.

Code: Select all
BEGIN MODEL LOAD
   Read in header
   Read in UV to TEMP_UV
   FOR each triangle
      FOR each index
         // We want to copy UV to a vertex indexed UV array, VI_UV,
         // but if the UV is already set in
         // this array and it is different than the UV referenced
         // from the triangle, then we need to make
         // a new index.  We also keep a COPY_LIST here to be
         // used later when creating frame vertex and
         // normal lists
         IF UV set in VI_UV
             IF this UV is different
                Lookup and add UV to end of VI_UV.
                Write corrected index to INDEX_LIST
                Add index copy info to COPY_LIST
             ELSE
                // Don't need to do copy list or UV writing
                Write uncorrected index to INDEX_LIST
             END IF this UV is different
         ELSE
             // UV is new to the VI_UV array
             Lookup and copy UV to VI_UV.
             Write uncorrected index to INDEX_LIST
          END IF UV set in VI_UV
      END FOR each index
   END FOR each triangle
   
   Create UV and indice buffers.

   FOR each frame
      CALL FRAME LOAD(COPY_LIST,this)
   END FOR each frame

END MODEL LOAD

BEGIN FRAME LOAD (COPY_LIST,MODEL)
   FOR each vertex
      Copy vertex to VERTEX_LIST
      Lookup and copy normal to NORMAL_LIST
   END FOR each vertex
 
   FOR all new indices in COPY LIST
      Lookup and copy vertex to new spot in VERTEX_LIST
      Lookup and copy normal to new spot in NORMAL_LIST
   END FOR

   Create vertex and normal buffers
   Create references to MODEL uv and indice buffers.

END FRAME LOAD


Note that if you find split UV in a triangle, the pseudo code above ALWAYS creates a new vertex. An optimization would be to search to see if you already created a new vertex for this 'different' UV and to just change the indexing to that rather than creating another new vertex. But, considering the reasons that UV is usually split, I didn't consider this optimization worth it. I didn't think too hard though;)

I am curious what your plans were with creating groups. If you go this route, I would be interested in hearing what you did.
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby jonbonazza » Wed Oct 27, 2010 9:16 pm

Charlie,
I finally got the model "Loaded" however, the indices are still throwing me off.

Because I am relatively new to the glDrawElements() function, I am not quite understanding how to go about assigning indices to the vertices. I think if I can figure this out, it will work fine.

With this said, to my understanding, the vertices in the data portion of the MD2 file are ordered already. That is, they are written into the file in the order that they should be rendered. If this is the case, wouldn't the indices just be 0 to vertexCount in order? If it is, then why can't I just use glDrawArrays()?

Im sorry if I seem a bit naive, it's just Vertex pointers are relatively new to me as I have always used immediate rendering in the past.
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: 3D Model Loading Problem

Postby seed » Thu Oct 28, 2010 12:05 pm

jonbonazza wrote:harlie,
I finally got the model "Loaded" however, the indices are still throwing me of

With this said, to my understanding, the vertices in the data portion of the MD2 file are ordered already. That is, they are written into the file in the order that they should be rendered. If this is the case, wouldn't the indices just be 0 to vertexCount in order? If it is, then why can't I just use glDrawArrays()?

Im sorry if I seem a bit naive, it's just Vertex pointers are relatively new to me as I have always used immediate rendering in the past.


The indices are the order elements are drawn in. In this case we are drawing triangles. In a complicated model like this multiple triangles share the same vertex so no it is not just 0 to num vertices. For example if two tirangles shared one vertex your index list would be something like 0 1 2 0 3 4. Further when using draw elements you need the same numder of uv as vertices. So if multiple triangles reference the same vertex but with different uv then you need to duplicate the vertex.

I supposes you could duplicate all vertices for every triangle but this would make a much longer list of verices which would render slower because the write of this list to the gpu(dma or otherwise) would be slower. If you did do this then you could use indices 0 to num triangles times three. I don't advise this.
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby jonbonazza » Mon Nov 01, 2010 6:17 pm

I see, so how would I go about determining the index buffer?

Sorry for all of the questions.
jonbonazza
Master Developer
Master Developer
 
Posts: 665
Joined: Thu Jul 15, 2010 2:58 pm
Location: WV USA

Re: 3D Model Loading Problem

Postby seed » Thu Nov 04, 2010 8:44 pm

jonbonazza wrote:I see, so how would I go about determining the index buffer?

Sorry for all of the questions.


Not sure the what you are asking. The indices in the index buffer are the indices in the model triangles, except in cases where you created a new vertice to handle the split uv.
Visit Exit 4 Gaming - http://www.exit4games.com/
Home of LavaBall - http://exit4games.com/?page_id=3
Home of Rebound - http://exit4games.com/?page_id=138
Home of Tap Crazy - http://exit4games.com/?page_id=219
Download "Caveman Pool" From the Market Today!
seed
Senior Developer
Senior Developer
 
Posts: 103
Joined: Mon Mar 15, 2010 3:22 pm

Re: 3D Model Loading Problem

Postby SilverLogic » Thu Nov 04, 2010 10:03 pm

seed wrote:I supposes you could duplicate all vertices for every triangle but this would make a much longer list of verices which would render slower because the write of this list to the gpu(dma or otherwise) would be slower. If you did do this then you could use indices 0 to num triangles times three. I don't advise this.


Just thought I'd throw my 2 cents in here. I wrote an obj model loader, and I used the method described above, I admit it does load a little slow, but I've tested it with 50 medium poly trees on the screen and was still getting a decent 20 fps. It could probabaly be optimized because I'm using a loop sprinkled with FloatBuffer.put calls, but as for rendering, re-ordering vertices, normals, and uv's to pass into a buffer actually renders pretty fast. If you want you can check out the code below:
http://codepad.org/hpzwKNWK

Also I remember reading that someone wanted to know if anyone got handling seperate objects to work? If you look at my code, you'll see that creating one instance of the ModelOBJ class, it automatically handles creating new instances of itself internally, so each object handles its own material properties and so forth :D

Heres a screenshot, still achieving pretty decent framerates :wink:
Image
User avatar
SilverLogic
Junior Developer
Junior Developer
 
Posts: 10
Joined: Thu Oct 21, 2010 10:31 pm

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 5 guests