You mixed ARB_shader_objects code (glGetUniformLocationARB) with actual core GLSL code (glUniform1i). That's never a good thing. Pick one: you're either using core GLSL (in which case you should be using glGetUniformLocation) or you're using ARB_shader_objects (in which case you should be using glUniform1iARB).

More importantly, you store the return value in a GLuint. That's broken. Uniform locations can be -1, which means that the uniform is not present or active in the shader. Your conversion of -1 into an unsigned integer yields... unknown results, especially when you shove that back into a GLint later.

I think I am missing some explanation or a concept of sampler2d and the binding, when I change the glActiveTexture(GL_TEXTURE1); then the second texture is shown, but why cant I change it in the fragment shader ?

Do you still have "textures" bound to texture unit 0 and "textures1" bound to unit 1 when you make the draw call?

Unlike the way glVertexAttribPointer operates (with latched state), the texture isn't set when you make the glUniform1i call, you only tell it what texture unit will be used when the draw call is made. This means you could have this code:

Code :

glUseProgram(my_prog); // did you remember to use the program when setting uniforms?
glUniform1i(location1, 0); // Tex1 will use texture unit 0
glUniform1i(location2, 1); // Tex2 will use texture unit 1
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures1);