【问题标题】:LWJGL - Interleaved VAO/VBO not texturingLWJGL - 交错的 VAO/VBO 没有纹理
【发布时间】:2016-08-29 08:54:28
【问题描述】:

我一直在尝试将我的游戏原型渲染器从它的即时模式测试实现转换为实际的 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();
            */

    }
}

纹理绑定调用如下(其中 wrap = GL_REPEAT 和 filter = 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);
}

花了一个周末谷歌搜索它并没有找到答案,我做错了什么可怕的错误吗?我还使用即时模式进行了测试,该模式仍然使用纹理进行渲染。

【问题讨论】:

    标签: opengl lwjgl vbo vao


    【解决方案1】:

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

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

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

    编辑

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

    【讨论】:

    • 上面的代码会产生一个无纹理的正方形,或访问冲突,具体取决于“glVertexAttribPointer”还是“glVertexPointer”。另外,作为一个查询,“glTexCoordPointer”的核心配置文件替换是什么?
    • 核心配置文件替换为glVertexAttribPointer。属性由着色器定义,因此查询纹理坐标属性的位置并将其用作glVertexAttribPointer的第一个参数。
    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多