¿Por qué lwjgl (OpenGL) drawElements no atraen?

Joneron:

He tratado de seguir el LWJGL 3.2+ Tutorial sobre drawElements y obtener mi solicitud LWJGL para dibujar un quad. Mi código se ejecuta con éxito, pero no saca nada (aparte de la ventana básica), sin importar dónde dirigir mi método loopCycle que debe dibujar el cuádruple. Asumo que tiene que ver con el cambio de pantalla (Tutorial) a GLFW (mi código)? Vi algunos mensajes que hablan de proyección, vista y matrices modelo que no uso (que yo sepa), es que el problema de por qué no se muestra?

package org.tempest.game;

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import java.nio.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Graphics {

    // The window handle
    private long window;

    // Window setup
    private final String WINDOW_TITLE = "Test";
    // 1920x1080, 1600x900 and 1200x675 are all 16:9 ratios
    private final int WIDTH = 320;
    private final int HEIGHT = 240;

    // Quad variables
    private int vaoId = 0;
    private int vboId = 0;
    private int vboiId = 0;
    private int indicesCount = 0;

    public static void main(String[] args) {
        new Graphics().run();
    }

    public void run() {
        System.out.println("Hello LWJGL " + Version.getVersion() + "!");
        init();

        setupQuad();
        loop();
        destroyOpenGL();

        // Free the window callbacks and destroy the window
        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // Terminate GLFW and free the error callback
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void init() {
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialize GLFW. Most GLFW functions will not work before doing this.
        if ( !glfwInit() )
            throw new IllegalStateException("Unable to initialize GLFW");

        // Configure GLFW
        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

        // Create the window
        window = glfwCreateWindow(WIDTH, HEIGHT, WINDOW_TITLE, NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("Failed to create the GLFW window");

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
        });

        // Get the thread stack and push a new frame
        try ( MemoryStack stack = stackPush() ) {
            IntBuffer pWidth = stack.mallocInt(1); // int*
            IntBuffer pHeight = stack.mallocInt(1); // int*

            // Get the window size passed to glfwCreateWindow
            glfwGetWindowSize(window, pWidth, pHeight);

            // Get the resolution of the primary monitor
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

            // Center the window
            glfwSetWindowPos(
                    window,
                    (vidmode.width() - pWidth.get(0)) / 2,
                    (vidmode.height() - pHeight.get(0)) / 2
            );
        } // the stack frame is popped automatically

        // Make the OpenGL context current
        glfwMakeContextCurrent(window);
        // Enable v-sync with 1
        glfwSwapInterval(0);

        // Make the window visible
        glfwShowWindow(window);
    }

    private void loop() {
        // Initialize variables for fps calculation
        long time_start = System.nanoTime();
        int frames = 0;
        final double check_fps_time = 1d;

        // Set the clear color
        glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
        // TODO Where to initialize this?
        //GL11.glViewport(0, 0, WIDTH, HEIGHT);

        // Run the rendering loop until the user has attempted to close
        // the window or has pressed the ESCAPE key.
        while ( !glfwWindowShouldClose(window) ) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer

            glfwSwapBuffers(window); // swap the color buffers

            // Count, calculate and display fps
            frames++;
            long time_now = System.nanoTime();
            if ((double)(time_now - time_start)/1000000000 > check_fps_time) {
                int fps_prediction = (int)(frames/check_fps_time);
                System.out.println("FPS: " + fps_prediction);
                frames = 0;
                time_start = time_now;
            }

            // Poll for window events. The key callback above will only be
            // invoked during this call.
            glfwPollEvents();

            loopCycle();
        }
    }

    public void setupQuad() {
        GL.createCapabilities();
        // Vertices, the order is not important.
        float[] vertices = {
                -0.5f, 0.5f, 0f,    // Left top         ID: 0
                -0.5f, -0.5f, 0f,   // Left bottom      ID: 1
                0.5f, -0.5f, 0f,    // Right bottom     ID: 2
                0.5f, 0.5f, 0f      // Right left       ID: 3
        };
        // Sending data to OpenGL requires the usage of (flipped) byte buffers
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
        verticesBuffer.put(vertices);
        verticesBuffer.flip();

        // OpenGL expects to draw vertices in counter clockwise order by default
        byte[] indices = {
                // Left bottom triangle
                0, 1, 2,
                // Right top triangle
                2, 3, 0
        };
        indicesCount = indices.length;
        ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(indicesCount);
        indicesBuffer.put(indices);
        indicesBuffer.flip();

        // Create a new Vertex Array Object in memory and select it (bind)
        // A VAO can have up to 16 attributes (VBOs) assigned to it by default
        vaoId = GL30.glGenVertexArrays();
        GL30.glBindVertexArray(vaoId);

        // Create a new Vertex Buffer Object in memory and select it (bind)
        // A VBO is a collection of Vectors which in this case resemble the location of each vertex.
        vboId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
        // Put the VBO in the attributes list at index 0
        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
        // Deselect (bind to 0) the VBO
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        // Deselect (bind to 0) the VAO
        GL30.glBindVertexArray(0);

        // Create a new VBO for the indices and select it (bind)
        vboiId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
        // Deselect (bind to 0) the VBO
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    public void loopCycle() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

        // Bind to the VAO that has all the information about the vertices
        GL30.glBindVertexArray(vaoId);
        GL20.glEnableVertexAttribArray(0);

        // Bind to the index VBO that has all the information about the order of the vertices
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);

        // Draw the vertices
        GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_BYTE, 0);

        // Put everything back to default (deselect)
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        GL20.glDisableVertexAttribArray(0);
        GL30.glBindVertexArray(0);
    }
    public void destroyOpenGL() {
        // Disable the VBO index from the VAO attributes list
        GL20.glDisableVertexAttribArray(0);

        // Delete the vertex VBO
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL15.glDeleteBuffers(vboId);

        // Delete the index VBO
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        GL15.glDeleteBuffers(vboiId);

        // Delete the VAO
        GL30.glBindVertexArray(0);
        GL30.glDeleteVertexArrays(vaoId);
    }

    public int getWIDTH() {
        return WIDTH;
    }

    public int getHEIGHT() {
        return HEIGHT;
    }
}

