LWJGL教程08 - 变换

透视投影

当改变z坐标时,渲染的矩形并没有大小上的变化。

是由于x,y坐标没有改变。

Projection其中
$$
\alpha = \frac{W_w}{W_h}
$$
暂时先不推导。

使用JOML处理LWJGL内的数学运算。

1
2
3
4
5
<dependency>
<groupId>org.joml</groupId>
<artifactId>joml</artifactId>
<version>${joml.version}</version>
</dependency>
1
2
3
4
5
<properties>
[...]
<joml.version>1.9.6</joml.version>
[...]
</properties>

先创建Projection类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[imports ...]

public class Projection {

private static final float FOV = (float) Math.toRadians(60.0f);
private static final float Z_FAR = 1000.f;
private static final float Z_NEAR = 0.01f;

private Matrix4f projectionMatrix;

public Projection(int width, int height) {
projectionMatrix = new Matrix4f();
updateProjectionMatrix(width, height);
}

public void updateProjectionMatrix(int width, int height) {
float aspectRatio = (float) width / height;
projectionMatrix = new Matrix4f().perspective(FOV, aspectRatio,
Z_NEAR, Z_FAR);
}

public Matrix4f getProjectionMatrix() {
return projectionMatrix;
}

}

并修改一下vertex.vert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#version 330

layout (location=0) in vec3 position;
layout (location=1) in vec3 inColour;

out vec3 exColour;

uniform mat4 projectionMatrix;

void main()
{
gl_Position = projectionMatrix * vec4(position, 1.0);
exColour = inColour;
}

再创建UniformsMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[imports ...]

import static org.lwjgl.opengl.GL20.*;

public class UniformsMap {
private Map<String, Integer> uniforms;
private int programId;

public UniformsMap(int programId) {
uniforms = new HashMap<>();
this.programId = programId;
}

public void createUniform(String uniformName) {
int uniformLocation = glGetUniformLocation(programId, uniformName);
if (uniformLocation < 0)
throw new RuntimeException("Could not find uniform: " + uniformName);
uniforms.put(uniformName, uniformLocation);
}

public void setUniform(String uniformName, Matrix4f value) {
// 转储矩阵到FloatBuffer
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer floatBuffer = stack.mallocFloat(16);
value.get(floatBuffer);
glUniformMatrix4fv(uniforms.get(uniformName), false, floatBuffer);
}
}
}

方便起见,将Scene渲染的工作交给SceneRender,整理一下Render的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[imports ...]

public class SceneRender {
UniformsMap uniforms;

public SceneRender() {
[...]

shaderProgram.link();
uniforms = new UniformsMap(shaderProgram.getProgramId());
uniforms.createUniform("projectionMatrix");
}

public void render(Scene scene) {
shaderProgram.bind();

uniforms.setUniform("projectionMatrix", scene.getProjection().getProjectionMatrix());

[...]
}

[...]
}

再在Scene的构造函数中实例化Projection

1
2
3
public Scene() {
projection = new Projection(Window.getWidth(), Window.getHeight());
}

并让每一次窗口改变大小时调用Projection.updateProjectionMatrix()

最后测试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[imports ...]

public class TestLogic implements ILogic {

@Override
public void init() {
float[] vertices = new float[] {
-0.5f, 0.5f, -1.05f, // v1
-0.5f, -0.5f, -1.05f, // v2
0.5f, 0.5f, -1.05f, // v3
0.5f, -0.5f, -1.05f, // v4
};

[...]
}

[...]
}

运行结果

调整窗口大小后

改变一下图像的z坐标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[imports ...]

public class TestLogic implements ILogic {

@Override
public void init() {
float[] vertices = new float[] {
-0.5f, 0.5f, -1.05f, // v1
-0.5f, -0.5f, -2.05f, // v2
0.5f, 0.5f, -1.05f, // v3
0.5f, -0.5f, -2.05f, // v4
};

[...]
}

[...]
}

Projection起作用了 - 运行结果


随便整点有趣的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public void init() {
float[] vertices = new float[] {
0.0f , 0.5f , -1.05f, // v0
0.5f , 0.3f , -1.05f, // v1
0.5f , -0.3f , -1.05f, // v2
0.0f , -0.5f , -1.05f, // v3
-0.5f , -0.3f , -1.05f, // v4
-0.5f , 0.3f , -1.05f, // v5
0.0f , 0.1f , -1.05f, // v6
};
float[] colors = new float[]{
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
};
int[] indices = new int[] {
1, 0, 6,
2, 1, 6,
3, 2, 6,
4, 3, 6,
5, 4, 6,
0, 5, 6
};

Mesh mesh = new Mesh(vertices, colors, indices);
Engine.scene.addMesh(mesh);
}

运行结果


LWJGL教程08 - 变换
https://panxy02.github.io/2024/07/19/lwjgl-08/
作者
52Hertz
发布于
2024年7月19日
许可协议