Sprite3D Description and Structures, where?

Just starting out? Need help? Post your questions and find answers here.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Sprite3D Description and Structures, where?

Post by Shannara »

The newest description of the Sprite3D lib and its structures
should be in the PB Library SDK.
You have to rewrite the code every time the PB lib internals
change.
Anybody know where to find them? They are not in the newest PB 3.92 release.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Re: Sprite3D Description and Structures, where?

Post by traumatic »

isn't this up to date?

Code: Select all

  _PB_Sprite3D_ObjectsNumber
  _PB_Sprite3D_ObjectsArea
  _PB_Sprite3D_CurrentDC
  

  Structure PB_Sprite3D
  	Texture.l              ; DirectX7 surface
  	Vertice.D3DTLVERTEX[4] ; The 4 vertices for the rectangle sprite
  	Width.w
  	Height.w
  EndStructure
Good programmers don't comment their code. It was hard to write, should be hard to read.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

According to Danilo it is not up to date.

Quote from the PM I recieved from him when referencing his TransformSprite3D command :
Shannara wrote:
Ref: viewtopic.php?t=8938&highlight=

I have downloaded the newest sample on the bottom of the thread. Unfortunately, the code provided is not the code used to compile the EXE. The EXE works perfectly, but the code (when executed and/or compiled) only shows a blank texture.

It was the same code for the EXE, but the code is old and
the compiler (and PB libs in this case) have changed.

Shannara wrote:
Any way you could upload the correct code?

I dont use PB anymore, so you have to figure it out yourself.

The newest description of the Sprite3D lib and its structures
should be in the PB Library SDK.
You have to rewrite the code every time the PB lib internals
change.

_________________
cya,
...Danilo
...:-=< PureTools 0.21 >=-:...
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

So it is now safe to assume the new structures and descriptions of libraries are no longer available to PB users?
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

Hi Shannara

Fred changed the Structure PB_Sprite3D. :?
Now the structure is bigger.

Code: Select all

Structure PB_Sprite3D
Texture.l              ; DirectX7 surface
Vertice.D3DTLVERTEX[4] ; The 4 vertices for the rectangle sprite
Width.w   
Height.w
unknown.l 
EndStructure

I changed Danilos code so that it works now with PureBasic 3.92:

Code: Select all

;
; PB Sprite3D Special Effects
;
; by Danilo, 02.01.2004
;
; greetings to Ypser for the basic version
; that showed the wrong tranformation
;

!extrn _PB_3DViewPort
!extrn _PB_D3DBase
;!extrn _PB_Direct3D_Device
!extrn _PB_Direct3D_Start3DState
!extrn _PB_Sprite3D_ListFirstElement
!extrn _PB_Sprite3D_Quality
!extrn _PB_Sprite3D_ObjectsNumber
;!extrn _PB_Sprite3D_ObjectsArea
!extrn _PB_Sprite3D_CurrentDC


If InitSprite()=0 Or InitSprite3D()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Cant init DirectX !",#MB_ICONERROR)
EndIf

DisableDebugger

Procedure GetD3Ddevice_interface()
  Shared D3Ddevice_interface.IDirect3DDevice7
  ; Fill Interface variable
  !extrn _PB_Direct3D_Device
  !MOV dword EAX, [_PB_Direct3D_Device]
  !MOV dword [v_D3Ddevice_interface],EAX
  ProcedureReturn
EndProcedure

#D3DRENDERSTATE_CULLMODE = 22

#D3DCULL_NONE            = $1
#D3DCULL_CW              = $2
#D3DCULL_CCW             = $3
#D3DCULL_FORCE_DWORD     = $7FFFFFFF

Procedure Setrenderstate(a,b)
  Shared D3Ddevice_interface.IDirect3DDevice7
  If D3Ddevice_interface.IDirect3DDevice7=0
    GetD3Ddevice_interface()
  EndIf
  D3Ddevice_interface\Setrenderstate(a,b)
EndProcedure


Structure D3DTLVERTEX
  StructureUnion      ; Screen coordinates
    sx.f
    dvSX.f
  EndStructureUnion
  StructureUnion
    sy.f
    dvSY.f
  EndStructureUnion
  StructureUnion
    sz.f
    dvSZ.f
  EndStructureUnion
  StructureUnion      ; Reciprocal of homogeneous w
    rhw.f
    dvRHW.f
  EndStructureUnion
  StructureUnion      ; Vertex color
    color.l
    dcColor.l
  EndStructureUnion
  StructureUnion      ; Specular component of vertex
    specular.l
    dcSpecular.l
  EndStructureUnion
  StructureUnion      ; Texture coordinates
    tu.f
    dvTU.f
  EndStructureUnion
  StructureUnion
    tv.f
    dvTV.f
  EndStructureUnion
