javaopengllwjgl

LWJGL 3 not rendering anything


I can create the window, but I cannot render anything. Here's my code:

LWJGLTutorial.java:

package core;

import logger.Logger;
import model.ModelLoader;
import model.RawModel;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;

import java.nio.IntBuffer;

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.*;

// Main class
public class LWJGLTutorial {

    // The window
    private long window;

    // The game
    private void run() {
        // Create logger
        Logger logger = new Logger("MAIN");

        // Validate LWJGL installation
        logger.log("LWJGL Version: " + Version.getVersion());

        // Set a error callback
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialize and configure GLFW
        if(!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
        logger.log("Initialized GLFW");

        // Create window
        window = glfwCreateWindow(800, 600, "LWJGL Tutorial", NULL, NULL);
        if(window == NULL)
            throw new RuntimeException("Failed to create window");
        logger.log("Created window");

        // Set a key callback
        glfwSetKeyCallback(window, new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
                    glfwSetWindowShouldClose(window, true);
            }
        });
        // Set a framebuffer size callback
        glfwSetFramebufferSizeCallback(window, new GLFWFramebufferSizeCallback() {
            @Override
            public void invoke(long window, int width, int height) {
                glViewport(0, 0, width, height);
            }
        });
        logger.log("Callbacks set");

        // Get the thread stack and push a new frame
        try(MemoryStack stack = stackPush()) {
            IntBuffer pWidth = stack.mallocInt(1);
            IntBuffer pHeight = stack.mallocInt(1);
            glfwGetWindowSize(window, pWidth, pHeight);
            GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
            glfwSetWindowPos(window, (vidMode.width() - pWidth.get(0)) / 2, (vidMode.height() - pHeight.get(0)) / 2);
        }

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

        // This line is critical for LWJGL's interoperation with GLFW's OpenGL context
        GL.createCapabilities();

        float[] vertices = {
                // Left bottom triangle
                -0.5f, 0.5f, 0f,
                -0.5f, -0.5f, 0f,
                0.5f, -0.5f, 0f,
                // Right top triangle
                0.5f, -0.5f, 0f,
                0.5f, 0.5f, 0f,
                -0.5f, 0.5f, 0f
        };
        RawModel model = ModelLoader.load(vertices);

        // Enable depth test
        glEnable(GL_DEPTH_TEST);

        // Render loop
        while(!glfwWindowShouldClose(window)) {
            // Set clear color
            glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
            // Clear framebuffer
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            // Render models
            Renderer.render(model);

            // Swap color buffer
            glfwSwapBuffers(window);
            // Poll IO events
            glfwPollEvents();
        }

        // Clean up
        logger.log("Clean up...");
        ModelLoader.cleanUp();
        // Free the window callbacks and destroy the window
        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // Terminate GLFW and free error callback
        glfwTerminate();
        glfwSetErrorCallback(null).free();
        logger.log("Normal exit");
    }

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

}

ModelLoader.java:

package model;

import org.lwjgl.BufferUtils;

import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

import static org.lwjgl.opengl.GL30.*;

// Loads data into a RawModel
public class ModelLoader {

    // A list of VAOs
    private static List<Integer> VAOs = new ArrayList<>();
    // A list of VBOs
    private static List<Integer> VBOs = new ArrayList<>();

    // Load data into a RawModel
    public static RawModel load(float[] data) {
        int vao = createVAO();
        int vbo = createVBO();
        glBindVertexArray(vao);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);

        FloatBuffer buffer = storeDataInFloatBuffer(data);
        glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        return new RawModel(vao, data.length / 3);
    }

    // Deletes all created VAO and VBO
    public static void cleanUp() {
        for(int VAO : VAOs)
            glDeleteVertexArrays(VAO);
        for(int VBO : VBOs)
            glDeleteBuffers(VBO);
    }

    // Generates a new VAO and stores it into the VAO list
    private static int createVAO() {
        int vao = glGenVertexArrays();
        VAOs.add(vao);
        return vao;
    }

    // Generates a new VBO and stores it into the VBO list
    private static int createVBO() {
        int vbo = glGenBuffers();
        VBOs.add(vbo);
        return vbo;
    }

    // Convert data into FloatBuffer
    private static FloatBuffer storeDataInFloatBuffer(float[] data) {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }

}

Renderer.java:

package core;

import model.RawModel;

import static org.lwjgl.opengl.GL30.*;

// Renderer that render stuff onto the screen
public class Renderer {

    // Render a RawModel
    public static void render(RawModel model) {
        glBindVertexArray(model.getVAO());
        glDrawArrays(GL_TRIANGLES, 0, model.getVertexCount());
    }

}

RawModel.java:

package model;

import lombok.Getter;

// Represents a model that can be rendered
public class RawModel {

    // VAO
    @Getter
    private int VAO;
    // Number of vertices
    @Getter
    private int vertexCount;

    public RawModel(int VAO, int vertexCount) {
        this.VAO = VAO;
        this.vertexCount = vertexCount;
    }

}

I should be able to render a rectangle, but nothing is showing. I knew that it is not the problem with lombok, and I suspect that something went wrong in ModelLoader.java or Renderer.java. What is wrong with my code?


Solution

  • I don't see a shader created or being used in your code. A shader is what essentially renders the program. Do you have one?