-3

我正在尝试使用 java 学习 usinf 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;
}
}

这是处理游戏循环的类

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

1 回答 1

0

您的错误只是声明顺序中的一个简单错误。在您的以下行重新排序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 函数。
您使用 设置 OpenGL 上下文GL.createCapabilities();,并且此行在您的DisplayManager class.
因此,GL.createCapabilities();在您调用 OpenGL 函数之后执行MainGameLoop class(实际上从未执行,因为 JVM 之前会崩溃)。

于 2020-11-20T18:40:26.537 回答