-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image loading with stbi+gfx not working properly (Throwing unhandled exception) #16670
Comments
I suggested That commit corresponds to #16564 |
Probably also related #16754 We have situation were the amount of channels ( |
If I'm not mistaken, |
More info: nothings/stb#335 (comment). If the stbi folks are correct the data returned from Also note the |
@MightyPancake - what pixel format does your graphics pipeline use (the pipeline in which context you're loading the image)? |
btw, https://github.com/nothings/stb/blob/master/stb_image.h is already on v2.27, it may be a good idea to update our copy as well. Unlike some other thirdparty libraries, they are usually very careful to not make breaking API changes, so it should be relatively painless. edit: done in #16825 |
Is this still an issue with current V? Without a complete working example, I can't test... |
Reports have been in the few and very unclear / hard to reproduce since #16564 - I think we can close this. At least until we have something concrete, code to test against |
I have once again run into this issue -- I am just trying to render a square with a texture on it and I am getting an assertion issue: It seems like my image is loading properly (as I am printing out the result):
Here is my code, it is largely adapted from the sokol examples. // Copyright(C) 2022 Lars Pontoppidan. All rights reserved.
// Use of this source code is governed by an MIT license file distributed with this software package
module main
// Example shader triangle adapted to V from https://github.com/floooh/sokol-samples/blob/1f2ad36/sapp/triangle-sapp.c
import sokol.sapp
import sokol.gfx
import gg
import stbi
// Use `v shader` or `sokol-shdc` to generate the necessary `.h` file
// Using `v shader -v .` in this directory will show some additional
// info - and what you should include to make things work.
#include "@VMODROOT/simple_shader.h" # # It should be generated with `v shader .`
// simple_shader_desc is a C function declaration defined by
// the `@program` entry in the `simple_shader.glsl` shader file.
// When the shader is compiled this function name is generated
// by the shader compiler for easier inclusion of universal shader code
// in C (and V) code.
fn C.simple_shader_desc(gfx.Backend) &gfx.ShaderDesc
// Vertex_t makes it possible to model vertex buffer data
// for use with the shader system
struct Vertex_t {
// Position
x f32
y f32
z f32
// Color
r f32
g f32
b f32
a f32
// uv
u f32
v f32
}
//
//
//
fn create_texture(imgpath string) (gfx.Image, gfx.Sampler) {
data := stbi.load(imgpath, stbi.LoadParams{}) or {
println('Failed to load image')
panic(err)
}
println(data)
mut img_desc := gfx.ImageDesc{
width: data.width
height: data.height
pixel_format: .rgba8
num_mipmaps: 0
// wrap_u: .clamp_to_edge
// wrap_v: .clamp_to_edge
// min_filter: .linear
// max_filter: .linear
// usage: .dynamic
label: &u8(0)
d3d11_texture: 0
}
//println(tymeof(data.data[0]))
// comment if .dynamic is enabled
img_desc.data.subimage[0][0] = gfx.Range{
ptr: data.data
size: usize(data.width * data.height * 4)
}
println(img_desc)
sg_img := gfx.make_image(&img_desc)
//println(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) {
gfx.destroy_image(sg_img)
}
//
//
//
fn main() {
mut app := &App{
width: 800
height: 400
pass_action: gfx.create_clear_pass_action(0.0, 0.0, 0.0, 1.0) // This will create a black color as a default pass (window background color)
}
app.run()
}
struct App {
pass_action gfx.PassAction
mut:
width int
height int
texture gfx.Image
sampler gfx.Sampler
shader_pipeline gfx.Pipeline
bind gfx.Bindings
}
fn (mut a App) run() {
title := 'V Simple Shader Example'
desc := sapp.Desc{
width: a.width
height: a.height
user_data: a
init_userdata_cb: init
frame_userdata_cb: frame
window_title: title.str
html5_canvas_name: title.str
cleanup_userdata_cb: cleanup
sample_count: 4 // Enables MSAA (Multisample anti-aliasing) x4 on rendered output, this can be omitted.
}
sapp.run(&desc)
}
fn init(user_data voidptr) {
mut app := unsafe { &App(user_data) }
mut desc := sapp.create_desc()
app.texture, app.sampler = create_texture('testimg.png')
gfx.setup(&desc)
vertices := [
Vertex_t{-0.5, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0},
Vertex_t{0.5, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0},
Vertex_t{-0.5, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0},
Vertex_t{0.5, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0},
]
indices := [
u16(0),
3,
1,
0,
1,
2,
]
mut vertex_buffer_desc := gfx.BufferDesc{
label: c'triangle-vertices'
}
unsafe { vmemset(&vertex_buffer_desc, 0, int(sizeof(vertex_buffer_desc))) }
vertex_buffer_desc.size = usize(vertices.len * int(sizeof(Vertex_t)))
vertex_buffer_desc.data = gfx.Range{
ptr: vertices.data
size: vertex_buffer_desc.size
}
app.bind.vertex_buffers[0] = gfx.make_buffer(&vertex_buffer_desc)
mut index_buffer_desc := gfx.BufferDesc{
label: c'triangle-indices'
}
unsafe { vmemset(&index_buffer_desc, 0, int(sizeof(index_buffer_desc))) }
index_buffer_desc.size = usize(indices.len * int(sizeof(u16)))
index_buffer_desc.@type = .indexbuffer
index_buffer_desc.data = gfx.Range{
ptr: indices.data
size: index_buffer_desc.size
}
app.bind.index_buffer = gfx.make_buffer(&index_buffer_desc)
app.bind.fs.images[C.SLOT_tex] = app.texture
app.bind.fs.samplers[C.SLOT_smp] = app.sampler
shader := gfx.make_shader(C.simple_shader_desc(gfx.query_backend()))
mut pipeline_desc := gfx.PipelineDesc{}
unsafe { vmemset(&pipeline_desc, 0, int(sizeof(pipeline_desc))) }
pipeline_desc.shader = shader
pipeline_desc.layout.attrs[C.ATTR_vs_position].format = .float3
pipeline_desc.layout.attrs[C.ATTR_vs_color0].format = .float4
pipeline_desc.layout.attrs[C.ATTR_vs_texcoord].format = .float2
pipeline_desc.index_type = .uint16
pipeline_desc.label = c'triangle-pipeline'
app.shader_pipeline = gfx.make_pipeline(&pipeline_desc)
}
fn cleanup(user_data voidptr) {
gfx.shutdown()
}
fn frame(user_data voidptr) {
mut app := unsafe { &App(user_data) }
pass := sapp.create_default_pass(app.pass_action)
gfx.begin_pass(&pass)
gfx.apply_pipeline(app.shader_pipeline)
gfx.apply_bindings(&app.bind)
gfx.draw(0, 6, 1)
gfx.end_pass()
gfx.commit()
} and below is my shader code, which is also fairly basic. // The following defines a vertex shader main function
@vs vs
in vec4 position;
in vec4 color0;
in vec2 texcoord;
out vec4 color;
out vec2 uv;
// You can add more functions here
void main() {
gl_Position = position;
color = color0;
uv = texcoord;
}
@end
// The following defines a fragment shader main function
@fs fs
uniform texture2D tex;
uniform sampler smp;
in vec4 color;
in vec2 uv;
out vec4 frag_color;
// You can add more functions here
void main() {
//frag_color = color;
frag_color= texture(sampler2D(tex, smp), uv);
}
@end
// The value after `@program` and before `vs fs` decide a part of the name
// of the C function you need to define in V. The value entered is suffixed `_shader_desc`
// in the generated C code. Thus the name for this becomes: `simple_shader_desc`.
// In V it's signature then need to be defined as:
// `fn C.simple_shader_desc(gfx.Backend) &gfx.ShaderDesc`. See `simple_shader.v` for the define.
//
// Running `v shader -v .` in this dir will also show you brief information
// about how to use the compiled shader.
@program simple vs fs There seem to be no resources to help with this and I am completely lost. Any help is appreciated. |
Here's what I get when I try
of course, that's because no image was supplied to test with. So, I copied the image from the original comment, and saved it as When I ran it again, I got this output in the console
|
This should be it's own fresh issue, not a reopening IMO |
Describe the bug
Adding an image with stbi in the following (correct?) way is not working in this version.
The issue is related to the size of the image/data given and expected to sokol.gfx.
Here's the image I tried to load (although, I tried a few others; all of them didn't work)
in
Expected Behavior
The image should load correctly.
Current Behavior
The program crashes on this function call with a valid image path.
Reproduction Steps
Possible Solution
I noticed that in the
gg
implementation it's stated that the value for size should be: 4 * width * height, however, doing so makes crashes the program. This is possibly due to Sokol trying to read bytes that are out of range of the pointer (array) returned by stbi.A workaround for this might be just creating a more extensive array and pasting the content fetched from stbi while leaving the rest of the array
zeroed
. That's a waste of space, but it might work :)Additional Information/Context
This code worked a couple of months ago (4?)
@spytheman On discord advised reverting my V locally to
6e24f7e
, which fixed the issue, so something fishy probably happened after that commit.V version
V 0.3.2 69f7c45
Environment details (OS name and version, etc.)
Windows 11
The text was updated successfully, but these errors were encountered: