glClear()使屏幕保持黑色

时间:2016-09-29 17:48:44

标签: opengl lwjgl

我正在开发一款名为Spaceland的2D游戏,而且我在清除屏幕方面遇到了问题。每当我每帧呼叫glClear(GL_COLOR_BUFFER_BIT)时,它会让我的屏幕变黑,直到我停止呼叫它为止。我已经通过将glClear()分配给一个键进行了测试,当我按住它时屏幕变黑,当没有按下时,在屏幕上传播的四边形只会增长直到我再次清除。

我在创建窗口时使用glClearColor(0, 0, 0, 1)。我试过关掉glfwSwapInterval()

我的Window类中的

create()函数:

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);
}

精灵类:

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;
}
}

在实施此问题之前,我不认为您需要查看我的Camera班级或MatrixHelper班级。

主要课程(忽略rose[]roseI[]这只是我作为考试做出的一种很酷的模式):

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);
}
}

如果您需要查看Shader类,着色器vs和fs文件或其他任何内容,请告诉我。

谢谢!

2 个答案:

答案 0 :(得分:2)

glClear会影响输出缓冲区。所以它是渲染的一部分。如果要在渲染过程中清除,请将glClear放入render函数中。

你在update里面。我怀疑是谁调用renderupdate(LWJGL,大概是?)并不保证对他们有任何特定的排序。因此,每次您被要求更新时,您都会在最后渲染的内容上踩踏。

更新

  • 调整内部状态,通常部分地作为时间的函数。

渲染:

  • 直观地捕捉当前状态。

答案 1 :(得分:0)

在我的问题中不是很清楚,但答案是我清除了屏幕,交换缓冲区,渲染等等。哪些不起作用。

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

这就是目前的情况,但这并不起作用。

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

这就是我现在的做法,它运作良好。