我正在尝试在 LWJGL 中创建一个批处理渲染器,但我不确定为什么它不起作用。我有一个关于为什么它不起作用的理论,我认为它与索引和顶点的顺序有关但不确定。游戏的图形存储在一个 1,000-10,000 个顶点长的巨大列表中(一个批次),然后渲染该批次。我有一个 (addSprite) 方法,可以将顶点添加到不断增长的列表/数组中。
renderBatch.java
public class BatchRenderer {
private int VBO, IBO;
private float[] vertices = new float[1024];
private int[] indices = new int[1024];
private int currentSprite = 0;
public void addSprite(Vector2 position, Vector2 scale) {
Transform scalar = new Transform();
Vector2 tScale = scalar.transformScreenScaleToNCS(new Vector2(scale.getX(), scale.getY()));
Vector2 tPos = scalar.transformScreenToNCS(new Vector2(position.getX(), position.getY()), new Vector2(tScale.getX(), tScale.getY()));
// int offset = currentSprite * 4 *
// gets the position of the vertices
float[] pos = new float[]{
tPos.getX(), tPos.getY() + tScale.getY(), 0.0f,
tPos.getX() + tScale.getX(), tPos.getY() + tScale.getY(), 0.0f,
tPos.getX() + tScale.getX(), tPos.getY(), 0.0f,
tPos.getX(), tPos.getY(), 0.0f
};
int[] index = new int[]{
0, 1, 3,
1, 2, 3
};
// adds the new positions to the list
// vertex
int iv = 0;
for (Float p: pos) {
vertices[iv + currentSprite] = p.floatValue();
iv++;
}
int ii = 0;
// indices
for (Integer i: index) {
indices[currentSprite + ii] = i.intValue();
ii++;
}
currentSprite += 6;
System.out.println("Vertices: " + Arrays.toString(vertices));
System.out.println("Indices: " + Arrays.toString(indices));
}
public void start() {
// vertex
VBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
// indices
IBO = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
}
public void render() {
glDrawElements(GL_TRIANGLES, currentSprite * 6, GL_UNSIGNED_INT, 0);
}
}
窗口.java
public class Window implements Runnable {
// level
private Level level;
// game loop
private Thread thread;
private boolean running = false;
// window
private long window;
public void start() {
running = true;
thread = new Thread(this, "Game");
thread.start();
}
private void init() {
// checks if glfw is initialized or not
if (!glfwInit()) {
return;
} else {
glfwInit();
}
// sets window hints such as resizable as false
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
glfwWindowHint(GLFW_VISIBLE, GL_TRUE);
// creates the window
window = glfwCreateWindow(Consts.width, Consts.height, Consts.title, NULL, NULL);
// if failed window creation leave and exit program
if (window == NULL) {
return;
}
// position of window relative to the screen pixels
glfwSetWindowPos(window,300, 300);
// input detector
glfwSetKeyCallback(window, new Input());
// creates the opengl context for the program (think of it as a object that stores opengl)
glfwMakeContextCurrent(window);
GL.createCapabilities();
Shader shader = new Shader();
shader.create();
shader.use();
shader.uploadFloat4("u_Color", 0.0f, 1.0f, 0.0f, 1.0f);
level = new Level();
// clears the screen color to (black)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void run() {
init();
// while loop or the main game loop updates 60 times per second
while (running) {
update();
render();
if (glfwWindowShouldClose(window)) {
glfwDestroyWindow(window);
glfwTerminate();
running = false;
}
}
}
private void render() {
// fill the screen
glClear(GL_COLOR_BUFFER_BIT);
level.render();
int error = glGetError();
if (error != GL_NO_ERROR) {
System.out.println(error);
}
// updates the screen
glfwSwapBuffers(window);
}
private void update() {
glfwPollEvents();
}
}
结果是有一个工作批处理渲染,它能够放置一个坐标和大小(当然转换)并渲染数组......目前结果涉及整个窗口的随机绿线表明它很可能是索引问题订购...我没有尝试太多,正如我提到的,我是 OpenGl 的新手,所以不确定该尝试什么。