So, I just started learning LWJGL 3 and I used a mixture of a couple of tutorials and example code to make something that should render a rectangle to a magenta screen using VAOs and VBOs. There are no errors but the rectangle doesn't appear on screen (all I can see is a magenta screen). I tried using the old LWJGL pipeline (glBegin() and glEnd()) and it does work so I tried changing random things in the rendering code and the loading to VAOs and VBOs. I also tried to bind the VBO too but it didn't change anything. I also tried debugging and it seems like there is a VAO and a VBO that is created.

Can someone take a look at my code and see if something looks wrong? Here it is (sorry if its a bit messy):

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

import engine.io.Loader;
import engine.io.RawModel;
import engine.io.Renderer;
import engine.io.Window;

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 Main {

private Window window;

Loader loader = new Loader();
Renderer renderer = new Renderer();

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;

public void run() {


private void loop() {
    while ( !glfwWindowShouldClose(window.getWindowNum()) ) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
        glfwSwapBuffers(window.getWindowNum()); // swap the color buffers

public void setup() {
    window = new Window(900, 300, "Flappy Bird");

    model = loader.loadToVAO(vertices);
    GL11.glViewport(0, 0, 900, 300);

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


Here is the window class:

package engine.io;

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

import java.nio.IntBuffer;

//import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.system.MemoryStack;

public class Window {
private int width, height;
private String title;
private long window;

public Window(int width, int height, String title) {
    this.width = width;
    this.height = height;
    this.title = title;

public void create() {

    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); // the window will stay hidden after creation
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

    // Create the window
    window = glfwCreateWindow(width, height, "Flappy Bird", NULL, NULL);
    if (window == NULL)
        throw new RuntimeException("Failed to create the GLFW window");

    // 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
        // 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

    // Make the OpenGL context current
    // Enable v-sync

    // Make the window visible


public long getWindowNum() {
    return window;


And the Raw Model class:

package engine.io;

public class RawModel {
private int vaoID;
private int vertexCount;

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

public int getVaoID() {
    return vaoID;

public int getVertexCount() {
    return vertexCount;


The loader class:

package engine.io;

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

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;

public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();

public RawModel loadToVAO(float[] positions) {
    int vaoID = createVAO();
    storeDataInAttributeList(0, positions);
    return new RawModel(vaoID, positions.length/3);

private int createVAO() {
    int vaoID = GL30.glGenVertexArrays();
    return vaoID;

private void storeDataInAttributeList(int attributeNumber, float[] data) {
    int vboID = GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
    FloatBuffer buffer = storeDataInFloatBuffer(data);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

private void unbindVAO() {

private FloatBuffer storeDataInFloatBuffer(float[] data) {
    FloatBuffer buffer = MemoryUtil.memAllocFloat(data.length);
    return buffer;

public void cleanUp() {
    for (int vao : vaos) {
    for (int vbo : vbos) {


And lastly the renderer class:

    package engine.io;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

public class Renderer {

public void prepare() {
    GL11.glClearColor(1f, 0f, 1f, 1f);

public void render(RawModel model) {
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.