vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.77k stars 2.16k forks source link

gg.update_pixel_data() empty buffer still draws #10989

Open benstigsen opened 3 years ago

benstigsen commented 3 years ago

What did you do? Created an empty byte buffer, then I used that buffer on a streaming image with gg.update_pixel_data()

What did you expect to see? A black screen

What did you see instead? Some red pixels

Here's a full example:

module main

import gg

const (
  win_width  = 100
  win_height = 100
)

struct App {
mut:
  gg    &gg.Context
  image int // Will contain the image id
}

[console]
fn main() {
  mut app := &App{gg: 0}

  app.gg = gg.new_context(
    width: win_width
    height: win_height
    window_title: 'image buffer test'
    frame_fn: frame
    user_data: app
    init_fn: initialize
  )

  app.gg.run()
}

fn initialize(mut app App) {
  // 10x10 empty image bufffer
  buffer := [
    byte(0),0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  ]

  app.image = app.gg.new_streaming_image(10, 10, 1, gg.StreamingImageConfig{pixel_format: .r8})
  app.gg.update_pixel_data(app.image, buffer.data) // Update with empty buffer
}

fn frame(mut app App) {
  app.gg.begin()
  app.gg.draw_image_by_id(0, 0, 10, 10, app.image)
  app.gg.end()
}

This creates an empty byte buffer of size 10x10. Then we create a streaming image, where we update the pixel data of this image with the empty pixel buffer. But for some reason, even though the image was updated with an empty pixel buffer, it still draws some red pixels.

benstigsen commented 3 years ago

We found that if the streaming image and buffer was a multiple of 4 in size, then it would not draw random pixels. Why it would have to be a multiple of 4 I do not understand though. Here's an example where random pixels aren't being drawn, the only change is the buffer size is now 12x12:

module main

import gg

const (
  win_width  = 100
  win_height = 100
)

struct App {
mut:
  gg    &gg.Context
  image int // Will contain the image id
}

[console]
fn main() {
  mut app := &App{gg: 0}

  app.gg = gg.new_context(
    width: win_width
    height: win_height
    window_title: 'image buffer test'
    frame_fn: frame
    user_data: app
    init_fn: initialize
  )

  app.gg.run()
}

fn initialize(mut app App) {
  // 12x12
  buffer := [
    byte(0),0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  ]

  app.image = app.gg.new_streaming_image(12, 12, 1, gg.StreamingImageConfig{pixel_format: .r8})
  app.gg.update_pixel_data(app.image, buffer.data) // Update with empty buffer
}

fn frame(mut app App) {
  app.gg.begin()
  app.gg.draw_image_by_id(0, 0, 12, 12, app.image)
  app.gg.end()
}