2
2
3
3
from __future__ import annotations
4
4
5
+ import math
5
6
from dataclasses import dataclass
6
7
from pathlib import Path
7
8
from typing import Any
8
9
9
10
import importlib_resources as resources
11
+ import moderngl
10
12
import moderngl_window as mglw
11
13
import numpy as np
12
14
from moderngl import Context , Uniform
28
30
LIGHT_UP = 0.98
29
31
LIGHT_LEFT = 0.8
30
32
LIGHT_RIGHT = 0.608
31
-
32
- FACE_ORDER = list [FaceName ](["south" , "east" , "down" , "west" , "north" , "up" ])
33
+ LIGHT_BACK = 0.25
33
34
34
35
35
36
@dataclass
36
37
class BlockRenderer :
37
38
loader : ModResourceLoader
38
39
39
40
def __post_init__ (self ):
40
- self .window = HeadlessWindow ()
41
- self .config = BlockRendererConfig (ctx = self .window .ctx , wnd = self .window )
41
+ self .window = HeadlessWindow (
42
+ size = (300 , 300 ),
43
+ )
42
44
45
+ self .config = BlockRendererConfig (ctx = self .window .ctx , wnd = self .window )
43
46
self .window .config = self .config
47
+
44
48
self .window .swap_buffers ()
45
49
self .window .set_default_viewport ()
46
50
@@ -110,12 +114,7 @@ def __init__(self, ctx: Context, wnd: HeadlessWindow):
110
114
)
111
115
self .uniform ("m_proj" ).write (self .projection )
112
116
113
- self .camera = Matrix44 .look_at (
114
- eye = (256 , 64 , 16 ),
115
- target = (0 , 0 , 16 ),
116
- up = (0 , 1 , 0 ),
117
- dtype = "f4" ,
118
- )
117
+ self .camera = pitch_yaw_camera (30 , - 135 )
119
118
self .uniform ("m_camera" ).write (self .camera )
120
119
121
120
# TODO: implement animations
@@ -134,13 +133,15 @@ def render_block(
134
133
textures = dict [str , int ]()
135
134
for i , (name , info ) in enumerate (texture_vars .items ()):
136
135
textures [name ] = i
137
- self .load_texture_array (
136
+ texture = self .load_texture_array (
138
137
path = str (info .image_path ),
139
138
layers = info .layers ,
140
- ).use (i )
139
+ )
140
+ texture .filter = (moderngl .NEAREST , moderngl .NEAREST )
141
+ texture .use (i )
141
142
142
143
model_transform = Matrix44 .identity (dtype = "f4" )
143
- # model_transform *= Matrix44.from_translation((-8, -8, -8))
144
+ model_transform *= Matrix44 .from_translation ((- 8 , - 8 , - 8 ))
144
145
145
146
# TODO: order??? (see docstring)
146
147
# if gui := model.display.get("gui"):
@@ -158,25 +159,28 @@ def render_block(
158
159
159
160
self .uniform ("m_model" ).write (element_transform )
160
161
161
- for direction in FACE_ORDER :
162
- if not (face := element .faces .get (direction )):
162
+ # TODO: face order stuff...
163
+ for direction in ["down" , "west" , "north" , "south" , "east" , "up" ]:
164
+ # TODO: face.rotation
165
+ if direction not in element .faces :
163
166
continue
164
167
165
- # TODO: face.rotation
168
+ face = element . faces [ direction ]
166
169
167
170
match direction :
168
- case "up" | "down" :
171
+ case "up" :
169
172
light = LIGHT_UP
170
- case "north" | "south" :
171
- light = LIGHT_LEFT
172
- case "east" | "west" :
173
+ case "south" :
173
174
light = LIGHT_RIGHT
175
+ case "east" :
176
+ light = LIGHT_LEFT
177
+ case _:
178
+ light = LIGHT_BACK
174
179
175
180
self .uniform ("light" ).value = light
176
181
self .uniform ("texture0" ).value = textures [face .texture .lstrip ("#" )]
177
182
178
183
vao = get_element_face_vao (element , direction )
179
-
180
184
vao .render (self .prog )
181
185
182
186
self .ctx .finish ()
@@ -185,7 +189,7 @@ def render_block(
185
189
mode = "RGBA" ,
186
190
size = self .wnd .fbo .size ,
187
191
data = self .wnd .fbo .read (components = 4 ),
188
- ). transpose ( Image . FLIP_TOP_BOTTOM )
192
+ )
189
193
190
194
image .save ("out.png" , format = "png" )
191
195
@@ -366,3 +370,32 @@ def get_default_uv(element: ModelElement, direction: FaceName):
366
370
max (u_from , u_to ),
367
371
max (v_from , v_to ),
368
372
)
373
+
374
+
375
+ def pitch_yaw_camera (pitch : float , yaw : float ):
376
+ """Both values are in degrees."""
377
+
378
+ eye = np .matmul (
379
+ (- 64 , 0 , 0 , 1 ),
380
+ (
381
+ Matrix44 .identity (dtype = "f4" )
382
+ * Matrix44 .from_y_rotation (math .radians (yaw ))
383
+ * Matrix44 .from_z_rotation (math .radians (pitch ))
384
+ ),
385
+ )[:3 ]
386
+
387
+ up = np .matmul (
388
+ (- 1 , 0 , 0 , 1 ),
389
+ (
390
+ Matrix44 .identity (dtype = "f4" )
391
+ * Matrix44 .from_y_rotation (math .radians (yaw ))
392
+ * Matrix44 .from_z_rotation (math .radians (90 - pitch ))
393
+ ),
394
+ )[:3 ]
395
+
396
+ return Matrix44 .look_at (
397
+ eye = eye ,
398
+ target = (0 , 0 , 0 ),
399
+ up = up ,
400
+ dtype = "f4" ,
401
+ )
0 commit comments