java—调用gl30.glgenvertexarray()时出错;

fcwjkofz  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(297)

我正在尝试用java学习opengl和lwjgl,我有一个程序,并试图呈现一些网格,但处理vaos和vbos的类是错误的。在做了一些研究后,我了解到这可能是因为我调用方法相对于makecontextcurrent()的位置造成的;但是我在那里运气不好。
警告
前面有很多代码
错误的阶级

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;
}
}

这是处理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();

}

}

类处理窗口创建

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);
}

}
渲染器

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);
}

}
原始模型

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);
}

}
错误

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)
yrefmtwq

yrefmtwq1#

你的错误只是申报顺序上的一个简单错误。在您的订单中重新排序这些行 MainGameLoop class :

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

这样地:

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

因为在loader类中调用opengl函数( GL30.glGenVertexArrays(); )但是如果没有设置上下文,就不能调用opengl函数。
您可以使用 GL.createCapabilities(); ,这一行在您的 DisplayManager class .
所以 GL.createCapabilities(); 在调用 MainGameLoop class (实际上从来没有执行过,因为jvm以前会崩溃)。

相关问题