多个纹理绑定到单个VBO并使用着色器渲染(LWJGL)

时间:2014-04-04 22:14:59

标签: java opengl lwjgl

目前,我有一个OBJ加载器,可以加载必要的OBJ,解析材料,并在必要时绑定纹理。

但是,我需要澄清一下,当顶点指针移动你刚刚绑定的VBO时,是否可以绑定多个纹理。我的意思是:我想在一个VBO中将多个材质放在不同的网格中。研究告诉我,我需要使用着色器,但不要指定如何在VBO中途加载它们。

我试图尽量减少绘制调用和VBO的数量,同时(希望)尽可能远离多纹理。非常感谢任何帮助!

当前的抽奖代码:

private void Run() {
    GetInput inputController = new GetInput();
    while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
        CalculateFPS();
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        //Get Input
        GL11.glLoadIdentity();
        inputController.GetMouse();
        inputController.GetKeyboard();
        //Rotate
        GL11.glRotated(inputController.mousey, 1, 0, 0);
        GL11.glRotated(inputController.mousex, 0, 1, 0);
        //Move
        GL11.glTranslated(inputController.position.x, inputController.position.y, inputController.position.z);
        //Draw
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); //Allow vertex arrays
        GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY); //Allow normal arrays
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO_OBJ.vertexVBO); //Bind vertexVBO for drawing
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0L);  //Setup vertexPointer for drawing
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO_OBJ.normalVBO); //Bind normalVBO for drawing
        GL11.glNormalPointer(GL11.GL_FLOAT, 0, 0L); //Setup normalPointer for drawing
        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, VBO_OBJ.totalVertices); //Draw!
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); //Unbind
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
        //Update Display
        Display.update();
        Display.sync(1000);
    }
    System.exit(0);
}

1 个答案:

答案 0 :(得分:2)

您需要绘制部分(请参阅glDrawArrays的第二个和第三个参数)您的顶点缓冲区,其中每个部分之后可以执行状态切换(例如调整绑定纹理,调整着色器),或者你必须编程你的着色器,这样它就可以在没有'状态开关'的情况下渲染。可能的扩展完全取决于状态开关的类型和“可编程流水线”的当前可能性。

例如,如果您当前拥有的唯一状态切换是纹理。您可以将纹理放在纹理数组(或采样器数组)中;在对象几何体中,您需要添加一个属性,该属性确定用于采样的“纹理图层”。由于该属性必须存储在顶点缓冲区中,因此它也会成为一个复杂的问题:使其可以使用多少空间净性能增益相比

Original:
sampler2d texture;
varying vec2 uv;
void main()
{
    vec4 color = texture2D(texture, uv);
}

Array of samplers:
sampler2d texture[32];
varying vec2 uv;
varying float layer;

void main()
{
    vec4 color = texture2D(texture[layer], uv);
}

Texture Array version:
sampler2dArray texture;
varying vec2 uv;
varying float layer;

void main()
{
    vec4 color = texture3D(texture, vec3(uv, layer));
}

请注意,上面的代码只是粗略的伪代码。