LWJGL OpenGL glGenVertexArrays() 错误:此函数不可用

Posted

技术标签:

【中文标题】LWJGL OpenGL glGenVertexArrays() 错误:此函数不可用【英文标题】:LWJGL OpenGL glGenVertexArrays() Error: This Function is not available 【发布时间】:2016-05-22 17:04:47 【问题描述】:

所有,glGenVertexArrays() 遇到困难。我收到以下错误:

线程“main”java.lang.IllegalStateException 中的异常:此功能不可用。 在 org.lwjgl.system.Checks.checkFunctionality(Checks.java:57) 在 org.lwjgl.opengl.GL30.getInstance(GL30.java:667) 在 org.lwjgl.opengl.GL30.getInstance(GL30.java:662) 在 org.lwjgl.opengl.GL30.nglGenVertexArrays(GL30.java:2789) 在 org.lwjgl.opengl.GL30.glGenVertexArrays(GL30.java:2816) 在 renderEngine.Loader.createVAO(Loader.java:26) 在 renderEngine.Loader.loadToVAO(Loader.java:19) 在 renderEngine.MainGameLoop.main(MainGameLoop.java:27)

这是我的主游戏循环(我从 createDisplay() 方法调用 GL.createCapabilities()。)

package renderEngine;

import static org.lwjgl.glfw.GLFW.*;

public class MainGameLoop 

public static DisplayManager dm = new DisplayManager();

public static void main(String[] args) 

    //Create Display
    dm.createDisplay();

    Loader loader = new Loader();
    Renderer renderer = new Renderer();

    float[] vertices = 
        -0.5f,0.5f,0f,
        -0.5f,-0.5f,0f,
        0.5f,-0.5f,0f,

        0.5f,-0.5f,0f,
        0.5f,0.5f,0f,
        -0.5f,0.5f,0f
    ;

    RawModel model = loader.loadToVAO(vertices);
    //Game Loop
    while (glfwWindowShouldClose(dm.getWindowID()) != GLFW_TRUE) 
        renderer.prepare();
        renderer.render(model);
        dm.updateDisplay();
    

    //Destroy Display
    dm.destroyWindow();
    loader.cleanUp();


如上所述,这里是显示管理器类:

package renderEngine;

import static org.lwjgl.glfw.GLFW.*;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;

public class DisplayManager 

private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;

private long windowID; 

//Constructor
public DisplayManager()
    init();


private void init()
    if(glfwInit() != GLFW_TRUE)
        throw new IllegalStateException("Unable to initiate GLFW");
    


public long createDisplay()
    windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
    if(windowID == 0)
        glfwTerminate();
        throw new RuntimeException("Failed to create the GLFW window");
    

    GLFW.glfwSetWindowTitle(windowID, "GLFW Window");

    setErrorCallback();
    setKeyCallback();

    glfwMakeContextCurrent(windowID);
    GL.createCapabilities();

    return windowID;


public long getWindowID()
    return this.windowID;


private void setErrorCallback()
    errorCallback = GLFWErrorCallback.createPrint(System.err);
    glfwSetErrorCallback(errorCallback);


private void setKeyCallback()

    keyCallback = new GLFWKeyCallback()
        @Override
        public void invoke(long window, int key, int scancode, int action, int mods) 
            if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
                glfwSetWindowShouldClose(window, GLFW_TRUE);
            
        
    ;
    glfwSetKeyCallback(windowID, keyCallback);


public void updateDisplay()
    GLFW.glfwSwapInterval(1);
    glfwSwapBuffers(windowID);
    glfwPollEvents();


public void destroyWindow()
    glfwDestroyWindow(windowID);
    keyCallback.release();
    glfwTerminate();
    errorCallback.release();



如果上面提到的错误似乎与加载器类有关:

package renderEngine;

import java.util.List;
import java.nio.FloatBuffer;
import java.util.ArrayList;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

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);
    unbindVAO();
    return new RawModel(vaoID,positions.length/3);


private int createVAO() 
    int vaoID = GL30.glGenVertexArrays();
    vaos.add(vaoID);
    GL30.glBindVertexArray(vaoID);
    return vaoID;



private 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);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);


private void unbindVAO() 
    GL30.glBindVertexArray(0); //0 un-binds currently bound VAO


public void cleanUp()
    for(int vao:vaos)
        GL30.glDeleteVertexArrays(vao);
    

    for(int vbo:vbos)
        GL15.glDeleteBuffers(vbo);
    


private FloatBuffer storeDataInFloatBuffer(float[] data)
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;



特别是这行代码:

GL30.glBindVertexArray(vaoID);

据我所知,这是正确的方法,并且已从主线程设置/调用 GL 功能/上下文(主游戏循环主方法,利用显示管理器)

为了完整起见,这里是 RawModel 和 Renderer 类,不要怀疑这些问题:

package renderEngine;

public class RawModel 

private int vaoID;
private int vertexCount;

public RawModel(int vaoID, int vertexCount)
    this.vaoID = vaoID;
    this.vertexCount = vertexCount;


public int getVaoID() 
    return vaoID;


public int getVertexCount() 
    return vertexCount;



这里是渲染器类:

package renderEngine;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

public class Renderer 

public void prepare()
    GL11.glClearColor(1, 0, 0, 1);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);


public void render(RawModel model)
    GL30.glBindVertexArray(model.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);



您可以就我的“glGenVertexArrays”的实现提供任何帮助。

我现在添加了以下内容

    GLFW.glfwDefaultWindowHints();
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);

但是,现在出现以下错误:

线程“main”java.lang.RuntimeException 中的异常:无法创建 GLFW 窗口 在 renderEngine.DisplayManager.createDisplay(DisplayManager.java:37) 在 renderEngine.MainGameLoop.main(MainGameLoop.java:12)

我的createDisplay()的具体实现如下:

    public long createDisplay()
    GLFW.glfwDefaultWindowHints();
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);


    windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
    if(windowID == 0)
        glfwTerminate();
        throw new RuntimeException("Failed to create the GLFW window");
    



    GLFW.glfwSetWindowTitle(windowID, "GLFW Window");

    setErrorCallback();
    setKeyCallback();

    glfwMakeContextCurrent(windowID);
    GL.createCapabilities();

    return windowID;

更新

如果已删除错误回调,因为认为它们可能会导致问题。产生的错误是:

线程“main”java.lang.RuntimeException 中的异常:无法创建 GLFW 窗口 在 renderEngine.DisplayManager.createDisplay(DisplayManager.java:40) 在 renderEngine.MainGameLoop.main(MainGameLoop.java:12)

似乎正在抛出 RuntimeException,如果无法创建 glfw 窗口,则会显示我的自定义错误消息。这可能与我运行它的顺序有关吗?我已经玩弄了 noluck 的“init”方法的位置。一定有什么我忽略了?...谢谢。

显示管理器的更新代码:

package renderEngine;

导入静态 org.lwjgl.glfw.GLFW.*;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;

public class DisplayManager 

private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;

private long windowID; 

//Constructor
public DisplayManager()

    init();


private void init()

    if(glfwInit() != GLFW_TRUE)
        throw new IllegalStateException("Unable to initiate GLFW");
    


public long createDisplay()
    GLFW.glfwDefaultWindowHints();
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
    GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);


    windowID = glfwCreateWindow(640,480,"Hello World!", 0, 0);
    System.out.println(windowID);
    if(windowID == 0)
        glfwTerminate();
        throw new RuntimeException("Failed to create the GLFW window");
    

    glfwMakeContextCurrent(windowID);
    GL.createCapabilities();


    GLFW.glfwSetWindowTitle(windowID, "GLFW Window");

    //setErrorCallback();
    //setKeyCallback();


    return windowID;


public long getWindowID()
    return this.windowID;


private void setErrorCallback()
    errorCallback = GLFWErrorCallback.createPrint(System.err);
    glfwSetErrorCallback(errorCallback);


private void setKeyCallback()

    keyCallback = new GLFWKeyCallback()
        @Override
        public void invoke(long window, int key, int scancode, int action, int mods) 
            if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
                glfwSetWindowShouldClose(window, GLFW_TRUE);
            
        
    ;
    glfwSetKeyCallback(windowID, keyCallback);


public void updateDisplay()
    GLFW.glfwSwapInterval(1);
    glfwSwapBuffers(windowID);
    glfwPollEvents();


public void destroyWindow()
    glfwDestroyWindow(windowID);
    keyCallback.release();
    glfwTerminate();
    errorCallback.release();



非常感谢和亲切的问候, 杰克

【问题讨论】:

【参考方案1】:

glGenVertexArrays 函数需要 OpenGL 3.0 或更高版本。你必须明确告诉 GLFW。致电glfwCreateWindow之前:

GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.CONTEXT_VERSION_MINOR, 0);

您可以通过调用GL11.glGetString(GL11.GL_VERSION) 或查看GL.getCapabilities().OpenGL30 标志来检查您是否拥有OpenGL 3.0 或更高版本。

【讨论】:

感谢您,我已将其直接放在 glfwcreatewindow() 上方,但出现以下错误:线程“main”中的异常 java.lang.RuntimeException:无法在 renderEngine.DisplayManager 处创建 GLFW 窗口.createDisplay(DisplayManager.java:37) 在 renderEngine.MainGameLoop.main(MainGameLoop.java:12) 有什么想法吗? 对不起 - 我现在已经编辑了上面的答案。您的想法将不胜感激。谢谢 在调用 init 之前尝试设置错误回调 (setErrorCallback) 并查看输出是什么。 我已经按照您的说法尝试过,也尝试过在调用 init() 时更改点但没有运气?我已经更新了上面的内容,还有什么我忽略的吗? 由于某种原因 GLFW 无法创建窗口。您必须在创建窗口之前设置错误回调,以便 GLFW 可以告诉您确切的错误是什么(另请参阅the documentation)。

以上是关于LWJGL OpenGL glGenVertexArrays() 错误:此函数不可用的主要内容,如果未能解决你的问题,请参考以下文章

LWJGL OpenGL glGenVertexArrays() 错误:此函数不可用

使用 OpenGL / LWJGL 绘制纹理四边形使用旧纹理

是否可以使用 LWJGL 将 C++ OpenGL 代码与 Java 混合?

透视投影 OPENGL 和计算着色器

LWJGL3的内存管理,简介及目录

是否可以使用 LWJGL 以无头模式渲染到 FBO?