Soy un principiante y probablemente hay una serie de cosas que necesita para estudiar para hacer este trabajo. Me gustaría escuchar alguna orientación sobre lo que debe buscar en llegar a mi solicitud de hacer algo para que pueda tomar las cosas desde allí. Muchas gracias! :)

Daniele:

Hay por lo menos un problema con este código- que llama clara / dibujar / intercambio en el orden equivocado. Básicamente con OpenGL, el bucle principal debe llamar clear()primero, sacar algunas cosas, y luego llamar swapBuffers()para visualizar el contenido del búfer.

El ejemplo en su lugar: las llamadas clear(bien, borrar el búfer), intercambia los tampones (aquí se muestra una ventana en blanco, ya que se borra la memoria intermedia) y, a continuación, dibuja un montón de cosas a la memoria intermedia. Pero el contenido del búfer no se muestra (ya que en el próximo ciclo, la primera operación es clara () de nuevo).

A continuación el código ligeramente modificada; se dibuja un rectángulo blanco - No estoy totalmente seguro sobre el uso de glBindBuffer(he usado drawLiney drawTriangleen el pasado), pero es un comienzo.

package sample;

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
import java.nio.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class DrawExample {

  // The window handle
  private long window;

  // Window setup
  private final String WINDOW_TITLE = "Test";
  // 1920x1080, 1600x900 and 1200x675 are all 16:9 ratios
  private final int WIDTH = 320;
  private final int HEIGHT = 240;

  // Quad variables
  private int vaoId = 0;
  private int vboId = 0;
  private int vboiId = 0;
  private int indicesCount = 0;

  public static void main(String[] args) {
    new DrawExample().run();
  }

  public void run() {
    System.out.println("Hello LWJGL " + Version.getVersion() + "!");
    init();

    setupQuad();
    loop();
    destroyOpenGL();

    // Free the window callbacks and destroy the window
    glfwFreeCallbacks(window);
    glfwDestroyWindow(window);

    // Terminate GLFW and free the error callback
    glfwTerminate();
    glfwSetErrorCallback(null).free();
  }

  private void init() {
    // Setup an error callback. The default implementation
    // will print the error message in System.err.
    GLFWErrorCallback.createPrint(System.err).set();

    // Initialize GLFW. Most GLFW functions will not work before doing this.
    if (!glfwInit())
      throw new IllegalStateException("Unable to initialize GLFW");

    // Configure GLFW
    glfwDefaultWindowHints(); // optional, the current window hints are already the default
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

    // Create the window
    window = glfwCreateWindow(WIDTH, HEIGHT, WINDOW_TITLE, NULL, NULL);
    if (window == NULL)
      throw new RuntimeException("Failed to create the GLFW window");

    // Setup a key callback. It will be called every time a key is pressed, repeated or released.
    glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
      if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
        glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
    });


    // Get the resolution of the primary monitor
    GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    // Get the thread stack and push a new frame
    try (MemoryStack stack = stackPush()) {
      IntBuffer pWidth = stack.mallocInt(1); // int*
      IntBuffer pHeight = stack.mallocInt(1); // int*

      // Get the window size passed to glfwCreateWindow
      glfwGetWindowSize(window, pWidth, pHeight);



      // Center the window
      glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2,
          (vidmode.height() - pHeight.get(0)) / 2);
    } // the stack frame is popped automatically

    // Make the OpenGL context current
    glfwMakeContextCurrent(window);
    // Enable v-sync with 1
    glfwSwapInterval(1);

    // Make the window visible
    glfwShowWindow(window);
  }

  private void loop() {
    // Initialize variables for fps calculation
    long time_start = System.nanoTime();
    int frames = 0;
    final double check_fps_time = 1d;

    // Set the clear color
    glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
    // TODO Where to initialize this?
    // GL11.glViewport(0, 0, WIDTH, HEIGHT);

    // Run the rendering loop until the user has attempted to close
    // the window or has pressed the ESCAPE key.
    while (!glfwWindowShouldClose(window)) {
      // Count, calculate and display fps
      frames++;
      long time_now = System.nanoTime();
      if ((double) (time_now - time_start) / 1000000000 > check_fps_time) {
        int fps_prediction = (int) (frames / check_fps_time);
        System.out.println("FPS: " + fps_prediction);
        frames = 0;
        time_start = time_now;
      }

      // Poll for window events. The key callback above will only be
      // invoked during this call.
      glfwPollEvents();

      loopCycle();
      glfwSwapBuffers(window); // swap the color buffers

    }
  }

  public void setupQuad() {
    GL.createCapabilities();
    // Vertices, the order is not important.
    float[] vertices = {-0.5f, 0.5f, 0f, // Left top ID: 0
        -0.5f, -0.5f, 0f, // Left bottom ID: 1
        0.5f, -0.5f, 0f, // Right bottom ID: 2
        0.5f, 0.5f, 0f // Right left ID: 3
    };
    // Sending data to OpenGL requires the usage of (flipped) byte buffers
    FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
    verticesBuffer.put(vertices);
    verticesBuffer.flip();

    // OpenGL expects to draw vertices in counter clockwise order by default
    byte[] indices = {
        // Left bottom triangle
        0, 1, 2,
        // Right top triangle
        2, 3, 0};
    indicesCount = indices.length;
    ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(indicesCount);
    indicesBuffer.put(indices);
    indicesBuffer.flip();

    // Create a new Vertex Array Object in memory and select it (bind)
    // A VAO can have up to 16 attributes (VBOs) assigned to it by default
    vaoId = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vaoId);

    // Create a new Vertex Buffer Object in memory and select it (bind)
    // A VBO is a collection of Vectors which in this case resemble the location of each vertex.
    vboId = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
    // Put the VBO in the attributes list at index 0
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
    // Deselect (bind to 0) the VBO
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    // Deselect (bind to 0) the VAO
    GL30.glBindVertexArray(0);

    // Create a new VBO for the indices and select it (bind)
    vboiId = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
    // Deselect (bind to 0) the VBO
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
  }

  public void loopCycle() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Bind to the VAO that has all the information about the vertices
    GL30.glBindVertexArray(vaoId);
    GL20.glEnableVertexAttribArray(0);

    // Bind to the index VBO that has all the information about the order of the vertices
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);

    // Draw the vertices
    GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_BYTE, 0);

    // Put everything back to default (deselect)
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
  }

  public void destroyOpenGL() {
    // Disable the VBO index from the VAO attributes list
    GL20.glDisableVertexAttribArray(0);

    // Delete the vertex VBO
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL15.glDeleteBuffers(vboId);

    // Delete the index VBO
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL15.glDeleteBuffers(vboiId);

    // Delete the VAO
    GL30.glBindVertexArray(0);
    GL30.glDeleteVertexArrays(vaoId);
  }

  public int getWIDTH() {
    return WIDTH;
  }

  public int getHEIGHT() {
    return HEIGHT;
  }
}

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=478807&siteId=1
Recomendado
Clasificación