glDrawElements rendering deformed objects (imported from .obj)

Hello everyone :slight_smile:

So I have an issue with glDrawElements(). The issues is that the model I imported isn’t rendered the way it should. It always comes out deformed.
I am using LWJGL with JAVA but the issue here isn’t with java it is probably something to do with openGL -> and it is probably my error in some step :confused:

So here is the “cube.obj” (made in blender 2.72)

# Blender v2.72 (sub 0) OBJ File: ''
# www.blender.org
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8

And here is the code I use to load .obj and to render it:

package Objects;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import static org.lwjgl.opengl.ARBBufferObject.*;
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
import Math.Vector3;

import com.jogamp.opengl.*;

import javax.swing.JOptionPane;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import org.lwjgl.util.vector.Vector3f;
public class ObjectLoad {
   
   ByteBuffer inx;
   FloatBuffer vertexData;
   int indiciesCount = 0; 
   

   public int vaoID = 0;
   public int vboID = 0;
   public int vboiID = 0;
   public ObjectLoad(String objfolder, String objfile, int size)
   {
       
      ArrayList<Float> verticesL = new ArrayList<Float>();
      ArrayList<Byte> indicesL = new ArrayList<Byte>();
      // open the file 
      FileReader objectfile = null;
      try {
         objectfile = new FileReader(objfolder + "/" + objfile);
      } catch (FileNotFoundException e2) {
         System.out.println(" File not found !");
         JOptionPane.showMessageDialog(null,
                "File not found.",
                "Error - Failed to Load Object",
                JOptionPane.ERROR_MESSAGE);
         e2.printStackTrace();
      }

      //read the file
      String line;
      try{
            BufferedReader br = new BufferedReader(objectfile);
            while( (line=br.readLine()) != null)
            {
                //read and store vertices 
               if( line.startsWith("v"))
               {
                  String parts[] = line.split(" ");
                 
                  //verticesL.add(new Vector3f(Float.parseFloat(parts[1]),Float.parseFloat(parts[2]), Float.parseFloat(parts[3])));
                  verticesL.add(Float.parseFloat(parts[1]));
                  verticesL.add(Float.parseFloat(parts[2]));
                  verticesL.add(Float.parseFloat(parts[3]));
                  System.out.println(Float.parseFloat(parts[1]) + " " + Float.parseFloat(parts[2]) + " " + Float.parseFloat(parts[3]));
               }
               
              //read and store indices 
               if (line.startsWith("f"))
               {
                  String parts[] = line.split(" ");
                  if ( parts.length == 5)
                  {
            
                 indicesL.add(Byte.parseByte(parts[1]));
                 indicesL.add(Byte.parseByte(parts[2]));
                 indicesL.add(Byte.parseByte(parts[3]));
                 indicesL.add(Byte.parseByte(parts[4]));
                 System.out.println(Byte.parseByte(parts[1]) + " " + Byte.parseByte(parts[2]) + " " + Byte.parseByte(parts[3]) + " "+ Byte.parseByte(parts[4]));
                     
                  }
                    
               }
              
                   

            }
            //store loaded vertices and indices in arrays (from list)
            float verts[] = new float[verticesL.size()];
            byte indices[] = new byte[indicesL.size()];

               for(int i=0;i<verticesL.size();i++)
                  verts[i] = verticesL.get(i);
               for(int i=0;i<indicesL.size();i++)
                indices[i] = indicesL.get(i);
                
           //create floatBuffer for vertices 
            vertexData = BufferUtils.createFloatBuffer(verticesL.size());
            vertexData.put(verts);
            vertexData.flip();
          //create byteBuffer for indices
            inx = BufferUtils.createByteBuffer(indicesL.size()); 
            inx.put(indices);
            inx.flip();
            indiciesCount = indicesL.size();
            }catch(FileNotFoundException e){
               e.printStackTrace();
               
            }catch( Exception e1)
            {
               e1.printStackTrace();
            
            }
         
          
         }
         public void setUP()
         {
         
            
            vaoID = GL30.glGenVertexArrays();
            GL30.glBindVertexArray(vaoID);

            //buffer vertices data
            vboID = GL15.glGenBuffers();
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID );
            GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexData, GL15.GL_STATIC_DRAW);
            GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0 );
            GL30.glBindVertexArray(0);

            //buffer indices data
            vboiID = GL15.glGenBuffers();
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiID);
            GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, inx, GL15.GL_STATIC_DRAW);
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0 );
              
         }
         public void render()
         {
         //I use GL_QUADS because cube I am importing is only made up from quads
            GL30.glBindVertexArray(vaoID);
            GL20.glEnableVertexAttribArray(0);
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiID );
            //GL11.glDrawArrays(GL11.GL_QUADS, 0, amountofv * 3);
            GL11.glDrawElements(GL11.GL_QUADS, indiciesCount, GL11.GL_UNSIGNED_BYTE, 0);
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0 );
            GL20.glDisableVertexAttribArray(0);
            GL30.glBindVertexArray(0);
            
            
         }
         public void cleanMemory()
         {
            GL20.glDisableVertexAttribArray(0);
            
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
            GL15.glDeleteBuffers(vboID);
            
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0 );
            GL15.glDeleteBuffers(vboiID);
            
            GL30.glBindVertexArray(0);
            GL30.glDeleteVertexArrays(vaoID);
         }


}

I added 2 pictures of how it actually looks: Both pictures are from same model, one side looks okay but the other is deformed…

Does anybody have any solution to this ?
Any help is appreciated (:
Thanks in advance !

I fixed the issue. The issue was at parsing the indices. The Blender saved them from 1 to 8, while openGL starts from 0 to 7.
I changed this part of code :

 if (line.startsWith("f"))
               {
                  String parts[] = line.split(" ");
                  if ( parts.length == 5)
                  {
 
                 indicesL.add(Byte.parseByte(parts[1]));
                 indicesL.add(Byte.parseByte(parts[2]));
                 indicesL.add(Byte.parseByte(parts[3]));
                 indicesL.add(Byte.parseByte(parts[4]));
                 System.out.println(Byte.parseByte(parts[1]) + " " + Byte.parseByte(parts[2]) + " " + Byte.parseByte(parts[3]) + " "+ Byte.parseByte(parts[4]));
 
                  }
 
               }

to this

 
 if (line.startsWith("f"))
               {
                  String parts[] = line.split(" ");
                  if ( parts.length == 5)
                  {
 
                 indicesL.add(Byte.parseByte(parts[1])-1);
                 indicesL.add(Byte.parseByte(parts[2])-1);
                 indicesL.add(Byte.parseByte(parts[3])-1);
                 indicesL.add(Byte.parseByte(parts[4])-1);
                 System.out.println(Byte.parseByte(parts[1]) + " " + Byte.parseByte(parts[2]) + " " + Byte.parseByte(parts[3]) + " "+ Byte.parseByte(parts[4]));
 
                  }
 
               }

I’ve only looked at the code briefly, but I think that you’re overlooking that fact that OBJ uses one-based indices while OpenGL uses zero-based indices.

Yes, that was the problem, I fixed it :slight_smile:

Thank you :smiley: