Forum

Source code for the Screenshot (EX9.Texture)

devvvv

#1

heyho! Is there a source code for the Screenshot (EX9.Texture) node? I’d like to port it to DX11 preferably until saturday. I’ve already put together something based on the dx11 DynamicTexture and a device context approach but it’s unusably slow currently. (probably because i have only vague idea about what i’m doing)
here’s what i’ve done so far but be aware it may freeze your vvvv or make it unoparably slow.

this is the crappy version (94.7 kB)


Screenshot Texture DX11 any news?
#2

its probably faster to use a screen cast tool which you can read with VideoIn as a webcam. ManyCam for instance, the free version works but has a watermark…


#3

nah that’s not an option here. i don’t want to loose the speed of the screenshot native node. currently my workaround is to share the EX9 texture and get it from FromSharedTexture (DX11.Texture 2d) but that’s pure luck if it works or not.


#4

also videoin on dx11 still on beta-test


#5

screenshot > asImage (opencv) > asTexture (DX11) ?


#6

@sebl: hmm that’s not a bad idea!


#7

maybe one could easily code a dx9todx11 node with the ImagePack


#8

there’s one tiny problem though: there’s no such thing as AsImage from EX9 texture. there’s a workaround though to get the shared ex9 texture in the dynamic plugin


#9

ai micro, i am not sure if it will actually help you, but this should be the relevant code:

procedure TMex9ScreenshotNode.UpdateTextureCB(texture: TMex9Texture; 
    devicetexture: TMex9DynamicDeviceTexture; Slice: Integer);
var
  hr: HResult;
  good: Boolean;
  sTarget: IDirect3DSurface9;
  sR: TRect;
  tDC, sDC: HDC;
  r: TRect;
  MrCursor: TIcon;
  IconInfo: TIconInfo;
  canvas: TCanvas;
  h: HWND;
begin
  h := FHandlePin.AsPositiveInteger0[Slice](Slice);

  good := GetShotRect(Slice, r);

  if good then
  begin
    case FModePin[Slice](Slice) of
    ord(ssmWindowAreaOfHandle), ord(ssmWindowOfHandle): sDC := GetWindowDC(h);
    ord(ssmClientAreaOfHandle), ord(ssmClientOfHandle): sDC := GetDC(h);
    ord(ssmRectangle): sDC := GetDC(0); //desktop
    end;

    try
      hr := devicetexture.TextureI.GetSurfaceLevel(0, sTarget);
      hr := sTarget.GetDC(tDC);

      case FModePin[Slice](Slice) of
      0, 1: BitBlt(tDC, 0, 0, r.right, r.bottom, sDC, 0, 0, SRCCOPY);
      2: BitBlt(tDC, 0, 0, r.right, r.bottom, sDC, r.left, r.top, SRCCOPY);
      3:
      begin
        //todo: send message to all controls recursivly
        //SendMessage(FHandle.AsPositiveInteger0[i](i), WM_ERASEBKGND, Integer(tDC), 0);
        //SendMessage(FHandle.AsPositiveInteger0[i](i), WM_PAINT, Integer(tDC), 0);
        SendMessage(h, WM_PRINT, tDC, PRF_CHILDREN + PRF_CLIENT + PRF_ERASEBKGND + PRF_NONCLIENT + PRF_OWNED);
      end;
      4:
      begin
        //todo: send message to all controls recursivly
        SendMessage(h, WM_PRINTCLIENT, tDC, PRF_CHILDREN + PRF_CLIENT + PRF_ERASEBKGND + PRF_OWNED);
      end;
      end;

      ReleaseDC(h, sDC);

      if FShowCursorPin.AsBool[Slice](Slice) then
      begin
        MrCursor := TIcon.Create;
        MrCursor.Width := GetSystemMetrics(SM_CXCURSOR);
        MrCursor.Height := GetSystemMetrics(SM_CYCURSOR);
        try
          MrCursor.Handle := GetCursorHandle; // GetCursor;

          if MrCursor.Handle > 0 then
          begin
            GetIconInfo(MrCursor.Handle, IconInfo);
            //Draw the Cursor on the bitmap
            canvas := TCanvas.Create;
            canvas.handle := tDC;
            canvas.Draw(Mouse.CursorPos.X - IconInfo.xHotspot - r.Left, Mouse.CursorPos.Y - IconInfo.yHotspot - r.Top, MrCursor);
            canvas.Free;
          end;
        finally
          // Clean up
          MrCursor.ReleaseHandle;
          MrCursor.Free;
          DeleteObject(IconInfo.hbmMask);
          DeleteObject(IconInfo.hbmColor);
        end;
      end;
    finally
      sTarget.ReleaseDC(tDC);
      sTarget := nil;
    end;
  end;
end;

#10

thanks joreg! this is definitely progress. if i understood well this code releases the device context every frame too so that should be alright with my stuff as well, what is kind of unclear now is that how its data is copied to the output texture. mine is of course extremely slow (getting the captured bitmap pixel-by-pixel and do a dynamic texture) but i cannot see any bitmap or lower-level dataformat related stuff here.


#11

copy the bitmap pixel by pixel is not a good idea, you should use memcopy functions which copy a whole memory area. you can use this method: pluginspecs/html/M_VVVV_Utils_SlimDX_TextureUtils_CopyBitmapToTexture.htm


#12

in the code above thats the BitBlt call. not sure if it is available as such in c#.