AMD switches texture and normal VBOs around

100 Views Asked by At

AMD switches the locations of my texture VBO and my normals VBO. This leads to some odd results, if I run the NVIDIA code on AMD and vice versa.

*To specify; this is from results on GTX660 and A6 APU (I'm assuming the result would be the same for any NVIDIA or AMD card)

The code in question:

Full source code https://github.com/DigitalQR/QRDare

Relevent parts

Main Class:

public class TestingMain {


public static void main(String[] args){
    QRWindow window = new QRWindow("Test", 640, 480);


    Shader shader = new Shader(new File("Test/shader.vs"), new File("Test/shader.fs"));
    shader.bindFragData("out_colour");
    shader.genAttribList(new int[]{Loader.LOC_POSITION, Loader.LOC_TEXTURECOORD, Loader.LOC_NORMAL}, new String[]{"in_location", "in_textureCoord", "in_normal"});
    shader.genUniformList(new String[]{"cam_location", "cam_rotation","light_location"});


    RawModel model = Loader.loadRawModel(
            new float[]{//Vertex
                    -0.5f, 0.5f, 0.5f, 0.5f,
                    -0.5f, -0.5f, 0.5f, -0.5f,
            }, 
            new float[]{//Tex
                    0f, 0f, 1f, 0f,
                    0f, 1f, 1f, 1f
            }, 
            new float[]{//Norm
                    -0.5f, 0.5f, 0.5f, 0.5f,
                    -0.5f, -0.5f, 0.5f, -0.5f
            }, 
            new int[]{//Elem
                    0,1,2, 1,3,2
            },
            Loader.loadTexture("Test/Metal", GL11.GL_LINEAR)
            );

    RawModel model2 = Loader.loadRawModel(
            new float[]{//Vertex
                    0, 1, 1, 1,
                    0, 0, 1, 0,
            }, 
            new float[]{//Tex
                    0.0f, 0.0f,  1.0f, 0.0f,
                    0.0f, 1.0f,  1.0f, 1.0f
            }, 
            new float[]{//Norm
                    -0.5f, 0.5f, 0.5f, 0.5f,
                    -0.5f, -0.5f, 0.5f, -0.5f,
            }, 
            new int[]{//Elem
                    0,1,2, 1,3,2
            },
            Loader.loadTexture("Test/Grass", GL11.GL_NEAREST)
            );
    Camera.setDepth(0.5f);

    while(!window.closeRequested()){
        if(Keyboard.isKeyDown(Keyboard.KEY_W)){
            Camera.getLocation().y+=0.1f;
        }
        if(Keyboard.isKeyDown(Keyboard.KEY_S)){
            Camera.getLocation().y-=0.1f;
        }
        if(Keyboard.isKeyDown(Keyboard.KEY_A)){
            Camera.getLocation().x-=0.1f;
        }
        if(Keyboard.isKeyDown(Keyboard.KEY_D)){
            Camera.getLocation().x+=0.1f;
        }
        if(Keyboard.isKeyDown(Keyboard.KEY_Q)){
            Camera.setRotation(Camera.getRotation()-0.1f);
        }
        if(Keyboard.isKeyDown(Keyboard.KEY_E)){
            Camera.setRotation(Camera.getRotation()+0.1f);
        }

        shader.loadVector(shader.getUniformLocation("cam_location"), Camera.getLocation());
        shader.loadVector(shader.getUniformLocation("light_location"), Camera.getLocation());
        Camera.loadRotation(shader, shader.getUniformLocation("cam_rotation"));

        Renderer.render(model);
        Renderer.render(model2);


        window.update();
    }
    Loader.cleanUp();
    shader.destroy();
    window.close();
}
}

VBO Loader:

public class Loader {

public final static int LOC_POSITION = 0;
public final static int LOC_TEXTURECOORD = 1;
public final static int LOC_NORMAL = 2;

private static List<Integer> vaos = new ArrayList<Integer>();
private static List<Integer> vbos = new ArrayList<Integer>();
private static List<Integer> textures = new ArrayList<Integer>();

public static RawModel loadRawModel(float[] positions, float[] textureCoords, float[] normals, int[] indices, int texture){
    int VAO = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(VAO);
    vaos.add(VAO);

    bindElements(indices);
    bindAttrib(LOC_POSITION, 2, positions);
    bindAttrib(LOC_TEXTURECOORD, 2, textureCoords);
    bindAttrib(LOC_NORMAL, 2, normals);

    GL30.glBindVertexArray(0);
    return new RawModel(VAO, indices.length, texture);
}

public static void bindAttrib(int location, int size, float[] data){
    int VBO = GL15.glGenBuffers();
    vbos.add(VBO);

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO);
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();

    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(location, size, GL11.GL_FLOAT, false, 0, 0);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

}

public static void bindElements(int[] indices){
    int VBO = GL15.glGenBuffers();
    vbos.add(VBO);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, VBO);
    IntBuffer buffer = BufferUtils.createIntBuffer(indices.length);
    buffer.put(indices);
    buffer.flip();

    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);

}

