2016-08-29 2 views
0

Я пытаюсь преобразовать рендеринга прототипа моей игры из его немедленного тестирования режима в реальную реализацию VAO/VBO. VBO выводит на экран, но отказывается от текстуры. Ниже простейший тест класс, который показывает проблему:LWJGL - Interleaved VAO/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(); 
      */ 

    } 
} 

Текстуры привязывать вызов является следующее (где упаковка = GL_REPEAT и фильтр = 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); 
} 

Проведя выходные прибегая к помощи его в не найдя ответа, я делаю что-то ужасно неправильно? Я также тестировал, используя немедленный режим, который все еще визуализируется с текстурой.

ответ

4

Кроме того, вы смешиваете код ядра профиля (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); 

Редактировать

Использование ваших VAOs тоже неправильно. В инициализации вы храните glVertexPointer/glTexCoordPointer для VAO vaoId. Но в коде рендеринга вместо этого вы привязываете VAO 0. Скорее всего, настройки атрибута отсутствуют при рисовании. Кроме того, я не совсем уверен, работают ли VAO вместе с фиксированными вызовами функций. В этом случае вы можете удалить все вызовы VAO.

+0

Приведенный выше код создает неструктурированный квадрат или нарушение прав доступа в зависимости от того, является ли «glVertexAttribPointer» или «glVertexPointer». Кроме того, как запрос, какова будет замена основного профиля для «glTexCoordPointer»? – jediminer543

+0

Замена основного профиля будет 'glVertexAttribPointer'. Атрибуты определяются шейдером, поэтому запросите расположение атрибута координаты текстуры и используйте это как первый параметр для 'glVertexAttribPointer'. – BDL

+0

См. Править для получения дополнительной информации – BDL

Смежные вопросы