Java - LWJGL and OpenGL, How to apply texture to an object?

Viewed 46

everybody. So I am using LWJGL to learn OpenGL.

So I am trying to apply texture that is located in a folder called textures (full path -> src/textures/texture.png). However all I am getting is black box.

I don't know if the texture is too big or small, it doesn't crash, it just renders completely black box.

Does anybody knows what might be the problem ? I tried applying the texture the same way as colors but that did nothing.

This is my Texture class code

public class Texture {
    private String filePath;
    private int textureID;

    public Texture(String filePath){
        this.filePath = filePath;

        //Generate texture on GPU
        textureID = glGenTextures();

        //Set texture parameters
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        //When streching image pixelate
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        //When shrinking image pixelate
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        IntBuffer width = BufferUtils.createIntBuffer(1);
        IntBuffer height = BufferUtils.createIntBuffer(1);
        IntBuffer channels = BufferUtils.createIntBuffer(1);
        ByteBuffer image = stbi_load(filePath, width, height, channels, 0);

        if (image != null) {
            if (channels.get(0) == 3) {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width.get(0), height.get(0),
                        0, GL_RGB, GL_UNSIGNED_BYTE, image);
            } else if (channels.get(0) == 4) {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.get(0), height.get(0),
                        0, GL_RGBA, GL_UNSIGNED_BYTE, image);
            } else {
                assert false : "Error: (Texture) Unknown number of channesl '" + channels.get(0) + "'";
            }
        } else {
            assert false : "Error: (Texture) Could not load image '" + filePath + "'";
        }

        stbi_image_free(image);
    }

    public void Bind(){
        glBindTexture(GL_TEXTURE_2D, textureID);
    }

    public void Unbind(){
        glBindTexture(GL_TEXTURE_2D, 0);
    }
}

And this is my Mesh classs where I am rendering whole cube.

public class Mesh {
    private String vertexShaderSrc ="" +
            "#version 330 core\n" +
            "\n" +
            "layout (location=0) in vec3 aPos;\n" +
            "layout (location=1) in vec4 aColor;\n" +
            "layout (location=2) in vec2 aTexCoords;\n" +
            "\n" +
            "out vec4 fColor;\n" +
            "out vec2 fTexCoords;\n" +
            "\n" +
            "uniform mat4 worldMatrix;\n" +
            "uniform mat4 projectionMatrix;\n" +
            "\n" +
            "void main(){\n" +
            "    fColor = aColor;\n" +
            "    fTexCoords = aTexCoords;\n" +
            "    gl_Position = projectionMatrix * worldMatrix * vec4(aPos, 1.0);\n" +
            "}";

    private String fragmentShaderSrc = "" +
            "#version 330 core\n" +
            "\n" +
            "in vec4 fColor;\n" +
            "in vec2 fTexCoords;\n" +
            "\n" +
            "out vec4 Color;\n" +
            "\n" +
            "uniform sampler2D textureSampler;\n" +
            "void main(){\n" +
            "   // Color = fColor;\n" +
            "    Color = texture(textureSampler, fTexCoords);\n" +
            "}";

    private int vertexID;
    private int fragmentID;
    private int shaderProgram;

    private int VAO_ID;
    private int VBO_ID;
    private int EBO_ID;
    private int colourVBO_ID;
    private int textureID;

    private float[] vertices;
    private int[] triangles;    //MUST BE IN COUNTERCLOCKWISE ORDER
    private float[] colours;
    private float[] UVs;

    //CAMERA
    private float FOV;
    private float nearPlane;
    private float farPlane;
    private int width;
    private int height;

    private String fileName;
    private Matrix4f projectionMatrix;
    private Matrix4f worldMatrix;

    private Map<String, Integer> uniforms = new HashMap<>();
    private Map<String, Integer> uniformsPosition = new HashMap<>();
    private Map<String, Integer> uniformsTexture = new HashMap<>();
    private WorldTransformation transformation;

    private Texture texture;
    public Mesh(){
        this.transformation = new WorldTransformation();
    }

    public void SetTexture(String fileName) { this.fileName = fileName; }
    public void SetRenderSettings(float FOV, float nearPlane, float farPlane, int width, int height){
        this.FOV = FOV;
        this.nearPlane = nearPlane;
        this.farPlane = farPlane;
        this.width = width;
        this.height = height;
    }
    public void SetVertices(float[] vertices){
        this.vertices = vertices;
    }
    public void SetTriangles(int[] triangles){
        this.triangles = triangles;
    }
    public void SetColours(float[] colours) { this.colours = colours; }
    public void SetUVs(float[] UVs) { this.UVs = UVs; }

