当前位置: 首页 > 知识库问答 >
问题:

LWJGL/OpenGL顶点缓冲区对象

伯博
2023-03-14

我目前正在使用LWJGL / OpenGL创建一个2D,自上而下的游戏,但是在绘制实体之后,在使用顶点缓冲区对象渲染实体后,在让它们四处移动的过程中,我遇到了一些问题。这是渲染线程的 run() 方法,以及设置方法:

// Render thread
public void run() {
    setUpDisplay();
    setUpOpenGL();
    setUpEntities();
    while (isRunning) {
        getFPS();
        drawEntities();
        Display.update();
        Display.sync(60);
        if (Display.isCloseRequested()) {
            isRunning = false;
        }
    }
    destroyEntities();
    Display.destroy();
    System.exit(0);
}   

// Initialisation method for the display
private void setUpDisplay() {
    try {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.setTitle("Roguelike");
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
    }
}

// Initialisation method for OpenGL
private void setUpOpenGL() {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 640, 480, 0, 1, -1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    lastFrame = Main.getTime();
}

实体从抽象超类继承这些方法来设置 VBO 并绘制实体(呈现线程中的 drawEntities 方法仅调用该方法,实体更新方法(见下文),而 setUpEntities 调用 setUp 方法):

// Method to initialise VBOs for a given entity
public void setUp() {
    vertexData = BufferUtils.createFloatBuffer(12);
    vertexData.put(getVertices());
    vertexData.flip();

    textureData = BufferUtils.createFloatBuffer(12);
    textureData.put(textureVertices);
    textureData.flip();

    vboVertexHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    vboTextureCoordHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboTextureCoordHandle);
    glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

// Method to draw the entity
public void draw() {
    glBindTexture(GL_TEXTURE_2D, loadTexture(this.textureKey).getTextureID());

    glBindBuffer(GL_ARRAY_BUFFER, this.vboVertexHandle);
    glVertexPointer(2, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, this.vboTextureCoordHandle);
    glTexCoordPointer(2, GL_FLOAT, 0, 0L);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

到目前为止,我一直试图在屏幕上移动单个实体以使翻译工作,但无济于事——我试图使用以下更新实体的方法来更新其位置,但它导致在屏幕上绘制实体的副本,这显然不是我想要的:

public void update(int delta) { // Updates the position of the object
    this.x += this.dx * delta;
    this.y += this.dy * delta;
    this.setBounds();
    this.vertexData.rewind();
    this.vertexData.put(getVertices());
    this.vertexData.flip();
    glBindBuffer(GL_ARRAY_BUFFER, this.vboVertexHandle);
    glBufferData(GL_ARRAY_BUFFER, this.vertexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

这是使用此方法的结果(精灵只是我在一分钟内绘制的占位符来演示问题)-单击

任何帮助将不胜感激,如果您需要更多信息,我会更新它。

提前感谢!

编辑:快速笔记,获取Vertices():

public float[] getVertices() {  // Returns array of vertices (for vertex VBO)
    float[] vertices = {    this.bounds[0], this.bounds[3], this.bounds[2], this.bounds[3],
                            this.bounds[2], this.bounds[1], this.bounds[2], this.bounds[1],
                            this.bounds[0], this.bounds[1], this.bounds[0], this.bounds[3] };
    return vertices;
}

setBounds()如下:

public void setBounds() {
    this.bounds[0] = this.x;
    this.bounds[1] = this.y;
    this.bounds[2] = this.x + this.width;
    this.bounds[3] = this.y + this.height;
}

它在调用该方法时有效地更新为新的x/y值。

共有1个答案

范鸿畅
2023-03-14

这是因为您没有清除缓冲区。

您需要清除缓冲区,否则新呈现的数据将仅添加到旧数据中。

要清除缓冲区,您需要执行以下操作。

glClear(GL_COLOR_BUFFER_BIT);

如果您正在使用GL_DEPTH_TEST,请记住也清除它。(这更只是为了让你知道)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 类似资料:
  • 我正在尝试LWJGL库,但我有点困惑。当我尝试渲染具有2d顶点的四边形时:glVertex2f(0,0);glVertex2f(0, 1000);glVertex2f(1000, 1000);glVertex2f(1000, 0);,那么一切似乎都很好,但是当我使用下面的代码时,我只看到黑屏。是我使用了错误的坐标,因此它没有显示在屏幕上,还是其他问题?

  • 我正在尝试从ArrayList读取并创建VBO,然后对其进行渲染。问题是我只是渲染了一个空白屏幕。当我立即渲染时,一切都很好;只有现在VBO的才不起作用。 游戏循环如下所示,相机调用glTranslate和glRotate函数。 渲染方法: 阵列列表具有顶点和链接的颜色。每个体素将其顶点添加到ArrayList(而不是立即渲染)。

  • 我想做一个OpenGL游戏,但现在意识到我在学校学到的- 1)我应该使用OpenGL的glDrawArray还是glDrawElements? 2) 对于具有多个实体/场地/对象的游戏,渲染函数必须是多个glDrawArrays(): 或者只有一个glDrawArrays()封装每个实体: 3)每个图形层(如DirectX)现在都标准化顶点缓冲区对象吗?

  • 我正在努力理解这两个,如何使用它们,以及它们是如何联系的。假设我想创建一个简单的地形和一个有纹理的立方体。对于这两个对象,我有三角形、顶点的数组,对于立方体,我有一个包含纹理数据的数组。我的问题是:我如何使用VAOs和VBOs来创建和呈现这两个? null

  • 我在Android 3.2上尝试通过OpenGL ES 2.0绘制一个形状。我可以按照预期使用DrawArray和FloatBuffer进行场景渲染,但不能通过glGenBuffers和vbo/ibo。 以下是我使用的一些片段,去掉了不相关的部分 上面是我创建数组的代码。下面是我的渲染代码。 我知道我的顶点浮动缓冲区工作正常,因为如果我用下面的代码替换上面的代码,它会按预期工作: 当我正在调试以找

  • 问题内容: 我尝试将本教程与Golang一起使用:http : //www.opengl- tutorial.org/beginners-tutorials/tutorial-2-the-first- triangle/ go-version打开窗口并使背景变蓝,但是不显示三角形。C版本确实显示了它。这是Go中的代码: 这是c中有效的代码: 也许我给了vertexAttrib.AttribPoin