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 绘制纹理四边形使用旧纹理