sokol: fix usage of sokol sampler (#19527)

This commit is contained in:
Larpon 2023-10-07 20:05:30 +02:00 committed by GitHub
parent e19e17f10b
commit 3c68e78f32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 354 additions and 239 deletions

View file

@ -48,7 +48,6 @@ jobs:
sleep 1; ./v gret -t ./gg-regression-images/vgret.v_examples.toml -v ./gg-sample_images ./gg-regression-images sleep 1; ./v gret -t ./gg-regression-images/vgret.v_examples.toml -v ./gg-sample_images ./gg-regression-images
- name: Upload regression to imgur - name: Upload regression to imgur
continue-on-error: true
if: steps.compare.outcome != 'success' if: steps.compare.outcome != 'success'
run: | run: |
./imgur.sh /tmp/fail.png ./imgur.sh /tmp/fail.png

View file

@ -100,7 +100,6 @@ jobs:
run: ./v -autofree -o v2 cmd/v ## NB: this does not mean it runs, but at least keeps it from regressing run: ./v -autofree -o v2 cmd/v ## NB: this does not mean it runs, but at least keeps it from regressing
- name: Shader examples can be built - name: Shader examples can be built
continue-on-error: true
run: | run: |
wget https://github.com/floooh/sokol-tools-bin/raw/6040b18d39649d56dbae2ae1aed59fb755b26369/bin/linux/sokol-shdc wget https://github.com/floooh/sokol-tools-bin/raw/6040b18d39649d56dbae2ae1aed59fb755b26369/bin/linux/sokol-shdc
chmod +x ./sokol-shdc chmod +x ./sokol-shdc

View file

@ -24,7 +24,7 @@ pub fn (mut window Window) draw() {
sgl.rotate(angle, 0.0, 0.0, 1.0) // rotate around the Z axis pointing towards the camera sgl.rotate(angle, 0.0, 0.0, 1.0) // rotate around the Z axis pointing towards the camera
sgl.enable_texture() sgl.enable_texture()
sgl.texture(window.img.simg) sgl.texture(window.img.simg, window.img.ssmp)
sgl.begin_quads() sgl.begin_quads()
sgl.c4b(255, 255, 255, 255) sgl.c4b(255, 255, 255, 255)
sgl.v3f_t2f(200, 200, 0, 1.0, 1.0) sgl.v3f_t2f(200, 200, 0, 1.0, 1.0)

View file

@ -28,6 +28,7 @@ mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
pip_3d sgl.Pipeline pip_3d sgl.Pipeline
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
mouse_x int = -1 mouse_x int = -1
@ -39,17 +40,13 @@ mut:
* Texture functions * Texture functions
* *
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf &u8) gfx.Image { fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
height: h height: h
num_mipmaps: 0 num_mipmaps: 0
// min_filter: .linear
// mag_filter: .linear
// usage: .dynamic // usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &u8(0) label: &u8(0)
d3d11_texture: 0 d3d11_texture: 0
} }
@ -60,7 +57,16 @@ fn create_texture(w int, h int, buf &u8) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
fn destroy_texture(sg_img gfx.Image) { fn destroy_texture(sg_img gfx.Image) {
@ -205,7 +211,7 @@ fn draw_texture_cubes(app App) {
sgl.load_pipeline(app.pip_3d) sgl.load_pipeline(app.pip_3d)
sgl.enable_texture() sgl.enable_texture()
sgl.texture(app.texture) sgl.texture(app.texture, app.sampler)
sgl.matrix_mode_projection() sgl.matrix_mode_projection()
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0) sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0)
@ -242,7 +248,7 @@ fn cube_field(app App) {
sgl.load_pipeline(app.pip_3d) sgl.load_pipeline(app.pip_3d)
sgl.enable_texture() sgl.enable_texture()
sgl.texture(app.texture) sgl.texture(app.texture, app.sampler)
sgl.matrix_mode_projection() sgl.matrix_mode_projection()
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 200.0) sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 200.0)
@ -373,7 +379,7 @@ fn my_init(mut app App) {
} }
} }
unsafe { unsafe {
app.texture = create_texture(w, h, tmp_txt) app.texture, app.sampler = create_texture(w, h, tmp_txt)
free(tmp_txt) free(tmp_txt)
} }
} }

View file