public static void cleanUp(){
    for(int vao:vaos){
        GL30.glDeleteVertexArrays(vao);
    }
    for(int vbo:vbos){
        GL15.glDeleteBuffers(vbo);
    }
    for(int texture:textures){
        GL11.glDeleteTextures(texture);
    }
}

public static int loadTexture(String fileName, int type){
    Texture texture = null;

    try {
        texture = TextureLoader.getTexture("PNG", new FileInputStream(fileName + ".png"), type);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    int textureID = texture.getTextureID();
    textures.add(textureID);
    return textureID;
}
}

Renderer:

public class Renderer {

public static void render(RawModel model){
    GL30.glBindVertexArray(model.getVAO());

    GL20.glEnableVertexAttribArray(Loader.LOC_POSITION);
    GL20.glEnableVertexAttribArray(Loader.LOC_TEXTURECOORD);
    GL20.glEnableVertexAttribArray(Loader.LOC_NORMAL);

    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture());

    GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);


    GL20.glDisableVertexAttribArray(Loader.LOC_NORMAL);
    GL20.glDisableVertexAttribArray(Loader.LOC_TEXTURECOORD);
    GL20.glDisableVertexAttribArray(Loader.LOC_POSITION);

    GL30.glBindVertexArray(0);
}

public static void render(Entity entity){
    render(entity.getModel());
}
}

Vertex Shader:

#version 400 core

in vec2 in_location;
in vec2 in_textureCoord;
in vec2 in_normal;

uniform vec2 cam_location;
uniform mat4 cam_rotation;
uniform vec2 light_location;

out vec2 colour;
out vec2 normal;
out vec2 toLight;
out vec2 textureCoord;

void main(){
    textureCoord = in_textureCoord;
    colour = in_textureCoord;
    normal = normalize(in_normal);
    toLight = normalize(light_location-in_location);

    gl_Position = (vec4(in_location-cam_location, 1.0, 1.0)*cam_rotation).xyzw;
}

Fragment Shader:

#version 400 core

in vec2 colour;
in vec2 normal;
in vec2 toLight;
in vec2 textureCoord;

uniform sampler2D texture;

out vec4 out_colour;

void main(){

    float nDotl = dot(normal, toLight);
    float brightness = max(min(nDotl, 0.6), 0.1);

    out_colour = texture2D(texture, textureCoord.xy)*brightness;
    //out_colour = vec4(colour+0.5, 0.0, 1.0)*brightness;
}
1

There are 1 best solutions below

8
On BEST ANSWER

According to the documentation

Attribute bindings do not go into effect until glLinkProgram is called

You seem to link only once and that appears to be before you call genAttribList which is the function that calls glBindAttribLocation. So, use glLinkProgram again at the end of genAttribList would be my suggestion.