0
votes

I am coding a game in java and I recently tried adding the projection matrix, so I am able to move objects with the Z axis and actually see the object get smaller, have FOV, ect..

Now the problem is when I introduce this my object just doesn't render. I've been following a nice tutorial series, I beleive I did everything correctly and double checked for two hours, trying new solutions. I then gave up and had a look at LWJGL documentation. Still doesn't render my object.

Here is my vertexShader code.

#version 150 core

in vec3 position;
in vec2 textureCoords;

out vec3 color;

out vec2 pass_textureCoords;

uniform mat4 projectionMatrix;
uniform mat4 transformationMatrix;

void main(void) {
    gl_Position = projectionMatrix * transformationMatrix * vec4(position, 1.0);

    pass_textureCoords = textureCoords;

    color = vec3(position.x+0.5,0.0,position.y+0.5);
}

This is my fragmentShader code

#version 150 core

in vec2 pass_textureCoords;

out vec4 out_Color;

uniform sampler2D textureSampler;

void main(void) {
    out_Color = texture(textureSampler, pass_textureCoords);
}

This is my renderer class.

package me.purplex.jgame.renderer;

import me.purplex.jgame.entity.Entity;
import me.purplex.jgame.model.RawModel;
import me.purplex.jgame.model.TexturedModel;
import me.purplex.jgame.shaders.program.impl.StaticShader;
import me.purplex.jgame.utils.MathUtils;
import org.lwjgl.opengl.*;
import org.lwjgl.util.vector.Matrix4f;

public class Renderer {

    private Matrix4f projectionMatrix;

    public static final float FOV = 70;

    public static final float NEAR_PLANE = 0.1f;

    /**
     * VIEW DISTANCE
     */
    public static final float FAR_PLANE = 1000;

    public Renderer(StaticShader shader) {
        createProjectionMatrix();
        shader.start();
        shader.loadProjectionMatrix(projectionMatrix);
        shader.stop();
    }

    public void prepare() {
        GL11.glClearColor(1, 0, 0, 1);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    }

    public void render(Entity entity, StaticShader shader) {
        TexturedModel model = entity.getModel();
        RawModel rawModel = model.getRawModel();
        GL30.glBindVertexArray(rawModel.getVaoID());
        GL20.glEnableVertexAttribArray(0);
        GL20.glEnableVertexAttribArray(1);
        Matrix4f transformationMatrix = MathUtils.createTransformationMatrix(entity.getPosition(),
                entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale());
        shader.loadTransformationMatrix(transformationMatrix);
        GL13.glActiveTexture(GL13.GL_TEXTURE0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getModelTexture().getTextureID());
        GL11.glDrawElements(GL11.GL_TRIANGLES, rawModel.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(1);
        GL30.glBindVertexArray(0);
    }

    private void createProjectionMatrix() {
        final float width = Display.getWidth();
        final float height = Display.getHeight();

        final float fieldOfView = Renderer.FOV;
        final float aspectRatio = width / height;
        final float nearPlane = Renderer.NEAR_PLANE;
        final float farPlane = Renderer.FAR_PLANE;

        final float yScale = (float) coTanget(Math.toRadians(fieldOfView / 2f));
        final float xScale = yScale / aspectRatio;
        final float frustumLength = farPlane - nearPlane;

        projectionMatrix = new Matrix4f();
        projectionMatrix.m00 =xScale;
        projectionMatrix.m11 = yScale;
        projectionMatrix.m22 = -((farPlane + nearPlane) / frustumLength);
        projectionMatrix.m23 = -1;
        projectionMatrix.m32 = -((2 * nearPlane * farPlane) / frustumLength);
        projectionMatrix.m33 = 0;
    }

    private double coTanget(double rads) {
        return (1.0 / Math.tan(rads));
    }
}

This is my main loop

DisplayManager.createDisplay();
float[] vertices = {
        -0.5f, 0.5f, 0f,
        -0.5f, -0.5f, 0f,
        0.5f, -0.5f, 0.0f,
        0.5f, 0.5f, 0.0f
};
int[] indices = {
        0, 1, 3,
        3, 1, 2
};
float[] textureCoords = {
        0, 0,
        0, 1,
        1, 1,
        1, 0
};
ModelLoader modelLoader = new ModelLoader();

StaticShader shader = new StaticShader();

Renderer renderer = new Renderer(shader);

RawModel model = modelLoader.loadToVAO(vertices, textureCoords, indices);

TexturedModel staticModel = new TexturedModel(model,new ModelTexture(modelLoader.loadTexture("image")));

Entity entity = new Entity(staticModel, new Vector3f(0, 0, -1), 0, 0, 0, 1);
while (!Display.isCloseRequested()) {
    renderer.prepare();
    shader.start();
    renderer.render(entity, shader);
    shader.stop();
    DisplayManager.updateDisplay();
}
shader.cleanUp();
modelLoader.cleanUp();
DisplayManager.closeDisplay();

Why? I am kind of annoyed. In my vertexShader when I remove the projectionMatrix part, everything works fine but I can't have a projection matrix! When I add it my object is not rendered at all, all I see is my red background. If someone can help it would mean the world! Thank you.

All I see is my red background but no image.

2
Are you following this tutorial by any chance?Sweeper
Yes I am @Sweeperpurplex
This is my first time using LWJGL.purplex
I was in the middle of episode 8, he ran, his object rendered but mine didn't. I won't continue while mine isn't working. Edit: here is the video youtube.com/…purplex
What is entity.getPosition()? The object has to be in between the near and far plane of the frustum else the object is clipped. The view space z axis points out of the viewport, thus the z coordinate of entity.getPosition() has to be negative. You have to fulfill the following condition: near < -entity.getPosition().z < farRabbid76

2 Answers

0
votes

A perspective projection matrix can be defined by a frustum.
The distances left, right, bottom and top, are the distances from the center of the view to the side faces of the frustum, on the near plane. near and far specify the distances to the near and far plane of the frustum.

r = right, l = left, b = bottom, t = top, n = near, f = far

x:    2*n/(r-l)      0              0                0
y:    0              2*n/(t-b)      0                0
z:    (r+l)/(r-l)    (t+b)/(t-b)    -(f+n)/(f-n)    -1
t:    0              0              -2*f*n/(f-n)     0

If the projection is symmetrical and the line of sight is the axis of symmetry of the frustum, the matrix can be simplified:

a  = w / h
ta = tan( fov_y / 2 );

2 * n / (r-l) = 1 / (ta * a)
2 * n / (t-b) = 1 / ta
(r+l)/(r-l)   = 0
(t+b)/(t-b)   = 0

The symmetrically perspective projection matrix is:

x:    1/(ta*a)  0      0              0
y:    0         1/ta   0              0
z:    0         0     -(f+n)/(f-n)   -1
t:    0         0     -2*f*n/(f-n)    0

Thus your computation of yScale is wrong:

yScale = (float) coTanget(Math.toRadians(fieldOfView / 2f));

yScale = 1.0f / (float)coTanget(Math.toRadians(fieldOfView / 2f));
0
votes

I’d like to clarify the issue has been resolved, I forgot to call a method initiating all uniform variables I am surprised some stuff still worked. Thanks for helping me though!