0

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.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
purplex
  • 47
  • 4
  • Are you following [this tutorial](https://www.youtube.com/watch?v=VS8wlS9hF8E&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP) by any chance? – Sweeper May 06 '20 at 12:27
  • Yes I am @Sweeper – purplex May 06 '20 at 12:30
  • This is my first time using LWJGL. – purplex May 06 '20 at 12:31
  • 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 https://www.youtube.com/watch?v=50Y9u7K0PZo&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=8 – purplex May 06 '20 at 12:32
  • 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 < far` – Rabbid76 May 06 '20 at 12:41
  • entity.getPosition() is a Vector3f, a vector with 3 floats – purplex May 06 '20 at 12:43
  • @Rabbid76 (I'm not the OP but I followed the same tutorial) Entity's z coordinate should be -1. – Sweeper May 06 '20 at 12:45
  • Check the main loop code. The entity object takes in a Vector3f and my static shader class. The vector3f entered in the entity is the getPosition(). – purplex May 06 '20 at 12:46
  • Btw the Z is -1 – purplex May 06 '20 at 12:46
  • @Sweeper It should, but is it? I recommend to set `z = -(NEAR_PLANE + FAR_PLANE )/2` for debug reasons. _-(near+far)/2_ is in the center of the frustum. – Rabbid76 May 06 '20 at 12:46
  • Try setting the z position even further back, like -10. – Sweeper May 06 '20 at 12:46
  • I tried -10, haha, that also didn't work :c – purplex May 06 '20 at 12:47
  • I tried removing the projectionMatrix, rendering the image worked just fine, I could rotate, just as you know z axis won't work as no projectionMatrix. I recoded the projectionMatrix with lwjgl's docs, the code here are from lwjgl's docs – purplex May 06 '20 at 12:51
  • @Rabbid76 Your debugging value still doesn't render it. I dont see anything just a red background, i added a picture so you can see. – purplex May 06 '20 at 12:54
  • Ofcourse scale is 1 – purplex May 06 '20 at 13:05
  • @purplex Possibly the issue is related to the transformation matrix. Try the following for debug reasons: `gl_Position = projectionMatrix * vec4(position.xy, position.z-5.0, 1.0);` – Rabbid76 May 06 '20 at 13:13

2 Answers2

0

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));
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Do you think this caused it to render at all? – purplex May 06 '20 at 13:42
  • It still doesn't seem to work bro, here is my new code. I mention again, when I remove the projectionMatrix * in my vertexShader.txt, that is only when the entity renders. ;/ [hastebin link](http://hasteb.in/enolulex.cs) – purplex May 07 '20 at 05:59
  • Here is my DisplayManager incase for some weird reason I am doing something wrong, following tutorials this should be correct? http://hasteb.in/iyikehiv.java – purplex May 07 '20 at 06:13
0

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!

purplex
  • 47
  • 4