I programmed a LWJGL 3 code to render a quad on the screen. I even added the projection Matrix to it, still I don't see any changes in the appearance of the quad. If I change the FOV of the frustum the quad gets smaller (that's what I expected) but the quad remains a rectangle even though it should have been a square!
Here is the Renderer Class:
ShaderReader reader = new ShaderReader();
Shader shader = null;
Mesh mesh;
private static final float FOV = 45f;
private static final float Z_NEAR = 0.01f;
private static final float Z_FAR = 1000f;
private static Matrix4f projectionMatrix;
float[] vertices = {
-0.5f, 0.5f, -5.0f,
-0.5f, -0.5f,-5.0f,
0.5f, -0.5f, -5.0f,
0.5f, 0.5f, -5.0f
};
int[] indices = {
0,1,3,
3,1,2
};
public void init(Window window) {
GL11.glClearColor(.2f, .8f, 1f, 1f);
shader = new Shader(reader);
shader.createVertexShader(reader.readFile("shader.vs"));
shader.createFragmentShader(reader.readFile("shader.fs"));
shader.link();
mesh = new Mesh(vertices, indices);
float aspectRatio = 640 / 480;
projectionMatrix = new Matrix4f();
projectionMatrix.perspective((float) (Math.toRadians(FOV)), 1, Z_NEAR, Z_FAR);
}
public void clear() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
public void render() {
clear();
shader.bind();
shader.setUniform("projectionMatrix", projectionMatrix);
GL30.glBindVertexArray(mesh.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);;
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
Here is the Shader Class:
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public Shader(ShaderReader reader) {
programID = GL20.glCreateProgram();
if (programID ==0) {
System.err.println("Error : Couldn't create program");
}
}
public void createVertexShader(String shaderCode) {
vertexShaderID = createShader(shaderCode, GL20.GL_VERTEX_SHADER);
}
public void createFragmentShader(String shaderCode) {
fragmentShaderID = createShader(shaderCode, GL20.GL_FRAGMENT_SHADER);
}
private int createShader(String shaderCode, int type) {
int shaderID = GL20.glCreateShader(type);
if (shaderID == 0) {
System.err.println("Error : Couldn't create shader");
}
GL20.glShaderSource(shaderID, shaderCode);
GL20.glCompileShader(shaderID);
if ((GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS)) != 1) {
System.err.println("Error: Couldn't Compile Shader, " + GL20.glGetShaderInfoLog(shaderID));
}
GL20.glAttachShader(programID, shaderID);
return shaderID;
}
public void link() {
GL20.glLinkProgram(programID);
if ((GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS)) != GL11.GL_TRUE) {
System.err.println("Error: Couldn't Link Program, " + GL20.glGetProgramInfoLog(programID, 1024));
}
if (vertexShaderID != 0) {
GL20.glDetachShader(vertexShaderID, programID);
}
if (fragmentShaderID != 0) {
GL20.glDetachShader(fragmentShaderID, programID);
}
GL20.glValidateProgram(programID);
if ((GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS)) != GL11.GL_TRUE) {
System.err.println("Error: Couldn't Validate Program, " + GL20.glGetProgramInfoLog(programID));
}
}
public void setUniform(String name, Matrix4f mat) {
int location = GL20.glGetUniformLocation(programID, name);
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
mat.get(buffer);
GL20.glUniformMatrix4fv(location, false, buffer);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unBind() {
GL20.glUseProgram(0);
}
the source folder of my project :https://www.dropbox.com/scl/fo/hwlnz913jm6c9xli2dsb6/h?dl=0&rlkey=b2zj0w6kttwu3b1di9rejwnq3
[The Quad that gets rendered] (https://i.sstatic.net/H932c.jpg)
I first used JOML to program the projection matrix and also tried to calculate and put the values in the matrix individually still the quad was showing up as a rectangle and not a square even though the size changed when I change FOV. Please Help!
Your code for computing the projection matrix has multiple issues:
float aspectRatio = 640 / 480;
projectionMatrix = new Matrix4f();
projectionMatrix.perspective((float) (Math.toRadians(FOV)), 1, Z_NEAR, Z_FAR);
First of all, the division 640 / 480
is an integer division, so will always be exactly 1, regardless of later being assigned to a float variable.
And second, you do not actually use this variable in the call to perspective
. You simply use the literal constant 1
here as the argument.
So, change the computation of the aspect ratio e.g. to (float) 640 / 480
or 640f / 480
and actually use the aspectRatio
variable as the second argument to the perspective
call:
float aspectRatio = (float) 640 / 480;
projectionMatrix = new Matrix4f();
projectionMatrix.perspective((float) (Math.toRadians(FOV)), aspectRatio, Z_NEAR, Z_FAR);