Search code examples
opengllwjgl

glClear() keeps the screen black


I'm developing a 2D game called Spaceland and I've ran into a problem with clearing the screen. Whenever I call glClear(GL_COLOR_BUFFER_BIT) every frame, it keeps my screen black until i stop calling it. I have tested this by assigning glClear() to a key, and when I hold it down the screen turns black, when not pressed, the quad that is spreading across the screen just grows until I clear again.

I am using glClearColor(0, 0, 0, 1) when I create a window. I have tried turning off and on glfwSwapInterval().

create() function in my Window class:

public void create(boolean vsync) {
    GLFWErrorCallback.createPrint(System.err).set();

    GLFWVidMode vid = glfwGetVideoMode(glfwGetPrimaryMonitor());

    keys = new boolean[GLFW_KEY_LAST];
    for (int i = 0; i < GLFW_KEY_LAST; i ++) {
        keys[i] = false;
    }

    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    ID = glfwCreateWindow(vid.width(), vid.height(), TITLE, glfwGetPrimaryMonitor(), 0);
    if (ID == 0) 
        throw new IllegalStateException("Error whilst creating window: '" + TITLE + "'");

    glfwMakeContextCurrent(ID);
    createCapabilities();

    glClearColor(0, 0, 0, 1);

    camera = new Camera(getWidth(), getHeight());

    glfwSwapInterval(vsync ? 1 : 0);
}

Sprite Class:

public class Sprite {
private VertexArray vao;
private VertexBuffer
        pVbo,
        iVbo;

private int vertexCount;

private float scale;

private Vector3f position;
private Vector3f rotation;

private Matrix4f tMatrix;

public Sprite(float[] pos, int[] indices) {
    vertexCount = indices.length;

    position = new Vector3f(0, 0, 0);
    rotation = new Vector3f(0, 0, 0);
    scale = 0.1f;

    tMatrix = MatrixHelper.createTransformationMatrix(position, rotation, scale);

    vao = new VertexArray();
    pVbo = new VertexBuffer(false);
    iVbo = new VertexBuffer(true);

    vao.bind();

    pVbo.bind();
    pVbo.add(pos);
    vao.add();
    pVbo.unbind();

    iVbo.bind();
    iVbo.add(indices);
    iVbo.unbind();

    vao.unbind();
}

public void setPosition(float x, float y, float z) {
    position.x = x;
    position.y = y;
    position.z = z;
}

public void setRotation(Vector3f rot) {
    rotation = rot;
}

public void render(int renderType) {
    MatrixHelper.setTMatrixPosition(tMatrix, position);
    setPosition(getPosition().x + 0.0001f, 0, 0);

    System.out.println(tMatrix);

    Spaceland.shader.bind();
    Spaceland.shader.editValue("transformation", tMatrix);

    vao.bind();
    glEnableVertexAttribArray(0);
    iVbo.bind();

    glDrawElements(renderType, vertexCount, GL_UNSIGNED_INT, 0);

    iVbo.unbind();
    glDisableVertexAttribArray(0);
    vao.unbind();

    Spaceland.shader.unbind();
}

public Vector3f getPosition() {
    return position;
}
}

I don't think you need to see my Camera class or MatrixHelper class as the problem has occured before implementing this.

Main class (ignore rose[] and roseI[] it's just a cool pattern I made as a test):

public class Spaceland {
public static Window window;

public static Sprite sprite;

public static Shader shader;

public static float[] rose = {
        -0.45f, 0f,
        0.45f, 0f,
        0f, 0.45f,
        0f, -0.45f,
        -0.4f, -0.2f,
        -0.4f, 0.2f,
        0.4f, -0.2f,
        0.4f, 0.2f,
        -0.2f, -0.4f,
        -0.2f, 0.4f,
        0.2f, -0.4f,
        0.2f, 0.4f
};

public static int[] roseI = {
        0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11,

        1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11,

        2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11,

        3, 4, 3, 5, 3, 6, 3, 7, 3, 8, 3, 9, 3, 10, 3, 11,

        4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 4, 11,

        5, 6, 5, 7, 5, 8, 5, 9, 5, 10, 5, 11,

        6, 7, 6, 8, 6, 9, 6, 10, 6, 11,

        7, 8, 7, 9, 7, 10, 7, 11,

        8, 9, 8, 10, 8, 11,

        9, 10, 9, 11,

        10, 11,
};

public static float[] quad = {
        0.5f, 0.5f,
        0.5f, -0.5f,
        -0.5f, 0.5f,
        -0.5f, -0.5f
};

public static int[] quadI = {
        2, 0, 3,
        0, 1, 3
};

public static void main(String[] args) {
    init();
}

public static void loop() {
    while (!window.isCloseRequested()) {
        update();
        render();
    }

    destroy(0);
}

public static void init() {
    if (!glfwInit())
        throw new IllegalStateException("Error whilst initialising GLFW");

    window = new Window("Spaceland");

    window.create(true);

    shader = new Shader("src/main/java/com/spaceland/graphics/fragment.fs", "src/main/java/com/spaceland/graphics/vertex.vs");

    sprite = new Sprite(quad, quadI);

    loop();
}

public static void render() {
    window.render();

    sprite.render(GL11.GL_TRIANGLES);
}

public static void update() {
    window.update();

    if (window.isDown(GLFW_KEY_SPACE)) {
        glClear(GL_COLOR_BUFFER_BIT);
    }
}

public static void destroy(int error) {
    window.destroy();

    glfwTerminate();
    glfwSetErrorCallback(null).free();

    shader.destroy();

    VertexBuffer.deleteAll();
    VertexArray.destroyAll();

    System.exit(error);
}
}

Please tell me if you need to see the Shader class, shader vs and fs files, or anything else.

Thanks!


Solution

  • It is not very clear in my question, but the answer is that I cleared the screen, swapped buffers, rendered, etc. Which doesn't work.

    glClear(...);
    glfwSwapBuffers(...);
    ...render...
    

    This is how it is currently, and this doesn't work.

    glClear(...);
    ...render...
    glfwSwapBuffers(...);
    

    This is how I do it now, and it works fine.