-2

i am trying to learn usinf opengl and lwjgl with java and i have amde a program and am trying to render some mesh but the class handling the Vaos and Vbos is faulty.After doing some research , i have learnt that this may be cause because of the position of my calling the method relative to the MakecontextCurrent(); method but i got no luck there.

Warning

Alot of code ahead

The faulty class

package renderEngine;

import java.nio.FloatBuffer;
import java.util.*;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;

public class Loader {
private List<Integer>vaos = new ArrayList<Integer>();
private List<Integer>vbos = new ArrayList<Integer>();
public RawModel loadToVao(float[] positions) {
    int vaoID = createVAO();
    storeDataInAttributeList(0, positions);
    unbind();
    return new RawModel(vaoID,positions.length/3);
    
}
public void cleanup() {
    for(int vao : vaos) {
        GL30.glDeleteVertexArrays(vao);
    }
    for(int vbo : vbos) {
        GL30.glDeleteVertexArrays(vbo);
    }
}
public int createVAO() {
    int vaoID = GL30.glGenVertexArrays();
    vaos.add(vaoID);
    GL30.glBindVertexArray(vaoID);
    return vaoID;
}
public void storeDataInAttributeList(int attributeNumber , float [] data) {
    int vboID = GL15.glGenBuffers();
    vbos.add(vboID);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
    FloatBuffer buffer = storeDataInFloatBuffer(data);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(attributeNumber, 3,GL11.GL_FLOAT,false,0,0);
    GL30.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    }
public void unbind() {
    GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;
}
}

this is the class which handles the gameloop

package renderEngine;

import org.lwjgl.glfw.GLFW;

public class MainGameLoop implements Runnable{
public Loader loader;
public Thread gamethread;
public DisplayManager display;
public RawModel model;
Renderer renderer;
public static void main(String[] args) {
    new MainGameLoop().start();
}

private void start() {
    gamethread = new Thread(this , "game");
    gamethread.start();
}
@Override
public void run() {
    init();
    while (!display.shouldClose()) {
        update();
        render();
    }
    loader.cleanup();
}

private void render() {
    renderer.prepare();
    renderer.renderModel(model);
    display.render();
}

private void update() {
    display.update();
}

private void init() {
    float[] vertices = new float[] {
            0.5f , 0.5f , 0.0f , -0.5f , 0.5f , 0.0f , -0.5f , -0.5f , 0.0f , 0.5f , -0.5f , 0.0f
    };
    loader = new Loader();
    display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
    display.createDisplay();
    model = loader.loadToVao(vertices);
    renderer = new Renderer();
    
    
}

}

Class handling the window creating

package renderEngine;

import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;

public class DisplayManager {

public int width , height;
public String title;
public long monitor = 0;
private long window;

public DisplayManager(int width , int height , String title , long monitor) {
    this.width = width;
    this.title = title;
    this.height = height;
    this.monitor = monitor;
}
public void createDisplay() {
    if(glfwInit()) {
        //handle initialization error
        System.err.println("Error001:FailedInitialization");
    }
    //create window
    window = glfwCreateWindow(width, height, title,monitor , 0);
    if (window == 0) {
        //handle window creation error
        System.err.println("Error002:FailedDisplayCreation");
    }
    //create vidmode
    GLFWVidMode vm = glfwGetVideoMode(glfwGetPrimaryMonitor());
    int xpos  = vm.width()/2-width/2, ypos = vm.height()/2-height/2;
    //set position to center
    glfwSetWindowPos(window, xpos, ypos);
    glfwMakeContextCurrent(ypos);
    GL.createCapabilities();
    //show window
    glfwShowWindow(window);
}
public void destroyWindow() {
    glfwDestroyWindow(window);
    glfwTerminate();
}
public void render() {
    glfwSwapBuffers(window);
}
public void update() {
    glfwPollEvents();
}
public boolean shouldClose() {
    return glfwWindowShouldClose(window);
}

}

The renderer

package renderEngine;

import org.lwjgl.opengl.*;

public class Renderer {
public void prepare() {
    GL11.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    GL11.glClear(GL15.GL_ARRAY_BUFFER);
}
public void renderModel(RawModel model) {
    GL30.glBindVertexArray(model.getVaoID());
    GL30.glEnableVertexAttribArray(0);
    GL11.glDrawArrays(GL11.GL_TRIANGLES,0, model.getVertexCount());
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
}

}

the raw model

package renderEngine;

import org.lwjgl.opengl.*;

public class Renderer {
public void prepare() {
    GL11.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    GL11.glClear(GL15.GL_ARRAY_BUFFER);
}
public void renderModel(RawModel model) {
    GL30.glBindVertexArray(model.getVaoID());
    GL30.glEnableVertexAttribArray(0);
    GL11.glDrawArrays(GL11.GL_TRIANGLES,0, model.getVertexCount());
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
}

}

The error

FATAL ERROR in native method: Thread[game,5,main]: No context is current or a function that is not 
available in the current context was called. The JVM will abort execution.
at org.lwjgl.opengl.GL30C.nglGenVertexArrays(Native Method)
at org.lwjgl.opengl.GL30C.glGenVertexArrays(GL30C.java:2420)
at org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:2369)
at renderEngine.Loader.createVAO(Loader.java:28)
at renderEngine.Loader.loadToVao(Loader.java:13)
at renderEngine.MainGameLoop.init(MainGameLoop.java:47)
at renderEngine.MainGameLoop.run(MainGameLoop.java:21)
at java.lang.Thread.run(java.base@11.0.8/Thread.java:834)

1 Answers1

0

Your error is juste a simple mistake in declaration order. Reorder these line in your MainGameLoop class :

loader = new Loader();
display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
display.createDisplay();

Like this :

display = new DisplayManager(900, 500, "Our Game",GLFW.glfwGetPrimaryMonitor());
display.createDisplay();
loader = new Loader();

Because in your Loader class you call OpenGL function (GL30.glGenVertexArrays();) but you cannot call OpenGL function if no context have been already setup.
You setup an OpenGL context with GL.createCapabilities();, and this line is in your DisplayManager class.
So the GL.createCapabilities(); is executed after the call to OpenGL function in your MainGameLoop class (in reality is never executed because the JVM will crash before).

Hpn4
  • 119
  • 6