Problems rendering .obj file

I’m learning openGL for educational purposes and for the fun of it now and I’m trying to render a 3D model of a bunny.

I tried to render the .obj file but I get unclear picture
MainDisplay class :



package com.dryadengine.gui;

import com.dryadengine.core.Model;
import com.dryadengine.framework.OBJLoader;
import com.dryadengine.framework.ShaderFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.util.vector.Matrix4f;

/**
 *
 * @author Roy
 */
public class MainDisplay {

private Model bunny;
private Matrix4f mProjection;
private Matrix4f mView;
private Matrix4f mModel;
private int shaderProgramID;
private int vboID;
private int vPositionID;
private int mProjectionID;
private int mViewID;
private int mModelID;

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    MainDisplay md = new MainDisplay();
    md.create();
    md.init();
    md.run();
}

public MainDisplay() {

}

public void create() {
    try {
        Display.setDisplayMode(new DisplayMode(800, 600));
        Display.setTitle("Dryad Engine 1.0.0");
        Display.setFullscreen(false);
        Display.setResizable(true);
        Display.create();
    } catch (LWJGLException ex) {
        Logger.getLogger(MainDisplay.class.getName()).log(Level.SEVERE, null, ex);
        System.exit(-1);
    }
}

public void init() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    try {
        shaderProgramID = ShaderFactory.createShaderProgram("vertexShader", "fragmentShader");
        glUseProgram(shaderProgramID);
        bunny = OBJLoader.parseOBJ(new File("src/com/dryadengine/assets/bunny.obj"));
        FloatBuffer vbo = BufferUtils.createFloatBuffer(bunny.getVertices().length);
        vbo.put(bunny.getVertices());
        vbo.flip();
        vboID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW);
        vPositionID = glGetAttribLocation(shaderProgramID, "vPosition");
        glEnableVertexAttribArray(vPositionID);
        mProjection = new Matrix4f();
        float fieldOfView = 60f;
        float aspectRatio = (float)Display.getWidth() / (float)Display.getHeight();
        float nearPlane = 0.1f;
        float farPlane = 100f;
        float yScale = (float)(1.0f / Math.tan((fieldOfView / 2.0f) * Math.PI / 180));//this.coTangent(this.degreesToRadians(fieldOfView / 2f));
        float xScale = yScale / aspectRatio;
        float frustum_length = farPlane - nearPlane;
        mProjection.m00 = xScale;
        mProjection.m11 = yScale;
        mProjection.m22 = -((farPlane + nearPlane) / frustum_length);
        mProjection.m23 = -1;
        mProjection.m32 = -((2 * nearPlane * farPlane) / frustum_length);
        mProjection.m33 = 0;
        mView = new Matrix4f();
        mView.m23 = -5;
        mModel = new Matrix4f();
        mProjectionID = glGetUniformLocation(shaderProgramID, "mProjection");
        mViewID = glGetUniformLocation(shaderProgramID, "mView");
        mModelID = glGetUniformLocation(shaderProgramID, "mModel");
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
        glEnable(GL_DEPTH_TEST);
    } catch (FileNotFoundException ex) {
        Logger.getLogger(MainDisplay.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(MainDisplay.class.getName()).log(Level.SEVERE, null, ex);
    }
}



public void run() {
    while (!Display.isCloseRequested()) {
        if (Display.isVisible()) {
            render();
        }
        if (Display.wasResized()) {
            reshape();
        }
        Display.update();
        Display.sync(60);
    }
    destroy();
}

public void render() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    FloatBuffer fb1 = BufferUtils.createFloatBuffer(16);
    FloatBuffer fb2 = BufferUtils.createFloatBuffer(16);
    FloatBuffer fb3 = BufferUtils.createFloatBuffer(16);
    fb1.flip();
    fb2.flip();
    fb3.flip();
    mProjection.store(fb1);
    mView.store(fb2);
    mModel.store(fb3);
    glUniformMatrix4(mProjectionID, true, fb1);
    glUniformMatrix4(mViewID, true, fb2);
    glUniformMatrix4(mModelID, true, fb3);
    for (int i = 0; i < bunny.getVertices().length / 3; i += 3) {
        glVertexAttribPointer(vPositionID, 3, GL_FLOAT, false, 0, i);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
}

public void reshape() {
    glViewport(0, 0, Display.getWidth(), Display.getHeight());
}

public void dispose() {
    glDeleteProgram(shaderProgramID);
    glUseProgram(0);
    glDeleteBuffers(vboID);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

public void destroy() {
    Display.destroy();
}
}

ShaderFactory class :

package com.dryadengine.framework;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;

/**
 *
 * @author Roy
 */
