processing-video icon indicating copy to clipboard operation
processing-video copied to clipboard

Can't capture webcam pixel when switch to P3D, everything turns black

Open fairwelljack opened this issue 3 years ago • 7 comments

Hi, I encountered this in Processing video. I was following an old tutorial about 2018 step by step. The instructor had not encountered the same issue. Everything works fine on their end. Everthing works fine in 2D, size(800,600); while drawing rectangles using webcam pixels to fill the color

Cam Capture Pixel issue 01

when use size(800,600,P3D), to draw boxes, everything turns black, looks like it cannot catch the correct pixel[] in P3D. Cam Capture Pixel issue 02

here is the code

import processing.video.*;

Capture cam;

void setup(){
  background(255);
  size(800,600,P3D);
  cam = new Capture(this);
  cam.start();
}

void draw(){
  cam.loadPixels();
  int pixelSize = 50; 
  for (int y = 0; y < cam.height; y += pixelSize){
    for( int x = 0; x < cam.width; x += pixelSize){
       int camPixelPos = y * cam.width + x;
       color pixelCol = cam.pixels[camPixelPos];
       fill(pixelCol);
       
       pushMatrix();
       translate(x,y,0);
       box(pixelSize);
       popMatrix();
       
       //rect(x,y,pixelSize,pixelSize);
    }
  }
}

void captureEvent(Capture c){
  c.read();
}

fairwelljack avatar Oct 03 '22 23:10 fairwelljack

here's some screenshot to explain this bug. I only changed to P3D in size. When it changes to P3D, it only returns -16777216 in the console when i print pixelCol by using .pixel[] capture pixel issue 01 capture pixel issue 02

fairwelljack avatar Oct 04 '22 07:10 fairwelljack

Not fixed with video library 2.2.2

ajavamind avatar Jan 16 '23 16:01 ajavamind

I just tested and can also confirm the bug on Windows 11 with the latest Processing & Processing Video lib

cacheflowe avatar Jan 17 '23 21:01 cacheflowe

try to add this in draw(). image(cam,0,0,0,0);

I tested video library in P2D, P3D mode, there are some problems with getting pixels.(and found workaround)

  1. can't get pixel
color c = cam.get(x,y); 
fill(c);
rect(0,0,10,10); // just black only

add image()

color c = cam.get(x,y);
fill(c);
rect(0,0,10,10); 
image(cam,0,0,0,0);

I guess problem is in Capture.java(and Movie.java)

  public synchronized void read() {
    if (firstFrame) {
      super.init(sourceWidth, sourceHeight, RGB, 1);
      firstFrame = false;
    }
    if (useBufferSink) {
      if (bufferSink == null) {
        Object cache = parent.g.getCache(Capture.this); // can't get cache(texture) until call image() or texture()
        if (cache != null) {
          setBufferSink(cache);
          getSinkMethods();
  1. slow frame rate when get pixels and display image.
cam.loadPixels();
...
image(cam,0,0); // very slow frame rate

add updatePixels()

cam.loadPixels();
cam.updatePixels();  
...
image(cam,0,0); // ok

Processing 4.1.1 / Video library 2.2.2 / MacBook Pro m1

jaegonlee avatar Jan 18 '23 10:01 jaegonlee

Thanks jaegonlee! Nice work. Your work around fixed the problem for me using Windows 11. I tested it with a modified version of the Video library example "Mirror" with renderers P2D and P3D. Processing 4.1.1 / Video library 2.2.2 / Windows 11 AMD Ryzen 7 PRO 4750G with Radeon Graphics 3.60 GHz Also works with Processing 3.5.4

ajavamind avatar Jan 18 '23 18:01 ajavamind

Update: This does not work with captureEvent() or movieEvent()

~~I found the ways to fix it. In Capture.java(and Movie.java), replace~~ Object cache = parent.g.getCache(Capture.this);

to

import processing.opengl.PGraphicsOpenGL;
...
Object cache = ((PGraphicsOpenGL)(parent.g)).getTexture(Capture.this);

or

Object cache = null;
try {
  Method m = parent.g.getClass().getMethod("getTexture", new Class[] { PImage.class });
  cache = m.invoke(parent.g, new Object[] { Capture.this });
}
catch (Exception e) {
  e.printStackTrace();
}

jaegonlee avatar Jan 24 '23 06:01 jaegonlee

Related to #203

Asmatzaile avatar Feb 22 '23 15:02 Asmatzaile