Hopefully someone can help me. I am trying to load a model I made in Blender into my JOGL program. I was able to manual models working and set up my window but there is something wrong with parsing the .obj wavefront file. No errors in my code that I can see, the ImportedModel class came from a textbook.
Here is the code:
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import static com.jogamp.opengl.GL.*;
public class WalkingTour extends JFrame implements GLEventListener, KeyListener {
private static final int windowWidth = 800, windowHeight = 600;
private static final String windowTitle = "Walking Tour";
private static final String vertexShaderFile = "src/walkingtour-vertex.glsl",
fragmentShaderFile = "src/walkingtour-fragment.glsl";
private final GLCanvas glCanvas;
private int renderingProgram;
private final int[] vao = new int[1];
private final int[] vbo = new int[6];
private final FloatBuffer values = Buffers.newDirectFloatBuffer(16);
private final Matrix4f pMat = new Matrix4f(); // perspective matrix
private final Matrix4f vMat = new Matrix4f(); // view matrix
private final Matrix4f mMat = new Matrix4f(); // model matrix
private final Matrix4f mvMat = new Matrix4f(); // model-view matrix
private int gTexture;
private ImportedModel myModel;
private int numObjVertices;
private boolean keyPressedForward = false,
keyPressedBackward = false,
keyPressedMoveRight = false,
keyPressedMoveLeft = false,
keyPressedTurnRight = false,
keyPressedTurnLeft = false,
keyPressedSpace = false,
keyPressedControl = false,
keyPressedShift = false;
private final ArrayList<Float> vertexValues = new ArrayList<>();
private final ArrayList<Float> stVals = new ArrayList<>();
private final ArrayList<Float> normalValues = new ArrayList<>();
private final ArrayList<Float> triangleVerts = new ArrayList<>();
private final ArrayList<Float> textureCoordinates = new ArrayList<>();
private final ArrayList<Float> normals = new ArrayList<>();
private List<float[]> vertices = new ArrayList<float[]>();
private List<int[]> faces =new ArrayList<int[]>();
public WalkingTour() {
setTitle(windowTitle);
setSize(windowWidth, windowHeight);
glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getMaxProgrammableCore(true)));
glCanvas.addGLEventListener(this);
this.add(glCanvas);
this.setVisible(true);
Animator animator = new Animator(glCanvas);
animator.start();
}
public static void main(String[] args) {
new WalkingTour();
}
@Override
public void init(GLAutoDrawable glAutoDrawable) {
myModel = new ImportedModel("hwk5Model.obj");
GL4 gl = (GL4) GLContext.getCurrentGL();
numObjVertices = myModel.getNumVertices();
Vector3f[ ] vertices = myModel.getVertices();
Vector2f[ ] texCoords = myModel.getTexCoords();
Vector3f[ ] normals = myModel.getNormals();
float[ ] pvalues = new float[numObjVertices*3]; // vertex positions
float[ ] tvalues = new float[numObjVertices*2]; // texture coordinates
float[ ] nvalues = new float[numObjVertices*3]; // normal vectors
for (int i=0; i<numObjVertices; i++)
{ pvalues[i*3] = (float) (vertices[i]).x();
pvalues[i*3+1] = (float) (vertices[i]).y();
pvalues[i*3+2] = (float) (vertices[i]).z();
tvalues[i*2] = (float) (texCoords[i]).x();
tvalues[i*2+1] = (float) (texCoords[i]).y();
nvalues[i*3] = (float) (normals[i]).x();
nvalues[i*3+1] = (float) (normals[i]).y();
nvalues[i*3+2] = (float) (normals[i]).z();
}
// VBO for vertex locations
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit()*4, vertBuf, GL_STATIC_DRAW);
// VBO for texture coordinates
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
FloatBuffer texBuf = Buffers.newDirectFloatBuffer(tvalues);
gl.glBufferData(GL_ARRAY_BUFFER, texBuf.limit()*4, texBuf, GL_STATIC_DRAW);
// VBO for normal vectors
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[4]);
FloatBuffer norBuf = Buffers.newDirectFloatBuffer(nvalues);
gl.glBufferData(GL_ARRAY_BUFFER, norBuf.limit()*4,norBuf, GL_STATIC_DRAW);
renderingProgram = Utils.createShaderProgram(vertexShaderFile, fragmentShaderFile);
gTexture = Utils.loadTexture("groundTexture.jpeg");
gl.glActiveTexture(GL_TEXTURE0);
gl.glBindTexture(GL_TEXTURE_2D, gTexture);
float[] floor = {
-2000.0f, -50.0f, -2000.0f, -2000.0f, -50.0f, 2000.0f, 2000.0f, -50.0f, 2000.0f,
-2000.0f, -50.0f, -2000.0f, 2000.0f, -50.0f, -2000.0f, 2000.0f, -50.0f, 2000.0f,
};
gl.glGenVertexArrays(vao.length, vao, 0);
gl.glBindVertexArray(vao[0]);
gl.glGenBuffers(vbo.length, vbo, 0);
FloatBuffer corBuf = Buffers.newDirectFloatBuffer(floor);
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
gl.glBufferData(GL_ARRAY_BUFFER, corBuf.limit() * 4L, corBuf, GL_STATIC_DRAW);
float[] textureCoords = {
0f, 1f, 0f, 0f, 1f, 0f,
0f, 1f, 1f, 1f, 1f, 0f
};
FloatBuffer textureBuffer = Buffers.newDirectFloatBuffer(textureCoords);
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
gl.glBufferData(GL_ARRAY_BUFFER, textureBuffer.limit() * 4L, textureBuffer, GL_STATIC_DRAW);
this.addKeyListener(this);
}
@Override
public void dispose(GLAutoDrawable glAutoDrawable) {
this.removeKeyListener(this);
}
@Override
public void display(GLAutoDrawable glAutoDrawable) {
GL4 gl = (GL4) GLContext.getCurrentGL();
gl.glClear(GL_COLOR_BUFFER_BIT);
gl.glClear(GL_DEPTH_BUFFER_BIT);
gl.glUseProgram(renderingProgram);
int mvLoc = gl.glGetUniformLocation(renderingProgram, "mv_matrix");
int pLoc = gl.glGetUniformLocation(renderingProgram, "p_matrix");
float aspect = (float) glCanvas.getWidth() / (float) glCanvas.getHeight();
pMat.identity().setPerspective((float) Math.toRadians(60.0f), aspect, 0.1f, 5000.0f);
gl.glUniformMatrix4fv(pLoc, 1, false, pMat.get(values));
vMat.translate(0f,0f,0f);
mvMat.identity();
mvMat.mul(vMat);
mvMat.mul(mMat);
gl.glUniformMatrix4fv(mvLoc, 1, false, mvMat.get(values));
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
gl.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(0);
gl.glEnable(GL_DEPTH_TEST);
gl.glDepthFunc(GL_LEQUAL);
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
gl.glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(1);
gl.glBindTexture(GL_TEXTURE_2D, gTexture);
gl.glDrawArrays(GL_TRIANGLES, 0, 6);
gl.glDrawArrays(GL_TRIANGLES, 0, myModel.getNumVertices());
if (keyPressedForward) {
vMat.translateLocal(0f, 0f, 0.1f);
}
if (keyPressedBackward) {
vMat.translateLocal(0f,0f,-0.1f);
}
if (keyPressedMoveLeft) {
vMat.translateLocal(0.1f,0f,0f);
}
if (keyPressedMoveRight) {
vMat.translateLocal(-0.1f,0f,0f);
}
if (keyPressedTurnLeft) {
vMat.rotateLocalY(-0.001f);
}
if (keyPressedTurnRight) {
vMat.rotateLocalY(0.001f);
}
if (keyPressedSpace) {
vMat.translateLocal(0f,-0.1f,0f);
}
if (keyPressedControl) {
vMat.translateLocal(0f,0.1f,0f);
}
if (keyPressedForward && keyPressedShift){
vMat.translateLocal(0f,0f,0.2f);
}
}
@Override
public void reshape(GLAutoDrawable glAutoDrawable, int i, int i1, int i2, int i3) {
}
@Override
public void keyTyped(KeyEvent e) {
//do nothing
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
// Move camera forward
keyPressedForward = true;
} else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
// Move camera backward
keyPressedBackward = true;
} else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
// Move camera to the left
keyPressedMoveLeft = true;
} else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
// Move camera to the right
keyPressedMoveRight = true;
} else if (keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_Q) {
// Turn camera to the left
keyPressedTurnLeft = true;
} else if (keyCode == KeyEvent.VK_PAGE_UP || keyCode == KeyEvent.VK_E) {
// Turn camera to the right
keyPressedTurnRight = true;
} else if (keyCode == KeyEvent.VK_SPACE) {
// Move camera up
keyPressedSpace = true;
} else if (keyCode == KeyEvent.VK_CONTROL) {
// Move camera down
keyPressedControl = true;
} else if (keyCode == KeyEvent.VK_SHIFT) {
//hold shift to "sprint"
//can only sprint while forward buttons are pressed
keyPressedShift = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
// Move camera forward
keyPressedForward = false;
} else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
// Move camera backward
keyPressedBackward = false;
} else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
// Move camera to the left
keyPressedMoveLeft = false;
} else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
// Move camera to the right
keyPressedMoveRight = false;
} else if (keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_Q) {
// Turn camera to the left
keyPressedTurnLeft = false;
} else if (keyCode == KeyEvent.VK_PAGE_UP || keyCode == KeyEvent.VK_E) {
// Turn camera to the right
keyPressedTurnRight = false;
} else if (keyCode == KeyEvent.VK_SPACE) {
// Move camera up
keyPressedSpace = false;
} else if (keyCode == KeyEvent.VK_CONTROL) {
// Move Camera down
keyPressedControl = false;
} else if (keyCode == KeyEvent.VK_SHIFT) {
//hold shift to "sprint"
keyPressedShift = false;
}
}
}
import org.joml.Vector2f;
import org.joml.Vector3f;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
public class ImportedModel {
private Vector3f[ ] vertices;
private Vector2f[ ] texCoords;
private Vector3f[] normals;
private int numVertices;
public ImportedModel(String filename) {
ModelImporter modelImporter = new ModelImporter();
try {
modelImporter.parseOBJ(filename); // uses modelImporter to get vertex information
numVertices = modelImporter.getNumVertices();
float[ ] verts = modelImporter.getVertices();
float[ ] tcs = modelImporter.getTextureCoordinates();
float[ ] norm = modelImporter.getNormals();
this.vertices = new Vector3f[numVertices];
this.texCoords = new Vector2f[numVertices];
this.normals = new Vector3f[numVertices];
for(int i=0; i<vertices.length; i++)
{ vertices[i] = new Vector3f();
vertices[i].set(verts[i*3], verts[i*3+1], verts[i*3+2]);
texCoords[i] = new Vector2f();
texCoords[i].set(tcs[i*2], tcs[i*2+1]);
this.normals[i] = new Vector3f();
this.normals[i].set(norm[i*3], norm[i*3+1], norm[i*3+2]);
}
} catch (IOException e)
{ e.printStackTrace();
} }
public int getNumVertices() { return numVertices; } // accessors
public Vector3f[ ] getVertices() { return vertices; }
public Vector2f[ ] getTexCoords() { return texCoords; }
public Vector3f[ ] getNormals() { return normals; }
private static class ModelImporter
{ // values as read in from OBJ file
private final ArrayList<Float> vertVals = new ArrayList<>();
private final ArrayList<Float> stVals = new ArrayList<>();
private final ArrayList<Float> normVals = new ArrayList<>();
// values stored for later use as vertex attributes
private final ArrayList<Float> triangleVerts = new ArrayList<>();
private final ArrayList<Float> textureCoords = new ArrayList<>();
private final ArrayList<Float> normals = new ArrayList<>();
public void parseOBJ(String filename) throws IOException
{ InputStream input = Files.newInputStream(new File(filename).toPath());
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = br.readLine()) != null)
{ if(line.startsWith("v")) // vertex position ("v" case)
{ for(String s : (line.substring(2)).split(" "))
{ vertVals.add(Float.valueOf(s)); // extract the vertex position values
} }
else if(line.startsWith("vt")) // texture coordinates ("vt" case)
{ for(String s : (line.substring(3)).split(" "))
{ stVals.add(Float.valueOf(s)); // extract the texture coordinate values
} }
else if(line.startsWith("vn")) // vertex normals ("vn" case)
{ for(String s : (line.substring(3)).split(" "))
{ normVals.add(Float.valueOf(s)); // extract the normal vector values
} }
else if(line.startsWith("f")) // triangle faces ("f" case)
{ for(String s : (line.substring(2)).split(" "))
{ String v = s.split("/")[0]; // extract triangle face references
String vt = s.split("/")[1];
String vn = s.split("/")[2];
int vertRef = (Integer.parseInt(v)-1)*3;
int tcRef = (Integer.parseInt(vt)-1)*2;
int normRef = (Integer.parseInt(vn)-1)*3;
triangleVerts.add(vertVals.get(vertRef)); // build array of vertices
triangleVerts.add(vertVals.get(vertRef+1));
triangleVerts.add(vertVals.get(vertRef+2));
textureCoords.add(stVals.get(tcRef)); // build array of
textureCoords.add(stVals.get(tcRef+1)); // texture coordinates.
normals.add(normVals.get(normRef)); //… and normals
normals.add(normVals.get(normRef+1));
normals.add(normVals.get(normRef+2));
} }}
System.out.println(vertVals);
System.out.println(stVals);
System.out.println(normVals);
input.close();
}
// accessors for retrieving the number of vertices, the vertices themselves,
// and the corresponding texture coordinates and normals (only called once per model)
public int getNumVertices() { return (triangleVerts.size()/3); }
public float[ ] getVertices()
{ float[ ] p = new float[triangleVerts.size()];
for(int i = 0; i < triangleVerts.size(); i++)
{ p[i] = triangleVerts.get(i);
}
return p;
}
public float[] getTextureCoordinates() {
float[] p = new float[textureCoords.size()];
for (int i = 0; i < textureCoords.size(); i++) {
p[i] = textureCoords.get(i);
}
return p;
}
public float[] getNormals() {
float[ ] p = new float[normals.size()];
for(int i = 0; i < normals.size(); i++)
{ p[i] = normals.get(i);
}
return p;
}
// similar accessors for texture coordinates and normal vectors go here
} }
Here are the errors I am getting:
Exception in thread "main-AWTAnimator#00" com.jogamp.opengl.util.AnimatorBase$UncaughtAnimatorException: java.lang.RuntimeException: com.jogamp.opengl.GLException: Caught NumberFormatException: empty String on thread AWT-EventQueue-0
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:92)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:204)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: com.jogamp.opengl.GLException: Caught NumberFormatException: empty String on thread AWT-EventQueue-0
at com.jogamp.common.util.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:58)
at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:103)
at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:201)
at com.jogamp.opengl.Threading.invokeOnOpenGLThread(Threading.java:202)
at com.jogamp.opengl.Threading.invoke(Threading.java:221)
at com.jogamp.opengl.awt.GLCanvas.display(GLCanvas.java:505)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
... 3 more
Caused by: com.jogamp.opengl.GLException: Caught NumberFormatException: empty String on thread AWT-EventQueue-0
at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.opengl.awt.GLCanvas$12.run(GLCanvas.java:1438)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:451)
at java.lang.Float.valueOf(Float.java:416)
at ImportedModel$ModelImporter.parseOBJ(ImportedModel.java:60)
at ImportedModel.<init>(ImportedModel.java:18)
at WalkingTour.init(WalkingTour.java:83)
at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:644)
at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:667)
at com.jogamp.opengl.awt.GLCanvas$10.run(GLCanvas.java:1407)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1291)
... 16 more
Exception in thread "AWT-EventQueue-0" com.jogamp.opengl.GLException: Caught GLException: array vertex_buffer_object must be bound to call this method on thread AWT-EventQueue-0
at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.opengl.awt.GLCanvas$12.run(GLCanvas.java:1438)
at com.jogamp.opengl.Threading.invoke(Threading.java:223)
at com.jogamp.opengl.awt.GLCanvas.display(GLCanvas.java:505)
at com.jogamp.opengl.awt.GLCanvas.paint(GLCanvas.java:559)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:264)
at sun.lwawt.LWRepaintArea.paintComponent(LWRepaintArea.java:59)
at sun.awt.RepaintArea.paint(RepaintArea.java:240)
at sun.lwawt.LWComponentPeer.handleJavaPaintEvent(LWComponentPeer.java:1314)
at sun.lwawt.LWComponentPeer.handleEvent(LWComponentPeer.java:1198)
at java.awt.Component.dispatchEventImpl(Component.java:4965)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: com.jogamp.opengl.GLException: array vertex_buffer_object must be bound to call this method
at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:40621)
at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOBound(GL4bcImpl.java:40653)
at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:12429)
at WalkingTour.display(WalkingTour.java:180)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at com.jogamp.opengl.awt.GLCanvas$11.run(GLCanvas.java:1424)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
... 30 more
Exception in thread "AWT-EventQueue-0" com.jogamp.opengl.GLException: Caught GLException: array vertex_buffer_object must be bound to call this method on thread AWT-EventQueue-0
at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.opengl.awt.GLCanvas$12.run(GLCanvas.java:1438)
at com.jogamp.opengl.Threading.invoke(Threading.java:223)
at com.jogamp.opengl.awt.GLCanvas.display(GLCanvas.java:505)
at com.jogamp.opengl.awt.GLCanvas.paint(GLCanvas.java:559)
at com.jogamp.opengl.awt.GLCanvas.update(GLCanvas.java:866)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:255)
at sun.lwawt.LWRepaintArea.updateComponent(LWRepaintArea.java:47)
at sun.awt.RepaintArea.paint(RepaintArea.java:232)
at sun.lwawt.LWComponentPeer.handleJavaPaintEvent(LWComponentPeer.java:1314)
at sun.lwawt.LWComponentPeer.handleEvent(LWComponentPeer.java:1198)
at java.awt.Component.dispatchEventImpl(Component.java:4965)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: com.jogamp.opengl.GLException: array vertex_buffer_object must be bound to call this method
at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:40621)
at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOBound(GL4bcImpl.java:40653)
at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:12429)
at WalkingTour.display(WalkingTour.java:180)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at com.jogamp.opengl.awt.GLCanvas$11.run(GLCanvas.java:1424)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
... 31 more
Any help would be appreciated.
Trying to parse a .obj model and use the extracted information to load my model into a JOGL program.