Now we load textures from png

This commit is contained in:
Андреев Григорий 2025-09-06 20:43:07 +03:00
parent 48882dd251
commit e33dd979d6
8 changed files with 97 additions and 59 deletions

View File

@ -37,7 +37,7 @@ add_executable(1_test src/l1_4/tests/t1.c)
add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
add_executable(0_render_test src/l2/tests/r0/r0.c gen/l_wl_protocols/xdg-shell-private.c)
target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon)
target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -lpng)
add_executable(0r_tex_init_prep src/l2/tests/r0/r0_tex_init_prep.c)
target_link_libraries(0r_tex_init_prep -lm -lpng)

View File

@ -75,7 +75,7 @@ void TextureDataR8G8B8A8_write_to_png_nofail(const TextureDataR8G8B8A8* self, Sp
ResultVoidOrVecU8 res = TextureDataR8G8B8A8_write_to_png(self, filename);
if (res.variant == Result_Err) {
SpanU8_fprint(VecU8_to_span(&res.err), stderr);
abortf("TextureDataR8G8B8A8_write_to_png");
abortf(" TextureDataR8G8B8A8_write_to_png\n");
}
}
@ -199,7 +199,7 @@ ResultVoidOrVecU8 MargaretPromisedPngR8G8B8A8_finish(MargaretPromisedPngR8G8B8A8
row_pointers = calloc(dim.height, sizeof(row_pointers));
for (U32 y = 0; y < dim.height; y++) {
row_pointers[y] = ((png_bytep)buffer) + 4 * dim.width * y;
row_pointers[dim.height - 1 - y] = ((png_bytep)buffer) + 4 * dim.width * y;
}
png_read_image(self.pngshka, row_pointers);
png_read_end(self.pngshka, self.end_info);
@ -240,13 +240,13 @@ TextureDataR8G8B8A8 TextureDataR8G8B8A8_read_from_png_nofail(SpanU8 name) {
ResultMargaretPromisedPngR8G8B8A8OrVecU8 res_1 = MargaretPromisedPngR8G8B8A8_begin(name);
if (res_1.variant == Result_Err) {
SpanU8_fprint(VecU8_to_span(&res_1.err), stderr);
abortf("MargaretPromisedPngR8G8B8A8_begin");
abortf(" MargaretPromisedPngR8G8B8A8_begin\n");
}
/* res_1 invalidated, we moved ownership to _finish methos */
ResultTextureDataR8G8B8A8OrVecU8 res_2 = MargaretPromisedPngR8G8B8A8_finish_into_TextureDataR8G8B8A8(res_1.ok);
if (res_2.variant == Result_Err) {
SpanU8_fprint(VecU8_to_span(&res_2.err), stderr);
abortf("MargaretPromisedPngR8G8B8A8_finish (into TextureData)");
abortf(" MargaretPromisedPngR8G8B8A8_finish (into TextureData)\n");
}
return res_2.ok;
}

View File

@ -0,0 +1,65 @@
#ifndef PROTOTYPE1_SRC_L2_MARIE_TEXTURE_PROCESSING_H
#define PROTOTYPE1_SRC_L2_MARIE_TEXTURE_PROCESSING_H
#include "../../../gen/l1/pixel_masses.h"
void TextureDataR8G8B8A8_print(const TextureDataR8G8B8A8* self) {
U64 width = self->width;
U64 height = TextureDataR8G8B8A8_get_height(self);
U64 cell_width = MAX_U64(1, width / 350);
U64 cell_height = MAX_U64(1, cell_width * 14 / 8);
for (U64 CY = 0; CY < height; CY += cell_height) {
for (U64 CX = 0; CX < width; CX += cell_width) {
float lum = 0;
for (U64 j = 0; j < cell_height; j++) {
U64 y = cell_height * CY + j;
if (y >= height)
continue;
for (U64 i = 0; i < cell_width; i++) {
U64 x = cell_width * CX + i;
if (x >= width)
continue;
cvec4 pix = *TextureDataR8G8B8A8_at(self, x, y);
lum += (float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f;
}
}
lum /= (float)cell_width * (float)cell_height;
printf("%s", lum > 0.95 ? "@" : (lum > 0.8 ? "#" : (lum > 0.65 ? "*" : (lum > 0.4 ? "_" : (lum > 0.2 ? "." : " ")))));
}
printf("\n");
}
}
/* Fixes several of my generated textures */
NODISCARD TextureDataR8G8B8A8 TextureDataR8G8B8A8_expand_nontransparent_1px(const TextureDataR8G8B8A8* self) {
S32 width = (S32)self->width;
S32 height = (S32)TextureDataR8G8B8A8_get_height(self);
TextureDataR8G8B8A8 res = TextureDataR8G8B8A8_new(width, height);
// S32 chain[9][2] = {{0, 0}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
for (S32 y = 0; y < height; y++) {
for (S32 x = 0; x < width;) {
cvec4 p = *TextureDataR8G8B8A8_at(self, x, y);
cvec4* r = TextureDataR8G8B8A8_mat(&res, x, y);
if (p.w != 255) {
for (S32 i = -1; i <= 1; i++) {
for (S32 j = -1; j <= 1; j++) {
S32 X = x + i, Y = y + i;
if (X < 0 || X >= width || Y < 0 || Y >= height || i == 0 || y == 0)
continue;
cvec4 n = *TextureDataR8G8B8A8_at(self, X, Y);
if (n.w == 255) {
*r = n;
goto done;
}
}
}
}
*r = p;
done:
x++;
}
}
return res;
}
#endif

View File

@ -10,6 +10,8 @@
#include "../../../../gen/l_wl_protocols/xdg-shell-client.h"
#include <xkbcommon/xkbcommon.h>
#include "../../margaret/png_pixel_masses.h"
// todo: generate this structure in l2
typedef struct {
VkPipelineLayout pipeline_layout;
@ -1766,10 +1768,10 @@ int main() {
// todo: generate more cool shiny models
// todo: learn how to use libpng
state.vk_ctx.cyl_1_diffuse_tex = TextureDataR8G8B8A8_read_from_file("textures/log_10_2_6.r8g8b8a8");
state.vk_ctx.cyl_1_diffuse_tex = TextureDataR8G8B8A8_read_from_png_nofail(cstr("textures/log_10_2_6.png"));
// todo: learn how to write texture immediately from file to mapped host memory buffer
// todo: and at the same time I need to add methods to convert between these formats
state.vk_ctx.cyl_1_normal_tex = TextureDataR8G8B8A8_read_from_file("textures/log_10_2_6_NORMAL.r8g8b8a8");
state.vk_ctx.cyl_1_normal_tex = TextureDataR8G8B8A8_read_from_png_nofail(cstr("textures/log_10_2_6_NORMAL.png"));
// todo: kill myself (update: still WiP)

View File

@ -466,20 +466,22 @@ typedef struct {
} FnNormalVectorGenCallback;
typedef struct {
TextureDataR8G8B8* tex;
TextureDataR8G8B8A8* tex;
FnNormalVectorGenCallback my_client;
} draw_polygon_on_normal_texture_smooth_param_surf_H_DrawGuest;
void draw_polygon_on_normal_texture_smooth_param_surf_h_draw_cb(void* ug, S32 x, S32 y, vec4 attr) {
draw_polygon_on_normal_texture_smooth_param_surf_H_DrawGuest* g = ug;
vec3 normal = g->my_client.fn(g->my_client.guest, (vec2){attr.x, attr.y});
*TextureDataR8G8B8_mat(g->tex, x, y) = compress_normal_vec_into_norm_texel(normal);
cvec3 ans = compress_normal_vec_into_norm_texel(normal);
*TextureDataR8G8B8A8_mat(g->tex, x, y) = (cvec4){ans.x, ans.y, ans.z, 255};
}
void draw_polygon_on_normal_texture_smooth_param_surf(
TextureDataR8G8B8* tex, vec2 pa, vec2 pb, vec2 pc, mat3x2 trop, FnNormalVectorGenCallback cb
TextureDataR8G8B8A8* tex, vec2 pa, vec2 pb, vec2 pc, mat3x2 trop, FnNormalVectorGenCallback cb
) {
draw_polygon_on_normal_texture_smooth_param_surf_H_DrawGuest aboba = {.tex = tex, .my_client = cb};
// todo: generate rasterization function (with different precision + different attributes)
marie_rasterize_triangle_with_attr(
(MariePlaneVertAttr){.pos = mat3x2_mul_vec3(trop, vec2_and_one(pa)), .attr = {pa.x, pa.y, 0, 0} },
(MariePlaneVertAttr){.pos = mat3x2_mul_vec3(trop, vec2_and_one(pb)), .attr = {pb.x, pb.y, 0, 0} },
@ -520,16 +522,16 @@ void draw_polygon_on_normal_texture_nat_cords_exaggerated_param_surf(
typedef struct {
TextureDataR8G8B8* tex;
TextureDataR8G8B8A8* tex;
cvec3 normal_compr;
} draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest;
void draw_polygon_on_normal_texture_absolutely_flat_h_draw_cb(void* ug, S32 x, S32 y, vec4 attr) {
draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest* g = ug;
*TextureDataR8G8B8_mat(g->tex, x, y) = g->normal_compr;
*TextureDataR8G8B8A8_mat(g->tex, x, y) = (cvec4){g->normal_compr.x, g->normal_compr.y, g->normal_compr.z, 255};
}
void draw_polygon_on_normal_texture_nat_cords_absolutely_flat(TextureDataR8G8B8* tex,
void draw_polygon_on_normal_texture_nat_cords_absolutely_flat(TextureDataR8G8B8A8* tex,
vec2 ta, vec2 tb, vec2 tc, vec3 c_normal
) {
draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest aboba = {tex, compress_normal_vec_into_norm_texel(c_normal)};
@ -538,7 +540,7 @@ void draw_polygon_on_normal_texture_nat_cords_absolutely_flat(TextureDataR8G8B8*
.fn = draw_polygon_on_normal_texture_absolutely_flat_h_draw_cb, .guest = (void*)&aboba});
}
void draw_polygon_on_normal_texture_absolutely_flat(TextureDataR8G8B8* tex,
void draw_polygon_on_normal_texture_absolutely_flat(TextureDataR8G8B8A8* tex,
vec2 pa, vec2 pb, vec2 pc, mat3x2 trop, vec3 c_normal
) {
draw_polygon_on_normal_texture_nat_cords_absolutely_flat(tex, mat3x2_mul_vec3(trop, vec2_and_one(pa)),
@ -564,7 +566,7 @@ vec3 draw_polygon_on_normal_texture_flat_param_surf_h_draw_cb(void* ug, vec2 p)
}
/* The simplest case of normal texture generation: for a smooth flat surface of a polygon */
void draw_polygon_on_normal_texture_flat_param_surf(TextureDataR8G8B8* tex, vec2 pa, vec2 pb, vec2 pc, mat3x2 trop,
void draw_polygon_on_normal_texture_flat_param_surf(TextureDataR8G8B8A8* tex, vec2 pa, vec2 pb, vec2 pc, mat3x2 trop,
mat3 surf_orient, FnHeightMapGradFlatSurfCallback height_map_cb
) {
draw_polygon_on_normal_texture_flat_param_surf_H_DrawGuest aboba = {surf_orient, height_map_cb};
@ -628,7 +630,7 @@ vec2 height_map_cb_that_uses_bublazhuzhka(void* ug, vec2 v) {
return Bublazhuzhka_get_derivative(bzh, v);
}
TextureDataR8G8B8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
TextureDataR8G8B8A8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
assert(k >= 1);
const float a = M_PI_2f / (float)k;
const float l = 2 * r * sinf(M_PI_4f / (float)k);
@ -641,7 +643,7 @@ TextureDataR8G8B8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_resol
// const vec2 v3tex = {r + w, 2 * r};
const vec2 v4tex = {r, 0};
const vec2 v5tex = {r + w, 0};
TextureDataR8G8B8 res = TextureDataR8G8B8_new(width_pix, height_pix);
TextureDataR8G8B8A8 res = TextureDataR8G8B8A8_new(width_pix, height_pix);
Bublazhuzhka crap_on_the_back_side = fill_rectangle_with_crap(w, r);
mat3x2 trop_back_side = {.x.x = cord_resol.x, .y.y = cord_resol.y, .z = vec2_mul_vec2((vec2){r, r}, cord_resol)};

View File

@ -1,57 +1,26 @@
#include "r0_assets.h"
#include "../../marie/rasterization.h"
#include "../../margaret/png_pixel_masses.h"
// todo: move it to some other file
void TextureDataR8G8B8A8_print(const TextureDataR8G8B8A8* self) {
U64 width = self->width;
U64 height = TextureDataR8G8B8A8_get_height(self);
U64 cell_width = MAX_U64(1, width / 350);
U64 cell_height = MAX_U64(1, cell_width * 14 / 8);
for (U64 CY = 0; CY < height; CY += cell_height) {
for (U64 CX = 0; CX < width; CX += cell_width) {
float lum = 0;
for (U64 j = 0; j < cell_height; j++) {
U64 y = cell_height * CY + j;
if (y >= height)
continue;
for (U64 i = 0; i < cell_width; i++) {
U64 x = cell_width * CX + i;
if (x >= width)
continue;
cvec4 pix = *TextureDataR8G8B8A8_at(self, x, y);
lum += (float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f;
}
}
lum /= (float)cell_width * (float)cell_height;
printf("%s", lum > 0.95 ? "@" : (lum > 0.8 ? "#" : (lum > 0.65 ? "*" : (lum > 0.4 ? "_" : (lum > 0.2 ? "." : " ")))));
}
printf("\n");
}
}
#include "../../marie/texture_processing.h"
void model_1_template() {
TextureDataR8 tex_1 = generate_tex_template_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
TextureDataR8G8B8A8 tex_1_big = TextureDataR8G8B8A8_new(tex_1.width, TextureDataR8_get_height(&tex_1));
for (size_t i = 0; i < tex_1.pixels.len; i++) {
U8 g = *VecU8_at(&tex_1.pixels, i);
TextureDataR8 tex = generate_tex_template_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
TextureDataR8G8B8A8 tex_1_big = TextureDataR8G8B8A8_new(tex.width, TextureDataR8_get_height(&tex));
for (size_t i = 0; i < tex.pixels.len; i++) {
U8 g = *VecU8_at(&tex.pixels, i);
*Veccvec4_mat(&tex_1_big.pixels, i) = (cvec4){g, g, g, 255};
}
TextureDataR8G8B8A8_write_to_png_nofail(&tex_1_big, cstr("textures/log_10_2_6_TEMPLATE.png"));
TextureDataR8G8B8A8_drop(tex_1_big);
TextureDataR8_drop(tex_1);
TextureDataR8_drop(tex);
}
void model_1_normal() {
TextureDataR8G8B8 tex_2 = generate_normal_tex_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
TextureDataR8G8B8A8 tex_2_big = TextureDataR8G8B8A8_new(tex_2.width, TextureDataR8G8B8_get_height(&tex_2));
for (size_t i = 0; i < tex_2.pixels.len; i++) {
cvec3 rgb = *Veccvec3_at(&tex_2.pixels, i);
*Veccvec4_mat(&tex_2_big.pixels, i) = (cvec4){rgb.x, rgb.y, rgb.z, 255};
}
TextureDataR8G8B8A8_write_to_png_nofail(&tex_2_big, cstr("textures/log_10_2_6_NORMAL.png"));
TextureDataR8G8B8A8_drop(tex_2_big);
TextureDataR8G8B8_drop(tex_2);
TextureDataR8G8B8A8 tex = generate_normal_tex_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
TextureDataR8G8B8A8 fixed_tex = TextureDataR8G8B8A8_expand_nontransparent_1px(&tex);
TextureDataR8G8B8A8_write_to_png_nofail(&fixed_tex, cstr("textures/log_10_2_6_NORMAL.png"));
TextureDataR8G8B8A8_drop(fixed_tex);
TextureDataR8G8B8A8_drop(tex);
}
int main() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB