简体   繁体   中英

LWJGL OpenGL Projection Matrix Issue

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.

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

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM