我正在尝试用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)
1条答案
按热度按时间yrefmtwq1#
你的错误只是申报顺序上的一个简单错误。在您的订单中重新排序这些行
MainGameLoop class
:这样地:
因为在loader类中调用opengl函数(
GL30.glGenVertexArrays();
)但是如果没有设置上下文,就不能调用opengl函数。您可以使用
GL.createCapabilities();
,这一行在您的DisplayManager class
.所以
GL.createCapabilities();
在调用MainGameLoop class
(实际上从来没有执行过,因为jvm以前会崩溃)。