1
\$\begingroup\$

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.

Correct texture behind & incorrect texture front

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!

\$\endgroup\$
12
  • \$\begingroup\$ "the value is 1 for current active texture" - no, it should be 0. \$\endgroup\$ Commented Jan 15, 2018 at 10:37
  • \$\begingroup\$ @MaximusMinimus Yes i tried that, but getting same results. \$\endgroup\$
    – Saumi
    Commented Jan 15, 2018 at 11:01
  • \$\begingroup\$ Can you post the rest of the code around setting up this sampler, plesae? Your glUniform call, your glActiveTexture call, your texture creation? \$\endgroup\$ Commented Jan 15, 2018 at 12:09
  • \$\begingroup\$ "Shader.BASIC.setUnifrom1i("tex", 1);" - you should be calling "glActiveTexture (GL_TEXTURE1)" before binding your texture for drawing. \$\endgroup\$ Commented Jan 15, 2018 at 13:59
  • 2
    \$\begingroup\$ If the left triangle showed the image in a span of 10 pixels, then that makes me think that the issue is with your texture coordinates. I notice that the "size" argument to glVertexAttribPointer() is being set to 3 for texture coords, but you only have 2 texture coordinates. Might that be the issue? \$\endgroup\$ Commented Jan 16, 2018 at 17:20

1 Answer 1

1
\$\begingroup\$

The "size" argument to glVertexAttribPointer() is being set to 3 for texture coords, but there are 2 texture coordinates. Setting it to 2, corrects the error.

Thanks to @user1118321 I realised the mistake !

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .