Question

Currently, I have an OBJ loader that can load an the necessary OBJs, parse the materials, and bind textures when necessary.

However, I need clarification on whether or not you can bind Multiple Textures while the Vertex Pointer is moving through your VBO that you just bound. What I mean is: I would like to put multiple materials across different meshes all within a single VBO. Research tells me I need to use shaders, but don't specify how you can load them mid-way through the VBO.

I'm trying to minimize draw calls and the number of VBOs while (hopefully) staying away from multi-texturing if possible. Any help is much appreciated!

Current Draw Code:

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);
}
Was it helpful?

Solution

Either you need to draw portions (see the second and third parameter of glDrawArrays) of your vertex buffer where after each part you can perform a state switch (such as adjusting the bound textures, adjusting the shader), or you have to program your shader so it can render without ‘state switches’. The extend that this is possible entirely depends on the type of state switches and current possibilities of the ‘programmable pipeline’.

For example, if the only state switch you currently have, are textures. You could put the textures in a texture array (or an array of samplers); in your objects geometry you need to add an attribute that determines which ‘texture layer’ is used for sampling. Since the attribute has to be stored in your vertex buffer, it also becomes a complex issues of how much space it consumes to make it batchable versus the net performance gain.

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));
}

Please note that the code above is just rough pseudocode.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top