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

LWJGL-交错VAO/VBO非纹理

史景铄
2023-03-14

我一直在尝试将我的游戏原型渲染器从即时模式测试实现转换为实际的VAO/VBO实现。VBO正在屏幕上渲染,但拒绝纹理。下面是显示问题的最简单测试类:

public static void main(String[] args) throws Exception {

    //                          VertX,VertY         TexX,  TexY
    float[] data = new float[] {0.0f, 0.0f,     0.25f, 0.75f,
                                0.0f, 64.0f,    0.25f, 1.0f,
                                64.0f, 64.0f,   0.5f, 1.0f,

                                0.0f, 0.0f,     0.25f, 0.75f,
                                64.0f, 64.0f,   0.5f, 1.0f,
                                64.0f, 0.0f,    0.5f, 0.75f};

    glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
    if (!glfwInit())
        throw new IllegalStateException("Unable to initialize GLFW");

    long window = GLFW.glfwCreateWindow(1600, 900, "TEST", 0, 0);
    GLFW.glfwMakeContextCurrent(window);

    GL.createCapabilities();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1600, 900, 0, 0.000001, 100);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    int vboId = glGenBuffers();
    int vaoId = glGenVertexArrays();

    glClientActiveTexture(GL_TEXTURE0);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindVertexArray(vaoId);
    glBindBuffer(GL_ARRAY_BUFFER, vboId);

    glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 4*Float.BYTES, 0);
    glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 4*Float.BYTES);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);   
    glDisableClientState(GL_VERTEX_ARRAY);

    glTranslatef(50, 50, 0);

    Texture t = new Texture(TEST.class.getClassLoader().getResourceAsStream("test/WallFloor.png"));

    while (!GLFW.glfwWindowShouldClose(window)) {
        GLFW.glfwPollEvents();
        GLFW.glfwSwapBuffers(window);

        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);


            glClientActiveTexture(GL_TEXTURE0);
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);



            glBindVertexArray(vaoId);
            glEnableVertexAttribArray(0);

            t.bind();

            glDrawArrays(GL_TRIANGLES, 0, 6);


            glDisableVertexAttribArray(0);
            glBindVertexArray(0);

            glDisableClientState(GL_TEXTURE_COORD_ARRAY);   
            glDisableClientState(GL_VERTEX_ARRAY);

            /* Equivelent immediate mode code - that works
            t.bind();

            glBegin(GL_TRIANGLES);
            glTexCoord2f(0.25f, 0.75f);
            glVertex2f(0, 0);
            glTexCoord2f(0.25f, 1f);
            glVertex2f(0, 64);
            glTexCoord2f(0.5f, 0.75f);
            glVertex2f(64, 0);

            glTexCoord2f(0.5f, 1f);
            glVertex2f(64, 64);
            glTexCoord2f(0.25f, 1f);
            glVertex2f(0, 64);
            glTexCoord2f(0.5f, 0.75f);
            glVertex2f(64, 0);
            glEnd();
            */

    }
}

纹理绑定调用如下所示(其中包装=GL_REPEAT和过滤器=GL_NEAREST):

public void bind()
{
    glActiveTexture(GL_TEXTURE0);
    glClientActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(target, id);
    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
    glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
    glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
}

花了一个周末的时间在谷歌上搜索,却没有找到答案,我是不是做错了什么?我还测试了使用即时模式,它仍然使用纹理进行渲染。

共有1个答案

蒙勇
2023-03-14

此外,您正在将核心配置文件代码(glvertexattributepointer)与非核心配置文件(glTexCoordPointer)混合使用

但真正的问题来自使用了错误的步幅和偏移量。步长定义一个顶点的数据有多大,而偏移指定实际数据从每个顶点的起点开始有多远。在您的例子中,每个顶点由4个浮点组成,因此步幅必须是<代码>4*浮点。字节。位置是每个顶点中的前两个浮点(偏移0),而纹理坐标是第三个和第四个浮点,这意味着偏移=2*浮点。字节。正确的代码可能看起来像这样(注意使用了glVertexPointer而不是glVertexAttribPointer):

glVertexPointer(2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 2*Float.BYTES);

编辑

VAO的用法也是错误的。在初始化中,您将glVertexPointer/glTexCoordPointer存储到VAOvaoId。但是在渲染代码中,您绑定了VAO 0。绘图时很可能不存在属性设置。此外,我不完全确定VAO是否与固定函数调用一起工作。在这种情况下,您可以删除所有VAO调用。

 类似资料:
  • 我尝试使用VBO来渲染我的3D对象。 我创建了这个类: 我的物体都渲染正确,但我有一个纹理问题。我的肌理被磨平了。看看这张图片...为什么我的纹理是这样的,以及我如何修复这个错误。 battleofground.fr_game_render_error_vbo_texture.png

  • 在我的理解中:一个VAO代表一个特定的状态。如果我绑定了一个VAO,添加一些VBO和元素缓冲区,用于索引和东西,我可以保存我想绘制和激活的对象的某个状态,然后在我想渲染东西的时候轻松地绘制它们。对吧? 所以VBO保存实际数据,而VAO只是一个“包装器-对象”,保存指向我为它定义的所有缓冲区的指针? 更改VAOs成本很高(更改VBO也是如此?!)。目前,我加载网格,并将它们组合到模型中。每个模型都使

  • (这是我第二次问这个问题了。上次我得到了一个没有解决问题的答案(那里的答案提到了我试图修复这个问题时偶然留下的一点代码)。我还稍微改变了问题本身——我改变了代码的顺序,把我认为错误更高的部分放在前面,并补充说我正在使用macOS,这可能是它不起作用的原因)。 所以,我刚刚开始学习LWJGL 3,我混合使用了一些教程和示例代码来制作一些东西,应该使用VAOs和VBOs将矩形渲染到洋红屏幕上。没有错误

  • 经过大量的谷歌搜索,我在LWJGL渲染VBO立方体时遇到了这个问题。基本上,当我启用法线时,JVM会崩溃。这很可能与我在Plane.java中设置常态的方式有关。由于我仍在学习VBO,我似乎不知道如何解决这个问题。你能看一看,让我知道我可能在哪里出错了吗? Cube.java: 平面. java: 让我知道你们的想法。我已经在三台独立的计算机上测试了代码,每一台都有相同的结果。

  • 当第一次尝试绘制VAOS时,它崩溃了。我画没有着色器(所以它不会引起问题)。 在一个VAO和纹理坐标中最多有12个面(12*3个顶点)。有多达50万个VAO。 我如何创造一张脸: 错误如下: 我不认为把整个错误贴在这里是明智的。你知道为什么会这样吗?我找不到任何关于VBOS的错误。

  • 目前,我有一个类的集合,其中包含一个纹理、一个VAO和一个VBO。由于所有的状态切换和使用少量三角形调用,绘制数千个这样的对象会导致性能下降。 因此,现在我将更改我的实现,以便创建一系列1MIB VBO(从一个开始,一旦它满了,创建第二个1MIB VBO并继续填充它)。每个VBO需要单独的VAO吗?VBO已经使用了交错的顶点数据,所以我不是在谈论使用多个VBO来处理顶点、法线、纹理库等。