aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/gg/image.c.v
diff options
context:
space:
mode:
authorIndrajith K L2022-12-03 17:00:20 +0530
committerIndrajith K L2022-12-03 17:00:20 +0530
commitf5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch)
tree2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/vlib/gg/image.c.v
downloadcli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.gz
cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.bz2
cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.zip
Adds most of the toolsHEADmaster
Diffstat (limited to 'v_windows/v/vlib/gg/image.c.v')
-rw-r--r--v_windows/v/vlib/gg/image.c.v169
1 files changed, 169 insertions, 0 deletions
diff --git a/v_windows/v/vlib/gg/image.c.v b/v_windows/v/vlib/gg/image.c.v
new file mode 100644
index 0000000..352eac4
--- /dev/null
+++ b/v_windows/v/vlib/gg/image.c.v
@@ -0,0 +1,169 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
+module gg
+
+import os
+import stbi
+import sokol.gfx
+
+fn C.sg_isvalid() bool
+
+// TODO return ?Image
+pub fn (mut ctx Context) create_image(file string) Image {
+ // println('\ncreate_image("$file")')
+ if !os.exists(file) {
+ return Image{}
+ }
+ $if macos {
+ if ctx.native_rendering {
+ // return C.darwin_create_image(file)
+ mut img := C.darwin_create_image(file)
+ // println('created macos image: $img.path w=$img.width')
+ // C.printf('p = %p\n', img.data)
+ img.id = ctx.image_cache.len
+ ctx.image_cache << img
+ return img
+ }
+ }
+ if !C.sg_isvalid() {
+ // Sokol is not initialized yet, add stbi object to a queue/cache
+ // ctx.image_queue << file
+ stb_img := stbi.load(file) or { return Image{} }
+ img := Image{
+ width: stb_img.width
+ height: stb_img.height
+ nr_channels: stb_img.nr_channels
+ ok: false
+ data: stb_img.data
+ ext: stb_img.ext
+ path: file
+ id: ctx.image_cache.len
+ }
+ ctx.image_cache << img
+ return img
+ }
+ mut img := create_image(file)
+ img.id = ctx.image_cache.len
+ ctx.image_cache << img
+ return img
+}
+
+pub fn (mut img Image) init_sokol_image() &Image {
+ // println('\n init sokol image $img.path ok=$img.simg_ok')
+ mut img_desc := C.sg_image_desc{
+ width: img.width
+ height: img.height
+ num_mipmaps: 0
+ wrap_u: .clamp_to_edge
+ wrap_v: .clamp_to_edge
+ label: img.path.str
+ d3d11_texture: 0
+ }
+ img_desc.data.subimage[0][0] = C.sg_range{
+ ptr: img.data
+ size: size_t(img.nr_channels * img.width * img.height)
+ }
+ img.simg = C.sg_make_image(&img_desc)
+ img.simg_ok = true
+ img.ok = true
+ return img
+}
+
+// draw_image draws the provided image onto the screen
+pub fn (ctx &Context) draw_image(x f32, y f32, width f32, height f32, img_ &Image) {
+ $if macos {
+ if img_.id >= ctx.image_cache.len {
+ eprintln('gg: draw_image() bad img id $img_.id (img cache len = $ctx.image_cache.len)')
+ return
+ }
+ if ctx.native_rendering {
+ if img_.width == 0 {
+ return
+ }
+ if !os.exists(img_.path) {
+ return
+ }
+ C.darwin_draw_image(x, ctx.height - (y + height), width, height, img_)
+ return
+ }
+ }
+
+ ctx.draw_image_with_config(
+ img: img_
+ img_rect: Rect{x, y, width, height}
+ part_rect: Rect{0, 0, img_.width, img_.height}
+ )
+}
+
+// new_streaming_image returns a cached `image_idx` of a special image, that
+// can be updated *each frame* by calling: gg.update_pixel_data(image_idx, buf)
+// ... where buf is a pointer to the actual pixel data for the image.
+// NB: you still need to call app.gg.draw_image after that, to actually draw it.
+pub fn (mut ctx Context) new_streaming_image(w int, h int, channels int, sicfg StreamingImageConfig) int {
+ mut img := Image{}
+ img.width = w
+ img.height = h
+ img.nr_channels = channels // 4 bytes per pixel for .rgba8, see pixel_format
+ mut img_desc := C.sg_image_desc{
+ width: img.width
+ height: img.height
+ pixel_format: sicfg.pixel_format
+ num_slices: 1
+ num_mipmaps: 1
+ usage: .stream
+ wrap_u: sicfg.wrap_u
+ wrap_v: sicfg.wrap_v
+ min_filter: sicfg.min_filter
+ mag_filter: sicfg.mag_filter
+ label: img.path.str
+ }
+ // Sokol requires that streamed images have NO .ptr/.size initially:
+ img_desc.data.subimage[0][0] = C.sg_range{
+ ptr: 0
+ size: size_t(0)
+ }
+ img.simg = C.sg_make_image(&img_desc)
+ img.simg_ok = true
+ img.ok = true
+ img_idx := ctx.cache_image(img)
+ return img_idx
+}
+
+// update_pixel_data is a helper for working with image streams (i.e. images,
+// that are updated dynamically by the CPU on each frame)
+pub fn (mut ctx Context) update_pixel_data(cached_image_idx int, buf &byte) {
+ mut image := ctx.get_cached_image_by_idx(cached_image_idx)
+ image.update_pixel_data(buf)
+}
+
+pub fn (mut img Image) update_pixel_data(buf &byte) {
+ mut data := C.sg_image_data{}
+ data.subimage[0][0].ptr = buf
+ data.subimage[0][0].size = size_t(img.width * img.height * img.nr_channels)
+ gfx.update_image(img.simg, &data)
+}
+
+// TODO copypasta
+pub fn (mut ctx Context) create_image_with_size(file string, width int, height int) Image {
+ if !C.sg_isvalid() {
+ // Sokol is not initialized yet, add stbi object to a queue/cache
+ // ctx.image_queue << file
+ stb_img := stbi.load(file) or { return Image{} }
+ img := Image{
+ width: width
+ height: height
+ nr_channels: stb_img.nr_channels
+ ok: false
+ data: stb_img.data
+ ext: stb_img.ext
+ path: file
+ id: ctx.image_cache.len
+ }
+ ctx.image_cache << img
+ return img
+ }
+ mut img := create_image(file)
+ img.id = ctx.image_cache.len
+ ctx.image_cache << img
+ return img
+}