Проблема с матрицей проекции LWJGL OpenGL - PullRequest
0 голосов
/ 06 мая 2020

Я кодирую игру на java, и недавно я попытался добавить матрицу проекции, поэтому я могу перемещать объекты по оси Z и видеть, как объект становится меньше, имеет FOV и т.д. 1002 * Теперь проблема в том, что когда я представляю это, мой объект просто не отображается. Я слежу за хорошей серией руководств, думаю, я все сделал правильно и дважды проверял в течение двух часов, пробуя новые решения. Затем я сдался и взглянул на документацию LWJGL. Мой объект все еще не отображается.

Вот мой код vertexShader.

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

Это мой код fragmentShader

#version 150 core

in vec2 pass_textureCoords;

out vec4 out_Color;

uniform sampler2D textureSampler;

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

Это мой класс визуализатора.

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

Это моя основная л oop

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

Почему? Я немного раздражен. В моем vertexShader, когда я удаляю часть projectionMatrix, все работает нормально, но у меня нет матрицы проекции! Когда я добавляю его, мой объект вообще не отображается, я вижу только красный фон. Если кто-то может помочь, это будет означать весь мир! Спасибо.

Я вижу только красный фон, но без изображения.

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Я хотел бы уточнить, что проблема решена, я забыл вызвать метод, запускающий все унифицированные переменные. Я удивлен, что некоторые вещи все еще работают. Спасибо, что помогли мне!

0 голосов
/ 06 мая 2020

Матрица перспективной проекции может быть определена как усеченная пирамида .
Расстояния left, right, bottom и top - это расстояния от центра обзора к боковым граням усеченного конуса на ближней плоскости. near и far указывают расстояния до ближней и дальней плоскости усеченной вершины.

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

Если проекция симметрична и луч зрения является осью симметрии усеченной кости, матрица можно упростить:

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

Матрица симметричной перспективной проекции:

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

Таким образом, ваше вычисление yScale неверно:

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

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