本文介绍了LWJGL OpenGL glGenVertexArrays()错误:该功能不可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,使用glGenVertexArrays()遇到困难.我收到以下错误:

All, Having difficulty with glGenVertexArrays(). I get the following error:

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

Here is my Main Game Loop (I call GL.createCapabilities() from the createDisplay() method.)

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

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

As referenced above, here is the Display Manager class:

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

}

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

If would seem the above mentioned error is with the loader class:

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功能/上下文(主游戏循环main方法,使用显示管理器)

As far as I can see this is the correct method to do it, and the GL capabilities/context have been set/called from the main thread (main game loops main method, utilising the display manager)

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

For completeness, here are the RawModel and Renderer Classes, do not suspect an issue these these:

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'的实现提供的任何帮助,将不胜感激.

Any assistance you can give me regarding my implementation of 'glGenVertexArrays' would be much appreciated.

我现在添加了以下内容

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

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

However, am now getting the following error:

createDisplay()的具体实现如下:

The specific implementation of my createDisplay() is as follows:

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

更新

如果已删除错误回调,则认为它们可能会引起问题.产生的错误是:

If have removed the error callbacks, as thought they might be causing an issue. The resulting error is:

如果无法创建glfw窗口,则似乎抛出了RuntimeException,并显示了我的自定义错误消息.这可以与我执行此命令的顺序有关吗?我已经尝试过使用noluck来放置'init'方法.一定有我要忽略的东西吗?...谢谢.

It seems the RuntimeException is being thrown, and is displaying my custom error message if the glfw window cannot be created. Could this be todo with the order in which I run this? I have played around with the placement of the 'init' method with noluck. There has got to be something I am overlooking?... Thanks.

显示管理器的更新代码:

Updated code for the Display Manager:

package renderEngine;

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

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

}

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

Many Thanks and Kind Regards,Jake

推荐答案

glGenVertexArrays函数需要OpenGL 3.0或更高版本.您必须明确告诉GLFW这件事.呼叫glfwCreateWindow之前:

The glGenVertexArrays function requires OpenGL 3.0 or higher. You have to explicitly tell GLFW this. Before calling 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或更高版本.

You can check that you have OpenGL 3.0 or higher by calling GL11.glGetString(GL11.GL_VERSION) or by looking at the GL.getCapabilities().OpenGL30 flag.

这篇关于LWJGL OpenGL glGenVertexArrays()错误:该功能不可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 05:48