LWJGL - чередующийся VAO/VBO не текстурируется
Я пытался перевести рендерер прототипа моей игры из реализации тестирования в непосредственном режиме в реальную реализацию VAO/VBO. VBO рендерится на экране, но отказывается от текстуры. Ниже приведен простейший тестовый класс, который показывает проблему:
public static void main(String[] args) throws Exception {
// VertX,VertY TexX, TexY
float[] data = new float[] {0.0f, 0.0f, 0.25f, 0.75f,
0.0f, 64.0f, 0.25f, 1.0f,
64.0f, 64.0f, 0.5f, 1.0f,
0.0f, 0.0f, 0.25f, 0.75f,
64.0f, 64.0f, 0.5f, 1.0f,
64.0f, 0.0f, 0.5f, 0.75f};
glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
if (!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
long window = GLFW.glfwCreateWindow(1600, 900, "TEST", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1600, 900, 0, 0.000001, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int vboId = glGenBuffers();
int vaoId = glGenVertexArrays();
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 4*Float.BYTES);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glTranslatef(50, 50, 0);
Texture t = new Texture(TEST.class.getClassLoader().getResourceAsStream("test/WallFloor.png"));
while (!GLFW.glfwWindowShouldClose(window)) {
GLFW.glfwPollEvents();
GLFW.glfwSwapBuffers(window);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
t.bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
/* Equivelent immediate mode code - that works
t.bind();
glBegin(GL_TRIANGLES);
glTexCoord2f(0.25f, 0.75f);
glVertex2f(0, 0);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glTexCoord2f(0.5f, 1f);
glVertex2f(64, 64);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glEnd();
*/
}
}
Вызов связывания текстуры выглядит следующим образом (где wrap = GL_REPEAT и filter = GL_NEAREST):
public void bind()
{
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(target, id);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
}
Проведя выходные в поисках ответа, не найдя ответа, я делаю что-то ужасно неправильно? Я также протестировал использование немедленного режима, который по-прежнему отображается с текстурой.
1 ответ
Кроме того, вы смешиваете код профиля ядра (glVertexAttribPointer
) с непрофильным профилем (glTexCoordPointer
)
Но настоящая проблема заключается в неправильном шаге и смещении. Stride определяет, насколько велики данные одной вершины, а смещение указывает, как далеко от начала каждой вершины начинаются фактические данные. В вашем случае каждая вершина состоит из 4-х чисел, поэтому шаг должен быть 4 * Float.BYTES
, Позиции - это первые два числа с плавающей точкой в каждой вершине (смещение 0), а координаты текстуры - это 3-е и 4-е число, что означает offset = 2 * Float.BYTES
, Правильный код может выглядеть примерно так (обратите внимание на использование glVertexPointer
вместо glVertexAttribPointer
):
glVertexPointer(2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 2*Float.BYTES);
редактировать
Использование ваших VAO также неправильно. При инициализации вы сохраняете glVertexPointer/glTexCoordPointer в VAO vaoId
, Но в коде рендеринга вы связываете VAO 0 вместо этого. Скорее всего, настройки атрибута отсутствуют при рисовании. Кроме того, я не совсем уверен, работают ли VAO вместе с вызовами фиксированных функций. В этом случае вы можете удалить все вызовы VAO.