Compare commits

..

2 Commits

Author SHA1 Message Date
Sven Balzer 4c158f25f0 add trees into the game
buildbot/windows Build done.
buildbot/linux Build done.
2026-08-05 20:48:57 +02:00
Sven Balzer 6a984b40d9 remove vertex_buffer and index_buffer for characters and character shadows
refactor world shader vertex position calculation
2026-08-05 20:48:57 +02:00
18 changed files with 983 additions and 240 deletions
+1
View File
@@ -108,6 +108,7 @@ endfunction()
add_shader(character) add_shader(character)
add_shader(character_shadow) add_shader(character_shadow)
add_shader(world) add_shader(world)
add_shader(tree)
add_shader(grid) add_shader(grid)
add_custom_target(shaders-spv DEPENDS ${SHADERS_SPV}) add_custom_target(shaders-spv DEPENDS ${SHADERS_SPV})
Binary file not shown.
+312 -43
View File
@@ -1,3 +1,4 @@
#include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <bit> #include <bit>
@@ -9,6 +10,7 @@
#include <tracy/Tracy.hpp> #include <tracy/Tracy.hpp>
#include <tracy/TracyC.h> #include <tracy/TracyC.h>
#include <webgpu/webgpu.h> #include <webgpu/webgpu.h>
#include "smol-atlas.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
@@ -31,6 +33,7 @@ using namespace glm;
#define TILE_SIZE (32) #define TILE_SIZE (32)
#define TILE_ATLAS_SIZE (512) #define TILE_ATLAS_SIZE (512)
#define TREE_ATLAS_SIZE (256)
static SDL_Window *window; static SDL_Window *window;
static R_Texture framebuffer; static R_Texture framebuffer;
@@ -39,15 +42,17 @@ static R_Texture player_texture;
static R_Texture character_shadow_texture; static R_Texture character_shadow_texture;
static R_Texture tile_textures_atlas; static R_Texture tile_textures_atlas;
static R_Texture tile_textures_atlas_imgui; static R_Texture tile_textures_atlas_imgui;
static R_Texture tree_textures_atlas;
static R_Texture tree_textures_atlas_imgui;
static R_Buffer view_projection_matrix_buffer; static R_Buffer view_projection_matrix_buffer;
static R_Buffer per_frame_buffer; static R_Buffer per_frame_buffer;
static R_Buffer tint_color_buffer; static R_Buffer tint_color_buffer;
static R_Buffer vertex_buffer;
static R_Buffer index_buffer;
static R_Buffer player_instance_buffer; static R_Buffer player_instance_buffer;
static R_Buffer trees_instance_buffer;
static R_Buffer tile_uvs_buffer; static R_Buffer tile_uvs_buffer;
static R_Buffer tree_uvs_buffer;
static i32vec2 window_size = { 1280, 720 }; static i32vec2 window_size = { 1280, 720 };
@@ -89,6 +94,7 @@ static float editor_camera_distance = 30.0f;
static bool show_demo_window; static bool show_demo_window;
static bool show_tile_picker; static bool show_tile_picker;
static bool show_tree_editor;
static bool show_settings; static bool show_settings;
static float character_speed = 4.0f; static float character_speed = 4.0f;
@@ -170,23 +176,6 @@ enum Settings_Category {
SETTINGS_AUDIO, SETTINGS_AUDIO,
}; };
struct Vertex {
vec3 pos;
vec2 uv;
};
static Vertex vertices[] = {
{{ -0.5f, 0.5f, 0.0f }, { 0.0f, 0.0f }},
{{ -0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f }},
{{ 0.5f, -0.5f, 0.0f }, { 1.0f, 1.0f }},
{{ 0.5f, 0.5f, 0.0f }, { 1.0f, 0.0f }},
};
static Uint16 indices[] = {
0, 1, 2,
0, 2, 3,
};
struct Instance { struct Instance {
vec2 pos; vec2 pos;
uint32_t sprite_selection; uint32_t sprite_selection;
@@ -194,15 +183,22 @@ struct Instance {
static Instance player_instance = {{ 0.0f, 0.0f }}; static Instance player_instance = {{ 0.0f, 0.0f }};
struct Map { struct Tree {
Uint32 version; u32vec2 pos;
Uint32 kind;
};
struct Map {
i32vec2 size; i32vec2 size;
Uint16 *tiles; Uint16 *tiles;
Uint32 num_trees;
Tree *trees;
char name[64]; char name[64];
R_Texture texture; R_Texture texture;
R_Buffer trees_buffer;
}; };
static Map current_map; static Map current_map;
@@ -414,6 +410,19 @@ static TileInfo tile_infos[] = {
static vec4 tile_uvs[SDL_arraysize(tile_infos)]; static vec4 tile_uvs[SDL_arraysize(tile_infos)];
struct TreeInfo {
Uint16 serialization_id;
const char *asset_path;
};
static TreeInfo tree_infos[] = {
{ 0, "decorations/tree_standard_tile.png" },
};
static vec4 tree_uvs[SDL_arraysize(tree_infos)];
static Sint32 selected_tree = -1;
static Sint32 selected_tile_kind = -1; static Sint32 selected_tile_kind = -1;
static Sint32 selected_tile = -1; static Sint32 selected_tile = -1;
@@ -446,11 +455,12 @@ static R_Texture create_texture(const char *path) {
return result; return result;
} }
#define MAP_FILE_VERSION (2u) #define MAP_FILE_VERSION (3u)
static bool save_map(Map map) { static bool save_map(Map map) {
char path[256] = ASSETS_PATH "maps/"; char path[256] = ASSETS_PATH "maps/";
SDL_strlcat(path, map.name, SDL_arraysize(path)); SDL_strlcat(path, map.name, SDL_arraysize(path));
SDL_strlcat(path, ".sv", SDL_arraysize(path));
SDL_IOStream *file = SDL_IOFromFile(path, "wb"); SDL_IOStream *file = SDL_IOFromFile(path, "wb");
if (!file) { if (!file) {
@@ -483,6 +493,30 @@ static bool save_map(Map map) {
} }
} }
if (!SDL_WriteU32LE(file, map.num_trees)) {
log_error("Failed to write num_trees to map file.");
return false;
}
for (int i = 0; i < map.num_trees; i++) {
Uint16 id = tree_infos[map.trees[i].kind].serialization_id;
if (!SDL_WriteU16LE(file, id)) {
log_error("Failed to write tree kind to map file.");
return false;
}
if (!SDL_WriteU32LE(file, map.trees[i].pos.x)) {
log_error("Failed to write tree pos.x to map file.");
return false;
}
if (!SDL_WriteU32LE(file, map.trees[i].pos.y)) {
log_error("Failed to write tree pos.y to map file.");
return false;
}
}
if(!SDL_FlushIO(file)) { if(!SDL_FlushIO(file)) {
log_error("Failed to flush data to map file."); log_error("Failed to flush data to map file.");
return false; return false;
@@ -495,6 +529,7 @@ static bool save_map(Map map) {
static bool load_map(const char *name, Map *result) { static bool load_map(const char *name, Map *result) {
char path[256] = ASSETS_PATH "maps/"; char path[256] = ASSETS_PATH "maps/";
SDL_strlcat(path, name, SDL_arraysize(path)); SDL_strlcat(path, name, SDL_arraysize(path));
SDL_strlcat(path, ".sv", SDL_arraysize(path));
SDL_IOStream *file = SDL_IOFromFile(path, "rb"); SDL_IOStream *file = SDL_IOFromFile(path, "rb");
if (!file) { if (!file) {
@@ -504,13 +539,19 @@ static bool load_map(const char *name, Map *result) {
defer(SDL_CloseIO(file)); defer(SDL_CloseIO(file));
SDL_memcpy(result->name, name, SDL_min(strlen(name), SDL_arraysize(result->name) - 1)); SDL_memcpy(result->name, name, SDL_min(strlen(name), SDL_arraysize(result->name) - 1));
if (!SDL_ReadU32LE(file, &result->version)) { Uint32 version = 0;
if (!SDL_ReadU32LE(file, &version)) {
log_error("Failed read version from map file."); log_error("Failed read version from map file.");
return false; return false;
} }
if (result->version > MAP_FILE_VERSION) { if (!version) {
log_error("Map file version (%u) is higher than the highest supported.", result->version); log_error("Map file version for map '%s' was 0 which is not valid.", name);
return false;
}
if (version > 3) {
log_error("Map file version (%u) is higher than the highest supported.", version);
return false; return false;
} }
@@ -524,10 +565,10 @@ static bool load_map(const char *name, Map *result) {
return false; return false;
} }
result->tiles = (Uint16*)malloc(result->size.x * result->size.y * sizeof(Uint16)); result->tiles = (Uint16 *)SDL_malloc(result->size.x * result->size.y * sizeof(Uint16));
for (int i = 0; i < result->size.x * result->size.y; i++) { for (int i = 0; i < result->size.x * result->size.y; i++) {
if (result->version == 2) { if (version >= 2) {
Uint16 serialization_id = 0; Uint16 serialization_id = 0;
if (!SDL_ReadU16LE(file, &serialization_id)) { if (!SDL_ReadU16LE(file, &serialization_id)) {
free(result->tiles); free(result->tiles);
@@ -551,11 +592,58 @@ static bool load_map(const char *name, Map *result) {
} }
} }
if (version >= 3) {
if (!SDL_ReadU32LE(file, &result->num_trees)) {
log_error("Failed to read num_trees from map file.");
free(result->tiles);
return false;
}
result->trees = (Tree *)SDL_malloc(result->num_trees * sizeof(Tree));
for (int i = 0; i < result->num_trees; i++) {
Uint16 serialization_id = 0;
if (!SDL_ReadU16LE(file, &serialization_id)) {
free(result->tiles);
free(result->trees);
return false;
}
Uint16 info_index = 0;
for (int i = 0; i < SDL_arraysize(tree_infos); i++) {
if (tree_infos[i].serialization_id == serialization_id) {
info_index = i;
break;
}
}
result->trees[i].kind = info_index;
if (!SDL_ReadU32LE(file, &result->trees[i].pos.x)) {
free(result->tiles);
free(result->trees);
log_error("Failed to read tree pos.x from map file.");
return false;
}
if (!SDL_ReadU32LE(file, &result->trees[i].pos.y)) {
free(result->tiles);
free(result->trees);
log_error("Failed to read tree pos.y from map file.");
return false;
}
}
}
char buffer_name[256] = "Map "; char buffer_name[256] = "Map ";
SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name)); SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name));
result->texture = renderer_texture_create(R_TEXTURE_FORMAT_R16_UINT, R_TEXTURE_USAGE_STORAGE, false, result->size.x, result->size.y, result->tiles, "map_texture"); result->texture = renderer_texture_create(R_TEXTURE_FORMAT_R16_UINT, R_TEXTURE_USAGE_STORAGE, false, result->size.x, result->size.y, result->tiles, "map_texture");
if (result->num_trees) {
result->trees_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, result->num_trees * sizeof(*result->trees), result->trees, "trees_buffer");
}
SDL_Log("Loaded map file."); SDL_Log("Loaded map file.");
return true; return true;
} }
@@ -658,6 +746,20 @@ static bool SelectableTile(const char *label, bool selected, Uint32 tile_index,
return pressed; return pressed;
} }
static bool SelectableImage(const char *label, R_Texture texture, ImVec2 image_size, vec2 uv_min, vec2 uv_max, bool selected) {
const ImGuiContext *context = ImGui::GetCurrentContext();
const ImVec2 padding = context->Style.FramePadding;
bool pressed = ImGui::Selectable(label, selected, 0, ImVec2(image_size.x, image_size.y) + padding * 2.0f);
ImVec2 min = ImGui::GetItemRectMin();
ImVec2 max = ImGui::GetItemRectMax();
context->CurrentWindow->DrawList->AddImageQuad((ImTextureID)ImGui_ImplRenderer_GetTextureID(texture), min + padding, ImVec2(max.x - padding.x, min.y + padding.y), max - padding, ImVec2(min.x + padding.x, max.y - padding.y), ImVec2(uv_min.x, uv_min.y), ImVec2(uv_max.x, uv_min.y), ImVec2(uv_max.x, uv_max.y), ImVec2(uv_min.x, uv_max.y));
return pressed;
}
static ImVec4 linear_to_sRGB(ImVec4 linear) { static ImVec4 linear_to_sRGB(ImVec4 linear) {
float red = linear.x <= 0.0031308f ? 12.92f * linear.x : 1.055f * powf(linear.x, 1.0f / 2.4f) - 0.055; float red = linear.x <= 0.0031308f ? 12.92f * linear.x : 1.055f * powf(linear.x, 1.0f / 2.4f) - 0.055;
float green = linear.y <= 0.0031308f ? 12.92f * linear.y : 1.055f * powf(linear.y, 1.0f / 2.4f) - 0.055; float green = linear.y <= 0.0031308f ? 12.92f * linear.y : 1.055f * powf(linear.y, 1.0f / 2.4f) - 0.055;
@@ -795,6 +897,68 @@ static bool recreate_tile_textures() {
return true; return true;
} }
static bool recreate_tree_textures() {
smol_atlas_t *tree_atlas = sma_atlas_create(TREE_ATLAS_SIZE, TREE_ATLAS_SIZE);
smol_atlas_item_t **tree_atlas_items = (smol_atlas_item_t **)SDL_calloc(SDL_arraysize(tree_infos), sizeof(smol_atlas_item_t *));
defer(sma_atlas_destroy(tree_atlas));
defer(SDL_free(tree_atlas_items));
for (Uint32 i = 0; i < SDL_arraysize(tree_infos); i++) {
char path[256] = ASSETS_PATH;
SDL_strlcat(path, tree_infos[i].asset_path, SDL_arraysize(path));
int width = 0, height = 0;
if (!stbi_info(path, &width, &height, NULL))
return false;
tree_atlas_items[i] = sma_item_add(tree_atlas, width, height);
if (!tree_atlas_items[i])
return false;
}
tree_textures_atlas = renderer_texture_create(R_TEXTURE_FORMAT_RGBA8_UNORM_SRGB, R_TEXTURE_USAGE_SAMPLED, false, TREE_ATLAS_SIZE, TREE_ATLAS_SIZE, NULL, "tree_atlas_texture");
if (!tree_textures_atlas) {
log_error("Failed to create texture.");
return false;
}
tree_textures_atlas_imgui = renderer_texture_create(R_TEXTURE_FORMAT_RGBA8_UNORM, R_TEXTURE_USAGE_SAMPLED, false, TREE_ATLAS_SIZE, TREE_ATLAS_SIZE, NULL, "tree_atlas_texture imgui");
if (!tree_textures_atlas_imgui) {
log_error("Failed to create texture.");
return false;
}
for (Uint32 i = 0; i < SDL_arraysize(tree_infos); i++) {
char path[256] = ASSETS_PATH;
SDL_strlcat(path, tree_infos[i].asset_path, SDL_arraysize(path));
int width = 0, height = 0;
stbi_uc *data = stbi_load(path, &width, &height, NULL, 4);
if (!data) {
log_error("Failed to load texture (\"%s\"). Exiting.", path);
renderer_texture_destroy(tree_textures_atlas);
tree_textures_atlas = NULL;
renderer_texture_destroy(tree_textures_atlas_imgui);
tree_textures_atlas_imgui = NULL;
return false;
}
tree_uvs[i].x = sma_item_x(tree_atlas_items[i]);
tree_uvs[i].y = sma_item_y(tree_atlas_items[i]);
tree_uvs[i].z = sma_item_x(tree_atlas_items[i]) + sma_item_width (tree_atlas_items[i]);
tree_uvs[i].w = sma_item_y(tree_atlas_items[i]) + sma_item_height(tree_atlas_items[i]);
renderer_texture_update(tree_textures_atlas, sma_item_x(tree_atlas_items[i]), sma_item_y(tree_atlas_items[i]), sma_item_width(tree_atlas_items[i]), sma_item_height(tree_atlas_items[i]), data, sma_item_width(tree_atlas_items[i]) * 4);
renderer_texture_update(tree_textures_atlas_imgui, sma_item_x(tree_atlas_items[i]), sma_item_y(tree_atlas_items[i]), sma_item_width(tree_atlas_items[i]), sma_item_height(tree_atlas_items[i]), data, sma_item_width(tree_atlas_items[i]) * 4);
stbi_image_free(data);
}
tree_uvs_buffer = renderer_buffer_create(R_BUFFER_USAGE_STORAGE, sizeof(tree_uvs), tree_uvs, "tree_uvs_buffer");
return true;
}
static int real_mod(int a, int b) { static int real_mod(int a, int b) {
int result = a % b; int result = a % b;
return result >= 0 ? result : result + b; return result >= 0 ? result : result + b;
@@ -873,6 +1037,13 @@ static i32vec2 grid_tile_pos_from_floor_intersection(vec2 floor_intersection) {
}; };
} }
static i32vec2 grid_entity_pos_from_floor_intersection(vec2 floor_intersection) {
return {
(Sint32)SDL_floorf(floor_intersection.x + 0.5f),
(Sint32)SDL_floorf(floor_intersection.y + 0.5f),
};
}
static bool init_resources() { static bool init_resources() {
view_projection_matrix_buffer = renderer_buffer_create(R_BUFFER_USAGE_UNIFORM, sizeof(mat4x4), NULL, "view_projection_matrix_buffer"); view_projection_matrix_buffer = renderer_buffer_create(R_BUFFER_USAGE_UNIFORM, sizeof(mat4x4), NULL, "view_projection_matrix_buffer");
if (!view_projection_matrix_buffer) { if (!view_projection_matrix_buffer) {
@@ -892,18 +1063,6 @@ static bool init_resources() {
return false; return false;
} }
vertex_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(vertices), vertices, "vertex_buffer");
if (!vertex_buffer) {
log_error("Failed to create buffer.");
return false;
}
index_buffer = renderer_buffer_create(R_BUFFER_USAGE_INDEX, sizeof(indices), indices, "index_buffer");
if (!index_buffer) {
log_error("Failed to create buffer.");
return false;
}
player_instance_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(player_instance), &player_instance, "player_instance_buffer"); player_instance_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, sizeof(player_instance), &player_instance, "player_instance_buffer");
if (!player_instance_buffer) { if (!player_instance_buffer) {
log_error("Failed to create buffer."); log_error("Failed to create buffer.");
@@ -927,6 +1086,11 @@ static bool init_resources() {
return false; return false;
} }
if (!recreate_tree_textures()) {
log_error("Failed to create tree textures.");
return false;
}
return true; return true;
} }
@@ -984,7 +1148,8 @@ static void process_event_editor(SDL_Event event) {
return; return;
vec2 floor_intersection = get_floor_intersection_of_mouse(vec2(event.button.x, event.button.y)); vec2 floor_intersection = get_floor_intersection_of_mouse(vec2(event.button.x, event.button.y));
i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection); i32vec2 tile_pos = grid_tile_pos_from_floor_intersection(floor_intersection);
i32vec2 entity_pos = grid_entity_pos_from_floor_intersection(floor_intersection);
drag_start_pos = floor_intersection; drag_start_pos = floor_intersection;
@@ -993,6 +1158,48 @@ static void process_event_editor(SDL_Event event) {
} }
if (event.button.button == SDL_BUTTON_LEFT) { if (event.button.button == SDL_BUTTON_LEFT) {
if (selected_tree != -1 && 0 <= tile_pos.x && tile_pos.x < current_map.size.x -1 && 0 <= tile_pos.y && tile_pos.y < current_map.size.y - 1) {
Sint32 found_tree = -1;
for (Sint32 i = 0; i < current_map.num_trees; i++) {
if ((current_map.trees[i].pos.x == entity_pos.x) && (current_map.trees[i].pos.y == entity_pos.y)) {
found_tree = i;
break;
}
}
if (found_tree != -1) {
Tree tmp = current_map.trees[found_tree];
SDL_memmove(&current_map.trees[found_tree], &current_map.trees[found_tree + 1], (current_map.num_trees - (found_tree + 1)) * sizeof(*current_map.trees));
current_map.trees[current_map.num_trees - 1] = tmp;
} else {
current_map.trees = (Tree *)SDL_realloc(current_map.trees, (current_map.num_trees + 1) * sizeof(*current_map.trees));
current_map.trees[current_map.num_trees] = {
.pos = entity_pos,
.kind = (Uint32)selected_tree,
};
current_map.num_trees++;
}
std::stable_sort(&current_map.trees[0], &current_map.trees[current_map.num_trees], [](const Tree &a, const Tree &b){ return a.pos.y > b.pos.y; });
if (current_map.trees_buffer) renderer_buffer_destroy(current_map.trees_buffer);
current_map.trees_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, current_map.num_trees * sizeof(*current_map.trees), current_map.trees, "trees_buffer");
}
if (show_tree_editor && selected_tree == -1) {
for (Sint32 i = 0; i < current_map.num_trees; i++) {
if ((current_map.trees[i].pos.x == entity_pos.x) && (current_map.trees[i].pos.y == entity_pos.y)) {
SDL_memmove(&current_map.trees[i], &current_map.trees[i + 1], (current_map.num_trees - (i + 1)) * sizeof(*current_map.trees));
current_map.num_trees--;
break;
}
}
if (current_map.trees_buffer) renderer_buffer_destroy(current_map.trees_buffer);
if (current_map.num_trees) current_map.trees_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, current_map.num_trees * sizeof(*current_map.trees), current_map.trees, "trees_buffer");
}
if (selected_tile_kind != -1) { if (selected_tile_kind != -1) {
change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind); change_map_tile(tile_pos.x, tile_pos.y, (TileKind)selected_tile_kind);
@@ -1106,6 +1313,7 @@ static void update_state_editor() {
if (ImGui::BeginMenu("File")) { if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Reload")) { if (ImGui::MenuItem("Reload")) {
recreate_tile_textures(); recreate_tile_textures();
recreate_tree_textures();
} }
if (ImGui::MenuItem("Save")) { if (ImGui::MenuItem("Save")) {
@@ -1126,6 +1334,7 @@ static void update_state_editor() {
if (ImGui::BeginMenu("Edit")) { if (ImGui::BeginMenu("Edit")) {
ImGui::MenuItem("Tile Picker", NULL, &show_tile_picker); ImGui::MenuItem("Tile Picker", NULL, &show_tile_picker);
ImGui::MenuItem("Trees", NULL, &show_tree_editor);
ImGui::EndMenu(); ImGui::EndMenu();
} }
@@ -1140,6 +1349,7 @@ static void update_state_editor() {
ImGuiID left_dock = ImGui::DockBuilderSplitNode(main_viewport_dock, ImGuiDir_Left, 0.2f, NULL, NULL); ImGuiID left_dock = ImGui::DockBuilderSplitNode(main_viewport_dock, ImGuiDir_Left, 0.2f, NULL, NULL);
ImGui::DockBuilderDockWindow("Tile Picker", left_dock); ImGui::DockBuilderDockWindow("Tile Picker", left_dock);
ImGui::DockBuilderDockWindow("Trees", left_dock);
ImGui::DockBuilderFinish(main_viewport_dock); ImGui::DockBuilderFinish(main_viewport_dock);
} }
ImGui::DockSpaceOverViewport(main_viewport_dock, ImGui::GetMainViewport(), ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingOverCentralNode); ImGui::DockSpaceOverViewport(main_viewport_dock, ImGui::GetMainViewport(), ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingOverCentralNode);
@@ -1258,6 +1468,29 @@ static void update_state_editor() {
selected_tile_kind = -1; selected_tile_kind = -1;
} }
if (show_tree_editor) {
if (ImGui::Begin("Trees", &show_tree_editor, ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGuiStyle &style = ImGui::GetStyle();
if (SelectableImage("##tree", tree_textures_atlas_imgui, ImVec2(64, 64), vec2(0, 0), vec2(0, 0), selected_tree == -1))
selected_tree = -1;
for (int i = 0; i < SDL_arraysize(tree_infos); i++) {
ImGui::PushID(i);
if (i != 0)
SameLineOrWrap(ImVec2(64, 1));
if (SelectableImage("##tree", tree_textures_atlas_imgui, ImVec2(tree_uvs[i].z, tree_uvs[i].w), tree_uvs[i].xy() / (float)TREE_ATLAS_SIZE, tree_uvs[i].zw() / (float)TREE_ATLAS_SIZE, selected_tree == i))
selected_tree = i;
ImGui::PopID();
}
}
ImGui::End();
} else {
selected_tree = -1;
}
ImGui::SetNextWindowPos({ viewport->WorkPos.x + viewport->WorkSize.x - 10.0f, viewport->WorkPos.y + 10.0f }, ImGuiCond_Always, { 1.0f, 0.0f }); ImGui::SetNextWindowPos({ viewport->WorkPos.x + viewport->WorkSize.x - 10.0f, viewport->WorkPos.y + 10.0f }, ImGuiCond_Always, { 1.0f, 0.0f });
if (ImGui::Begin("Overlay", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) { if (ImGui::Begin("Overlay", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) {
ImGui::Checkbox("Grid", &show_grid); ImGui::Checkbox("Grid", &show_grid);
@@ -1362,6 +1595,24 @@ static void render_editor() {
}); });
} }
if (current_map.num_trees) {
ZoneScopedN("Draw Trees");
renderer_frame_set_shader(R_SHADER_TREE);
renderer_frame_draw(NULL, NULL, current_map.trees_buffer, 6, current_map.num_trees, &(R_Draw_Resources){
.vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer, per_frame_buffer },
.num_vertex_uniform_buffers = 2,
.fragment_sampled_textures = (R_Texture[]){ tree_textures_atlas },
.fragment_storage_buffers = (R_Buffer[]){ tree_uvs_buffer },
.fragment_uniform_buffers = (R_Buffer[]){ tint_color_buffer },
.num_fragment_sampled_textures = 1,
.num_fragment_storage_buffers = 1,
.num_fragment_uniform_buffers = 1,
});
}
if (show_grid) { if (show_grid) {
ZoneScopedN("Draw Grid"); ZoneScopedN("Draw Grid");
@@ -1561,10 +1812,28 @@ static void render_game() {
}); });
} }
if (current_map.num_trees) {
ZoneScopedN("Draw Trees");
renderer_frame_set_shader(R_SHADER_TREE);
renderer_frame_draw(NULL, NULL, current_map.trees_buffer, 6, current_map.num_trees, &(R_Draw_Resources){
.vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer, per_frame_buffer },
.num_vertex_uniform_buffers = 2,
.fragment_sampled_textures = (R_Texture[]){ tree_textures_atlas },
.fragment_storage_buffers = (R_Buffer[]){ tree_uvs_buffer },
.fragment_uniform_buffers = (R_Buffer[]){ tint_color_buffer },
.num_fragment_sampled_textures = 1,
.num_fragment_storage_buffers = 1,
.num_fragment_uniform_buffers = 1,
});
}
{ {
ZoneScopedN("Draw Player"); ZoneScopedN("Draw Player");
renderer_frame_set_shader(R_SHADER_CHARACTER_SHADOW); renderer_frame_set_shader(R_SHADER_CHARACTER_SHADOW);
renderer_frame_draw(vertex_buffer, index_buffer, player_instance_buffer, 6, 1, &(R_Draw_Resources){ renderer_frame_draw(NULL, NULL, player_instance_buffer, 6, 1, &(R_Draw_Resources){
.vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer }, .vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer },
.num_vertex_uniform_buffers = 1, .num_vertex_uniform_buffers = 1,
@@ -1577,7 +1846,7 @@ static void render_game() {
}); });
renderer_frame_set_shader(R_SHADER_CHARACTER); renderer_frame_set_shader(R_SHADER_CHARACTER);
renderer_frame_draw(vertex_buffer, index_buffer, player_instance_buffer, 6, 1, &(R_Draw_Resources){ renderer_frame_draw(NULL, NULL, player_instance_buffer, 6, 1, &(R_Draw_Resources){
.vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer }, .vertex_uniform_buffers = (R_Buffer[]){ view_projection_matrix_buffer },
.num_vertex_uniform_buffers = 1, .num_vertex_uniform_buffers = 1,
@@ -1779,7 +2048,7 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
if (!load_map("map.sv", &current_map)) { if (!load_map("map", &current_map)) {
log_error("Failed to load initial map. Exiting."); log_error("Failed to load initial map. Exiting.");
return 1; return 1;
} }
+1
View File
@@ -11,6 +11,7 @@ typedef enum : Uint32 {
R_SHADER_CHARACTER, R_SHADER_CHARACTER,
R_SHADER_CHARACTER_SHADOW, R_SHADER_CHARACTER_SHADOW,
R_SHADER_WORLD, R_SHADER_WORLD,
R_SHADER_TREE,
R_SHADER_GRID, R_SHADER_GRID,
R_SHADER_COUNT, R_SHADER_COUNT,
} R_Shader; } R_Shader;
+139 -54
View File
@@ -343,8 +343,8 @@ void renderer_frame_draw(R_Buffer vertex_buffer, R_Buffer index_buffer, R_Buffer
for (int i = 0; i < resources->num_fragment_storage_buffers; i++) SDL_BindGPUFragmentStorageBuffers(render_pass, i, &resources->fragment_storage_buffers[i]->buffer, 1); for (int i = 0; i < resources->num_fragment_storage_buffers; i++) SDL_BindGPUFragmentStorageBuffers(render_pass, i, &resources->fragment_storage_buffers[i]->buffer, 1);
for (int i = 0; i < resources->num_fragment_uniform_buffers; i++) SDL_PushGPUFragmentUniformData(render_command_buffer, i, resources->fragment_uniform_buffers[i]->cpu_uniform_data, resources->fragment_uniform_buffers[i]->num_bytes); for (int i = 0; i < resources->num_fragment_uniform_buffers; i++) SDL_PushGPUFragmentUniformData(render_command_buffer, i, resources->fragment_uniform_buffers[i]->cpu_uniform_data, resources->fragment_uniform_buffers[i]->num_bytes);
if (vertex_buffer) SDL_BindGPUVertexBuffers(render_pass, 0, &(SDL_GPUBufferBinding){ .buffer = vertex_buffer->buffer, .offset = 0 }, 1); if (vertex_buffer) SDL_BindGPUVertexBuffers(render_pass, 0, &(SDL_GPUBufferBinding){ .buffer = vertex_buffer->buffer, .offset = 0 }, 1);
if (instance_buffer) SDL_BindGPUVertexBuffers(render_pass, 1, &(SDL_GPUBufferBinding){ .buffer = instance_buffer->buffer, .offset = 0 }, 1); if (instance_buffer) SDL_BindGPUVertexBuffers(render_pass, vertex_buffer ? 1 : 0, &(SDL_GPUBufferBinding){ .buffer = instance_buffer->buffer, .offset = 0 }, 1);
if (index_buffer) { if (index_buffer) {
SDL_BindGPUIndexBuffer(render_pass, &(SDL_GPUBufferBinding){ .buffer = index_buffer->buffer, .offset = 0 }, SDL_GPU_INDEXELEMENTSIZE_16BIT); SDL_BindGPUIndexBuffer(render_pass, &(SDL_GPUBufferBinding){ .buffer = index_buffer->buffer, .offset = 0 }, SDL_GPU_INDEXELEMENTSIZE_16BIT);
@@ -444,7 +444,7 @@ bool renderer_init(SDL_Window *window_) {
}); });
SDL_PropertiesID properties = SDL_CreateProperties(); SDL_PropertiesID properties = SDL_CreateProperties();
SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER basic"); SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER character");
shaders[R_SHADER_CHARACTER] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){ shaders[R_SHADER_CHARACTER] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){
.vertex_shader = vertex_shader, .vertex_shader = vertex_shader,
@@ -454,48 +454,29 @@ bool renderer_init(SDL_Window *window_) {
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){ .vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){
{ {
.slot = 0, .slot = 0,
.pitch = 20,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0,
},
{
.slot = 1,
.pitch = 12, .pitch = 12,
.input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE, .input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE,
.instance_step_rate = 0, .instance_step_rate = 0,
}, },
}, },
.num_vertex_buffers = 2, .num_vertex_buffers = 1,
.vertex_attributes = (SDL_GPUVertexAttribute[]){ .vertex_attributes = (SDL_GPUVertexAttribute[]){
{
.location = 0,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
.offset = 0,
},
{
.location = 1,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 12,
},
{ {
.location = 2, .location = 2,
.buffer_slot = 1, .buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 0, .offset = 0,
}, },
{ {
.location = 3, .location = 3,
.buffer_slot = 1, .buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_UINT, .format = SDL_GPU_VERTEXELEMENTFORMAT_UINT,
.offset = 8, .offset = 8,
}, },
}, },
.num_vertex_attributes = 4, .num_vertex_attributes = 2,
}, },
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
@@ -601,7 +582,7 @@ bool renderer_init(SDL_Window *window_) {
}); });
SDL_PropertiesID properties = SDL_CreateProperties(); SDL_PropertiesID properties = SDL_CreateProperties();
SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER basic"); SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER character_shadow");
shaders[R_SHADER_CHARACTER_SHADOW] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){ shaders[R_SHADER_CHARACTER_SHADOW] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){
.vertex_shader = vertex_shader, .vertex_shader = vertex_shader,
@@ -611,48 +592,29 @@ bool renderer_init(SDL_Window *window_) {
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){ .vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){
{ {
.slot = 0, .slot = 0,
.pitch = 20,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
.instance_step_rate = 0,
},
{
.slot = 1,
.pitch = 12, .pitch = 12,
.input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE, .input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE,
.instance_step_rate = 0, .instance_step_rate = 0,
}, },
}, },
.num_vertex_buffers = 2, .num_vertex_buffers = 1,
.vertex_attributes = (SDL_GPUVertexAttribute[]){ .vertex_attributes = (SDL_GPUVertexAttribute[]){
{
.location = 0,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3,
.offset = 0,
},
{
.location = 1,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 12,
},
{ {
.location = 2, .location = 2,
.buffer_slot = 1, .buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
.offset = 0, .offset = 0,
}, },
{ {
.location = 3, .location = 3,
.buffer_slot = 1, .buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_UINT, .format = SDL_GPU_VERTEXELEMENTFORMAT_UINT,
.offset = 8, .offset = 8,
}, },
}, },
.num_vertex_attributes = 4, .num_vertex_attributes = 2,
}, },
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
@@ -764,12 +726,129 @@ bool renderer_init(SDL_Window *window_) {
.vertex_shader = vertex_shader, .vertex_shader = vertex_shader,
.fragment_shader = fragment_shader, .fragment_shader = fragment_shader,
.vertex_input_state = {
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]) {},
.num_vertex_buffers = 0,
.vertex_attributes = (SDL_GPUVertexAttribute[]) {},
.num_vertex_attributes = 0,
},
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
.rasterizer_state = {
.fill_mode = SDL_GPU_FILLMODE_FILL,
.cull_mode = SDL_GPU_CULLMODE_BACK,
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
.depth_bias_constant_factor = 0.0f,
.depth_bias_clamp = 0.0f,
.depth_bias_slope_factor = 0.0f,
.enable_depth_bias = false,
.enable_depth_clip = false,
},
.multisample_state = {
.sample_count = SDL_GPU_SAMPLECOUNT_8,
.sample_mask = 0,
.enable_mask = 0,
.enable_alpha_to_coverage = false,
},
.depth_stencil_state = {
.compare_op = SDL_GPU_COMPAREOP_GREATER_OR_EQUAL,
.back_stencil_state = { .fail_op = SDL_GPU_STENCILOP_INVALID, .pass_op = SDL_GPU_STENCILOP_INVALID, .depth_fail_op = SDL_GPU_STENCILOP_INVALID, .compare_op = SDL_GPU_COMPAREOP_INVALID, },
.front_stencil_state = { .fail_op = SDL_GPU_STENCILOP_INVALID, .pass_op = SDL_GPU_STENCILOP_INVALID, .depth_fail_op = SDL_GPU_STENCILOP_INVALID, .compare_op = SDL_GPU_COMPAREOP_INVALID, },
.compare_mask = 0,
.write_mask = 0,
.enable_depth_test = false,
.enable_depth_write = false,
.enable_stencil_test = false,
},
.target_info = {
.color_target_descriptions = (SDL_GPUColorTargetDescription[]){
{
.format = texture_formats[surface.format],
.blend_state = {
.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.color_blend_op = SDL_GPU_BLENDOP_ADD,
.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.alpha_blend_op = SDL_GPU_BLENDOP_ADD,
.color_write_mask = 0,
.enable_blend = true,
.enable_color_write_mask = false,
},
}
},
.num_color_targets = 1,
.depth_stencil_format = SDL_GPU_TEXTUREFORMAT_INVALID,
.has_depth_stencil_target = false,
},
});
SDL_DestroyProperties(properties);
SDL_ReleaseGPUShader(device, vertex_shader);
SDL_ReleaseGPUShader(device, fragment_shader);
}
{ // Tree
const Uint8 shader_source[] = {
#embed "shaders/spirv/tree.spv"
};
SDL_GPUShader *vertex_shader = SDL_CreateGPUShader(device, &(SDL_GPUShaderCreateInfo){
.code_size = sizeof(shader_source),
.code = shader_source,
.entrypoint = "main_vertex",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_VERTEX,
.num_samplers = 0,
.num_storage_textures = 0,
.num_storage_buffers = 0,
.num_uniform_buffers = 2,
});
SDL_GPUShader *fragment_shader = SDL_CreateGPUShader(device, &(SDL_GPUShaderCreateInfo){
.code_size = sizeof(shader_source),
.code = shader_source,
.entrypoint = "main_fragment",
.format = SDL_GPU_SHADERFORMAT_SPIRV,
.stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
.num_samplers = 1,
.num_storage_textures = 0,
.num_storage_buffers = 1,
.num_uniform_buffers = 1,
});
SDL_PropertiesID properties = SDL_CreateProperties();
SDL_SetStringProperty(properties, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "R_SHADER tree");
shaders[R_SHADER_TREE] = SDL_CreateGPUGraphicsPipeline(device, &(SDL_GPUGraphicsPipelineCreateInfo){
.vertex_shader = vertex_shader,
.fragment_shader = fragment_shader,
.vertex_input_state = { .vertex_input_state = {
.vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){ .vertex_buffer_descriptions = (SDL_GPUVertexBufferDescription[]){
{ {
.slot = 0, .slot = 0,
.pitch = 20, .pitch = 12,
.input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, .input_rate = SDL_GPU_VERTEXINPUTRATE_INSTANCE,
.instance_step_rate = 0, .instance_step_rate = 0,
}, },
@@ -780,11 +859,17 @@ bool renderer_init(SDL_Window *window_) {
{ {
.location = 0, .location = 0,
.buffer_slot = 0, .buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .format = SDL_GPU_VERTEXELEMENTFORMAT_UINT2,
.offset = 0, .offset = 0,
}, },
{
.location = 1,
.buffer_slot = 0,
.format = SDL_GPU_VERTEXELEMENTFORMAT_UINT,
.offset = 8,
},
}, },
.num_vertex_attributes = 1, .num_vertex_attributes = 2,
}, },
.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
+114 -44
View File
@@ -475,8 +475,8 @@ void renderer_frame_draw(R_Buffer vertex_buffer, R_Buffer index_buffer, R_Buffer
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 3, NULL, 0, NULL); wgpuRenderPassEncoderSetBindGroup(pass_encoder, 3, NULL, 0, NULL);
} }
if (vertex_buffer) wgpuRenderPassEncoderSetVertexBuffer(pass_encoder, 0, vertex_buffer->buffer, 0, WGPU_WHOLE_SIZE); if (vertex_buffer) wgpuRenderPassEncoderSetVertexBuffer(pass_encoder, 0, vertex_buffer->buffer, 0, WGPU_WHOLE_SIZE);
if (instance_buffer) wgpuRenderPassEncoderSetVertexBuffer(pass_encoder, 1, instance_buffer->buffer, 0, WGPU_WHOLE_SIZE); if (instance_buffer) wgpuRenderPassEncoderSetVertexBuffer(pass_encoder, vertex_buffer ? 1 : 0, instance_buffer->buffer, 0, WGPU_WHOLE_SIZE);
if (index_buffer) { if (index_buffer) {
wgpuRenderPassEncoderSetIndexBuffer(pass_encoder, index_buffer->buffer, WGPUIndexFormat_Uint16, 0, WGPU_WHOLE_SIZE); wgpuRenderPassEncoderSetIndexBuffer(pass_encoder, index_buffer->buffer, WGPUIndexFormat_Uint16, 0, WGPU_WHOLE_SIZE);
@@ -683,14 +683,14 @@ bool renderer_init(SDL_Window *window_) {
.chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL }, .chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL },
.code = { .data = shader_source, .length = SDL_arraysize(shader_source) }, .code = { .data = shader_source, .length = SDL_arraysize(shader_source) },
}, },
.label = { .data = "basic shader", .length = WGPU_STRLEN } .label = { .data = "character shader", .length = WGPU_STRLEN }
}); });
shaders[R_SHADER_CHARACTER] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){ shaders[R_SHADER_CHARACTER] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){
.label = { .data = "basic render_pipeline", .length = WGPU_STRLEN }, .label = { .data = "character render_pipeline", .length = WGPU_STRLEN },
.layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){ .layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){
.label = { .data = "basic pipeline_layout", .length = WGPU_STRLEN }, .label = { .data = "character pipeline_layout", .length = WGPU_STRLEN },
.bindGroupLayoutCount = 4, .bindGroupLayoutCount = 4,
.bindGroupLayouts = (WGPUBindGroupLayout[]){ .bindGroupLayouts = (WGPUBindGroupLayout[]){
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
@@ -726,25 +726,8 @@ bool renderer_init(SDL_Window *window_) {
.entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN }, .entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN },
.constantCount = 0, .constantCount = 0,
.constants = NULL, .constants = NULL,
.bufferCount = 2, .bufferCount = 1,
.buffers = (WGPUVertexBufferLayout[]){ .buffers = (WGPUVertexBufferLayout[]){
{
.stepMode = WGPUVertexStepMode_Vertex,
.arrayStride = 20,
.attributeCount = 2,
.attributes = (WGPUVertexAttribute[]){
{
.format = WGPUVertexFormat_Float32x3,
.offset = 0,
.shaderLocation = 0,
},
{
.format = WGPUVertexFormat_Float32x2,
.offset = 12,
.shaderLocation = 1,
},
},
},
{ {
.stepMode = WGPUVertexStepMode_Instance, .stepMode = WGPUVertexStepMode_Instance,
.arrayStride = 12, .arrayStride = 12,
@@ -804,14 +787,14 @@ bool renderer_init(SDL_Window *window_) {
.chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL }, .chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL },
.code = { .data = shader_source, .length = SDL_arraysize(shader_source) }, .code = { .data = shader_source, .length = SDL_arraysize(shader_source) },
}, },
.label = { .data = "basic shader", .length = WGPU_STRLEN } .label = { .data = "character_shadow shader", .length = WGPU_STRLEN }
}); });
shaders[R_SHADER_CHARACTER_SHADOW] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){ shaders[R_SHADER_CHARACTER_SHADOW] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){
.label = { .data = "basic render_pipeline", .length = WGPU_STRLEN }, .label = { .data = "character_shadow render_pipeline", .length = WGPU_STRLEN },
.layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){ .layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){
.label = { .data = "basic pipeline_layout", .length = WGPU_STRLEN }, .label = { .data = "character_shadow pipeline_layout", .length = WGPU_STRLEN },
.bindGroupLayoutCount = 4, .bindGroupLayoutCount = 4,
.bindGroupLayouts = (WGPUBindGroupLayout[]){ .bindGroupLayouts = (WGPUBindGroupLayout[]){
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){ wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
@@ -847,25 +830,8 @@ bool renderer_init(SDL_Window *window_) {
.entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN }, .entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN },
.constantCount = 0, .constantCount = 0,
.constants = NULL, .constants = NULL,
.bufferCount = 2, .bufferCount = 1,
.buffers = (WGPUVertexBufferLayout[]){ .buffers = (WGPUVertexBufferLayout[]){
{
.stepMode = WGPUVertexStepMode_Vertex,
.arrayStride = 20,
.attributeCount = 2,
.attributes = (WGPUVertexAttribute[]){
{
.format = WGPUVertexFormat_Float32x3,
.offset = 0,
.shaderLocation = 0,
},
{
.format = WGPUVertexFormat_Float32x2,
.offset = 12,
.shaderLocation = 1,
},
},
},
{ {
.stepMode = WGPUVertexStepMode_Instance, .stepMode = WGPUVertexStepMode_Instance,
.arrayStride = 12, .arrayStride = 12,
@@ -1005,6 +971,110 @@ bool renderer_init(SDL_Window *window_) {
wgpuShaderModuleRelease(shader); wgpuShaderModuleRelease(shader);
} }
{ // Tree
const char shader_source[] = {
#embed "shaders/wgsl/tree.wgsl"
};
WGPUShaderModule shader = wgpuDeviceCreateShaderModule(device, &(WGPUShaderModuleDescriptor){
.nextInChain = (WGPUChainedStruct *)&(WGPUShaderSourceWGSL){
.chain = { .next = NULL, .sType = WGPUSType_ShaderSourceWGSL },
.code = { .data = shader_source, .length = SDL_arraysize(shader_source) },
},
.label = { .data = "tree shader", .length = WGPU_STRLEN }
});
shaders[R_SHADER_TREE] = wgpuDeviceCreateRenderPipeline(device, &(WGPURenderPipelineDescriptor){
.label = { .data = "tree render_pipeline", .length = WGPU_STRLEN },
.layout = wgpuDeviceCreatePipelineLayout(device, &(WGPUPipelineLayoutDescriptor){
.label = { .data = "tree pipeline_layout", .length = WGPU_STRLEN },
.bindGroupLayoutCount = 4,
.bindGroupLayouts = (WGPUBindGroupLayout[]){
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
.entryCount = 0,
.entries = (WGPUBindGroupLayoutEntry[]){},
}),
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
.entryCount = 2,
.entries = (WGPUBindGroupLayoutEntry[]){
{ .binding = 0, .visibility = WGPUShaderStage_Vertex, .buffer = { .type = WGPUBufferBindingType_Uniform } },
{ .binding = 1, .visibility = WGPUShaderStage_Vertex, .buffer = { .type = WGPUBufferBindingType_Uniform } },
},
}),
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
.entryCount = 3,
.entries = (WGPUBindGroupLayoutEntry[]){
{ .binding = 0, .visibility = WGPUShaderStage_Fragment, .texture = { .sampleType = WGPUTextureSampleType_Float, .viewDimension = WGPUTextureViewDimension_2D } },
{ .binding = 1, .visibility = WGPUShaderStage_Fragment, .sampler = { .type = WGPUSamplerBindingType_Filtering } },
{ .binding = 2, .visibility = WGPUShaderStage_Fragment, .buffer = { .type = WGPUBufferBindingType_ReadOnlyStorage } },
},
}),
wgpuDeviceCreateBindGroupLayout(device, &(WGPUBindGroupLayoutDescriptor){
.entryCount = 1,
.entries = (WGPUBindGroupLayoutEntry[]){
{ .binding = 0, .visibility = WGPUShaderStage_Fragment, .buffer = { .type = WGPUBufferBindingType_Uniform } },
},
}),
},
}),
.vertex = {
.module = shader,
.entryPoint = { .data = "main_vertex", .length = WGPU_STRLEN },
.constantCount = 0,
.constants = NULL,
.bufferCount = 1,
.buffers = (WGPUVertexBufferLayout[]){
{
.stepMode = WGPUVertexStepMode_Instance,
.arrayStride = 12,
.attributeCount = 2,
.attributes = (WGPUVertexAttribute[]){
{
.format = WGPUVertexFormat_Uint32x2,
.offset = 0,
.shaderLocation = 0,
},
{
.format = WGPUVertexFormat_Uint32,
.offset = 8,
.shaderLocation = 1,
},
},
},
},
},
.primitive = {
.topology = WGPUPrimitiveTopology_TriangleList,
.stripIndexFormat = WGPUIndexFormat_Undefined,
.frontFace = WGPUFrontFace_CCW,
.cullMode = WGPUCullMode_Back,
.unclippedDepth = false,
},
.depthStencil = NULL,
.multisample = {
.count = 4,
.mask = ~0u,
.alphaToCoverageEnabled = false,
},
.fragment = &(WGPUFragmentState){
.module = shader,
.entryPoint = { .data = "main_fragment", .length = WGPU_STRLEN },
.constantCount = 0,
.constants = NULL,
.targetCount = 1,
.targets = &color_target_state,
},
});
wgpuShaderModuleRelease(shader);
}
{ // Grid { // Grid
const char shader_source[] = { const char shader_source[] = {
#embed "shaders/wgsl/grid.wgsl" #embed "shaders/wgsl/grid.wgsl"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+15 -5
View File
@@ -5,9 +5,6 @@
struct VertexShaderInput { struct VertexShaderInput {
uint32_t vertex_index : SV_VulkanVertexID; uint32_t vertex_index : SV_VulkanVertexID;
[vk::location(0)] float3 pos;
[vk::location(1)] float2 uv;
// Per Instance // Per Instance
[vk::location(2)] float2 world_pos; [vk::location(2)] float2 world_pos;
[vk::location(3)] uint sprite_selection; [vk::location(3)] uint sprite_selection;
@@ -27,12 +24,25 @@ struct FragmentShaderOutput {
VertexShaderOutput main_vertex(VertexShaderInput input) { VertexShaderOutput main_vertex(VertexShaderInput input) {
var output: VertexShaderOutput; var output: VertexShaderOutput;
output.pos = mul(float4(input.world_pos + input.pos.xy, 0, 1), view_projection_matrix); var vertex_pos = float2(0, 0);
var vertex_uv = float2(0, 0);
switch (input.vertex_index) {
case 0: { vertex_pos = float2(-0.5, 0.5); vertex_uv = float2(0, 0); } break;
case 1: { vertex_pos = float2(-0.5, -0.5); vertex_uv = float2(0, 1); } break;
case 2: { vertex_pos = float2( 0.5, -0.5); vertex_uv = float2(1, 1); } break;
case 3: { vertex_pos = float2(-0.5, 0.5); vertex_uv = float2(0, 0); } break;
case 4: { vertex_pos = float2( 0.5, -0.5); vertex_uv = float2(1, 1); } break;
case 5: { vertex_pos = float2( 0.5, 0.5); vertex_uv = float2(1, 0); } break;
default: {}
}
output.pos = mul(float4(input.world_pos + vertex_pos, 0, 1), view_projection_matrix);
uint sprite_x = bitfieldExtract(input.sprite_selection, 16, 16); uint sprite_x = bitfieldExtract(input.sprite_selection, 16, 16);
uint sprite_y = bitfieldExtract(input.sprite_selection, 0, 16); uint sprite_y = bitfieldExtract(input.sprite_selection, 0, 16);
output.uv = (float2(sprite_x, sprite_y) + input.uv) * (1.0 / 4.0); output.uv = (float2(sprite_x, sprite_y) + vertex_uv) * (1.0 / 4.0);
return output; return output;
} }
+16 -6
View File
@@ -5,9 +5,6 @@
struct VertexShaderInput { struct VertexShaderInput {
uint32_t vertex_index : SV_VulkanVertexID; uint32_t vertex_index : SV_VulkanVertexID;
[vk::location(0)] float3 pos;
[vk::location(1)] float2 uv;
// Per Instance // Per Instance
[vk::location(2)] float2 world_pos; [vk::location(2)] float2 world_pos;
}; };
@@ -26,10 +23,23 @@ struct FragmentShaderOutput {
VertexShaderOutput main_vertex(VertexShaderInput input) { VertexShaderOutput main_vertex(VertexShaderInput input) {
var output: VertexShaderOutput; var output: VertexShaderOutput;
input.pos.xy *= 0.5; var vertex_pos = float2(0, 0);
var vertex_uv = float2(0, 0);
output.pos = mul(float4(input.world_pos + input.pos.xy + float2(0, -0.35), 0, 1), view_projection_matrix); switch (input.vertex_index) {
output.uv = input.uv; case 0: { vertex_pos = float2(-0.5, 0.5); vertex_uv = float2(0, 0); } break;
case 1: { vertex_pos = float2(-0.5, -0.5); vertex_uv = float2(0, 1); } break;
case 2: { vertex_pos = float2( 0.5, -0.5); vertex_uv = float2(1, 1); } break;
case 3: { vertex_pos = float2(-0.5, 0.5); vertex_uv = float2(0, 0); } break;
case 4: { vertex_pos = float2( 0.5, -0.5); vertex_uv = float2(1, 1); } break;
case 5: { vertex_pos = float2( 0.5, 0.5); vertex_uv = float2(1, 0); } break;
default: {}
}
vertex_pos *= 0.5;
output.pos = mul(float4(input.world_pos + vertex_pos + float2(0, -0.35), 0, 1), view_projection_matrix);
output.uv = vertex_uv;
return output; return output;
} }
+86
View File
@@ -0,0 +1,86 @@
#language 2026
#include "shared.slang"
#include "wgsl_workaround.slang"
struct VertexShaderInput {
uint32_t vertex_index : SV_VulkanVertexID;
uint32_t instance_index : SV_VulkanInstanceID;
// Per Instance
[vk::location(0)] uint32_t2 pos;
[vk::location(1)] uint32_t kind;
};
struct VertexShaderOutput {
float4 pos : SV_Position;
float2 uv;
uint32_t kind;
};
struct FragmentShaderOutput {
float4 color : SV_Target;
};
static const float2 offset = float2(0, 0.5);
[shader("vertex")]
VertexShaderOutput main_vertex(VertexShaderInput input) {
var output: VertexShaderOutput;
var vertex_pos = float2(0, 0);
var vertex_uv = float2(0, 0);
switch (input.vertex_index) {
case 0: { vertex_pos = float2(-1.0, 1.0); vertex_uv = float2(0, 0); } break;
case 1: { vertex_pos = float2(-1.0, -1.0); vertex_uv = float2(0, 1); } break;
case 2: { vertex_pos = float2( 1.0, -1.0); vertex_uv = float2(1, 1); } break;
case 3: { vertex_pos = float2(-1.0, 1.0); vertex_uv = float2(0, 0); } break;
case 4: { vertex_pos = float2( 1.0, -1.0); vertex_uv = float2(1, 1); } break;
case 5: { vertex_pos = float2( 1.0, 1.0); vertex_uv = float2(1, 0); } break;
default: {}
}
vertex_pos += offset;
output.pos = mul(float4(input.pos + vertex_pos, 0, 1), view_projection_matrix);
output.uv = vertex_uv;
output.kind = input.kind;
return output;
}
struct Block2 {
CombinedTextureSampler tree_atlas;
StructuredBuffer<float4> tree_uvs;
};
struct Block3 {
ConstantBuffer<float3> tint;
};
[vk::binding(0, 2)] ParameterBlock<Block2> block2;
[vk::binding(0, 3)]ParameterBlock<Block3> block3;
[shader("pixel")]
FragmentShaderOutput main_fragment(VertexShaderOutput input) {
var output: FragmentShaderOutput;
output.color = pixel_art_sample(block2.tree_atlas, input.uv, block2.tree_uvs[input.kind]);
output.color = float4(output.color.rgb * block3.tint.rgb, output.color.a);
return output;
}
float4 pixel_art_sample(CombinedTextureSampler input_texture, float2 input_uv, float4 tree_uv) {
var dimensions : float2;
input_texture.getTexture().GetDimensions(dimensions.x, dimensions.y);
let texture_uv = lerp(tree_uv.xy, tree_uv.zw, input_uv);
let sample_uv = (floor(texture_uv) + saturate(fract(texture_uv) / fwidth(texture_uv)) - 0.5) / dimensions;
let uv = clamp(sample_uv, (tree_uv.xy + 0.5) / dimensions, (tree_uv.zw - 0.5) / dimensions);
return input_texture.Sample(uv);
}
+14 -8
View File
@@ -26,19 +26,25 @@ struct FragmentShaderOutput {
VertexShaderOutput main_vertex(VertexShaderInput input) { VertexShaderOutput main_vertex(VertexShaderInput input) {
var output: VertexShaderOutput; var output: VertexShaderOutput;
let tile_pos = uint32_t2(input.instance_index % per_frame.map_width, input.instance_index / per_frame.map_width); var vertex_pos = float2(0, 0);
output.tile = map_texture.Load(uint32_t3(tile_pos, 0)); var vertex_uv = float2(0, 0);
switch (input.vertex_index) { switch (input.vertex_index) {
case 0: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2(-0.5, 0.5), 0, 1), view_projection_matrix); output.uv = float2(0, 0); } break; case 0: { vertex_pos = float2(-1.0, 0.0); vertex_uv = float2(0, 0); } break;
case 1: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2(-0.5, -0.5), 0, 1), view_projection_matrix); output.uv = float2(0, 1); } break; case 1: { vertex_pos = float2(-1.0, -1.0); vertex_uv = float2(0, 1); } break;
case 2: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2( 0.5, -0.5), 0, 1), view_projection_matrix); output.uv = float2(1, 1); } break; case 2: { vertex_pos = float2( 0.0, -1.0); vertex_uv = float2(1, 1); } break;
case 3: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2(-0.5, 0.5), 0, 1), view_projection_matrix); output.uv = float2(0, 0); } break; case 3: { vertex_pos = float2(-1.0, 0.0); vertex_uv = float2(0, 0); } break;
case 4: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2( 0.5, -0.5), 0, 1), view_projection_matrix); output.uv = float2(1, 1); } break; case 4: { vertex_pos = float2( 0.0, -1.0); vertex_uv = float2(1, 1); } break;
case 5: { output.pos = mul(float4(float2(tile_pos) - float2(0.5, 0.5) + float2( 0.5, 0.5), 0, 1), view_projection_matrix); output.uv = float2(1, 0); } break; case 5: { vertex_pos = float2( 0.0, 0.0); vertex_uv = float2(1, 0); } break;
default: {} default: {}
} }
let tile_pos = uint32_t2(input.instance_index % per_frame.map_width, input.instance_index / per_frame.map_width);
output.tile = map_texture.Load(uint32_t3(tile_pos, 0));
output.pos = mul(float4(tile_pos + vertex_pos, 0, 1), view_projection_matrix);
output.uv = vertex_uv;
return output; return output;
} }
+59 -16
View File
@@ -17,8 +17,6 @@ struct VertexShaderOutput_0
struct vertexInput_0 struct vertexInput_0
{ {
@location(0) pos_1 : vec3<f32>,
@location(1) uv_1 : vec2<f32>,
@location(2) world_pos_0 : vec2<f32>, @location(2) world_pos_0 : vec2<f32>,
@location(3) sprite_selection_0 : u32, @location(3) sprite_selection_0 : u32,
}; };
@@ -27,8 +25,53 @@ struct vertexInput_0
fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_0 : u32) -> VertexShaderOutput_0 fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_0 : u32) -> VertexShaderOutput_0
{ {
var output_0 : VertexShaderOutput_0; var output_0 : VertexShaderOutput_0;
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S1.world_pos_0 + _S1.pos_1.xy, 0.0f, 1.0f)))); const _S2 : vec2<f32> = vec2<f32>(0.0f, 0.0f);
output_0.uv_0 = (vec2<f32>(f32((u32(_S1.sprite_selection_0>>(u32(16)))&((((u32(1)<<u32(16))-u32(1)))))), f32((u32(_S1.sprite_selection_0>>(u32(0)))&((((u32(1)<<u32(16))-u32(1))))))) + _S1.uv_1) * vec2<f32>(0.25f); var vertex_pos_0 : vec2<f32>;
var vertex_uv_0 : vec2<f32>;
switch(vertex_index_0)
{
case u32(0):
{
vertex_pos_0 = vec2<f32>(-0.5f, 0.5f);
vertex_uv_0 = _S2;
}
case u32(1):
{
const _S3 : vec2<f32> = vec2<f32>(0.0f, 1.0f);
vertex_pos_0 = vec2<f32>(-0.5f, -0.5f);
vertex_uv_0 = _S3;
}
case u32(2):
{
const _S4 : vec2<f32> = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = vec2<f32>(0.5f, -0.5f);
vertex_uv_0 = _S4;
}
case u32(3):
{
vertex_pos_0 = vec2<f32>(-0.5f, 0.5f);
vertex_uv_0 = _S2;
}
case u32(4):
{
const _S5 : vec2<f32> = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = vec2<f32>(0.5f, -0.5f);
vertex_uv_0 = _S5;
}
case u32(5):
{
const _S6 : vec2<f32> = vec2<f32>(1.0f, 0.0f);
vertex_pos_0 = vec2<f32>(0.5f, 0.5f);
vertex_uv_0 = _S6;
}
default :
{
vertex_pos_0 = _S2;
vertex_uv_0 = _S2;
}
}
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S1.world_pos_0 + vertex_pos_0, 0.0f, 1.0f))));
output_0.uv_0 = (vec2<f32>(f32((u32(_S1.sprite_selection_0>>(u32(16)))&((((u32(1)<<u32(16))-u32(1)))))), f32((u32(_S1.sprite_selection_0>>(u32(0)))&((((u32(1)<<u32(16))-u32(1))))))) + vertex_uv_0) * vec2<f32>(0.25f);
return output_0; return output_0;
} }
@@ -41,15 +84,15 @@ fn GetDimensions_0( texture_texture_0 : texture_2d<f32>, texture_sampler_0 : sa
fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>) -> vec4<f32> fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>) -> vec4<f32>
{ {
var dimensions_0 : vec2<f32>; var dimensions_0 : vec2<f32>;
var _S2 : f32 = dimensions_0[i32(0)]; var _S7 : f32 = dimensions_0[i32(0)];
var _S3 : f32 = dimensions_0[i32(1)]; var _S8 : f32 = dimensions_0[i32(1)];
GetDimensions_0(input_texture_texture_0, input_texture_sampler_0, &(_S2), &(_S3)); GetDimensions_0(input_texture_texture_0, input_texture_sampler_0, &(_S7), &(_S8));
dimensions_0[i32(0)] = _S2; dimensions_0[i32(0)] = _S7;
dimensions_0[i32(1)] = _S3; dimensions_0[i32(1)] = _S8;
var _S4 : vec2<f32> = input_uv_0 * dimensions_0.xy; var _S9 : vec2<f32> = input_uv_0 * dimensions_0.xy;
var _S5 : vec2<f32> = (floor(_S4) + min(fract(_S4) / (fwidth((_S4))), vec2<f32>(1.0f, 1.0f)) - vec2<f32>(0.5f)) / dimensions_0.xy; var _S10 : vec2<f32> = (floor(_S9) + min(fract(_S9) / (fwidth((_S9))), vec2<f32>(1.0f, 1.0f)) - vec2<f32>(0.5f)) / dimensions_0.xy;
; ;
return (textureSample((input_texture_texture_0), (input_texture_sampler_0), (_S5))); return (textureSample((input_texture_texture_0), (input_texture_sampler_0), (_S10)));
} }
struct FragmentShaderOutput_0 struct FragmentShaderOutput_0
@@ -59,15 +102,15 @@ struct FragmentShaderOutput_0
struct pixelInput_0 struct pixelInput_0
{ {
@location(0) uv_2 : vec2<f32>, @location(0) uv_1 : vec2<f32>,
}; };
@fragment @fragment
fn main_fragment( _S6 : pixelInput_0, @builtin(position) pos_2 : vec4<f32>) -> FragmentShaderOutput_0 fn main_fragment( _S11 : pixelInput_0, @builtin(position) pos_1 : vec4<f32>) -> FragmentShaderOutput_0
{ {
var output_1 : FragmentShaderOutput_0; var output_1 : FragmentShaderOutput_0;
var _S7 : vec4<f32> = pixel_art_sample_0(texture1_texture_0, texture1_sampler_0, _S6.uv_2); var _S12 : vec4<f32> = pixel_art_sample_0(texture1_texture_0, texture1_sampler_0, _S11.uv_1);
output_1.color_0 = vec4<f32>(_S7.xyz * tint_0.xyz, _S7.w); output_1.color_0 = vec4<f32>(_S12.xyz * tint_0.xyz, _S12.w);
return output_1; return output_1;
} }
+62 -33
View File
@@ -17,33 +17,62 @@ struct VertexShaderOutput_0
struct vertexInput_0 struct vertexInput_0
{ {
@location(0) pos_1 : vec3<f32>,
@location(1) uv_1 : vec2<f32>,
@location(2) world_pos_0 : vec2<f32>, @location(2) world_pos_0 : vec2<f32>,
}; };
struct VertexShaderInput_0
{
vertex_index_0 : u32,
pos_2 : vec3<f32>,
uv_2 : vec2<f32>,
world_pos_1 : vec2<f32>,
};
@vertex @vertex
fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_1 : u32) -> VertexShaderOutput_0 fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_0 : u32) -> VertexShaderOutput_0
{ {
var _S2 : VertexShaderInput_0;
_S2.vertex_index_0 = vertex_index_1;
_S2.pos_2 = _S1.pos_1;
_S2.uv_2 = _S1.uv_1;
_S2.world_pos_1 = _S1.world_pos_0;
var _S3 : vec2<f32> = _S2.pos_2.xy * vec2<f32>(0.5f);
_S2.pos_2.x = _S3.x;
_S2.pos_2.y = _S3.y;
var output_0 : VertexShaderOutput_0; var output_0 : VertexShaderOutput_0;
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S2.world_pos_1 + _S2.pos_2.xy + vec2<f32>(0.0f, -0.34999999403953552f), 0.0f, 1.0f)))); const _S2 : vec2<f32> = vec2<f32>(0.0f, 0.0f);
output_0.uv_0 = _S2.uv_2; var vertex_uv_0 : vec2<f32>;
var vertex_pos_0 : vec2<f32>;
switch(vertex_index_0)
{
case u32(0):
{
const _S3 : vec2<f32> = vec2<f32>(-0.5f, 0.5f);
vertex_uv_0 = _S2;
vertex_pos_0 = _S3;
}
case u32(1):
{
const _S4 : vec2<f32> = vec2<f32>(-0.5f, -0.5f);
vertex_uv_0 = vec2<f32>(0.0f, 1.0f);
vertex_pos_0 = _S4;
}
case u32(2):
{
const _S5 : vec2<f32> = vec2<f32>(0.5f, -0.5f);
vertex_uv_0 = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = _S5;
}
case u32(3):
{
const _S6 : vec2<f32> = vec2<f32>(-0.5f, 0.5f);
vertex_uv_0 = _S2;
vertex_pos_0 = _S6;
}
case u32(4):
{
const _S7 : vec2<f32> = vec2<f32>(0.5f, -0.5f);
vertex_uv_0 = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = _S7;
}
case u32(5):
{
const _S8 : vec2<f32> = vec2<f32>(0.5f, 0.5f);
vertex_uv_0 = vec2<f32>(1.0f, 0.0f);
vertex_pos_0 = _S8;
}
default :
{
vertex_uv_0 = _S2;
vertex_pos_0 = _S2;
}
}
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(_S1.world_pos_0 + vertex_pos_0 * vec2<f32>(0.5f) + vec2<f32>(0.0f, -0.34999999403953552f), 0.0f, 1.0f))));
output_0.uv_0 = vertex_uv_0;
return output_0; return output_0;
} }
@@ -56,15 +85,15 @@ fn GetDimensions_0( texture_texture_0 : texture_2d<f32>, texture_sampler_0 : sa
fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>) -> vec4<f32> fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>) -> vec4<f32>
{ {
var dimensions_0 : vec2<f32>; var dimensions_0 : vec2<f32>;
var _S4 : f32 = dimensions_0[i32(0)]; var _S9 : f32 = dimensions_0[i32(0)];
var _S5 : f32 = dimensions_0[i32(1)]; var _S10 : f32 = dimensions_0[i32(1)];
GetDimensions_0(input_texture_texture_0, input_texture_sampler_0, &(_S4), &(_S5)); GetDimensions_0(input_texture_texture_0, input_texture_sampler_0, &(_S9), &(_S10));
dimensions_0[i32(0)] = _S4; dimensions_0[i32(0)] = _S9;
dimensions_0[i32(1)] = _S5; dimensions_0[i32(1)] = _S10;
var _S6 : vec2<f32> = input_uv_0 * dimensions_0.xy; var _S11 : vec2<f32> = input_uv_0 * dimensions_0.xy;
var _S7 : vec2<f32> = (floor(_S6) + min(fract(_S6) / (fwidth((_S6))), vec2<f32>(1.0f, 1.0f)) - vec2<f32>(0.5f)) / dimensions_0.xy; var _S12 : vec2<f32> = (floor(_S11) + min(fract(_S11) / (fwidth((_S11))), vec2<f32>(1.0f, 1.0f)) - vec2<f32>(0.5f)) / dimensions_0.xy;
; ;
return (textureSample((input_texture_texture_0), (input_texture_sampler_0), (_S7))); return (textureSample((input_texture_texture_0), (input_texture_sampler_0), (_S12)));
} }
struct FragmentShaderOutput_0 struct FragmentShaderOutput_0
@@ -74,15 +103,15 @@ struct FragmentShaderOutput_0
struct pixelInput_0 struct pixelInput_0
{ {
@location(0) uv_3 : vec2<f32>, @location(0) uv_1 : vec2<f32>,
}; };
@fragment @fragment
fn main_fragment( _S8 : pixelInput_0, @builtin(position) pos_3 : vec4<f32>) -> FragmentShaderOutput_0 fn main_fragment( _S13 : pixelInput_0, @builtin(position) pos_1 : vec4<f32>) -> FragmentShaderOutput_0
{ {
var output_1 : FragmentShaderOutput_0; var output_1 : FragmentShaderOutput_0;
var _S9 : vec4<f32> = pixel_art_sample_0(texture1_texture_0, texture1_sampler_0, _S8.uv_3); var _S14 : vec4<f32> = pixel_art_sample_0(texture1_texture_0, texture1_sampler_0, _S13.uv_1);
output_1.color_0 = vec4<f32>(_S9.xyz * tint_0.xyz, _S9.w); output_1.color_0 = vec4<f32>(_S14.xyz * tint_0.xyz, _S14.w);
return output_1; return output_1;
} }
+123
View File
@@ -0,0 +1,123 @@
struct _MatrixStorage_float4x4_ColMajorstd140_0
{
@align(16) data_0 : array<vec4<f32>, i32(4)>,
};
@binding(0) @group(1) var<uniform> view_projection_matrix_0 : _MatrixStorage_float4x4_ColMajorstd140_0;
@binding(0) @group(2) var block2_tree_atlas_texture_0 : texture_2d<f32>;
@binding(1) @group(2) var block2_tree_atlas_sampler_0 : sampler;
@binding(2) @group(2) var<storage, read> block2_tree_uvs_0 : array<vec4<f32>>;
@binding(0) @group(3) var<uniform> block3_tint_0 : vec3<f32>;
struct VertexShaderOutput_0
{
@builtin(position) pos_0 : vec4<f32>,
@location(0) uv_0 : vec2<f32>,
@location(1) kind_0 : u32,
};
struct vertexInput_0
{
@location(0) pos_1 : vec2<u32>,
@location(1) kind_1 : u32,
};
@vertex
fn main_vertex( _S1 : vertexInput_0, @builtin(vertex_index) vertex_index_0 : u32, @builtin(instance_index) instance_index_0 : u32) -> VertexShaderOutput_0
{
var output_0 : VertexShaderOutput_0;
const _S2 : vec2<f32> = vec2<f32>(0.0f, 0.0f);
var vertex_uv_0 : vec2<f32>;
var vertex_pos_0 : vec2<f32>;
switch(vertex_index_0)
{
case u32(0):
{
const _S3 : vec2<f32> = vec2<f32>(-1.0f, 1.0f);
vertex_uv_0 = _S2;
vertex_pos_0 = _S3;
}
case u32(1):
{
const _S4 : vec2<f32> = vec2<f32>(-1.0f, -1.0f);
vertex_uv_0 = vec2<f32>(0.0f, 1.0f);
vertex_pos_0 = _S4;
}
case u32(2):
{
const _S5 : vec2<f32> = vec2<f32>(1.0f, -1.0f);
vertex_uv_0 = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = _S5;
}
case u32(3):
{
const _S6 : vec2<f32> = vec2<f32>(-1.0f, 1.0f);
vertex_uv_0 = _S2;
vertex_pos_0 = _S6;
}
case u32(4):
{
const _S7 : vec2<f32> = vec2<f32>(1.0f, -1.0f);
vertex_uv_0 = vec2<f32>(1.0f, 1.0f);
vertex_pos_0 = _S7;
}
case u32(5):
{
const _S8 : vec2<f32> = vec2<f32>(1.0f, 1.0f);
vertex_uv_0 = vec2<f32>(1.0f, 0.0f);
vertex_pos_0 = _S8;
}
default :
{
vertex_uv_0 = _S2;
vertex_pos_0 = _S2;
}
}
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S1.pos_1) + (vertex_pos_0 + vec2<f32>(0.0f, 0.5f)), 0.0f, 1.0f))));
output_0.uv_0 = vertex_uv_0;
output_0.kind_0 = _S1.kind_1;
return output_0;
}
fn CombinedTextureSampler_Sample_0( this_texture_0 : texture_2d<f32>, this_sampler_0 : sampler, location_0 : vec2<f32>) -> vec4<f32>
{
return (textureSample((this_texture_0), (this_sampler_0), (location_0)));
}
fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>, tree_uv_0 : vec4<f32>) -> vec4<f32>
{
var dimensions_0 : vec2<f32>;
var _S9 : f32 = dimensions_0[i32(0)];
var _S10 : f32 = dimensions_0[i32(1)];
{var dim = textureDimensions((input_texture_texture_0));((_S9)) = f32(dim.x);((_S10)) = f32(dim.y);};
dimensions_0[i32(0)] = _S9;
dimensions_0[i32(1)] = _S10;
var _S11 : vec2<f32> = tree_uv_0.xy;
var _S12 : vec2<f32> = tree_uv_0.zw;
var _S13 : vec2<f32> = mix(_S11, _S12, input_uv_0);
var _S14 : vec2<f32> = vec2<f32>(0.5f);
return CombinedTextureSampler_Sample_0(input_texture_texture_0, input_texture_sampler_0, clamp((floor(_S13) + saturate(fract(_S13) / (fwidth((_S13)))) - _S14) / dimensions_0, (_S11 + _S14) / dimensions_0, (_S12 - _S14) / dimensions_0));
}
struct FragmentShaderOutput_0
{
@location(0) color_0 : vec4<f32>,
};
struct pixelInput_0
{
@location(0) uv_1 : vec2<f32>,
@location(1) kind_2 : u32,
};
@fragment
fn main_fragment( _S15 : pixelInput_0, @builtin(position) pos_2 : vec4<f32>) -> FragmentShaderOutput_0
{
var output_1 : FragmentShaderOutput_0;
var _S16 : vec4<f32> = pixel_art_sample_0(block2_tree_atlas_texture_0, block2_tree_atlas_sampler_0, _S15.uv_1, block2_tree_uvs_0[_S15.kind_2]);
output_1.color_0 = vec4<f32>(_S16.xyz * block3_tint_0.xyz, _S16.w);
return output_1;
}
+41 -31
View File
@@ -34,49 +34,59 @@ struct VertexShaderOutput_0
@vertex @vertex
fn main_vertex(@builtin(vertex_index) vertex_index_0 : u32, @builtin(instance_index) instance_index_0 : u32) -> VertexShaderOutput_0 fn main_vertex(@builtin(vertex_index) vertex_index_0 : u32, @builtin(instance_index) instance_index_0 : u32) -> VertexShaderOutput_0
{ {
var _S1 : u32 = instance_index_0 % per_frame_0.map_width_0;
var _S2 : u32 = instance_index_0 / per_frame_0.map_width_0;
var _S3 : vec2<u32> = vec2<u32>(_S1, _S2);
var output_0 : VertexShaderOutput_0; var output_0 : VertexShaderOutput_0;
var _S4 : vec3<i32> = vec3<i32>(vec3<u32>(_S3, u32(0))); const _S1 : vec2<f32> = vec2<f32>(0.0f, 0.0f);
output_0.tile_0 = (textureLoad((map_texture_0), ((_S4)).xy, ((_S4)).z).x); var vertex_pos_0 : vec2<f32>;
var vertex_uv_0 : vec2<f32>;
switch(vertex_index_0) switch(vertex_index_0)
{ {
case u32(0): case u32(0):
{ {
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - vec2<f32>(0.5f, 0.5f) + vec2<f32>(-0.5f, 0.5f), 0.0f, 1.0f)))); vertex_pos_0 = vec2<f32>(-1.0f, 0.0f);
output_0.uv_0 = vec2<f32>(0.0f, 0.0f); vertex_uv_0 = _S1;
} }
case u32(1): case u32(1):
{ {
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - vec2<f32>(0.5f, 0.5f) + vec2<f32>(-0.5f, -0.5f), 0.0f, 1.0f)))); const _S2 : vec2<f32> = vec2<f32>(0.0f, 1.0f);
output_0.uv_0 = vec2<f32>(0.0f, 1.0f); vertex_pos_0 = vec2<f32>(-1.0f, -1.0f);
vertex_uv_0 = _S2;
} }
case u32(2): case u32(2):
{ {
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - vec2<f32>(0.5f, 0.5f) + vec2<f32>(0.5f, -0.5f), 0.0f, 1.0f)))); const _S3 : vec2<f32> = vec2<f32>(1.0f, 1.0f);
output_0.uv_0 = vec2<f32>(1.0f, 1.0f); vertex_pos_0 = vec2<f32>(0.0f, -1.0f);
vertex_uv_0 = _S3;
} }
case u32(3): case u32(3):
{ {
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - vec2<f32>(0.5f, 0.5f) + vec2<f32>(-0.5f, 0.5f), 0.0f, 1.0f)))); vertex_pos_0 = vec2<f32>(-1.0f, 0.0f);
output_0.uv_0 = vec2<f32>(0.0f, 0.0f); vertex_uv_0 = _S1;
} }
case u32(4): case u32(4):
{ {
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - vec2<f32>(0.5f, 0.5f) + vec2<f32>(0.5f, -0.5f), 0.0f, 1.0f)))); const _S4 : vec2<f32> = vec2<f32>(1.0f, 1.0f);
output_0.uv_0 = vec2<f32>(1.0f, 1.0f); vertex_pos_0 = vec2<f32>(0.0f, -1.0f);
vertex_uv_0 = _S4;
} }
case u32(5): case u32(5):
{ {
const _S5 : vec2<f32> = vec2<f32>(0.5f, 0.5f); const _S5 : vec2<f32> = vec2<f32>(1.0f, 0.0f);
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S3) - _S5 + _S5, 0.0f, 1.0f)))); vertex_pos_0 = _S1;
output_0.uv_0 = vec2<f32>(1.0f, 0.0f); vertex_uv_0 = _S5;
} }
default : default :
{ {
vertex_pos_0 = _S1;
vertex_uv_0 = _S1;
} }
} }
var _S6 : u32 = instance_index_0 % per_frame_0.map_width_0;
var _S7 : u32 = instance_index_0 / per_frame_0.map_width_0;
var _S8 : vec2<u32> = vec2<u32>(_S6, _S7);
var _S9 : vec3<i32> = vec3<i32>(vec3<u32>(_S8, u32(0)));
output_0.tile_0 = (textureLoad((map_texture_0), ((_S9)).xy, ((_S9)).z).x);
output_0.pos_0 = (((mat4x4<f32>(view_projection_matrix_0.data_0[i32(0)][i32(0)], view_projection_matrix_0.data_0[i32(1)][i32(0)], view_projection_matrix_0.data_0[i32(2)][i32(0)], view_projection_matrix_0.data_0[i32(3)][i32(0)], view_projection_matrix_0.data_0[i32(0)][i32(1)], view_projection_matrix_0.data_0[i32(1)][i32(1)], view_projection_matrix_0.data_0[i32(2)][i32(1)], view_projection_matrix_0.data_0[i32(3)][i32(1)], view_projection_matrix_0.data_0[i32(0)][i32(2)], view_projection_matrix_0.data_0[i32(1)][i32(2)], view_projection_matrix_0.data_0[i32(2)][i32(2)], view_projection_matrix_0.data_0[i32(3)][i32(2)], view_projection_matrix_0.data_0[i32(0)][i32(3)], view_projection_matrix_0.data_0[i32(1)][i32(3)], view_projection_matrix_0.data_0[i32(2)][i32(3)], view_projection_matrix_0.data_0[i32(3)][i32(3)])) * (vec4<f32>(vec2<f32>(_S8) + vertex_pos_0, 0.0f, 1.0f))));
output_0.uv_0 = vertex_uv_0;
return output_0; return output_0;
} }
@@ -88,16 +98,16 @@ fn CombinedTextureSampler_Sample_0( this_texture_0 : texture_2d<f32>, this_samp
fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>, tile_uv_0 : vec4<f32>) -> vec4<f32> fn pixel_art_sample_0( input_texture_texture_0 : texture_2d<f32>, input_texture_sampler_0 : sampler, input_uv_0 : vec2<f32>, tile_uv_0 : vec4<f32>) -> vec4<f32>
{ {
var dimensions_0 : vec2<f32>; var dimensions_0 : vec2<f32>;
var _S6 : f32 = dimensions_0[i32(0)]; var _S10 : f32 = dimensions_0[i32(0)];
var _S7 : f32 = dimensions_0[i32(1)]; var _S11 : f32 = dimensions_0[i32(1)];
{var dim = textureDimensions((input_texture_texture_0));((_S6)) = f32(dim.x);((_S7)) = f32(dim.y);}; {var dim = textureDimensions((input_texture_texture_0));((_S10)) = f32(dim.x);((_S11)) = f32(dim.y);};
dimensions_0[i32(0)] = _S6; dimensions_0[i32(0)] = _S10;
dimensions_0[i32(1)] = _S7; dimensions_0[i32(1)] = _S11;
var _S8 : vec2<f32> = tile_uv_0.xy; var _S12 : vec2<f32> = tile_uv_0.xy;
var _S9 : vec2<f32> = tile_uv_0.zw; var _S13 : vec2<f32> = tile_uv_0.zw;
var _S10 : vec2<f32> = mix(_S8, _S9, input_uv_0); var _S14 : vec2<f32> = mix(_S12, _S13, input_uv_0);
var _S11 : vec2<f32> = vec2<f32>(0.5f); var _S15 : vec2<f32> = vec2<f32>(0.5f);
return CombinedTextureSampler_Sample_0(input_texture_texture_0, input_texture_sampler_0, clamp((floor(_S10) + saturate(fract(_S10) / (fwidth((_S10)))) - _S11) / dimensions_0, (_S8 + _S11) / dimensions_0, (_S9 - _S11) / dimensions_0)); return CombinedTextureSampler_Sample_0(input_texture_texture_0, input_texture_sampler_0, clamp((floor(_S14) + saturate(fract(_S14) / (fwidth((_S14)))) - _S15) / dimensions_0, (_S12 + _S15) / dimensions_0, (_S13 - _S15) / dimensions_0));
} }
struct FragmentShaderOutput_0 struct FragmentShaderOutput_0
@@ -112,11 +122,11 @@ struct pixelInput_0
}; };
@fragment @fragment
fn main_fragment( _S12 : pixelInput_0, @builtin(position) pos_1 : vec4<f32>) -> FragmentShaderOutput_0 fn main_fragment( _S16 : pixelInput_0, @builtin(position) pos_1 : vec4<f32>) -> FragmentShaderOutput_0
{ {
var output_1 : FragmentShaderOutput_0; var output_1 : FragmentShaderOutput_0;
var _S13 : vec4<f32> = pixel_art_sample_0(block2_tile_atlas_texture_0, block2_tile_atlas_sampler_0, _S12.uv_1, block2_tile_uvs_0[_S12.tile_1]); var _S17 : vec4<f32> = pixel_art_sample_0(block2_tile_atlas_texture_0, block2_tile_atlas_sampler_0, _S16.uv_1, block2_tile_uvs_0[_S16.tile_1]);
output_1.color_0 = vec4<f32>(_S13.xyz * block3_tint_0.xyz, _S13.w); output_1.color_0 = vec4<f32>(_S17.xyz * block3_tint_0.xyz, _S17.w);
return output_1; return output_1;
} }