EndStructure

Structure PB_Sprite3D
  Texture.l              ; DirectX7 surface
  Vertice.D3DTLVERTEX[4] ; The 4 vertices for the rectangle sprite
  Width.w   
  Height.w
  unknown.l 
EndStructure


Procedure Display3DObject(sprite)
  *p.PB_Sprite3D
  !extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,140 ; sizeof(PB_Sprite3D)
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+4],EBX
  
  StartDrawing(ScreenOutput())
  DrawingMode(1):FrontColor($FF,$FF,$00)
  DrawingFont(UseFont(1))
  Locate(100,320):DrawText("Texture: "+StrU(*p\Texture,#Long))
  Locate(300,320):DrawText("Width: "+StrU(*p\Width&$FFFF,#Word))
  Locate(450,320):DrawText("Height: "+StrU(*p\Height&$FFFF,#Word))
  
  Locate(100,350):DrawText("X:        "+StrF(*p\Vertice[0]\sx,2))
  Locate(100,365):DrawText("Y:        "+StrF(*p\Vertice[0]\sy,2))
  Locate(100,380):DrawText("Z:        "+StrF(*p\Vertice[0]\sz,2))
  Locate(100,395):DrawText("rhw:      "+StrF(*p\Vertice[0]\rhw,2))
  Locate(100,410):DrawText("color:    "+Hex( *p\Vertice[0]\color))
  Locate(100,425):DrawText("specular: "+Hex( *p\Vertice[0]\specular))
  Locate(100,440):DrawText("tu :      "+StrF(*p\Vertice[0]\tu,2))
  Locate(100,455):DrawText("tv :      "+StrF(*p\Vertice[0]\tv,2))
  
  Locate(500,350):DrawText("X:        "+StrF(*p\Vertice[1]\sx,2))
  Locate(500,365):DrawText("Y:        "+StrF(*p\Vertice[1]\sy,2))
  Locate(500,380):DrawText("Z:        "+StrF(*p\Vertice[1]\sz,2))
  Locate(500,395):DrawText("rhw:      "+StrF(*p\Vertice[1]\rhw,2))
  Locate(500,410):DrawText("color:    "+Hex( *p\Vertice[1]\color))
  Locate(500,425):DrawText("specular: "+Hex( *p\Vertice[1]\specular))
  Locate(500,440):DrawText("tu :      "+StrF(*p\Vertice[1]\tu,2))
  Locate(500,455):DrawText("tv :      "+StrF(*p\Vertice[1]\tv,2))
  
  Locate(100,485):DrawText("X:        "+StrF(*p\Vertice[2]\sx,2))
  Locate(100,500):DrawText("Y:        "+StrF(*p\Vertice[2]\sy,2))
  Locate(100,515):DrawText("Z:        "+StrF(*p\Vertice[2]\sz,2))
  Locate(100,530):DrawText("rhw:      "+StrF(*p\Vertice[2]\rhw,2))
  Locate(100,545):DrawText("color:    "+Hex( *p\Vertice[2]\color))
  Locate(100,560):DrawText("specular: "+Hex( *p\Vertice[2]\specular))
  Locate(100,575):DrawText("tu :      "+StrF(*p\Vertice[2]\tu,2))
  Locate(100,590):DrawText("tv :      "+StrF(*p\Vertice[2]\tv,2))
  
  Locate(500,485):DrawText("X:        "+StrF(*p\Vertice[3]\sx,2))
  Locate(500,500):DrawText("Y:        "+StrF(*p\Vertice[3]\sy,2))
  Locate(500,515):DrawText("Z:        "+StrF(*p\Vertice[3]\sz,2))
  Locate(500,530):DrawText("rhw:      "+StrF(*p\Vertice[3]\rhw,2))
  Locate(500,545):DrawText("color:    "+Hex( *p\Vertice[3]\color))
  Locate(500,560):DrawText("specular: "+Hex( *p\Vertice[3]\specular))
  Locate(500,575):DrawText("tu :      "+StrF(*p\Vertice[3]\tu,2))
  Locate(500,590):DrawText("tv :      "+StrF(*p\Vertice[3]\tv,2))
  
  ;Debug StrU(*p\unknown,#Long)
  
  StopDrawing()
EndProcedure

Procedure CorrectSprite3D(sprite)
  *p.PB_Sprite3D
  ;!extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,140
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+4],EBX
  
  ; PB:
  ;
  ; 0,0
  ;  0     1
  ;
  ;
  ;  2     3
  ;
  ;
  ; dvRHW 
  ; Value of the D3DVALUE type that is the reciprocal
  ; of homogeneous w from homogeneous coordinates (x,y,z,w).
  ; This value is often 1 divided by the distance from the
  ; origin To the object along the z-axis. 
  
  ; X   = x / w
  ; Y   = y / w
  ; Z   = z / w
  ; RHW = 1 / w ; Distanz   des   Punktes zum    Bildschirm
  ;             ; Distance of the Point   to the Screen
  
  ; test
  ;  a.f =  (0 - *p\vertice[0]\sx) / (*p\Width/2)
  ;  *p\vertice[0]\rhw = 1.0 + a.f
  
  ; ok, works
  ;*p\vertice[0]\rhw = 1.0 - ((*p\vertice[0]\sx            + *p\vertice[0]\sy             + 

;*p\vertice[0]\sz)/(*p\Width/2))
  ;*p\vertice[1]\rhw = 1.0 + ((*p\vertice[1]\sx-*p\Width-1 + *p\vertice[1]\sy             + 

*p\vertice[1]\sz)/(*p\Width/2))
  ;*p\vertice[2]\rhw = 1.0 - ((*p\vertice[2]\sx            + *p\vertice[2]\sy-*p\Height-1 + 

;*p\vertice[2]\sz)/(*p\Width/2))
  ;*p\vertice[3]\rhw = 1.0 + ((*p\vertice[3]\sx-*p\Width-1 + *p\vertice[3]\sy-*p\Height-1 + 

;*p\vertice[3]\sz)/(*p\Width/2))
  
  ; z is always 0, can be removed
  *p\Vertice[0]\rhw = 1.0 - ((*p\Vertice[0]\sx            + *p\Vertice[0]\sy             )/(*p\Width/2))
  *p\Vertice[1]\rhw = 1.0 + ((*p\Vertice[1]\sx-*p\Width-1 + *p\Vertice[1]\sy             )/(*p\Width/2))
  *p\Vertice[2]\rhw = 1.0 - ((*p\Vertice[2]\sx            + *p\Vertice[2]\sy-*p\Height-1 )/(*p\Width/2))
  *p\Vertice[3]\rhw = 1.0 + ((*p\Vertice[3]\sx-*p\Width-1 + *p\Vertice[3]\sy-*p\Height-1 )/(*p\Width/2))
EndProcedure


Procedure SetSprite3DColor(sprite,a,b,c,d)
  ;
  ; set a color for the 4 Sprite3D corners
  ;
  *p.PB_Sprite3D
  ;!extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,140
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+20],EBX
  
  *p\Vertice[0]\color = $FF000000+a
  *p\Vertice[1]\color = $FF000000+b
  *p\Vertice[2]\color = $FF000000+c
  *p\Vertice[3]\color = $FF000000+d
EndProcedure

Procedure SetSprite3DSpecular(sprite,a,b,c,d)
  ;
  ; set specular light for the 4 Sprite3D corners
  ;
  *p.PB_Sprite3D
  ;!extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,140
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+20],EBX
  
  *p\Vertice[0]\specular = a
  *p\Vertice[1]\specular = b
  *p\Vertice[2]\specular = c
  *p\Vertice[3]\specular = d
EndProcedure

Procedure SetSprite3DTextureCoordinates(sprite,corner,a.f,b.f)
  ;
  ; set new texture coordinates for a Sprite3D corner
  ;
  *p.PB_Sprite3D
  ;!extrn _PB_Sprite3D_ObjectsArea
  !MOV  dword EBX,[_PB_Sprite3D_ObjectsArea]
  !MOV  dword EAX,140
  !MUL  dword [ESP]
  !ADD  dword EBX,EAX
  !MOV  dword [ESP+16],EBX
  
  *p\Vertice[corner]\tu = a
  *p\Vertice[corner]\tv = b
EndProcedure



Global Size, texture_transform.f

texture_transform = 1.0

If OpenWindow(0,0,0,800,650,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"")
  If OpenWindowedScreen(WindowID(),0,0,800,650,0,0,0)
    
    LoadFont(1,"Lucida Console",10,#PB_Font_Bold)
    
    #UseSprite = 1
    CompilerIf #UseSprite
    LoadSprite(0,"Danilo.bmp",#PB_Sprite_Texture) ; 256x256!
    CompilerElse
    CreateSprite (0, 256, 256, #PB_Sprite_Texture) 
    StartDrawing (SpriteOutput (0)) 
    Box (0, 0, 256, 256, RGB (0, 0, 100)) 
    For I = 0 To 250 Step 10 
      Box (I, 0, 5, 256, RGB (60, 80, 255)) 
    Next 
    StopDrawing ()
    CompilerEndIf
    
    CreateSprite3D(10, 0) 
    
    Repeat
      Select WindowEvent()
        Case #PB_Event_CloseWindow
          Quit = 1
        Case 0
          Delay(10)
      EndSelect
      
      ExamineKeyboard() 
      ClearScreen (0, 0, 0) 
      
      Start3D()
      
      ; disable culling
      ;SetRenderState(#D3DRENDERSTATE_CULLMODE,#D3DCULL_NONE)
      
      TransformSprite3D (10, Size, 0, 256 - Size, 0, 256+Size, 256, 0-Size, 256)
      
      ; correct texture mapping
      CorrectSprite3D(10)
      
      ; set corner colors
      SetSprite3DColor(10,$FFFF00,$FF0000,$0000FF,$00FFFF)
      
      ; display infos
      DisplaySprite3D (10, 250,250, 255)
      
      ; display sprite
      Display3DObject(10)
      
      Stop3D()
      
      StartDrawing(ScreenOutput()) 
      FrontColor(255, 255, 255) 
      DrawingMode(1):DrawingFont(UseFont(1))
      Locate(10,10):DrawText("CURSOR: left+right to adjust the sprite.")
      Locate(10,25):DrawText("   (Value: "+Str(Size)+")")
      Locate(10,45):DrawText("CURSOR: up+down to change texture mapping.")
      Locate(10,60):DrawText("   (Value: "+Str(texture_transform)+")")
      StopDrawing() 
      
      FlipBuffers() 
      
      If KeyboardPushed(#PB_Key_Right)
        Size + 1
        If Size >  100 : Size =  100 : EndIf
      ElseIf KeyboardPushed(#PB_Key_Left) 
        Size - 1
        If Size < -100 : Size = -100 : EndIf
      ElseIf KeyboardPushed(#PB_Key_Up)
        texture_transform + 1.0
        If texture_transform > 10.0
          texture_transform = 10.0
        EndIf
        ; set new texture mapping coordinates
        SetSprite3DTextureCoordinates(10,1,texture_transform,0.0)
        SetSprite3DTextureCoordinates(10,2,0.0              ,texture_transform)
        SetSprite3DTextureCoordinates(10,3,texture_transform,texture_transform)
      ElseIf KeyboardPushed(#PB_Key_Down)
        texture_transform - 1.0
        If texture_transform < 1.0
          texture_transform = 1.0
        EndIf
        ; set new texture mapping coordinates
        SetSprite3DTextureCoordinates(10,1,texture_transform,0.0)
        SetSprite3DTextureCoordinates(10,2,0.0              ,texture_transform)
        SetSprite3DTextureCoordinates(10,3,texture_transform,texture_transform)
      ElseIf KeyboardPushed(#PB_Key_Escape)
        Quit = #True
      EndIf 
      
    Until Quit
  Else
    MessageRequester("ERROR","Cant open screen !",#MB_ICONERROR)
  EndIf
Else
  MessageRequester("ERROR","Cant open window !",#MB_ICONERROR)
EndIf
I hope it is usefull for you. :D

Sorry for my bad English. :oops:

regards
Stefan
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

English is great :) My question is, how did you get those structures and descriptions? :) That'll save me future trouble for future versions of PB :)
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

Hi Shannara

The descriptions were created with a tool, that i made a few months ago.
It was/is a very useful tool for creating my own Userlibraries.

Here is it:

Code: Select all

PB$="C:\PureBasic2"; PB directory

cmd$=InputRequester("Extrn-Creator","Enter a command form the Library(with parameters)","DisplaySprite3D(0,0,0,0)")        ;"OpenWindow(1,0,0,1,1,1,"+Chr(34)+Chr(34)+")") 

CreateFile(1,PB$+"\Compilers\pb.pb")
WriteStringN("ExitProcess_(0)")
WriteStringN(cmd$)
CloseFile(1)
RunProgram(PB$+"\Compilers\pbcompiler"," /commented "+PB$+"\Compilers\pb.pb",PB$+"\Compilers") 

S=GetTickCount_()
Dim Lib(1000)
Dim Size(1000)
Dim Name$(1000)
Repeat  
  For X=0 To 1000
    If ReadFile(1,PB$+"\Compilers\"+Str(X)+".LIB")
      Size(X)=Lof()
      Lib(X)=AllocateMemory(Size(X))
      ReadData(Lib(X),Size(X))
      CloseFile(1)
      Found=1
    EndIf
  Next
Until GetTickCount_()-S>4000 Or Found=1

If Found=0
  MessageRequester("ERROR !!!","check your command !")
  End
EndIf

hWnd=OpenWindow(1,0,0,400,300,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"Output")
CreateGadgetList(hWnd)

ReadFile(1,PB$+"\Compilers\PureBasic.asm")
For T=0 To 6
  ReadString()
Next
C=1
Repeat
  A$=ReadString()
  Name$(C)=Right(A$,Len(A$)-1)+Chr(32)
  C+1
Until Eof(1) Or C>=1000
CloseFile(1)

A$=";"
For X=0 To 1000
  If Lib(X)
    A$+Chr(13)+Chr(10)
    A$+";-------------------- Lib "+Str(X)+" ("+Name$(X)+") --------------------"+Chr(13)+Chr(10)
    A$+";------------------------------------------------------------------------"+Chr(13)+Chr(10)
    Pos=Lib(X)
    Repeat
      If PeekL(Pos)=PeekL(@"_PB_"):A$+"!extrn "+PeekS(Pos)+Chr(13)+Chr(10):EndIf
      Pos+1
    Until Pos>(Lib(X)+Size(X)-4) 
  EndIf
Next

StringGadget(1,0,0,400,300,A$,#PB_String_MultiLine|#WS_VSCROLL)
Repeat:Until WaitWindowEvent()=#WM_CLOSE
I hope you understand how it works. :wink:



The new size of the structure I got with that code:

Code: Select all

Structure D3DTLVERTEX 
  StructureUnion      ; Screen coordinates 
    sx.f 
    dvSX.f 
  EndStructureUnion 
  StructureUnion 
    sy.f 
    dvSY.f 
  EndStructureUnion 
  StructureUnion 
    sz.f 
    dvSZ.f 
  EndStructureUnion 
  StructureUnion      ; Reciprocal of homogeneous w 
    rhw.f 
    dvRHW.f 
  EndStructureUnion 
  StructureUnion      ; Vertex color 
    color.l 
    dcColor.l 
  EndStructureUnion 
  StructureUnion      ; Specular component of vertex 
    specular.l 
    dcSpecular.l 
  EndStructureUnion 
  StructureUnion      ; Texture coordinates 
    tu.f 
    dvTU.f 
  EndStructureUnion 
  StructureUnion 
    tv.f 
    dvTV.f 
  EndStructureUnion 
EndStructure 

Structure PB_Sprite3D
Texture.l
Vertice.D3DTLVERTEX[4]
Width.w
Height.w
EndStructure

InitSprite()
InitSprite3D()

hWnd=OpenWindow(1,0,0,100,100,1,"TEST")
OpenWindowedScreen(hWnd,0,0,100,100,0,0,0)

CreateSprite(1,256,256,#PB_Sprite_Texture)
CreateSprite3D(1,1)
CreateSprite3D(2,1)
*Addr1.PB_Sprite3D=IsSprite3D(1)
*Addr2.PB_Sprite3D=IsSprite3D(2)
;Debug SizeOf(PB_Sprite3D)
Debug "Size of the Structure(in bytes): "+Str(*Addr2-*Addr1)

;Debug *Addr1\Texture
;Debug *Addr1\Width
;Debug *Addr1\Height

The rest was, more or less, trying out.

Sorry for the ugly code. :roll:

regards
Stefan
chris_b
Enthusiast
Enthusiast
Posts: 103
Joined: Sun Apr 27, 2003 1:54 am

Post by chris_b »

S.M. wrote:The descriptions were created with a tool, that i made a few months ago.
It was/is a very useful tool for creating my own Userlibraries.
Is a PB 4.0 version of this tool possible? I'm trying to discover the IDirectSound interface which is created with InitSound()

[edit]Aha...I found it in "PureBasic library descriptor.txt" in the Library SDK folder of my old version of PB..for some reason this file isn't in my version 4 folder[/edit]
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

I tried to use this tool without any result.
It does not work with PB4.20
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

This one should still be up to date:

http://www.purebasic.fr/english/viewtop ... 503#129503
bye,
Daniel
User avatar
IceSoft
Addict
Addict
Posts: 1682
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

Will be great if the used structures by PureBasic will be publicity by @Fred.
So some better userlibs and addon can be made.

That will improve PureBasic.
Belive! C++ version of Puzzle of Mystralia
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
Post Reply