Opengl LWJGL-交错VAO/VBO非纹理

Opengl LWJGL-交错VAO/VBO非纹理,opengl,lwjgl,vbo,vao,Opengl,Lwjgl,Vbo,Vao,我一直在尝试将游戏的原型渲染器从即时模式测试实现转换为实际的VAO/VBO实现。VBO正在屏幕上渲染,但拒绝渲染纹理。下面是显示问题的最简单测试类: public static void main(String[] args) throws Exception { // VertX,VertY TexX, TexY float[] data = new float[] {0.0f, 0.0f, 0.25

我一直在尝试将游戏的原型渲染器从即时模式测试实现转换为实际的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\u REPEAT和filter=GL\u NEAREST):


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

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

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

编辑


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

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

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

编辑


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

上面的代码会生成一个无纹理的方块或访问冲突,具体取决于“GLVERTEXAttributePointer”还是“glVertexPointer”。另外,作为一个查询,“glTexCoordPointer”的核心配置文件替换是什么?核心配置文件替换是
glvertexattributepointer
。属性由着色器定义,因此查询纹理坐标属性的位置,并将其用作
glVertexAttribPointer
的第一个参数。上面的代码生成未纹理的正方形或访问冲突,具体取决于“glVertexAttribPointer”还是“glVertexPointer”。另外,作为一个查询,“glTexCoordPointer”的核心配置文件替换是什么?核心配置文件替换是
glvertexattributepointer
。属性由着色器定义,因此查询纹理坐标属性的位置并将其用作
glvertexattributepointer
的第一个参数。
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);
}
glVertexPointer(2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 2*Float.BYTES);