@ -26,7 +26,10 @@ void main() {
#pragma sokol @end #pragma sokol @end
#pragma sokol @fs fs #pragma sokol @fs fs
uniform sampler2D tex;
uniform texture2D tex;
uniform sampler smp;
uniform fs_params { uniform fs_params {
vec2 text_res; vec2 text_res;
float iTime; float iTime;
@ -83,7 +86,7 @@ vec4 mainImage(vec2 fragCoord)
void main() { void main() {
vec4 c = color; vec4 c = color;
vec4 txt = texture(tex, uv/4.0); vec4 txt = texture(sampler2D(tex, smp), uv/4.0);
c = txt * c; c = txt * c;
vec4 col_ray = mainImage(uv); vec4 col_ray = mainImage(uv);
float txt_mix = mod(iTime,5); float txt_mix = mod(iTime,5);

View file

@ -39,6 +39,7 @@ mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
pip_3d sgl.Pipeline pip_3d sgl.Pipeline
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
mouse_x int = -1 mouse_x int = -1
@ -55,17 +56,13 @@ mut:
* Texture functions * Texture functions
* *
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf &byte) gfx.Image { fn create_texture(w int, h int, buf &byte) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
height: h height: h
num_mipmaps: 0 num_mipmaps: 0
// min_filter: .linear
// mag_filter: .linear
// usage: .dynamic // usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &u8(0) label: &u8(0)
d3d11_texture: 0 d3d11_texture: 0
} }
@ -76,7 +73,16 @@ fn create_texture(w int, h int, buf &byte) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
fn destroy_texture(sg_img gfx.Image) { fn destroy_texture(sg_img gfx.Image) {
@ -374,7 +380,7 @@ fn draw_cube_glsl(app App) {
// clear // clear
ws := gg.window_size_real_pixels() ws := gg.window_size_real_pixels()
mut color_action := gfx.ColorAttachmentAction{ mut color_action := gfx.ColorAttachmentAction{
load_action: unsafe { gfx.Action(C.SG_LOADACTION_DONTCARE) } // C.SG_ACTION_CLEAR) load_action: unsafe { gfx.LoadAction(C.SG_LOADACTION_DONTCARE) } // C.SG_ACTION_CLEAR)
clear_value: gfx.Color{ clear_value: gfx.Color{
r: 1.0 r: 1.0
g: 1.0 g: 1.0
@ -433,7 +439,7 @@ fn draw_texture_cubes(app App) {
sgl.load_pipeline(app.pip_3d) sgl.load_pipeline(app.pip_3d)
sgl.enable_texture() sgl.enable_texture()
sgl.texture(app.texture) sgl.texture(app.texture, app.sampler)
sgl.matrix_mode_projection() sgl.matrix_mode_projection()
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0) sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0)
@ -573,7 +579,7 @@ fn my_init(mut app App) {
i += 4 i += 4
} }
} }
app.texture = create_texture(w, h, tmp_txt) app.texture, app.sampler = create_texture(w, h, tmp_txt)
unsafe { free(tmp_txt) } unsafe { free(tmp_txt) }
// glsl // glsl

View file

@ -26,7 +26,8 @@ void main() {
#pragma sokol @end #pragma sokol @end
#pragma sokol @fs fs #pragma sokol @fs fs
uniform sampler2D tex; uniform texture2D tex;
uniform sampler smp;
uniform fs_params { uniform fs_params {
vec2 iResolution; vec2 iResolution;
vec2 iMouse; vec2 iMouse;
@ -679,7 +680,7 @@ vec4 mainImage( vec2 fragCoord )
void main() { void main() {
vec4 c = color; vec4 c = color;
vec4 txt = texture(tex, uv); vec4 txt = texture(sampler2D(tex, smp), uv);
c = txt * c; c = txt * c;
vec2 uv1 = uv * iResolution; vec2 uv1 = uv * iResolution;
vec4 col_ray = mainImage(uv1); vec4 col_ray = mainImage(uv1);

View file

@ -39,6 +39,7 @@ struct App {
mut: mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
@ -54,7 +55,7 @@ mut:
/****************************************************************************** /******************************************************************************
* Texture functions * Texture functions
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf &byte) gfx.Image { fn create_texture(w int, h int, buf &byte) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
@ -75,7 +76,16 @@ fn create_texture(w int, h int, buf &byte) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
fn destroy_texture(sg_img gfx.Image) { fn destroy_texture(sg_img gfx.Image) {
@ -224,6 +234,7 @@ fn init_cube_glsl(mut app App) {
app.cube_bind.vertex_buffers[0] = vbuf app.cube_bind.vertex_buffers[0] = vbuf
app.cube_bind.index_buffer = ibuf app.cube_bind.index_buffer = ibuf
app.cube_bind.fs.images[C.SLOT_tex] = app.texture app.cube_bind.fs.images[C.SLOT_tex] = app.texture
app.cube_bind.fs.samplers[C.SLOT_smp] = app.sampler
app.cube_pip_glsl = gfx.make_pipeline(&pipdesc) app.cube_pip_glsl = gfx.make_pipeline(&pipdesc)
println('GLSL init DONE!') println('GLSL init DONE!')
} }
@ -377,7 +388,7 @@ fn my_init(mut app App) {
} }
} }
unsafe { unsafe {
app.texture = create_texture(w, h, tmp_txt) app.texture, app.sampler = create_texture(w, h, tmp_txt)
free(tmp_txt) free(tmp_txt)
} }
// glsl // glsl

View file

@ -40,6 +40,7 @@ struct App {
mut: mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
mouse_x int = -1 mouse_x int = -1
@ -57,7 +58,7 @@ mut:
/****************************************************************************** /******************************************************************************
* Texture functions * Texture functions
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf byteptr) gfx.Image { fn create_texture(w int, h int, buf byteptr) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
@ -78,11 +79,16 @@ fn create_texture(w int, h int, buf byteptr) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
}
fn destroy_texture(sg_img gfx.Image) { mut smp_desc := gfx.SamplerDesc{
gfx.destroy_image(sg_img) min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
// Use only if usage: .dynamic is enabled // Use only if usage: .dynamic is enabled
@ -228,6 +234,7 @@ fn init_cube_glsl_m(mut app App) {
bind.vertex_buffers[0] = vbuf bind.vertex_buffers[0] = vbuf
bind.index_buffer = ibuf bind.index_buffer = ibuf
bind.fs.images[C.SLOT_tex] = app.texture bind.fs.images[C.SLOT_tex] = app.texture
bind.fs.samplers[C.SLOT_smp] = app.sampler
app.bind['march'] = bind app.bind['march'] = bind
app.pipe['march'] = gfx.make_pipeline(&pipdesc) app.pipe['march'] = gfx.make_pipeline(&pipdesc)
@ -343,6 +350,7 @@ fn init_cube_glsl_p(mut app App) {
bind.vertex_buffers[0] = vbuf bind.vertex_buffers[0] = vbuf
bind.index_buffer = ibuf bind.index_buffer = ibuf
bind.fs.images[C.SLOT_tex] = app.texture bind.fs.images[C.SLOT_tex] = app.texture
bind.fs.samplers[C.SLOT_smp] = app.sampler
app.bind['puppy'] = bind app.bind['puppy'] = bind
app.pipe['puppy'] = gfx.make_pipeline(&pipdesc) app.pipe['puppy'] = gfx.make_pipeline(&pipdesc)
@ -574,7 +582,7 @@ fn my_init(mut app App) {
i += 4 i += 4
} }
} }
app.texture = create_texture(w, h, tmp_txt) app.texture, app.sampler = create_texture(w, h, tmp_txt)
unsafe { free(tmp_txt) } unsafe { free(tmp_txt) }
// glsl // glsl

View file

@ -26,7 +26,9 @@ void main() {
#pragma sokol @end #pragma sokol @end
#pragma sokol @fs fs_m #pragma sokol @fs fs_m
uniform sampler2D tex; uniform texture2D tex;
uniform sampler smp;
uniform fs_params_m { uniform fs_params_m {
vec2 iResolution; vec2 iResolution;
vec2 iMouse; vec2 iMouse;
@ -679,7 +681,7 @@ vec4 mainImage( vec2 fragCoord )
void main() { void main() {
vec4 c = color; vec4 c = color;
vec4 txt = texture(tex, uv); vec4 txt = texture(sampler2D(tex, smp), uv);
c = txt * c; c = txt * c;
vec2 uv1 = uv * iResolution; vec2 uv1 = uv * iResolution;
vec4 col_ray = mainImage(uv1); vec4 col_ray = mainImage(uv1);

View file

@ -26,7 +26,9 @@ void main() {
#pragma sokol @end #pragma sokol @end
#pragma sokol @fs fs_p #pragma sokol @fs fs_p
uniform sampler2D tex; uniform texture2D tex;
uniform sampler smp;
uniform fs_params_p { uniform fs_params_p {
vec2 iResolution; vec2 iResolution;
vec2 iMouse; vec2 iMouse;
@ -552,7 +554,7 @@ vec4 mainImage( vec2 fragCoord )
void main() { void main() {
vec4 c = color; vec4 c = color;
vec4 txt = texture(tex, uv); vec4 txt = texture(sampler2D(tex, smp), uv);
c = txt * c; c = txt * c;
vec2 uv1 = uv * iResolution; vec2 uv1 = uv * iResolution;
vec4 col_ray = mainImage(uv1); vec4 col_ray = mainImage(uv1);

View file

@ -32,6 +32,7 @@ struct App {
mut: mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
@ -64,7 +65,7 @@ fn C.instancing_shader_desc(gfx.Backend) &gfx.ShaderDesc
/****************************************************************************** /******************************************************************************
* Texture functions * Texture functions
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf byteptr) gfx.Image { fn create_texture(w int, h int, buf byteptr) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
// vfmt off // vfmt off
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
@ -87,7 +88,16 @@ fn create_texture(w int, h int, buf byteptr) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
fn destroy_texture(sg_img gfx.Image) { fn destroy_texture(sg_img gfx.Image) {
@ -258,6 +268,7 @@ fn init_cube_glsl_i(mut app App) {
bind.vertex_buffers[1] = inst_buf // instance buffer bind.vertex_buffers[1] = inst_buf // instance buffer
bind.index_buffer = ibuf bind.index_buffer = ibuf
bind.fs.images[C.SLOT_tex] = app.texture bind.fs.images[C.SLOT_tex] = app.texture
bind.fs.samplers[C.SLOT_smp] = app.sampler
app.bind['inst'] = bind app.bind['inst'] = bind
app.pipe['inst'] = gfx.make_pipeline(&pipdesc) app.pipe['inst'] = gfx.make_pipeline(&pipdesc)
@ -440,7 +451,7 @@ fn my_init(mut app App) {
} }
} }
unsafe { unsafe {
app.texture = create_texture(w, h, tmp_txt) app.texture, app.sampler = create_texture(w, h, tmp_txt)
free(tmp_txt) free(tmp_txt)
} }
// glsl // glsl

View file

@ -45,7 +45,8 @@ void main() {
#pragma sokol @end #pragma sokol @end
#pragma sokol @fs fs_i #pragma sokol @fs fs_i
uniform sampler2D tex; uniform texture2D tex;
uniform sampler smp;
in vec4 color; in vec4 color;
in vec4 color_inst; in vec4 color_inst;
@ -54,7 +55,7 @@ out vec4 frag_color;
void main() { void main() {
vec4 c = color; vec4 c = color;
vec4 txt = texture(tex, uv); vec4 txt = texture(sampler2D(tex, smp), uv);
c = txt * c * color_inst; c = txt * c * color_inst;
frag_color = c ; frag_color = c ;
} }

View file

@ -42,7 +42,8 @@ void main()
#pragma sokol @fs fs #pragma sokol @fs fs
//precision mediump float; // Set the default precision to medium. We don't need as high of a precision in the fragment shader //precision mediump float; // Set the default precision to medium. We don't need as high of a precision in the fragment shader
uniform sampler2D tex; uniform texture2D tex;
uniform sampler smp;
uniform fs_params { uniform fs_params {
vec4 u_LightPos; // The position of the light in eye space. vec4 u_LightPos; // The position of the light in eye space.
vec4 ambientColor; vec4 ambientColor;
@ -93,7 +94,7 @@ vec4 getPhong(in vec4 diffuseColor) {
// The entry point for our fragment shader. // The entry point for our fragment shader.
void main() void main()
{ {
vec4 txt = texture(tex, uv); vec4 txt = texture(sampler2D(tex, smp), uv);
// Directional light // Directional light
float directional = dot(normalize(v_Normal1), normalize(vec3(0,0.5,1))) ; float directional = dot(normalize(v_Normal1), normalize(vec3(0,0.5,1))) ;

View file

@ -18,7 +18,7 @@ import stbi
/****************************************************************************** /******************************************************************************
* Texture functions * Texture functions
******************************************************************************/ ******************************************************************************/
pub fn create_texture(w int, h int, buf &u8) gfx.Image { pub fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
@ -39,29 +39,38 @@ pub fn create_texture(w int, h int, buf &u8) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
pub fn destroy_texture(sg_img gfx.Image) { pub fn destroy_texture(sg_img gfx.Image) {
gfx.destroy_image(sg_img) gfx.destroy_image(sg_img)
} }
pub fn load_texture(file_name string) gfx.Image { pub fn load_texture(file_name string) (gfx.Image, gfx.Sampler) {
buffer := read_bytes_from_file(file_name) buffer := read_bytes_from_file(file_name)
stbi.set_flip_vertically_on_load(true) stbi.set_flip_vertically_on_load(true)
img := stbi.load_from_memory(buffer.data, buffer.len) or { img := stbi.load_from_memory(buffer.data, buffer.len) or {
eprintln('Texure file: [${file_name}] ERROR!') eprintln('Texure file: [${file_name}] ERROR!')
exit(0) exit(0)
} }
res := create_texture(int(img.width), int(img.height), img.data) sg_img, sg_smp := create_texture(int(img.width), int(img.height), img.data)
img.free() img.free()
return res return sg_img, sg_smp
} }
/****************************************************************************** /******************************************************************************
* Pipeline * Pipeline
******************************************************************************/ ******************************************************************************/
pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader gfx.Shader, texture gfx.Image) Render_data { pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader gfx.Shader, texture gfx.Image, sampler gfx.Sampler) Render_data {
mut res := Render_data{} mut res := Render_data{}
obj_buf := obj_part.get_buffer(in_part) obj_buf := obj_part.get_buffer(in_part)
res.n_vert = obj_buf.n_vertex res.n_vert = obj_buf.n_vertex
@ -134,6 +143,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader gfx.Shader,
res.bind.vertex_buffers[0] = vbuf res.bind.vertex_buffers[0] = vbuf
res.bind.index_buffer = ibuf res.bind.index_buffer = ibuf
res.bind.fs.images[C.SLOT_tex] = texture res.bind.fs.images[C.SLOT_tex] = texture
res.bind.fs.samplers[C.SLOT_smp] = sampler
res.pipeline = gfx.make_pipeline(&pipdesc) res.pipeline = gfx.make_pipeline(&pipdesc)
// println('Buffers part [$in_part] init done!') // println('Buffers part [$in_part] init done!')
@ -144,7 +154,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader gfx.Shader,
* Render functions * Render functions
******************************************************************************/ ******************************************************************************/
// aggregate all the part by materials // aggregate all the part by materials
pub fn (mut obj_part ObjPart) init_render_data(texture gfx.Image) { pub fn (mut obj_part ObjPart) init_render_data(texture gfx.Image, sampler gfx.Sampler) {
// create shader // create shader
// One shader for all the model // One shader for all the model
shader := gfx.make_shader(C.gouraud_shader_desc(gfx.query_backend())) shader := gfx.make_shader(C.gouraud_shader_desc(gfx.query_backend()))
@ -162,6 +172,7 @@ pub fn (mut obj_part ObjPart) init_render_data(texture gfx.Image) {
// println("$k => Parts $v") // println("$k => Parts $v")
mut txt := texture mut txt := texture
mut smp := sampler
if k in obj_part.mat_map { if k in obj_part.mat_map {
mat_map := obj_part.mat[obj_part.mat_map[k]] mat_map := obj_part.mat[obj_part.mat_map[k]]
@ -171,15 +182,16 @@ pub fn (mut obj_part ObjPart) init_render_data(texture gfx.Image) {
txt = obj_part.texture[file_name] txt = obj_part.texture[file_name]
// println("Texture [${file_name}] => from CACHE") // println("Texture [${file_name}] => from CACHE")
} else { } else {
txt = load_texture(file_name) txt, smp = load_texture(file_name)
obj_part.texture[file_name] = txt obj_part.texture[file_name] = txt
obj_part.sampler[file_name] = smp
// println("Texture [${file_name}] => LOADED") // println("Texture [${file_name}] => LOADED")
} }
} }
} }
// key := obj_part.texture.keys()[0] // key := obj_part.texture.keys()[0]
// obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key]) // obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key])
obj_part.rend_data << obj_part.create_pipeline(v, shader, txt) obj_part.rend_data << obj_part.create_pipeline(v, shader, txt, smp)
} }
// println("Texture array len: ${obj_part.texture.len}") // println("Texture array len: ${obj_part.texture.len}")
// println("Calc bounding box.") // println("Calc bounding box.")

View file

@ -52,6 +52,7 @@ pub mut:
mat []Material // list of the materials of the ObjPart mat []Material // list of the materials of the ObjPart
mat_map map[string]int // mapping material name to its material index mat_map map[string]int // mapping material name to its material index
texture map[string]gfx.Image // GPU loaded texture map texture map[string]gfx.Image // GPU loaded texture map
sampler map[string]gfx.Sampler // GPU loaded sampler
material_file string // .mtl file name for the .obj material_file string // .mtl file name for the .obj
rend_data []Render_data // render data used for the rendering rend_data []Render_data // render data used for the rendering

View file

@ -47,6 +47,7 @@ struct App {
mut: mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
@ -224,11 +225,11 @@ fn my_init(mut app App) {
tmp_txt[1] = u8(0xFF) tmp_txt[1] = u8(0xFF)
tmp_txt[2] = u8(0xFF) tmp_txt[2] = u8(0xFF)
tmp_txt[3] = u8(0xFF) tmp_txt[3] = u8(0xFF)
app.texture = obj.create_texture(1, 1, tmp_txt) app.texture, app.sampler = obj.create_texture(1, 1, tmp_txt)
free(tmp_txt) free(tmp_txt)
} }
// glsl // glsl
app.obj_part.init_render_data(app.texture) app.obj_part.init_render_data(app.texture, app.sampler)
app.init_flag = true app.init_flag = true
} }

View file

@ -63,6 +63,7 @@ mut:
gg &gg.Context = unsafe { nil } gg &gg.Context = unsafe { nil }
pip_viewer sgl.Pipeline pip_viewer sgl.Pipeline
texture gfx.Image texture gfx.Image
sampler gfx.Sampler
init_flag bool init_flag bool
frame_count int frame_count int
mouse_x int = -1 mouse_x int = -1
@ -103,6 +104,7 @@ mut:
// logo // logo
logo_path string // path of the temp font logo logo_path string // path of the temp font logo
logo_texture gfx.Image logo_texture gfx.Image
logo_sampler gfx.Sampler
logo_w int logo_w int
logo_h int logo_h int
logo_ratio f32 = 1.0 logo_ratio f32 = 1.0
@ -115,17 +117,13 @@ mut:
* Texture functions * Texture functions
* *
******************************************************************************/ ******************************************************************************/
fn create_texture(w int, h int, buf &u8) gfx.Image { fn create_texture(w int, h int, buf &u8) (gfx.Image, gfx.Sampler) {
sz := w * h * 4 sz := w * h * 4
mut img_desc := gfx.ImageDesc{ mut img_desc := gfx.ImageDesc{
width: w width: w
height: h height: h
num_mipmaps: 0 num_mipmaps: 0
// min_filter: .linear
// mag_filter: .linear
// usage: .dynamic // usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &u8(0) label: &u8(0)
d3d11_texture: 0 d3d11_texture: 0
} }
@ -136,7 +134,16 @@ fn create_texture(w int, h int, buf &u8) gfx.Image {
} }
sg_img := gfx.make_image(&img_desc) sg_img := gfx.make_image(&img_desc)
return sg_img
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
sg_smp := gfx.make_sampler(&smp_desc)
return sg_img, sg_smp
} }
fn destroy_texture(sg_img gfx.Image) { fn destroy_texture(sg_img gfx.Image) {
@ -225,22 +232,22 @@ pub fn read_bytes_from_file(file_path string) []u8 {
return buffer return buffer
} }
fn (mut app App) load_texture_from_buffer(buf voidptr, buf_len int) (gfx.Image, int, int) { fn (mut app App) load_texture_from_buffer(buf voidptr, buf_len int) (gfx.Image, gfx.Sampler, int, int) {
// load image // load image
stbi.set_flip_vertically_on_load(true) stbi.set_flip_vertically_on_load(true)
img := stbi.load_from_memory(buf, buf_len) or { img := stbi.load_from_memory(buf, buf_len) or {
eprintln('ERROR: Can not load image from buffer, file: [${app.item_list.lst[app.item_list.item_index]}].') eprintln('ERROR: Can not load image from buffer, file: [${app.item_list.lst[app.item_list.item_index]}].')
return app.logo_texture, app.logo_w, app.logo_h return app.logo_texture, app.sampler, app.logo_w, app.logo_h
// exit(1) // exit(1)
} }
res := create_texture(int(img.width), int(img.height), img.data) sg_img, sg_smp := create_texture(int(img.width), int(img.height), img.data)
unsafe { unsafe {
img.free() img.free()
} }
return res, int(img.width), int(img.height) return sg_img, sg_smp, int(img.width), int(img.height)
} }
pub fn (mut app App) load_texture_from_file(file_name string) (gfx.Image, int, int) { pub fn (mut app App) load_texture_from_file(file_name string) (gfx.Image, gfx.Sampler, int, int) {
app.read_bytes(file_name) app.read_bytes(file_name)
return app.load_texture_from_buffer(app.mem_buf, app.mem_buf_size) return app.load_texture_from_buffer(app.mem_buf, app.mem_buf_size)
} }
@ -249,8 +256,10 @@ pub fn show_logo(mut app App) {
clear_modifier_params(mut app) clear_modifier_params(mut app)
if app.texture != app.logo_texture { if app.texture != app.logo_texture {
destroy_texture(app.texture) destroy_texture(app.texture)
gfx.destroy_sampler(app.sampler)
} }
app.texture = app.logo_texture app.texture = app.logo_texture
app.sampler = app.logo_sampler
app.img_w = app.logo_w app.img_w = app.logo_w
app.img_h = app.logo_h app.img_h = app.logo_h
app.img_ratio = f32(app.img_w) / f32(app.img_h) app.img_ratio = f32(app.img_w) / f32(app.img_h)
@ -268,11 +277,12 @@ pub fn load_image(mut app App) {
// destroy the texture, avoid to destroy the logo // destroy the texture, avoid to destroy the logo
if app.texture != app.logo_texture { if app.texture != app.logo_texture {
destroy_texture(app.texture) destroy_texture(app.texture)
gfx.destroy_sampler(app.sampler)
} }
// load from .ZIP file // load from .ZIP file
if app.item_list.is_inside_a_container() == true { if app.item_list.is_inside_a_container() == true {
app.texture, app.img_w, app.img_h = app.load_texture_from_zip() or { app.texture, app.sampler, app.img_w, app.img_h = app.load_texture_from_zip() or {
eprintln('ERROR: Can not load image from .ZIP file [${app.item_list.lst[app.item_list.item_index]}].') eprintln('ERROR: Can not load image from .ZIP file [${app.item_list.lst[app.item_list.item_index]}].')
show_logo(mut app) show_logo(mut app)
app.state = .show app.state = .show
@ -293,11 +303,12 @@ pub fn load_image(mut app App) {
file_path := app.item_list.get_file_path() file_path := app.item_list.get_file_path()
if file_path.len > 0 { if file_path.len > 0 {
// println("${app.item_list.lst[app.item_list.item_index]} $file_path ${app.item_list.lst.len}") // println("${app.item_list.lst[app.item_list.item_index]} $file_path ${app.item_list.lst.len}")
app.texture, app.img_w, app.img_h = app.load_texture_from_file(file_path) app.texture, app.sampler, app.img_w, app.img_h = app.load_texture_from_file(file_path)
app.img_ratio = f32(app.img_w) / f32(app.img_h) app.img_ratio = f32(app.img_w) / f32(app.img_h)
// println("texture: [${app.img_w},${app.img_h}] ratio: ${app.img_ratio}") // println("texture: [${app.img_w},${app.img_h}] ratio: ${app.img_ratio}")
} else { } else {
app.texture = app.logo_texture app.texture = app.logo_texture
app.sampler = app.logo_sampler
app.img_w = app.logo_w app.img_w = app.logo_w
app.img_h = app.logo_h app.img_h = app.logo_h
app.img_ratio = f32(app.img_w) / f32(app.img_h) app.img_ratio = f32(app.img_w) / f32(app.img_h)
@ -335,13 +346,14 @@ fn app_init(mut app App) {
app.pip_viewer = sgl.make_pipeline(&pipdesc) app.pip_viewer = sgl.make_pipeline(&pipdesc)
// load logo // load logo
app.logo_texture, app.logo_w, app.logo_h = app.load_texture_from_file(app.logo_path) app.logo_texture, app.logo_sampler, app.logo_w, app.logo_h = app.load_texture_from_file(app.logo_path)
app.logo_ratio = f32(app.img_w) / f32(app.img_h) app.logo_ratio = f32(app.img_w) / f32(app.img_h)
app.img_w = app.logo_w app.img_w = app.logo_w
app.img_h = app.logo_h app.img_h = app.logo_h
app.img_ratio = app.logo_ratio app.img_ratio = app.logo_ratio
app.texture = app.logo_texture app.texture = app.logo_texture
app.sampler = app.logo_sampler
println('INIT DONE!') println('INIT DONE!')
@ -383,7 +395,7 @@ fn frame(mut app App) {
// enable our pipeline // enable our pipeline
sgl.load_pipeline(app.pip_viewer) sgl.load_pipeline(app.pip_viewer)
sgl.enable_texture() sgl.enable_texture()
sgl.texture(app.texture) sgl.texture(app.texture, app.sampler)
// translation // translation
tr_x := app.tr_x / app.img_w tr_x := app.tr_x / app.img_w

View file

@ -47,7 +47,7 @@ fn (mut il Item_list) scan_zip(path string, in_index int) ! {
zp.close() zp.close()
} }
fn (mut app App) load_texture_from_zip() !(gfx.Image, int, int) { fn (mut app App) load_texture_from_zip() !(gfx.Image, gfx.Sampler, int, int) {
item := app.item_list.lst[app.item_list.item_index] item := app.item_list.lst[app.item_list.item_index]
// println("Load from zip [${item.path}]") // println("Load from zip [${item.path}]")

View file

@ -21,6 +21,7 @@ pub mut:
ext string ext string
simg_ok bool simg_ok bool
simg gfx.Image simg gfx.Image
ssmp gfx.Sampler
path string path string
} }
@ -112,6 +113,16 @@ pub fn (mut img Image) init_sokol_image() &Image {
size: img_size size: img_size
} }
img.simg = gfx.make_image(&img_desc) img.simg = gfx.make_image(&img_desc)
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
img.ssmp = gfx.make_sampler(&smp_desc)
img.simg_ok = true img.simg_ok = true
img.ok = true img.ok = true
return img return img
@ -142,10 +153,6 @@ pub fn (mut ctx Context) new_streaming_image(w int, h int, channels int, sicfg S
num_slices: 1 num_slices: 1
num_mipmaps: 1 num_mipmaps: 1
usage: .stream usage: .stream
// wrap_u: sicfg.wrap_u // SAMPLER
// wrap_v: sicfg.wrap_v
// min_filter: sicfg.min_filter
// mag_filter: sicfg.mag_filter
label: img.path.str label: img.path.str
} }
// Sokol requires that streamed images have NO .ptr/.size initially: // Sokol requires that streamed images have NO .ptr/.size initially:
@ -154,6 +161,15 @@ pub fn (mut ctx Context) new_streaming_image(w int, h int, channels int, sicfg S
size: usize(0) size: usize(0)
} }
img.simg = gfx.make_image(&img_desc) img.simg = gfx.make_image(&img_desc)
mut smp_desc := gfx.SamplerDesc{
wrap_u: sicfg.wrap_u // SAMPLER
wrap_v: sicfg.wrap_v
min_filter: sicfg.min_filter
mag_filter: sicfg.mag_filter
}
img.ssmp = gfx.make_sampler(&smp_desc)
img.simg_ok = true img.simg_ok = true
img.ok = true img.ok = true
img_idx := ctx.cache_image(img) img_idx := ctx.cache_image(img)
@ -359,7 +375,7 @@ pub fn (ctx &Context) draw_image_with_config(config DrawImageConfig) {
} }
sgl.enable_texture() sgl.enable_texture()
sgl.texture(img.simg) sgl.texture(img.simg, img.ssmp)
if config.rotate != 0 { if config.rotate != 0 {
width := img_rect.width * ctx.scale width := img_rect.width * ctx.scale

View file

@ -50,6 +50,11 @@ pub fn make_image(desc &ImageDesc) Image {
return C.sg_make_image(desc) return C.sg_make_image(desc)
} }
[inline]
pub fn make_sampler(desc &SamplerDesc) Sampler {
return C.sg_make_sampler(desc)
}
[inline] [inline]
pub fn make_shader(desc &ShaderDesc) Shader { pub fn make_shader(desc &ShaderDesc) Shader {
return C.sg_make_shader(desc) return C.sg_make_shader(desc)
@ -75,6 +80,11 @@ pub fn destroy_image(img Image) {
C.sg_destroy_image(img) C.sg_destroy_image(img)
} }
[inline]
pub fn destroy_sampler(smp Sampler) {
C.sg_destroy_sampler(smp)
}
[inline] [inline]
pub fn destroy_shader(shd Shader) { pub fn destroy_shader(shd Shader) {
C.sg_destroy_shader(shd) C.sg_destroy_shader(shd)

View file

@ -113,18 +113,12 @@ pub mut:
vertex_buffer_offsets [8]int vertex_buffer_offsets [8]int
index_buffer Buffer index_buffer Buffer
index_buffer_offset int index_buffer_offset int
vs C.sg_stage_bindings vs StageBindings
fs C.sg_stage_bindings fs StageBindings
// vs_images [8]Image // old // vs_images [8]Image // old
// fs_images [8]Image // old // fs_images [8]Image // old
} }
pub struct C.sg_stage_bindings {
pub mut:
images [12]Image
samplers [8]Sampler
}
pub type Bindings = C.sg_bindings pub type Bindings = C.sg_bindings
pub fn (mut b Bindings) set_vert_image(index int, img Image) { pub fn (mut b Bindings) set_vert_image(index int, img Image) {
@ -167,6 +161,14 @@ pub fn (b &Bindings) append_index_buffer(data voidptr, element_size int, element
return C.sg_append_buffer(b.index_buffer, &range) return C.sg_append_buffer(b.index_buffer, &range)
} }
pub struct C.sg_stage_bindings {
pub mut:
images [12]Image
samplers [8]Sampler
}
pub type StageBindings = C.sg_stage_bindings
[heap] [heap]
struct C.sg_shader_desc { struct C.sg_shader_desc {
pub mut: pub mut:
@ -479,6 +481,8 @@ pub struct C.sg_sampler_desc {
wgpu_sampler voidptr wgpu_sampler voidptr
} }
pub type SamplerDesc = C.sg_sampler_desc
pub struct C.sg_image_info { pub struct C.sg_image_info {
pub mut: pub mut:
slot SlotInfo // resource pool slot info slot SlotInfo // resource pool slot info

View file

@ -122,8 +122,8 @@ pub fn disable_texture() {
} }
[inline] [inline]
pub fn texture(img gfx.Image) { pub fn texture(img gfx.Image, smp gfx.Sampler) {
C.sgl_texture(img, C.sg_sampler{}) // TODO need to pass SG_INVALID_ID ? C.sgl_texture(img, smp)
} }
// pipeline stack functions // pipeline stack functions

View file

@ -22,6 +22,7 @@ pub mut:
bmp &BitMap = unsafe { nil } // Base bitmap render bmp &BitMap = unsafe { nil } // Base bitmap render
// rendering fields // rendering fields
sg_img gfx.Image // sokol image sg_img gfx.Image // sokol image
sg_smp gfx.Sampler // sokol sampler
scale_reduct f32 = 2.0 // scale of the cpu texture for filtering scale_reduct f32 = 2.0 // scale of the cpu texture for filtering
device_dpi int = 72 // device DPI device_dpi int = 72 // device DPI
} }
@ -123,11 +124,7 @@ pub fn (mut tf_skl TTF_render_Sokol) create_texture() {
width: w width: w
height: h height: h
num_mipmaps: 0 num_mipmaps: 0
// min_filter: .linear
// mag_filter: .linear
// usage: .dynamic // usage: .dynamic
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
label: &char(0) label: &char(0)
d3d11_texture: 0 d3d11_texture: 0
} }
@ -139,11 +136,23 @@ pub fn (mut tf_skl TTF_render_Sokol) create_texture() {
simg := gfx.make_image(&img_desc) simg := gfx.make_image(&img_desc)
// free(tf_skl.bmp.buf) // DONT FREE IF Dynamic // free(tf_skl.bmp.buf) // DONT FREE IF Dynamic
mut smp_desc := gfx.SamplerDesc{
min_filter: .linear
mag_filter: .linear
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
}
ssmp := gfx.make_sampler(&smp_desc)
tf_skl.sg_img = simg tf_skl.sg_img = simg
tf_skl.sg_smp = ssmp
} }
pub fn (tf_skl TTF_render_Sokol) destroy_texture() { pub fn (tf_skl TTF_render_Sokol) destroy_texture() {
gfx.destroy_image(tf_skl.sg_img) gfx.destroy_image(tf_skl.sg_img)
gfx.destroy_sampler(tf_skl.sg_smp)
} }
// Use only if usage: .dynamic // Use only if usage: .dynamic
@ -198,7 +207,7 @@ pub fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) {
// //
sgl.load_pipeline(ctx.pipeline.alpha) sgl.load_pipeline(ctx.pipeline.alpha)
sgl.enable_texture() sgl.enable_texture()
sgl.texture(tf_skl.sg_img) sgl.texture(tf_skl.sg_img, tf_skl.sg_smp)
sgl.begin_quads() sgl.begin_quads()
sgl.c4b(255, 255, 255, 255) sgl.c4b(255, 255, 255, 255)
sgl.v2f_t2f(x0, y0, u0, v0) sgl.v2f_t2f(x0, y0, u0, v0)