LWJGL教程10 - 贴图

先改进循环

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
33
34
35
36
37
38
public void run() {

[...]

long initialTime = System.currentTimeMillis();
float timeU = 1000.0f / window_settings.targetUPS;
float deltaUpdate = 0;

int updateTimes = 0;
while(!Window.windowShouldClose()) {
[...]

long now = System.currentTimeMillis();
deltaUpdate += (now - initialTime) / timeU;

[...]

if (deltaUpdate >= 1) {
logic.update();
++updateTimes;
deltaUpdate--;
}

[...]

initialTime = now;

++frames;

while(System.currentTimeMillis() >= lastTime + 1000L) {
System.out.println(frames + " fps, " + updateTimes + "times");
lastTime += 1000L;
frames = 0;
updateTimes = 0;
}
}
cleanup();
}

测试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class TestEngine {
public static void main(String[] args) {
Engine.init();
Engine.window_settings
.setTitle("Test Application")
// .setVsync(true)
// .setWidth(1920).setHeight(1080)
// .setFullscreen(true)
.setTargetUPS(128)
.setColor(255, 255, 255, 255);
Engine.logic = new TestLogic();
new Engine().run();
}
}

运行结果

添加纹理

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
<version>${lwjgl.version}</version>
<classifier>${lwjgl.natives}</classifier>
<scope>runtime</scope>
</dependency>

添加Texture

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
33
34
35
public class Texture {
private int textureId;

public Texture(String filename) {

try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);

ByteBuffer byteBuffer = stbi_load(filename, w, h, channels, 4);
if (byteBuffer == null)
throw new RuntimeException("Failed to load texture: " + filename);

generateTexture(w.get(), h.get(), byteBuffer);
stbi_image_free(byteBuffer);
}
}

private void generateTexture(int width, int height, ByteBuffer byteBuffer) {
textureId = glGenTextures();

glBindTexture(GL_TEXTURE_2D, textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, byteBuffer);
glGenerateMipmap(GL_TEXTURE_2D);
}

public int getTextureId() {
return textureId;
}
}

然后需改Mesh类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Mesh(float[] vertices, float[] textCoords, int[] indices, Texture texture) {
this.verticesCount = indices.length;
this.texture = texture;
[...]s

// 贴图
vboId = glGenBuffers();
FloatBuffer textCoordsBuffer = MemoryUtil.memAllocFloat(textCoords.length);
textCoordsBuffer.put(textCoords).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, textCoordsBuffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);

[...]

MemoryUtil.memFree(textCoordsBuffer);
}

需改顶点着色器。

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

layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;

out vec2 outTexCoord;

uniform mat4 worldMatrix;
uniform mat4 projectionMatrix;

void main()
{
gl_Position = projectionMatrix * worldMatrix * vec4(position, 1.0);
outTexCoord = texCoord;
}

片段着色器。

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

in vec2 outTexCoord;
out vec4 fragColor;

uniform sampler2D texture_sampler;

void main()
{
fragColor = texture(texture_sampler, outTexCoord);
}

UniformsMap中添加setUniform()

1
2
3
public void setUniform(String uniformName, int value) {
glUniform1i(uniforms.get(uniformName), value);
}

SceneRender的构造器中创建新的Uniform

1
uniforms.createUniform("texture_sampler");

最后。

1
2
3
4
5
6
7
8
9
10
11
12
13
public void render(Scene scene) {
[...]
uniforms.setUniform("texture_sampler", 0);

scene.getEntities().forEach(entity -> {
// 激活第一个纹理单元
glActiveTexture(GL_TEXTURE0);
// 绑定纹理
glBindTexture(GL_TEXTURE_2D, entity.getMesh().getTexture().getTextureId());
[...]
});
[...]
}

测试一下。

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
@Override
public void init() {
float[] vertices = new float[]{ //8, 10, 11, 9, 8, 11,
// V0
-0.5f, 0.5f, 0.5f,
// V1
-0.5f, -0.5f, 0.5f,
// V2
0.5f, -0.5f, 0.5f,
// V3
0.5f, 0.5f, 0.5f,
// V4
-0.5f, 0.5f, -0.5f,
// V5
0.5f, 0.5f, -0.5f,
// V6
-0.5f, -0.5f, -0.5f,
// V7
0.5f, -0.5f, -0.5f,

// For text coords in top face
// V8: V4 repeated
-0.5f, 0.5f, -0.5f,
// V9: V5 repeated
0.5f, 0.5f, -0.5f,
// V10: V0 repeated
-0.5f, 0.5f, 0.5f,
// V11: V3 repeated
0.5f, 0.5f, 0.5f,

// For text coords in right face
// V12: V3 repeated
0.5f, 0.5f, 0.5f,
// V13: V2 repeated
0.5f, -0.5f, 0.5f,

// For text coords in left face
// V14: V0 repeated
-0.5f, 0.5f, 0.5f,
// V15: V1 repeated
-0.5f, -0.5f, 0.5f,

// For text coords in bottom face
// V16: V6 repeated
-0.5f, -0.5f, -0.5f,
// V17: V7 repeated
0.5f, -0.5f, -0.5f,
// V18: V1 repeated
-0.5f, -0.5f, 0.5f,
// V19: V2 repeated
0.5f, -0.5f, 0.5f,
};
float[] textCoords = new float[]{
0.0f, 0.0f,
0.0f, 0.5f,
0.5f, 0.5f,
0.5f, 0.0f,

0.0f, 0.0f,
0.5f, 0.0f,
0.0f, 0.5f,
0.5f, 0.5f,

// For text coords in top face
0.0f, 0.5f,
0.5f, 0.5f,
0.0f, 1.0f,
0.5f, 1.0f,

// For text coords in right face
0.0f, 0.0f,
0.0f, 0.5f,

// For text coords in left face
0.5f, 0.0f,
0.5f, 0.5f,

// For text coords in bottom face
0.5f, 0.0f,
1.0f, 0.0f,
0.5f, 0.5f,
1.0f, 0.5f,
};
int[] indices = new int[]{
// Front face
0, 1, 3, 3, 1, 2,
// Top Face
8, 10, 11, 9, 8, 11,
// Right face
12, 13, 7, 5, 12, 7,
// Left face
14, 15, 6, 4, 14, 6,
// Bottom face
16, 18, 19, 17, 16, 19,
// Back face
4, 6, 7, 5, 4, 7,
};
Texture texture = new Texture("src/main/resources/cube.png");
Mesh mesh = new Mesh(vertices, textCoords, indices, texture);
entity = new Entity(mesh);
entity.setPosition(0, 0, -2);
Engine.scene.addEntity(entity);
}
材质

运行结果


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