public class ShaderFactory {

private static final String COMMON_SHADERS_PATH = "/com/dryadengine/shaders/";
private static final String SHADER_EXTENSION = ".dsf";

/**
 * 
 * @param vertexShaderName
 * @param fragmentShaderName
 * @return a shader program
 * @throws FileNotFoundException
 * @throws IOException 
 */
public static int createShaderProgram(String vertexShaderName, String fragmentShaderName) throws FileNotFoundException, IOException {
    ArrayList<Integer> shaders = new ArrayList();
    shaders.add(ShaderFactory.compileShader(GL_VERTEX_SHADER, getShaderFileCode(COMMON_SHADERS_PATH + vertexShaderName + SHADER_EXTENSION)));
    shaders.add(ShaderFactory.compileShader(GL_FRAGMENT_SHADER, getShaderFileCode(COMMON_SHADERS_PATH + fragmentShaderName + SHADER_EXTENSION)));
    return ShaderFactory.linkProgram(shaders);
}

/**
 * 
 * @param shaderFilePath
 * @return a shader file code
 * @throws FileNotFoundException
 * @throws IOException 
 */
private static String getShaderFileCode(String shaderFilePath) throws FileNotFoundException, IOException {
    StringBuilder shaderCode = new StringBuilder();
    String line;
    try {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(ShaderFactory.class.getResourceAsStream(shaderFilePath)))) {
            while ((line = br.readLine()) != null) {
                shaderCode.append(line).append("\n");
            }
        }
    } catch (FileNotFoundException e) {
        throw new FileNotFoundException(e.getMessage());
    }
    return shaderCode.toString();
}

/**
 * 
 * @param shaderType
 * @param shaderCode
 * @return a compiled shader file id
 */
public static int compileShader(int shaderType, String shaderCode) {
    int shaderID = glCreateShader(shaderType);
    glShaderSource(shaderID, shaderCode);
    glCompileShader(shaderID);
    int status = glGetShaderi(shaderID, GL_COMPILE_STATUS);
    if (status == GL_FALSE) {
        glDeleteShader(shaderID);
        throw new RuntimeException(glGetShaderInfoLog(shaderID, glGetShaderi(shaderID, GL_INFO_LOG_LENGTH)));
    }
    return shaderID;
}

/**
 * Link the vertex shader and the fragment shader to the shader program
 * @param shaders
 * @return a shader program
 */
public static int linkProgram(ArrayList <Integer> shaders) {
    int shaderProgramID = glCreateProgram();
    for (Integer shader : shaders) {
        glAttachShader(shaderProgramID, shader);
    }
    glLinkProgram(shaderProgramID);
    int status = glGetProgrami(shaderProgramID, GL_LINK_STATUS);
    if (status == GL_FALSE) {
        glDeleteProgram(shaderProgramID);
        throw new RuntimeException(glGetShaderInfoLog(shaderProgramID, glGetProgrami(shaderProgramID, GL_INFO_LOG_LENGTH)));
    }
    for (int shader : shaders) {
        glDeleteShader(shader);
    }
    return shaderProgramID;
}

}

OBJLoader class :

package com.dryadengine.framework;

import com.dryadengine.core.Model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Roy
 */
public class OBJLoader {

/**
 * Parse .obj file and make a model from it.
 * @param f
 * @return a model object
 * @throws FileNotFoundException
 * @throws IOException 
 */
public static Model parseOBJ(File f) throws FileNotFoundException, IOException {
    BufferedReader br = new BufferedReader(new FileReader(f));
    String line;
    Model m;
    List<Float> vertices = new ArrayList<>();
    List<Float> normals = new ArrayList<>();
    while ((line = br.readLine()) != null) {
        if (line.startsWith("v")) {
            float x = Float.valueOf(line.split(" ")[1]);
            float y = Float.valueOf(line.split(" ")[2]);
            float z = Float.valueOf(line.split(" ")[3]);
            vertices.add(x);
            vertices.add(y);
            vertices.add(z);
        } else if (line.startsWith("vn")) {
            float x = Float.valueOf(line.split(" ")[1]);
            float y = Float.valueOf(line.split(" ")[2]);
            float z = Float.valueOf(line.split(" ")[3]);
            normals.add(x);
            normals.add(y);
            normals.add(z);
        }
    }
    br.close();
    float[] a = new float[vertices.size()];
    float[] b = new float[normals.size()];
    for (int i = 0; i < vertices.size(); i++) {
        a[i] = vertices.get(i);
    }
    for (int i = 0; i < normals.size(); i++) {
        b[i] = normals.get(i);
    }
    m = new Model(a, b);
    return m;
}

}

Model class :

package com.dryadengine.core;

/**
 *
 * @author Roy
 */
public class Model {

private float[] vertices;
private float[] normals;

/**
 * Construct a new model object.
 * @param vertices
 * @param normals 
 */
public Model(float[] vertices, float[] normals) {
    this.vertices = vertices;
    this.normals = normals;
}

/**
 * 
 * @return the model vertices array
 */
public float[] getVertices() {
    return vertices;
}

/**
 * 
 * @return the model normals array
 */
public float[] getNormals() {
    return normals;
}

}

vertex shader code :

#version 330

uniform mat4 mProjection;
uniform mat4 mView;
uniform mat4 mModel;

in vec4 vPosition;

void main()
{
    gl_Position = mProjection * mView * mModel * vPosition;
}

fragment shader code :

#version 330

out vec4 color;

void main()
{
    color = vec4(1.0, 1.0, 1.0, 1.0);
}

Result :

Any ideas why ?