I'm learning openGl shaders and textures, and im running into a bit of a problem.
I made a VAO with vertices , tex coords and indices as :
float[] vertices = { // left is 10f and ratio is 16/9
-10f, 10f * 9f / 16f, 0f, // TOP LEFT
10f, 10f * 9f / 16f, 0f, // TOP RIGHT
10f, -10f * 9f / 16f, 0f, // BOTTOM RIGHT
-10f, -10f * 9f / 16f, 0f // BOTTOM LEFT
};
byte[] indices = {
0, 1, 2,
2, 3, 0
};
float[] texCoords = {
0, 0,
1, 0,
1, 1,
0, 1
};
But the texture i want is not being rendered properly.
My shaders are :
Vertex shader:
#version 330 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec2 tc;
uniform mat4 pr_matrix;
out DATA {
vec2 tc;
} vs_out;
void main() {
gl_Position = pr_matrix * position;
vs_out.tc = tc;
}
Fragment Shader :
#version 330 core
layout (location = 0) out vec4 color;
uniform sampler2D tex; // the value is 1 for current active texture
in DATA {
vec2 tc;
} fs_in;
void main() {
color = texture(tex , fs_in.tc);
}
glUniform call :
Shader.BASIC.setUnifrom1i("tex", 1);
public void setUnifrom1i(String name , int val) {
if(!enabled) enable();
glUniform1i(getUniform(name) , val);
}
Texture creation :
public int load(String path) {
int[] pixels = null;
try {
BufferedImage img = ImageIO.read(new FileInputStream(path));
width = img.getWidth();
height = img.getHeight();
pixels = new int[width * height];
img.getRGB(0, 0, width, height, pixels, 0, width);
} catch (IOException e) {
e.printStackTrace();
}
int[] data = new int[width * height];
for (int i = 0; i < width * height; i++) {
int a = (pixels[i] & 0xff000000) >> 24;
int r = (pixels[i] & 0xff0000) >> 16;
int g = (pixels[i] & 0xff00) >> 8;
int b = (pixels[i] & 0xff);
data[i] = a << 24 | b << 16 | g << 8 | r;
}
int tex = glGenTextures();
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameterf(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D , 0 , GL_RGBA , width , height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , BufferUtils.createIntBuffer(data));
glBindTexture(GL_TEXTURE_2D, 0);
return tex;
}
EDIT 2 :
Shader class :
public class Shader {
private int id;
public static final int VERTEX_ATTRIB = 0 , TCOORD_ATTRIB = 1;
public static Shader BASIC;
private boolean enabled = false;
private Map<String , Integer> locationCache = new HashMap<String , Integer>();
private Shader(String vert , String frag) {
id = ShaderUtils.load(vert, frag);
}
public static void loadAll() {
BASIC = new Shader("shaders/shader.vs", "shaders/shader.fs");
}
public void enable() {
glUseProgram(id);
enabled = true;
}
public void disable() {
glUseProgram(0);
enabled = false;
}
public int getUniform(String name){
if(locationCache.containsKey(name)){
return locationCache.get(name);
}
int result = glGetUniformLocation(id, name);
if(result == -1){
System.err.println("Unable to find uniform : "+ name);
System.exit(1);
}
locationCache.put(name, result);
return result;
}
public void setUnifrom1i(String name , int val) {
if(!enabled) enable();
glUniform1i(getUniform(name) , val);
}
public void setUnifrom1f(String name , float val) {
if(!enabled) enable();
glUniform1f(getUniform(name) , val);
}
public void setUnifrom2f(String name , float x , float y) {
glUniform2f(getUniform(name) , x , y);
}
public void setUnifrom3f(String name , Vector3f vector) {
if(!enabled) enable();
glUniform3f(getUniform(name) , vector.x , vector.y , vector.z);
}
public void setUnifromMat4f(String name , Matrix4f val) {
if(!enabled) enable();
glUniformMatrix4(getUniform(name) , false , val.toFloatBuffer());
}
}
Texture class :
public class Texture {
private int width, height;
private int texture;
public Texture(String path) {
texture = load(path);
}
private int load(String path) {
int[] pixels = null;
try {
BufferedImage image = ImageIO.read(new FileInputStream(path));
width = image.getWidth();
height = image.getHeight();
pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);
} catch (IOException e) {
e.printStackTrace();
}
int[] data = new int[width * height];
for (int i = 0; i < width * height; i++) {
int a = (pixels[i] & 0xff000000) >> 24;
int r = (pixels[i] & 0xff0000) >> 16;
int g = (pixels[i] & 0xff00) >> 8;
int b = (pixels[i] & 0xff);
data[i] = a << 24 | b << 16 | g << 8 | r;
}
int result = glGenTextures();
glBindTexture(GL_TEXTURE_2D, result);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, BufferUtils.createIntBuffer(data));
glBindTexture(GL_TEXTURE_2D, 0);
return result;
}
public void bind() {
glBindTexture(GL_TEXTURE_2D, texture);
}
public void unbind() {
glBindTexture(GL_TEXTURE_2D, 0);
}
}
VertexArray class :
public class VertexArray {
private int vao , vbo , tbo , ibo;
private int count;
public VertexArray(float[] vertices , float[] texCoords , byte[] indices) {
count = indices.length;
vao = glGenVertexArrays();
glBindVertexArray(vao);
vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(vertices), GL_STATIC_DRAW);
glVertexAttribPointer(Shader.VERTEX_ATTRIB, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(Shader.VERTEX_ATTRIB);
tbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(texCoords), GL_STATIC_DRAW);
glVertexAttribPointer(Shader.TCOORD_ATTRIB, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(Shader.TCOORD_ATTRIB);
ibo = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, BufferUtils.createByteBuffer(indices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public void bind() {
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
}
public void unbind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public void draw() {
glDrawElements(GL_TRIANGLES, count , GL_UNSIGNED_BYTE , 0);
}
public void render() {
bind();
draw();
}
}
Can someone please explain what went wrong? Thank you!
glVertexAttribPointer()
is being set to 3 for texture coords, but you only have 2 texture coordinates. Might that be the issue? \$\endgroup\$