    public void Init(){

        this.texture = new Texture(fileName);

        //COMPILE AND LINK SHADERS
        //************
        // Vertex Shader
        //************

        vertexID = glCreateShader(GL_VERTEX_SHADER); //Load shader type
        glShaderSource(vertexID, vertexShaderSrc); // Pass shader source to GPU
        glCompileShader(vertexID); // Compile shader

        //Error check in compilation process
        int success = glGetShaderi(vertexID,GL_COMPILE_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetShaderi(vertexID, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl: \n\t Vertex shader compilation failed !");
            System.out.println(glGetShaderInfoLog(vertexID,lenght));
        }

        //************
        // Fragment Shader
        //************
        fragmentID = glCreateShader(GL_FRAGMENT_SHADER); //Load shader type
        glShaderSource(fragmentID, fragmentShaderSrc); // Pass shader source to GPU
        glCompileShader(fragmentID); // Compile shader

        //Error check in compilation process
        success = glGetShaderi(fragmentID,GL_COMPILE_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetShaderi(fragmentID, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl: \n\t Vertex shader compilation failed !");
            System.out.println(glGetShaderInfoLog(fragmentID,lenght));
        }


        //************
        // Link shaders and Check for errors
        //************
        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexID);
        glAttachShader(shaderProgram, fragmentID);
        glLinkProgram(shaderProgram);

        //Check for linking errors
        success = glGetProgrami(shaderProgram, GL_LINK_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetProgrami(shaderProgram, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl:' \n\t Linking of shaders failed !");
            System.out.println(glGetProgramInfoLog(fragmentID,lenght));
            assert false : "";
        }



        int uniformLocation = glGetUniformLocation(shaderProgram,"projectionMatrix");
        uniforms.put("projectionMatrix",uniformLocation);

        int uniformPosLocation = glGetUniformLocation(shaderProgram,"worldMatrix");
        uniformsPosition.put("worldMatrix",uniformPosLocation);

        //TEXTURE 
        int uniformTexturePosition = glGetUniformLocation(shaderProgram, "textureSampler");
        uniformsTexture.put("textureSampler", uniformTexturePosition);


        //************
        // Generate VAO, VBO and EBO and send them to GPU
        //************

        // GENERATE VAO
        VAO_ID = glGenVertexArrays();
        glBindVertexArray(VAO_ID);

        //POSITION VBO
        // GENERATE VBO and upload VertexBuffer
        VBO_ID = glGenBuffers();
        //Create float buffer of vertices
        FloatBuffer vertexBuffer = MemoryUtil.memAllocFloat(vertices.length);
        vertexBuffer.put(vertices).flip();
        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
        glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

        //COLOR VBO
        //GENERATE VBO and upload colourBuffer
        colourVBO_ID = glGenBuffers();
        FloatBuffer colourBuffer = MemoryUtil.memAllocFloat(colours.length);
        colourBuffer.put(colours).flip();
        glBindBuffer(GL_ARRAY_BUFFER, colourVBO_ID);
        glBufferData(GL_ARRAY_BUFFER, colourBuffer, GL_STATIC_DRAW);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 4, GL_FLOAT, false, 0,  0);

        textureID = glGenBuffers();
        FloatBuffer textureBuffer = MemoryUtil.memAllocFloat(UVs.length);
        textureBuffer.put(UVs).flip();
        glBindBuffer(GL_ARRAY_BUFFER, textureID);
        glBufferData(GL_ARRAY_BUFFER, textureBuffer, GL_STATIC_DRAW);
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, false, 0,  0);


        //TRIANGLE VBO
        //Create Indices and upload them
        EBO_ID = glGenBuffers();
        IntBuffer elementBuffer = MemoryUtil.memAllocInt(triangles.length);
        elementBuffer.put(triangles).flip();
        //Create EBO
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_ID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER,0);
        glBindVertexArray(0);
        // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

        //Free Buffers
        memFree(vertexBuffer);
        memFree(colourBuffer);
        memFree(elementBuffer);
        memFree(textureBuffer);

    }

    public void Render(){

        //Bind shader program
        glUseProgram(shaderProgram);

        glActiveTexture(GL_TEXTURE0);
        texture.Bind();
        SetTextureSample("textureSampler", 0);

        SetUniform("projectionMatrix", projectionMatrix, uniforms);
        SetUniform("worldMatrix", worldMatrix, uniformsPosition);

        //Bind VAO currently in use
        glBindVertexArray(VAO_ID);

        //Enable vertex atribute pointers
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        //Draw triangles
        glDrawElements(GL_TRIANGLES,triangles.length, GL_UNSIGNED_INT,0);

        //Unbind everything
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindVertexArray(0);
        glUseProgram(0);

    }

    void SetUniform(String uniformName, Matrix4f value, Map<String, Integer> uniformsMap){
        try (MemoryStack stack = MemoryStack.stackPush()) {
            FloatBuffer fb = stack.mallocFloat(16);
            value.get(fb);
            glUniformMatrix4fv(uniformsMap.get(uniformName), false, fb);
        }
    }

    void SetTextureSample(String uniformName, int slot){
        int location = glGetUniformLocation(shaderProgram, uniformName);
        glUniform1i(location, slot);
    }


    public void SetWorldMetrix(Matrix4f worldMatrix){
         this.worldMatrix = worldMatrix;
    }

    public void SetProjectionMatrix(Matrix4f projectionMatrix){
        this.projectionMatrix = projectionMatrix;
    }

}
0 Answers
Related