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\$
  • \$\begingroup\$ "the value is 1 for current active texture" - no, it should be 0. \$\endgroup\$ – Maximus Minimus Jan 15 '18 at 10:37
  • \$\begingroup\$ @MaximusMinimus Yes i tried that, but getting same results. \$\endgroup\$ – Saumi Jan 15 '18 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\$ – Maximus Minimus Jan 15 '18 at 12:09
  • \$\begingroup\$ "Shader.BASIC.setUnifrom1i("tex", 1);" - you should be calling "glActiveTexture (GL_TEXTURE1)" before binding your texture for drawing. \$\endgroup\$ – Maximus Minimus Jan 15 '18 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\$ – user1118321 Jan 16 '18 at 17:20
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.