work on ground rendering and tacoma integration

This commit is contained in:
Tuomas Katajisto 2025-10-04 22:47:36 +03:00
parent b8e4f0f3ed
commit 4a6c56d36d
20 changed files with 1700 additions and 2341 deletions

14
.zed/debug.json Normal file
View File

@ -0,0 +1,14 @@
[
{
"label": "Debug Jai",
"adapter": "CodeLLDB",
// Request:
"request": "launch",
"program": "first",
"cwd": "$ZED_WORKTREE_ROOT",
"build": {
"command": "jai",
"args": ["first.jai"]
}
}
]

View File

@ -7,31 +7,32 @@ cam : Camera = .{
far = 2000.0, far = 2000.0,
near = 1.0, near = 1.0,
target = .{0.0, 0.0, 0.0}, target = .{0.0, 0.0, 0.0},
position = .{0.0, 0.0, 0.0} position = .{3.0, 5.0, 3.0}
}; };
world : World;
#scope_export #scope_export
game_init :: () { game_init :: () {
world.ground[500][500] = .GRASS;
world.ground[500][501] = .GRASS;
world.ground[500][499] = .GRASS;
world.ground[499][500] = .GRASS;
world.ground[500][500] = .GRASS;
world.ground[501][500] = .GRASS;
} }
game_tick :: () { game_tick :: () {
speed := 0.1;
forward := Vector3.{1.0, 0.0, 0.0};
char_pos += speed * forward;
cam.position = char_pos;
cam.target = char_pos + forward;
} }
game_draw :: () { game_draw :: () {
if !is_in_reflection_pass then update_image_from_ground(*world, *gPipelines.plane.bind.images[1]);
if is_in_reflection_pass { if is_in_reflection_pass {
cam.position.y *= -1; cam.position.y *= -1;
cam.target.y *= -1; cam.target.y *= -1;
} }
draw_sky(*cam); draw_sky(*cam);
if !is_in_reflection_pass then draw_ground_plane(*cam); if !is_in_reflection_pass then draw_ground_plane(*cam, *world.conf);
if is_in_reflection_pass { if is_in_reflection_pass {
cam.position.y *= -1; cam.position.y *= -1;
cam.target.y *= -1; cam.target.y *= -1;

Binary file not shown.

View File

@ -24,7 +24,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -51,7 +51,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -78,7 +78,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -105,7 +105,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -132,7 +132,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -159,7 +159,7 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 0.0MB -> 0.0MB (0.0MB saved, 41.3% smaller) BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________ _______________
Vulkan Version: Vulkan Version:
- available: 1.4.309 - available: 1.4.309
@ -169,4 +169,343 @@ Used Instance Layers :
VK_LAYER_KHRONOS_validation VK_LAYER_KHRONOS_validation
Used Instance Extensions : Used Instance Extensions :
__________________ ____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 0.2MB -> 0.1MB (0.2MB saved, 65.8% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query

Binary file not shown.

View File

@ -86,6 +86,8 @@ get_level_editor_camera :: () -> Camera {
tick_level_editor_camera :: () { tick_level_editor_camera :: () {
if console_open_ignore_input then return; if console_open_ignore_input then return;
world.ground[500][500] = .GRASS;
if get_time() - lastInputTime > CAMERA_INACTIVE_TIME_TO_ORBIT { // idle rotating camera if get_time() - lastInputTime > CAMERA_INACTIVE_TIME_TO_ORBIT { // idle rotating camera
cameraRotation += cast(float) delta_time; cameraRotation += cast(float) delta_time;
} }
@ -136,7 +138,7 @@ tick_level_editor_camera :: () {
editY = max(editY - 1, 0); editY = max(editY - 1, 0);
} }
if input_button_states[Key_Code.MOUSE_BUTTON_RIGHT] & .DOWN { if get_mouse_state(Key_Code.MOUSE_BUTTON_RIGHT) & .DOWN {
if mouse2Active { if mouse2Active {
lastInputTime = get_time(); lastInputTime = get_time();
diff := mouse2ActivationPosition - Vector2.{input_mouse_x, input_mouse_y}; diff := mouse2ActivationPosition - Vector2.{input_mouse_x, input_mouse_y};
@ -156,7 +158,7 @@ tick_level_editor_camera :: () {
} }
if input_button_states[Key_Code.MOUSE_BUTTON_MIDDLE] & .DOWN { if get_mouse_state(Key_Code.MOUSE_BUTTON_MIDDLE) & .DOWN {
if mouse3Active { if mouse3Active {
lastInputTime = get_time(); lastInputTime = get_time();
diff := mouse3ActivationPosition - Vector2.{input_mouse_x, input_mouse_y}; diff := mouse3ActivationPosition - Vector2.{input_mouse_x, input_mouse_y};
@ -179,15 +181,16 @@ draw_tacoma_tab :: (theme: *GR.Overall_Theme, total_r: GR.Rect) {
#if HAS_TACOMA { #if HAS_TACOMA {
if GR.button(r, "Render with Tacoma", *theme.button_theme) { if GR.button(r, "Render with Tacoma", *theme.button_theme) {
cam := get_level_editor_camera(); cam := get_level_editor_camera();
test_gen(tacomaResolution, tacomaResolution, .{tacomaExposure, tacomaContrast, tacomaSaturation}, .{cam.target, cam.position, tacomaSamples, true}, world.conf); gen_reference(tacomaResolution, tacomaResolution, .{tacomaExposure, tacomaContrast, tacomaSaturation}, .{cam.target, cam.position, tacomaSamples, true}, world);
} }
r.y += r.h; r.y += r.h;
if current_screenshot.valid { if current_screenshot.valid {
aspect := cast(float)current_screenshot.width / cast(float)current_screenshot.height; aspect := cast(float)current_screenshot.width / cast(float)current_screenshot.height;
r.h = r.w / aspect; r.h = r.w / aspect;
uiTex := Ui_Texture.{*current_screenshot.image}; uiTex := New(Ui_Texture,, temp);
set_shader_for_images(*uiTex); uiTex.tex = *current_screenshot.image;
set_shader_for_images(uiTex);
immediate_quad(.{r.x, r.y}, .{r.x + r.w, r.y}, .{r.x + r.w, r.y + r.h}, .{r.x, r.y + r.h}); immediate_quad(.{r.x, r.y}, .{r.x + r.w, r.y}, .{r.x + r.w, r.y + r.h}, .{r.x, r.y + r.h});
set_shader_for_color(); set_shader_for_color();
r.y += r.h; r.y += r.h;
@ -221,12 +224,65 @@ draw_tacoma_tab :: (theme: *GR.Overall_Theme, total_r: GR.Rect) {
} }
} }
handle_tool_click :: (x: int, y: int, z: int) { #scope_file
if editor_current_trile != null then add_trile(editor_current_trile.name, cast(float)x, cast(float)y, cast(float)z);
Edit_Mode :: enum {
TRILES;
GROUND;
} }
groundType : Ground_Tile;
editMode : Edit_Mode;
#scope_export #scope_export
draw_tools_tab :: (theme: *GR.Overall_Theme, total_r: GR.Rect) {
r := total_r;
r.h = ui_h(3,0);
r.w = r.w/2.0;
if GR.button(r, "Edit triles", *t_button_selectable(theme, editMode == .TRILES)) {
editMode = .TRILES;
}
r.x += r.w;
if GR.button(r, "Edit ground", *t_button_selectable(theme, editMode == .GROUND)) {
editMode = .GROUND;
}
r.x -= r.w;
r.w *= 2.0;
r.y += r.h * 1.5;
if editMode == .GROUND {
if GR.button(r, "Grass", *t_button_selectable(theme, groundType == .GRASS)) {
groundType = .GRASS;
}
r.y += r.h;
if GR.button(r, "Water", *t_button_selectable(theme, groundType == .WATER)) {
groundType = .WATER;
}
r.y += r.h;
if GR.button(r, "Sand", *t_button_selectable(theme, groundType == .WATER)) {
groundType = .SAND;
}
}
}
handle_tool_click :: (x: int, y: int, z: int) {
if editMode == {
case .TRILES;
if editor_current_trile != null then add_trile(editor_current_trile.name, cast(float)x, cast(float)y, cast(float)z);
case .GROUND;
ray := get_mouse_ray(*get_level_editor_camera());
hit, point := ray_plane_collision_point(ray, 0, 100);
print("ground point: %\n");
if hit {
world.ground[floor(point.y).(int) + 500][floor(point.x).(int) + 500] = groundType;
}
}
}
add_trile :: (name: string, x: float, y: float, z: float) { add_trile :: (name: string, x: float, y: float, z: float) {
loose_float_comp :: (a: float, b: float) -> bool { loose_float_comp :: (a: float, b: float) -> bool {
@ -275,7 +331,7 @@ tick_level_editor :: () {
trile_preview_y = editY; trile_preview_y = editY;
trile_preview_z = xx floor(point.y); trile_preview_z = xx floor(point.y);
if input_button_states[Key_Code.MOUSE_BUTTON_LEFT] & .START { if get_mouse_state(Key_Code.MOUSE_BUTTON_LEFT) & .START {
handle_tool_click(xx floor(point.x), xx editY, xx floor(point.y)); handle_tool_click(xx floor(point.x), xx editY, xx floor(point.y));
} }
} }
@ -328,7 +384,7 @@ draw_world_triles :: (cam: *Camera, world: *World) {
draw_level_editor :: () { draw_level_editor :: () {
cam := get_level_editor_camera(); cam := get_level_editor_camera();
update_image_from_ground(*world, *gPipelines.plane.bind.images[2]); if !is_in_reflection_pass then update_image_from_ground(*world, *gPipelines.plane.bind.images[1]);
draw_sky(*get_level_editor_camera(), *world.conf); draw_sky(*get_level_editor_camera(), *world.conf);
if !is_in_reflection_pass then draw_ground_plane(*get_level_editor_camera(), *world.conf); if !is_in_reflection_pass then draw_ground_plane(*get_level_editor_camera(), *world.conf);
draw_world_triles(*cam, *world); draw_world_triles(*cam, *world);
@ -336,6 +392,7 @@ draw_level_editor :: () {
draw_level_editor_ui :: (theme: *GR.Overall_Theme) { draw_level_editor_ui :: (theme: *GR.Overall_Theme) {
r := GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0)); r := GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0));
ui_add_mouse_occluder(r);
draw_bg_rectangle(r, theme); draw_bg_rectangle(r, theme);
tab_r := r; tab_r := r;
tab_r.h = ui_h(3,0); tab_r.h = ui_h(3,0);
@ -355,6 +412,8 @@ draw_level_editor_ui :: (theme: *GR.Overall_Theme) {
r.y += tab_r.h; r.y += tab_r.h;
if current_tab == { if current_tab == {
case .TOOLS;
draw_tools_tab(theme, r);
case .TACOMA; case .TACOMA;
draw_tacoma_tab(theme, r); draw_tacoma_tab(theme, r);
case .INFO; case .INFO;

View File

@ -45,9 +45,16 @@ post_process_pipeline :: (color: Vector3, post_process: Post_Process) -> Vector3
return lerp(vec3(grayscale), sdr, post_process.saturation); return lerp(vec3(grayscale), sdr, post_process.saturation);
} }
test_gen :: (w: s32, h: s32, postprocess: Post_Process, conf: Tacoma.Gen_Config, worldConf: World_Config) { gen_reference :: (w: s32, h: s32, postprocess: Post_Process, conf: Tacoma.Gen_Config, world: World) {
trile := get_trile("test"); // Trile BLASes.
trile_list : [..]Tacoma.Trile_Data;
trile_list.allocator = temp;
// BLAS instances to create TLAS.
world_triles : [..]Tacoma.World_Trile;
world_triles.allocator = temp;
for world.positions {
trile := get_trile(it.trileName);
ttrile : Tacoma.Trile_Data; ttrile : Tacoma.Trile_Data;
for x: 0..15 { for x: 0..15 {
for y: 0..15 { for y: 0..15 {
@ -60,43 +67,33 @@ test_gen :: (w: s32, h: s32, postprocess: Post_Process, conf: Tacoma.Gen_Config,
} }
} }
} }
gfx := get_trile_gfx(it.trileName);
gfx := get_trile_gfx("test");
ttrile.vertices = gfx.vertices.data; ttrile.vertices = gfx.vertices.data;
ttrile.vertexCount = cast(s32) (gfx.vertices.count / 3); ttrile.vertexCount = cast(s32) (gfx.vertices.count / 3);
array_add(*trile_list, ttrile);
for pos: it.positions {
array_add(*world_triles, Tacoma.World_Trile.{cast(s32)it_index, pos.xyz});
}
}
trile_list : [1]Tacoma.Trile_Data;
trile_list[0] = ttrile;
sky : Tacoma.Sky_Config; sky : Tacoma.Sky_Config;
sky.skyBase = worldConf.skyBase; sky.skyBase = world.conf.skyBase;
sky.skyTop = worldConf.skyTop; sky.skyTop = world.conf.skyTop;
sky.sunDisk = worldConf.sunDisk; sky.sunDisk = world.conf.sunDisk;
sky.horizonHalo = worldConf.horizonHalo; sky.horizonHalo = world.conf.horizonHalo;
sky.sunHalo = worldConf.sunHalo; sky.sunHalo = world.conf.sunHalo;
sky.sunLightColor = worldConf.sunLightColor; sky.sunLightColor = world.conf.sunLightColor;
sky.sunPosition = worldConf.sunPosition; sky.sunPosition = world.conf.sunPosition;
sky.sunIntensity = worldConf.sunIntensity; sky.sunIntensity = world.conf.sunIntensity;
sky.skyIntensity = worldConf.skyIntensity; sky.skyIntensity = world.conf.skyIntensity;
ts : Tacoma.Trile_Set = .{trile_list.data, trile_list.count}; blases : Tacoma.Trile_Set = .{trile_list.data, cast(s32)trile_list.count};
tlas : Tacoma.World = .{world_triles.data, cast(s32)world_triles.count};
wTrile : Tacoma.World_Trile = .{ ptr := Tacoma.do_gen("./modules/Tacoma/", w, h, sky, blases, tlas, conf);
0,
.{1.0, 0.0, 0.0}
};
wTrile2 : Tacoma.World_Trile = .{
0,
.{0.0, 1.0, 1.0}
};
triles : [2]Tacoma.World_Trile = .[wTrile, wTrile2];
world : Tacoma.World = .{triles.data, 2};
ptr := Tacoma.do_gen("./modules/Tacoma/", w, h, sky, ts, world, conf);
data := cast(*float) talloc(w*h*4*size_of(float)); data := cast(*float) talloc(w*h*4*size_of(float));
memcpy(data, ptr, w*h*4*4); memcpy(data, ptr, w*h*4*4);
for 0..(w*h) { for 0..(w*h) {

View File

@ -2,24 +2,46 @@
subwindow : GR.Subwindow_Info; subwindow : GR.Subwindow_Info;
subwindow_initted : bool = false; subwindow_initted : bool = false;
// @Hack: This is probably kinda a bad idea, I don't really know atm how else to get the theme into the subwindow.
theme_ptr : GR.Overall_Theme;
current_pipeline : s32 = 0; current_pipeline : s32 = 0;
current_slot : s32 = 0; current_slot : s32 = 0;
pipeline_names : []string = .["arbtri", "trixel", "sky", "trile", "plane"]; pipeline_names : []string = .["arbtri", "trixel", "sky", "trile", "plane"];
slot_names : []string = .["Slot 1","Slot 2","Slot 3","Slot 4","Slot 5","Slot 6","Slot 7","Slot 8"]; slot_names : []string = .["Slot 1","Slot 2","Slot 3","Slot 4","Slot 5","Slot 6","Slot 7","Slot 8"];
draw_subwindow_texture_debug :: (state: *GR.Subwindow_State, r: GR.Rect, data: *void) { draw_subwindow_texture_debug :: (state: *GR.Subwindow_State, r: GR.Rect, data: *void) {
r2 := r; r2 := r;
r2.h = ui_h(5,0); r2.h = ui_h(5,0);
r2.w = r.w * 0.75; r2.w = r.w * 0.75;
GR.dropdown(r2, pipeline_names, *current_pipeline, null); GR.dropdown(r2, pipeline_names, *current_pipeline, *theme_ptr.dropdown_theme);
r2.x += r2.w; r2.x += r2.w;
r2.w = r.w * 0.25; r2.w = r.w * 0.25;
GR.dropdown(r2, slot_names, *current_slot, null); GR.dropdown(r2, slot_names, *current_slot, *theme_ptr.dropdown_theme);
r2.h = r.h - r2.h;
r2.y = r.y + r2.h; r2.y = r.y + r2.h;
r2.h = r.h - r2.h;
r2.x = r.x;
r2.w = r.w;
uiTex := New(Ui_Texture ,,temp);
bind : sg_bindings;
if current_pipeline == {
case 0; bind = gPipelines.arbtri.bind;
case 1; bind = gPipelines.trixel.bind;
case 2; bind = gPipelines.sky.bind;
case 3; bind = gPipelines.trile.bind;
case 4; bind = gPipelines.plane.bind;
}
uiTex.tex = bind.images[current_slot];
if uiTex.tex.id != INVALID_ID {
set_shader_for_images(uiTex);
immediate_quad(.{r2.x, r2.y}, .{r2.x + r2.w, r2.y}, .{r2.x + r2.w, r2.y + r2.h}, .{r2.x, r2.y + r2.h});
set_shader_for_color();
}
immediate_flush(); immediate_flush();
} }
@ -35,10 +57,12 @@ toggle_texdebug :: () {
draw_texture_debugger :: (theme: *GR.Overall_Theme) { draw_texture_debugger :: (theme: *GR.Overall_Theme) {
if !subwindow.open then return; if !subwindow.open then return;
if !subwindow_initted { if !subwindow_initted {
theme_ptr = theme;
r := GR.get_rect(ui_w(40, 0), ui_w(40, 0), ui_h(50,0), ui_h(50,0)); r := GR.get_rect(ui_w(40, 0), ui_w(40, 0), ui_h(50,0), ui_h(50,0));
subwindow.rect = r; subwindow.rect = r;
subwindow.draw = draw_subwindow_texture_debug; subwindow.draw = draw_subwindow_texture_debug;
subwindow.title_text = "Texture Debugger"; subwindow.title_text = "Texture Debugger";
subwindow.open = false;
subwindow_initted = true; subwindow_initted = true;
} }
if subwindow.open { // The Subwindow starts open, but pressing the Close button can close it. if subwindow.open { // The Subwindow starts open, but pressing the Close button can close it.

View File

@ -259,6 +259,8 @@ draw_trile_editor :: () {
} }
draw_trile :: () { draw_trile :: () {
if is_in_reflection_pass then return; // We don't want to double update the buffer.
if editor_current_trile == null then return; if editor_current_trile == null then return;
cam := get_trile_editor_camera(); cam := get_trile_editor_camera();
@ -372,6 +374,7 @@ trile_editor_shortcuts :: () {
draw_trile_editor_ui :: (theme: *GR.Overall_Theme) { draw_trile_editor_ui :: (theme: *GR.Overall_Theme) {
r := GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0)); r := GR.get_rect(0, ui_h(5,0), ui_w(20, 20), ui_h(95, 0));
ui_add_mouse_occluder(r);
draw_bg_rectangle(r, theme); draw_bg_rectangle(r, theme);
tab_r := r; tab_r := r;
tab_r.h = ui_h(3,0); tab_r.h = ui_h(3,0);

View File

@ -32,7 +32,7 @@ last_frame_time : float64;
delta\ _time : float64; delta\ _time : float64;
V_MAJOR :: 0; V_MAJOR :: 0;
V_MINOR :: 4; V_MINOR :: 5;
state: struct { state: struct {
pass_action_clear : sg_pass_action; pass_action_clear : sg_pass_action;
@ -119,6 +119,7 @@ init_after_asset_pack :: () {
is_in_reflection_pass : bool = false; is_in_reflection_pass : bool = false;
frame :: () { frame :: () {
check_and_handle_window_resize();
delta_time = get_time() - last_frame_time; delta_time = get_time() - last_frame_time;
last_frame_time = get_time(); last_frame_time = get_time();
@ -147,7 +148,7 @@ frame :: () {
tick_ui(); tick_ui();
sg_begin_pass(*(sg_pass.{ action = gPipelines.plane.pass_action, attachments = gPipelines.plane.attachments})); sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = gPipelines.plane.attachments}));
is_in_reflection_pass = true; is_in_reflection_pass = true;
draw_editor(); draw_editor();
if !in_editor_view then game_draw(); if !in_editor_view then game_draw();
@ -157,14 +158,7 @@ frame :: () {
sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, swapchain = cast,force(sg_swapchain) sglue_swapchain() })); sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
draw_editor(); draw_editor();
if !in_editor_view then game_draw(); if !in_editor_view then game_draw();
ui_clear_mouse_occluders();
uiTex := Ui_Texture.{gPipelines.plane.bind.images[0]};
set_shader_for_images(*uiTex);
r := GR.Rect.{0,0,500,500};
immediate_quad(.{r.x, r.y}, .{r.x + r.w, r.y}, .{r.x + r.w, r.y + r.h}, .{r.x, r.y + r.h});
set_shader_for_color();
ui_pass(); ui_pass();
sg_end_pass(); sg_end_pass();
sg_commit(); sg_commit();

View File

@ -47,6 +47,8 @@ Position_Color :: struct {
} }
create_trixel_pipeline :: () { create_trixel_pipeline :: () {
platconf := get_plat_conf();
pipeline: sg_pipeline_desc; pipeline: sg_pipeline_desc;
shader_desc := trixel_shader_desc(sg_query_backend()); shader_desc := trixel_shader_desc(sg_query_backend());
pipeline.shader = sg_make_shader(*shader_desc); pipeline.shader = sg_make_shader(*shader_desc);
@ -73,6 +75,8 @@ create_trixel_pipeline :: () {
} }
}; };
pipeline.sample_count = platconf.sample_count;
vertices : [24]Vector3 = .[ vertices : [24]Vector3 = .[
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2}, .{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
@ -162,6 +166,7 @@ create_trixel_pipeline :: () {
} }
create_trile_pipeline :: () { create_trile_pipeline :: () {
platconf := get_plat_conf();
pipeline: sg_pipeline_desc; pipeline: sg_pipeline_desc;
shader_desc := trile_shader_desc(sg_query_backend()); shader_desc := trile_shader_desc(sg_query_backend());
pipeline.shader = sg_make_shader(*shader_desc); pipeline.shader = sg_make_shader(*shader_desc);
@ -180,6 +185,7 @@ create_trile_pipeline :: () {
write_enabled = true, write_enabled = true,
compare = .LESS_EQUAL, compare = .LESS_EQUAL,
}; };
pipeline.sample_count = platconf.sample_count;
color_state := sg_color_target_state.{ color_state := sg_color_target_state.{
pixel_format = .RGBA8, pixel_format = .RGBA8,
@ -205,10 +211,12 @@ create_trile_pipeline :: () {
} }
create_sky_pipeline :: () { create_sky_pipeline :: () {
platconf := get_plat_conf();
pipeline: sg_pipeline_desc; pipeline: sg_pipeline_desc;
shader_desc := sky_shader_desc(sg_query_backend()); shader_desc := sky_shader_desc(sg_query_backend());
pipeline.shader = sg_make_shader(*shader_desc); pipeline.shader = sg_make_shader(*shader_desc);
pipeline.layout.buffers[0].stride = 4*3; pipeline.layout.buffers[0].stride = 4*3;
pipeline.sample_count = platconf.sample_count;
pipeline.layout.attrs[ATTR_sky_position] = .{ format = .FLOAT3, buffer_index = 0 }; pipeline.layout.attrs[ATTR_sky_position] = .{ format = .FLOAT3, buffer_index = 0 };
pipeline.index_type = .UINT16; pipeline.index_type = .UINT16;
@ -284,8 +292,13 @@ create_sky_pipeline :: () {
} }
// @ToDo: This needs to be redone when the window is resized; // @ToDo: This needs to be redone when the window is resized;
create_plane_pipeline_reflection_image :: (binding: *sg_bindings) { create_plane_pipeline_reflection_images :: () {
reflection_img := sg_alloc_image(); platconf := get_plat_conf();
binding := *gPipelines.plane.bind;
if binding.images[4].id != INVALID_ID then sg_destroy_image(binding.images[4]);
if binding.images[5].id != INVALID_ID then sg_destroy_image(binding.images[5]);
if binding.images[0].id != INVALID_ID then sg_destroy_image(binding.images[0]);
w, h := get_window_size(); w, h := get_window_size();
img_desc := sg_image_desc.{ img_desc := sg_image_desc.{
width = w, width = w,
@ -296,14 +309,33 @@ create_plane_pipeline_reflection_image :: (binding: *sg_bindings) {
depth_desc := sg_image_desc.{ depth_desc := sg_image_desc.{
width = w, width = w,
height = h, height = h,
pixel_format = .DEPTH, pixel_format = .DEPTH_STENCIL,
render_target = true, render_target = true,
}; };
binding.images[4] = sg_make_image(*img_desc);
img_desc.sample_count = 1;
binding.images[0] = sg_make_image(*img_desc); binding.images[0] = sg_make_image(*img_desc);
binding.images[1] = sg_make_image(*depth_desc); binding.images[5] = sg_make_image(*depth_desc);
attachmentsDesc : sg_attachments_desc;
if platconf.sample_count > 1 {
attachmentsDesc = .{
colors[0].image = gPipelines.plane.bind.images[4],
resolves[0].image = gPipelines.plane.bind.images[0],
depth_stencil.image = gPipelines.plane.bind.images[5],
};
} else {
attachmentsDesc = .{
colors[0].image = gPipelines.plane.bind.images[0],
depth_stencil.image = gPipelines.plane.bind.images[5],
};
}
sg_destroy_attachments(gPipelines.plane.attachments);
gPipelines.plane.attachments = sg_make_attachments(*attachmentsDesc);
} }
create_plane_pipeline :: () { create_plane_pipeline :: () {
platconf := get_plat_conf();
pipeline: sg_pipeline_desc; pipeline: sg_pipeline_desc;
shader_desc := plane_shader_desc(sg_query_backend()); shader_desc := plane_shader_desc(sg_query_backend());
pipeline.shader = sg_make_shader(*shader_desc); pipeline.shader = sg_make_shader(*shader_desc);
@ -315,7 +347,7 @@ create_plane_pipeline :: () {
pipeline.depth = .{ pipeline.depth = .{
write_enabled = true, write_enabled = true,
compare = .LESS_EQUAL, compare = .LESS_EQUAL,
pixel_format = .DEPTH, pixel_format = .DEPTH_STENCIL
}; };
color_state := sg_color_target_state.{ color_state := sg_color_target_state.{
@ -339,6 +371,8 @@ create_plane_pipeline :: () {
0, 2, 3, 0, 2, 3,
]; ];
pipeline.sample_count = platconf.sample_count;
pipeline.color_count = 1; pipeline.color_count = 1;
pipeline.colors[0] = color_state; pipeline.colors[0] = color_state;
@ -349,14 +383,8 @@ create_plane_pipeline :: () {
gPipelines.plane.bind.index_buffer = sg_make_buffer(*ibuffer); gPipelines.plane.bind.index_buffer = sg_make_buffer(*ibuffer);
gPipelines.plane.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer); gPipelines.plane.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
create_plane_pipeline_reflection_image(*gPipelines.plane.bind); create_plane_pipeline_reflection_images();
attachmentsDesc := sg_attachments_desc.{
colors[0].image = gPipelines.plane.bind.images[0],
depth_stencil.image = gPipelines.plane.bind.images[1],
};
gPipelines.plane.attachments = sg_make_attachments(*attachmentsDesc);
gPipelines.plane.pass_action = .{ gPipelines.plane.pass_action = .{
@ -370,9 +398,13 @@ create_plane_pipeline :: () {
mag_filter = .NEAREST, mag_filter = .NEAREST,
})); }));
materialdata : [1000*1000*4]u8; gPipelines.plane.bind.samplers[1] = sg_make_sampler(*(sg_sampler_desc.{
imgdata : sg_image_data; wrap_u = .CLAMP_TO_EDGE,
imgdata.subimage[0][0] = .{materialdata.data, materialdata.count}; wrap_v = .CLAMP_TO_EDGE,
min_filter = .NEAREST,
mag_filter = .NEAREST,
}));
ground_img_desc := sg_image_desc.{ ground_img_desc := sg_image_desc.{
width = 1000, width = 1000,
@ -380,13 +412,14 @@ create_plane_pipeline :: () {
pixel_format = .RGBA8, pixel_format = .RGBA8,
render_target = false, render_target = false,
sample_count = 1, sample_count = 1,
data = imgdata usage = .DYNAMIC,
}; };
gPipelines.plane.bind.images[2] = sg_make_image(*ground_img_desc); gPipelines.plane.bind.images[1] = sg_make_image(*ground_img_desc);
} }
create_arbtri_pipeline :: () { create_arbtri_pipeline :: () {
platconf := get_plat_conf();
pipeline: sg_pipeline_desc; pipeline: sg_pipeline_desc;
shader_desc := triangle_shader_desc(sg_query_backend()); shader_desc := triangle_shader_desc(sg_query_backend());
pipeline.shader = sg_make_shader(*shader_desc); pipeline.shader = sg_make_shader(*shader_desc);
@ -394,6 +427,7 @@ create_arbtri_pipeline :: () {
pipeline.layout.attrs[ATTR_triangle_position] = .{ format = .FLOAT3 }; pipeline.layout.attrs[ATTR_triangle_position] = .{ format = .FLOAT3 };
pipeline.layout.attrs[ATTR_triangle_color0] = .{ format = .FLOAT4 }; pipeline.layout.attrs[ATTR_triangle_color0] = .{ format = .FLOAT4 };
pipeline.layout.attrs[ATTR_triangle_uv] = .{ format = .FLOAT2 }; pipeline.layout.attrs[ATTR_triangle_uv] = .{ format = .FLOAT2 };
pipeline.sample_count = platconf.sample_count;
color_state := sg_color_target_state.{ color_state := sg_color_target_state.{
pixel_format = .RGBA8, pixel_format = .RGBA8,

View File

@ -16,6 +16,7 @@ temporary_storage: Temporary_Storage;
temporary_storage_data: [TEMPORARY_STORAGE_SIZE] u8 #align 64; temporary_storage_data: [TEMPORARY_STORAGE_SIZE] u8 #align 64;
sapp_init :: () { sapp_init :: () {
platconf := get_plat_conf();
default_context.temporary_storage = *temporary_storage; default_context.temporary_storage = *temporary_storage;
temporary_storage.data = temporary_storage_data.data; temporary_storage.data = temporary_storage_data.data;
temporary_storage.size = temporary_storage_data.count; temporary_storage.size = temporary_storage_data.count;
@ -37,7 +38,7 @@ sapp_init :: () {
window_title = wi.title, window_title = wi.title,
// icon = .{ sokol_default = true }, // icon = .{ sokol_default = true },
logger = .{ func = slog_func }, logger = .{ func = slog_func },
sample_count = 4, sample_count = platconf.sample_count,
})); }));
} }
} }
@ -62,3 +63,24 @@ cleanup_plat :: () #c_call {
cleanup(); cleanup();
} }
Platform_Conf :: struct {
sample_count: s32;
}
get_plat_conf :: () -> Platform_Conf {
#if OS == .WASM {
return .{
sample_count = 1,
};
}
#if OS == .LINUX {
return .{
sample_count = 4,
};
}
#if OS == .MACOS {
return .{
sample_count = 4,
};
}
}

View File

@ -21,9 +21,5 @@ draw_ground_plane :: (cam: *Camera, worldConfig: *World_Config = null) {
sg_apply_uniforms(UB_plane_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))})); sg_apply_uniforms(UB_plane_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
sg_apply_uniforms(UB_plane_data, *(sg_range.{ptr = *plane_data, size = size_of(type_of(plane_data))})); sg_apply_uniforms(UB_plane_data, *(sg_range.{ptr = *plane_data, size = size_of(type_of(plane_data))}));
if wc.planeType == 1 {
sg_draw(0, 6, 1); sg_draw(0, 6, 1);
} else {
sg_draw(0, 6, 128);
}
} }

View File

@ -1,2 +1,28 @@
#load "groundplane.jai"; #load "groundplane.jai";
#load "sky.jai"; #load "sky.jai";
#scope_file
initted : bool;
old_w : int;
old_h : int;
on_window_resize :: () {
create_plane_pipeline_reflection_images();
}
#scope_export
check_and_handle_window_resize :: () {
w,h := get_window_size();
if !initted {
old_w = w;
old_h = h;
initted = true;
return;
}
if w != old_w || h != old_h {
old_w = w; old_h = h;
on_window_resize();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ out flat int idx;
void main() { void main() {
vec3 multisize = vec3(position.xyz * 1000.0); vec3 multisize = vec3(position.xyz * 1000.0);
gl_Position = mvp * (vec4(multisize.x, 0.0 + float(gl_InstanceIndex) * 0.006, multisize.z, 1.0)); gl_Position = mvp * vec4(multisize, 1.0);
pos = vec4(multisize, 1.0); pos = vec4(multisize, 1.0);
idx = gl_InstanceIndex; idx = gl_InstanceIndex;
} }
@ -68,18 +68,9 @@ layout(binding=2) uniform plane_data {
}; };
layout(binding = 0) uniform texture2D reftex; layout(binding = 0) uniform texture2D reftex;
layout(binding = 2) uniform texture2D groundtex; layout(binding = 1) uniform texture2D groundtex;
layout(binding = 0) uniform sampler refsmp; layout(binding = 0) uniform sampler refsmp;
layout(binding = 1) uniform sampler groundsmp;
#define hash(p) fract(sin(dot(p, vec2(11.9898, 78.233))) * 43758.5453)
float B(vec2 U) {
float v = hash( U + vec2(-1, 0) )
+ hash( U + vec2( 1, 0) )
+ hash( U + vec2( 0, 1) )
+ hash( U + vec2( 0,-1) );
return hash(U) - v/4. + .5;
}
float random (vec2 st) { float random (vec2 st) {
return fract(sin(dot(st.xy, return fract(sin(dot(st.xy,
@ -108,135 +99,56 @@ float noise (vec2 st) {
(d - b) * u.x * u.y; (d - b) * u.x * u.y;
} }
vec3 wave(vec4 wave, vec3 p, inout vec3 tangent, inout vec3 binormal) { int sign2(float x) {
float steepness = wave.z; if(x < 0) return -1;
float wavelength = wave.w; return 1;
float k = 2.0 * 3.141 / wavelength; }
float c = 2.0;
vec2 d = normalize(vec2(wave.x, wave.y));
float f = k * (dot(d, p.xz) - c * (time * 0.1));
float a = steepness / k;
tangent += vec3( vec3 get_ground_sample(vec4 pos, float dirX, float dirY) {
-d.x * d.x * (steepness * sin(f)), ivec2 plane_coord = ivec2(floor(pos.x + dirX) + 500, floor(pos.z + dirY) + 500);
d.x * (steepness * cos(f)), vec4 reflection = texelFetch(sampler2D(reftex, refsmp), ivec2(gl_FragCoord.x, screen_h - gl_FragCoord.y), 0);
-d.x * d.y * (steepness * sin(f)) vec4 groundSample = texelFetch(sampler2D(groundtex, groundsmp), plane_coord, 0);
);
binormal += vec3( // Calculate all materials so we can blend them.
-d.x * d.y * (steepness * sin(f)), vec3 water = reflection.xyz * vec3(0.0, 0.8, 0.8);
d.y * (steepness * cos(f)), vec3 sand = vec3(mix(0.8, 1.0, hash12(pos.xz)) * vec3(0.8, 0.7, 0.5));
-d.y * d.y * (steepness * sin(f)) vec3 grass = vec3(mix(0.8, 1.0, hash12(pos.xz)) * vec3(0.4, 0.8, 0.3));
);
return vec3( if(groundSample.b == 1.0) {
d.x * (a * cos(f)), return water;
a * sin(f), } else if(groundSample.r == 1.0) {
d.y * (a * cos(f)) return sand;
); } else {
return grass;
}
} }
void main() { void main() {
vec4 npos = round(pos * 16.0) / 16.0;
vec2 tileCenter = vec2(floor(npos.x) + 0.5, floor(npos.z) + 0.5);
vec2 toCenter = npos.xz - tileCenter;
// Bilinear filtering
float u = smoothstep(0.2, 0.5, abs(toCenter.x)) * 0.5;
float v = smoothstep(0.2, 0.5, abs(toCenter.y)) * 0.5;
// @ToDo: We should implement some sort of fog system and stop doing all this sampling
// stuff if we are far enough from the camera. Currently ground rendering is taking way
// too much time each frame.
vec3 c0 = get_ground_sample(npos, 0.0, 0.0);
vec3 c1 = get_ground_sample(npos, sign2(toCenter.x), 0.0);
vec3 c2 = get_ground_sample(npos, 0.0, sign2(toCenter.y));
vec3 c3 = get_ground_sample(npos, sign2(toCenter.x), sign2(toCenter.y));
// @ToDo: Consider using cool Inigo Quilez trick here to make it even smoother.
vec3 b01 = mix(c0, c1, u);
vec3 b23 = mix(c2, c3, u);
vec3 bf = mix(b01, b23, v);
if(planeType == 1) { if(planeType == 1) {
vec4 reflection = texelFetch(sampler2D(reftex, refsmp), ivec2(gl_FragCoord.x, screen_h - gl_FragCoord.y), 0); frag_color = vec4(bf, 1.0);
frag_color = reflection * vec4(0.9, 0.9, 1.0, 1.0);
} else { } else {
float density = grassDensity; frag_color = vec4(b23, 1.0);
vec2 densifiedCoordinate = pos.xz * density;
densifiedCoordinate.x += sin(densifiedCoordinate.y) * 0.5;
densifiedCoordinate.y += sin(densifiedCoordinate.x) * 0.5;
vec2 ruohokeskus = round(densifiedCoordinate);
float noiseval_fine = noise(densifiedCoordinate / 50.0);
float noiseval_coarse = noise(densifiedCoordinate / 500.0);
float noiseval_plantti = noise(densifiedCoordinate / 500.0);
if(noiseval_plantti < 0.9) {
noiseval_plantti = 0.0;
} else {
noiseval_plantti = (noiseval_plantti - 0.9) * 10.0;
}
float noiseval_vesi = noise(densifiedCoordinate.yx / 700.0);
int is_water = 0;
float is_water_coast = 1.0;
float coast_multiplier = 0.0;
if(noiseval_vesi > 0.9) {
is_water = 1;
if(noiseval_vesi < 0.93) {
is_water_coast = (noiseval_vesi - 0.9) * 33.333;
}
}
if(noiseval_vesi > 0.8) {
coast_multiplier = (noiseval_vesi - 0.8) * 10;
}
float rand = (hash12(ruohokeskus)) - 0.4;
rand += 0.4 * noiseval_coarse;
vec2 sandDensifiedCoordinate = round(pos.xz * density * 10.0);
float sand_rand = (hash12(sandDensifiedCoordinate));
vec4 sandcolor = vec4(mix(0.8, 1.0, sand_rand) * vec3(0.8, 0.7, 0.5), 1.0);
if(is_water == 1) {
vec3 tangent = vec3(1.0, 0.0, 0.0);
vec3 binormal = vec3(0.0, 0.0, 1.0);
vec3 p = vec3(0.0);
p += wave(vec4(1.0, 0.5, 0.1, 0.9), pos.xyz, tangent, binormal);
vec3 normal = normalize(cross(normalize(binormal), normalize(tangent)));
vec2 rippleOffset = normal.xz * 0.005;
rippleOffset.x = clamp(rippleOffset.x, -0.01, 0.01);
rippleOffset.y = clamp(rippleOffset.y, -0.01, 0.01);
vec3 light = normalize(sunPosition);
float lightfactor = max(dot(light, normal),0.0);
lightfactor = min(max(lightfactor, 0.1), 1.0);
// float spec = max(dot(normalize(light + normalize(cv - fragWorldPos)), normal), 0.0);
// spec -= 0.9;
// spec = max(spec, 0.0);
// spec *= 4.0;
// vec3 specLight = spec * sunIntensity * sunColor.xyz;
vec3 diffLight = lightfactor * sunIntensity * sunLightColor.xyz * 0.1;
// vec3 totalLight = (specLight + diffLight);
if(idx > 0 || is_reflection_pass == 1) discard;
vec4 reflection = texelFetch(sampler2D(reftex, refsmp), ivec2(gl_FragCoord.x + int(rippleOffset.x * screen_w), screen_h + int(rippleOffset.y * screen_h) - gl_FragCoord.y), 0);
frag_color = vec4(min(vec3(1.0), vec3(mix(1.0, 0.8, smoothstep(0.0, 0.9, is_water_coast))) + diffLight), 1.0) * mix(sandcolor, reflection, smoothstep(0.0, 0.9, is_water_coast));
// frag_color = reflection;
} else {
float h = (1.0 / 128.0) * idx;
rand -= mix(0.0, 1.0, coast_multiplier);
rand = max(0.0, rand);
ruohokeskus.x += sin(time * 1.2) * 0.2 * h;
float distanceFromCenter = length(ruohokeskus - (densifiedCoordinate));
if(idx > 0 && rand < 0.2) {
discard;
}
float thickness = 0.5;
if(idx > 0 && (rand - h) * thickness < distanceFromCenter) {
discard;
} else {
if(idx == 0) {
frag_color = mix(vec4(noiseval_coarse * 0.5, 0.2 + noiseval_fine * 0.2, 0.1, 1.0),sandcolor,coast_multiplier);
} else {
vec4 grass_color = vec4(noiseval_coarse * 0.5, min(1.0, h + 0.2) + noiseval_fine * 0.2, 0.1, 1.0);
vec4 plantti_color = vec4(h, h * 0.3, 0.0, 1.0);
vec4 normal_ground_color = mix(grass_color, plantti_color, noiseval_plantti);
frag_color = mix(normal_ground_color, vec4(h * 2.0 + 0.4, h * 2.0 + 0.4, 0.0, 1.0), coast_multiplier);
}
}
}
} }
} }
@end @end

View File

@ -197,6 +197,7 @@ material_from_rgba :: (r: u8, g: u8, b: u8, a: u8) -> Material {
draw_trile_picker :: (theme: *GR.Overall_Theme) { draw_trile_picker :: (theme: *GR.Overall_Theme) {
r := GR.get_rect(ui_w(85,85), ui_h(5,0), ui_w(15, 15), ui_h(95, 0)); r := GR.get_rect(ui_w(85,85), ui_h(5,0), ui_w(15, 15), ui_h(95, 0));
ui_add_mouse_occluder(r);
draw_bg_rectangle(r, theme); draw_bg_rectangle(r, theme);
tpt := get_trile_table_ptr(); tpt := get_trile_table_ptr();
r.h = ui_h(4,4); r.h = ui_h(4,4);

View File

@ -86,6 +86,34 @@ defaultFont: Font;
ui_texture_counter : u32 = 0; ui_texture_counter : u32 = 0;
#scope_file
ui_mouse_occluders : [..]GR.Rect;
#scope_export
ui_add_mouse_occluder :: (r: GR.Rect) {
array_add(*ui_mouse_occluders, r);
}
ui_clear_mouse_occluders :: () {
array_reset_keeping_memory(*ui_mouse_occluders);
}
ui_is_mouse_in_occluder :: (mpos: Vector2) -> bool {
for ui_mouse_occluders {
if (mpos.x >= it.x && mpos.x <= it.x + it.w && mpos.y >= it.y && mpos.y <= it.y + it.h) {
return true;
};
}
return false;
}
get_mouse_state :: (kc: Key_Code) -> Key_Current_State {
if ui_is_mouse_in_occluder(.{input_mouse_x, input_mouse_y}) then return .NONE;
return input_button_states[kc];
}
texture_load_from_memory :: (texture: *Ui_Texture, memory: []u8, srgb: bool, build_mipmaps: bool) -> bool { texture_load_from_memory :: (texture: *Ui_Texture, memory: []u8, srgb: bool, build_mipmaps: bool) -> bool {
x : s32; x : s32;
y : s32; y : s32;
@ -158,14 +186,17 @@ prepare_text :: (font: *Ui_Type_Indicator.Font, text: string, effects: Ui_Type_I
gPreppedTextWidth = 0; gPreppedTextWidth = 0;
return 0; return 0;
} }
// print("Font: %\n", font);
fonsSetFont(state.fons, state.font_default.fons_font); fonsSetFont(state.fons, state.font_default.fons_font);
fonsSetSize(state.fons, xx font.character_height); fonsSetSize(state.fons, xx font.character_height);
w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null); w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null);
gPreppedText = text; gPreppedText = text;
gPreppedTextWidth = cast(s32) w; gPreppedTextWidth = cast(s32) w;
array_reset(*font.temporary_glyphs); // @Memory: there is a bug if we actually free these during subwindow popup draw.
array_reset(*font.temporary_glyphs_byte_offsets); // I'm not completely sure why, but it should be fine/better if we just reset keeping memory.
array_reset_keeping_memory(*font.temporary_glyphs);
array_reset_keeping_memory(*font.temporary_glyphs_byte_offsets);
font.temporary_glyphs_width_in_pixels = 0; font.temporary_glyphs_width_in_pixels = 0;

View File

@ -14,9 +14,9 @@ World_Config :: struct {
hasPlane : s32 = 0; @Slider,0,1,1 hasPlane : s32 = 0; @Slider,0,1,1
planeHeight : float = 0.0; @Slider,-100,100,1 planeHeight : float = 0.0; @Slider,-100,100,1
planeType : s32 = 0; @Slider,0,1,1 planeType : s32 = 1; @Slider,0,1,1
grassDensity : float = 30; @Slider,10,100,1 grassDensity : float = 200; @Slider,10,300,1
} }
// Copies over all the fields of our world config into a given shader type. // Copies over all the fields of our world config into a given shader type.
@ -43,6 +43,7 @@ TrilePositions :: struct {
Ground_Tile :: enum { Ground_Tile :: enum {
WATER; WATER;
GRASS; GRASS;
SAND;
} }
World :: struct { World :: struct {
@ -70,6 +71,13 @@ update_image_from_ground :: (world: *World, img: *sg_image) {
materialdata[counter + 2] = 255; materialdata[counter + 2] = 255;
materialdata[counter + 3] = 255; materialdata[counter + 3] = 255;
}
if world.ground[x][y] == .SAND {
materialdata[counter + 0] = 255;
materialdata[counter + 1] = 0;
materialdata[counter + 2] = 0;
materialdata[counter + 3] = 255;
} }
counter += 4; counter += 4;
} }

BIN
walloc.o

Binary file not shown.