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;
}
According to the documentation
You seem to link only once and that appears to be before you call
genAttribList
which is the function that callsglBindAttribLocation
. So, useglLinkProgram
again at the end ofgenAttribList
would be my suggestion.