commit a2e1d3f
uint
·
2026-07-29 16:26:43 +0000 UTC
parent 45dd938
load textures to block faces
4 files changed,
+104,
-19
+0,
-0
+18,
-18
1@@ -14,40 +14,40 @@ MGMesh block_mesh_create(void);
2
3 static const MGVertex vtc[24] = {
4 /* north: -z */
5- {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 0, 255)},
6+ {0.0f, 0.0f, 0.0f, 0.0f, 1.0f, RGBA(255, 0, 0, 255)},
7 {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 0, 255)},
8- {1.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 0, 255)},
9- {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 0, 255)},
10+ {1.0f, 1.0f, 0.0f, 1.0f, 0.0f, RGBA(255, 0, 0, 255)},
11+ {1.0f, 0.0f, 0.0f, 1.0f, 1.0f, RGBA(255, 0, 0, 255)},
12
13 /* south: +z */
14- {1.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 0, 255)},
15+ {1.0f, 0.0f, 1.0f, 0.0f, 1.0f, RGBA(0, 255, 0, 255)},
16 {1.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 0, 255)},
17- {0.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 0, 255)},
18- {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 0, 255)},
19+ {0.0f, 1.0f, 1.0f, 1.0f, 0.0f, RGBA(0, 255, 0, 255)},
20+ {0.0f, 0.0f, 1.0f, 1.0f, 1.0f, RGBA(0, 255, 0, 255)},
21
22 /* west: -x */
23- {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 0, 255, 255)},
24+ {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, RGBA(0, 0, 255, 255)},
25 {0.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 0, 255, 255)},
26- {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(0, 0, 255, 255)},
27- {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(0, 0, 255, 255)},
28+ {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, RGBA(0, 0, 255, 255)},
29+ {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, RGBA(0, 0, 255, 255)},
30
31 /* east: +x */
32- {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 255, 0, 255)},
33+ {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, RGBA(255, 255, 0, 255)},
34 {1.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 255, 0, 255)},
35- {1.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(255, 255, 0, 255)},
36- {1.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(255, 255, 0, 255)},
37+ {1.0f, 1.0f, 1.0f, 1.0f, 0.0f, RGBA(255, 255, 0, 255)},
38+ {1.0f, 0.0f, 1.0f, 1.0f, 1.0f, RGBA(255, 255, 0, 255)},
39
40 /* bottom: -y */
41- {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(255, 0, 255, 255)},
42+ {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, RGBA(255, 0, 255, 255)},
43 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 255, 255)},
44- {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, RGBA(255, 0, 255, 255)},
45- {1.0f, 0.0f, 1.0f, 0.0f, 0.0f, RGBA(255, 0, 255, 255)},
46+ {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, RGBA(255, 0, 255, 255)},
47+ {1.0f, 0.0f, 1.0f, 1.0f, 1.0f, RGBA(255, 0, 255, 255)},
48
49 /* top: +y */
50- {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(0, 255, 255, 255)},
51+ {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, RGBA(0, 255, 255, 255)},
52 {0.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 255, 255)},
53- {1.0f, 1.0f, 1.0f, 0.0f, 0.0f, RGBA(0, 255, 255, 255)},
54- {1.0f, 1.0f, 0.0f, 0.0f, 0.0f, RGBA(0, 255, 255, 255)}
55+ {1.0f, 1.0f, 1.0f, 1.0f, 0.0f, RGBA(0, 255, 255, 255)},
56+ {1.0f, 1.0f, 0.0f, 1.0f, 1.0f, RGBA(0, 255, 255, 255)}
57 };
58
59 static const u16 idc[36] = {
+5,
-0
1@@ -15,6 +15,11 @@ typedef enum { /* TODO: rename to MG_EC_... */
2
3 MG_ERR_PIPELINE_CREATE,
4
5+ MG_ERR_TEXTURE_LOAD,
6+ MG_ERR_TEXTURE_CREATE,
7+ MG_ERR_SAMPLER_CREATE,
8+ MG_ERR_VIEW_CREATE,
9+
10 MG_ERR_REN_CREATE,
11
12 MG_ERR_LAST
+81,
-1
1@@ -1,4 +1,5 @@
2 #include <sokol_gfx.h>
3+#include <stb_image_c89.h>
4
5 #include "util.h"
6 #include "types.h"
7@@ -22,12 +23,18 @@ typedef struct {
8 sg_shader shader;
9 sg_pipeline pipeline;
10
11+ sg_image texture;
12+ sg_view texture_view;
13+ sg_sampler sampler;
14+
15 RendererMesh meshes[MAX_MESHES];
16 } RendererState;
17
18 /* create the shader and render pipeline */
19 static void create_pipelines(void);
20
21+static void create_texture(void);
22+
23 /* logging function for passing to sokol */
24 static void sokol_log(const char* tag, u32 level, u32 item, const char* msg, u32 ln, const char* file, void* user);
25
26@@ -55,11 +62,13 @@ static const char* fsdr =
27 "in vec2 uv;\n"
28 "in vec4 colour;\n"
29 "\n"
30+"uniform sampler2D tex;\n"
31+"\n"
32 "out vec4 frag_colour;\n"
33 "\n"
34 "void main(void)\n"
35 "{\n"
36-" frag_colour = colour;\n"
37+" frag_colour = texture(tex, uv);\n"
38 "}\n";
39
40 static void create_pipelines(void)
41@@ -79,6 +88,17 @@ static void create_pipelines(void)
42 shader_desc.uniform_blocks[0] .glsl_uniforms[0].glsl_name = "mvp";
43 shader_desc.uniform_blocks[0] .glsl_uniforms[0].type = SG_UNIFORMTYPE_MAT4;
44
45+ /* textures */
46+ shader_desc.views[0].texture.stage = SG_SHADERSTAGE_FRAGMENT;
47+ shader_desc.views[0].texture.image_type = SG_IMAGETYPE_2D;
48+ shader_desc.views[0].texture.sample_type = SG_IMAGESAMPLETYPE_FLOAT;
49+ shader_desc.samplers[0].stage = SG_SHADERSTAGE_FRAGMENT;
50+ shader_desc.samplers[0].sampler_type = SG_SAMPLERTYPE_FILTERING;
51+ shader_desc.texture_sampler_pairs[0].stage = SG_SHADERSTAGE_FRAGMENT;
52+ shader_desc.texture_sampler_pairs[0].view_slot = 0;
53+ shader_desc.texture_sampler_pairs[0].sampler_slot = 0;
54+ shader_desc.texture_sampler_pairs[0].glsl_name = "tex";
55+
56 ren.shader = sg_make_shader(&shader_desc);
57 if (sg_query_shader_state(ren.shader) != SG_RESOURCESTATE_VALID)
58 mg_die(MG_ERR_SHADER_CREATE, "Failed to create shader");
59@@ -100,6 +120,56 @@ static void create_pipelines(void)
60 mg_die(MG_ERR_PIPELINE_CREATE, "Failed to create pipeline");
61 }
62
63+static void create_texture(void)
64+{
65+ sg_image_desc image_desc = {0};
66+ sg_sampler_desc sampler_desc = {0};
67+ sg_view_desc view_desc = {0};
68+ stbi_uc* pixels;
69+ int width;
70+ int height;
71+ int chanells;
72+
73+ pixels = stbi_load(
74+ /* "assets/resourcepacks/default/blocks/brick.png", */
75+ /* "assets/resourcepacks/default/blocks/dirt.png", */
76+ "assets/smile_test.png",
77+ &width, &height, &chanells, 4
78+ );
79+
80+ if (!pixels)
81+ mg_die(MG_ERR_TEXTURE_LOAD, "failed to load texture");
82+
83+ /* image */
84+ image_desc.width = width;
85+ image_desc.height = height;
86+ image_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
87+ image_desc.data.mip_levels[0].ptr = pixels;
88+ image_desc.data.mip_levels[0].size = width * height * 4;
89+ ren.texture = sg_make_image(&image_desc);
90+ stbi_image_free(pixels);
91+
92+ if (sg_query_image_state(ren.texture) != SG_RESOURCESTATE_VALID)
93+ mg_die(MG_ERR_TEXTURE_CREATE, "failed to create texture");
94+
95+ /* texture view */
96+ view_desc.texture.image = ren.texture;
97+ ren.texture_view = sg_make_view(&view_desc);
98+
99+ if (sg_query_view_state(ren.texture_view) != SG_RESOURCESTATE_VALID)
100+ mg_die(MG_ERR_VIEW_CREATE, "failed to texture view");
101+
102+ /* sampler */
103+ sampler_desc.min_filter = SG_FILTER_NEAREST;
104+ sampler_desc.mag_filter = SG_FILTER_NEAREST;
105+ sampler_desc.wrap_u = SG_WRAP_REPEAT;
106+ sampler_desc.wrap_v = SG_WRAP_REPEAT;
107+ ren.sampler = sg_make_sampler(&sampler_desc);
108+
109+ if (sg_query_sampler_state(ren.sampler) != SG_RESOURCESTATE_VALID)
110+ mg_die(MG_ERR_SAMPLER_CREATE, "failed to create sampler");
111+}
112+
113 static void sokol_log(const char* tag, u32 level, u32 item, const char* msg, u32 ln, const char* file, void* user)
114 {
115 LogType type;
116@@ -135,6 +205,7 @@ void renderer_create(MGContext* ctx)
117 mg_die(MG_ERR_REN_CREATE, "Failed to initialise renderer");
118
119 create_pipelines();
120+ create_texture();
121 }
122
123 void renderer_begin(void)
124@@ -189,9 +260,16 @@ void renderer_destroy(void)
125 for (id = 1; id < MAX_MESHES; id++)
126 renderer_mesh_destroy(id);
127
128+ sg_destroy_view(ren.texture_view);
129+ sg_destroy_sampler(ren.sampler);
130+ sg_destroy_image(ren.texture);
131+
132 sg_destroy_pipeline(ren.pipeline);
133 sg_destroy_shader(ren.shader);
134
135+ sg_destroy_image(ren.texture);
136+ sg_destroy_sampler(ren.sampler);
137+
138 if (sg_isvalid())
139 sg_shutdown();
140 ren.ctx = NULL;
141@@ -269,6 +347,8 @@ void renderer_mesh_draw(MGMesh id, const MGMat4* mvp)
142
143 bindings.vertex_buffers[0] = mesh->vb;
144 bindings.index_buffer = mesh->ib;
145+ bindings.views[0] = ren.texture_view;
146+ bindings.samplers[0] = ren.sampler;
147
148 uniforms.ptr = &mvp->Elements[0][0];
149 uniforms.size = sizeof(float) * 16;