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;
}
}