Software 3D.

Just starting out? Need help? Post your questions and find answers here.
Hkb
New User
New User
Posts: 6
Joined: Sun Sep 25, 2005 8:13 pm
Location: Sweden

Software 3D.

Post by Hkb »

Perspective texture now works. (PB4)

Code: Select all

EnableExplicit

Structure DrawingInfoStruct 
  Type.l 
  Window.l 
  DC.l 
  ReleaseProcedure.l 
  PixelBuffer.l 
  Pitch.l 
  Width.l 
  Height.l 
  Depth.l 
  PixelFormat.l 
  StopDirectAccess.l 
  StartDirectAccess.l 
EndStructure 

Structure fpoint
  Fpoint.l
EndStructure

Structure fplot
  fplot.l
EndStructure

Structure Entity
  name.l
  ;Parent.Entity
  ;Child.Entity
  EntityX.f
  EntityY.f
  EntityZ.f
  EntityRoll.f
  EntityPitch.f
  EntityYaw.f
EndStructure

Global Fps, Timer, NewTime, Frames 
Global FastImgOutputID.DrawingInfoStruct 


Declare triangle_textured(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,x3.f,y3.f,z3.f,tx1.f=0,ty1.f=0,tx2.f=0,ty2.f=0,tx3.f=0,ty3.f=0)
Declare triangle(x1.f,y1.f,x2.f,y2.f,x3.f,y3.f)


Declare  CreatebackImage()


Declare ___ReleaseFastImageOutput() 
Declare ___StopDirectAccess() 
Declare ___StartDirectAccess() 
Declare FastImageOutput(Image)

Declare DisplayFps() 
 #Win = 1 
 #WSM = #PB_Window_SystemMenu 
 #WSC = #PB_Window_ScreenCentered 

;Screen dimensions, used in PlotPixel 
 #Xmin = 0 
 #Ymin = 0 
 #Xmax = 800 
 #Ymax = 600


;- Open Window 
;If InitSprite() ;init directdraw 7 
If  OpenWindow(#Win,#Xmin-3,#Ymin-3,#Xmax,#Ymax,"BresAlgorithms",#WSM|#WSC) ;#WSM|#WSC|
    CreateImage(#Win,#Xmax,#Ymax,32) ; only 32bit seems to be really faster...   
    CreateImage(0,#Xmax,#Ymax,32) ; cls image 
EndIf


Define EventID


;init background
CreatebackImage()



Define a.f=91.0
Define b.f
Define x.f=400.0
Define y.f=300.0
Define z.f=200.0

Define P0X.f,P0Y.f,P0Z.f, P1X.f,P1Y.f,P1Z.f, P2X.f,P2Y.f,P2Z.f, P3X.f,P3Y.f,P3Z.f
Define P4X.f,P4Y.f,P4Z.f, P5X.f,P5Y.f,P5Z.f, P6X.f,P6Y.f,P6Z.f, P7X.f,P7Y.f,P7Z.f
Define tmp.f, q.f=0.01

Global xsc.f=x,ysc.f=y

Define u0,u1,u2,u3, v0,v1,v2,v3
Define u4,u5,u6,u7, v4,v5,v6,v7

  p0x=-50.0 : p0y= 50.0 : p0z=-50.0
  p1x= 50.0 : p1y= 50.0 : p1z=-50.0
  p2x= 50.0 : p2y=-50.0 : p2z=-50.0
  p3x=-50.0 : p3y=-50.0 : p3z=-50.0
 
  p4x=-50.0 : p4y= 50.0 : p4z= 50.0
  p5x= 50.0 : p5y= 50.0 : p5z= 50.0
  p6x= 50.0 : p6y=-50.0 : p6z= 50.0
  p7x=-50.0 : p7y=-50.0 : p7z= 50.0
    

Repeat 
  
  EventID = WindowEvent() 
  
  StartDrawing(FastImageOutput(#Win))  ;cls 
      DrawImage(ImageID(0), 0, 0)  
  StopDrawing() 
  
;roll
 tmp = p0x * Cos(q) - p0y * Sin(q) : p0y = p0x * Sin(q) + p0y * Cos(q) : p0x=tmp
 tmp = p1x * Cos(q) - p1y * Sin(q) : p1y = p1x * Sin(q) + p1y * Cos(q) : p1x=tmp
 tmp = p2x * Cos(q) - p2y * Sin(q) : p2y = p2x * Sin(q) + p2y * Cos(q) : p2x=tmp
 tmp = p3x * Cos(q) - p3y * Sin(q) : p3y = p3x * Sin(q) + p3y * Cos(q) : p3x=tmp
 tmp = p4x * Cos(q) - p4y * Sin(q) : p4y = p4x * Sin(q) + p4y * Cos(q) : p4x=tmp
 tmp = p5x * Cos(q) - p5y * Sin(q) : p5y = p5x * Sin(q) + p5y * Cos(q) : p5x=tmp
 tmp = p6x * Cos(q) - p6y * Sin(q) : p6y = p6x * Sin(q) + p6y * Cos(q) : p6x=tmp
 tmp = p7x * Cos(q) - p7y * Sin(q) : p7y = p7x * Sin(q) + p7y * Cos(q) : p7x=tmp
;pitch 
; tmp = p0z * Cos(q) - p0y * Sin(q) : p0y = p0z * Sin(q) + p0y * Cos(q) : p0z=tmp
; tmp = p1z * Cos(q) - p1y * Sin(q) : p1y = p1z * Sin(q) + p1y * Cos(q) : p1z=tmp
; tmp = p2z * Cos(q) - p2y * Sin(q) : p2y = p2z * Sin(q) + p2y * Cos(q) : p2z=tmp
; tmp = p3z * Cos(q) - p3y * Sin(q) : p3y = p3z * Sin(q) + p3y * Cos(q) : p3z=tmp
;yaw 
  tmp = p0x * Cos(q) - p0z * Sin(q) : p0z = p0x * Sin(q) + p0z * Cos(q) : p0x=tmp
  tmp = p1x * Cos(q) - p1z * Sin(q) : p1z = p1x * Sin(q) + p1z * Cos(q) : p1x=tmp
  tmp = p2x * Cos(q) - p2z * Sin(q) : p2z = p2x * Sin(q) + p2z * Cos(q) : p2x=tmp
  tmp = p3x * Cos(q) - p3z * Sin(q) : p3z = p3x * Sin(q) + p3z * Cos(q) : p3x=tmp
  tmp = p4x * Cos(q) - p4z * Sin(q) : p4z = p4x * Sin(q) + p4z * Cos(q) : p4x=tmp
  tmp = p5x * Cos(q) - p5z * Sin(q) : p5z = p5x * Sin(q) + p5z * Cos(q) : p5x=tmp
  tmp = p6x * Cos(q) - p6z * Sin(q) : p6z = p6x * Sin(q) + p6z * Cos(q) : p6x=tmp
  tmp = p7x * Cos(q) - p7z * Sin(q) : p7z = p7x * Sin(q) + p7z * Cos(q) : p7x=tmp


  u0=(p0x+0)*z/(p0z+z)  : v0=(p0y+0)*z/(p0z+z)
  u1=(p1x+0)*z/(p1z+z)  : v1=(p1y+0)*z/(p1z+z)
  u2=(p2x+0)*z/(p2z+z)  : v2=(p2y+0)*z/(p2z+z)
  u3=(p3x+0)*z/(p3z+z)  : v3=(p3y+0)*z/(p3z+z)
  u4=(p4x+0)*z/(p4z+z)  : v4=(p4y+0)*z/(p4z+z)
  u5=(p5x+0)*z/(p5z+z)  : v5=(p5y+0)*z/(p5z+z)
  u6=(p6x+0)*z/(p6z+z)  : v6=(p6y+0)*z/(p6z+z)
  u7=(p7x+0)*z/(p7z+z)  : v7=(p7y+0)*z/(p7z+z)
  

  triangle(260+a,150+a/10,150+a,100+a/10,200+a,160+a/10)

 triangle_textured(u0+x,v0+y,P0Z+z,  u2+x,v2+y,P2Z+z,  u3+x,v3+y,P3Z+z, 100,300,300,100,100,100)
 triangle_textured(u0+x,v0+y,P0Z+z,  u1+x,v1+y,P1Z+z,  u2+x,v2+y,P2Z+z, 100,300,300,300,300,100)
  
  triangle_textured(u1+x,v1+y,P1Z+z,  u6+x,v6+y,P6Z+z,  u2+x,v2+y,P2Z+z, 100,300,300,100,100,100)
  triangle_textured(u1+x,v1+y,P1Z+z,  u5+x,v5+y,P5Z+z,  u6+x,v6+y,P6Z+z, 100,300,300,300,300,100)

 triangle_textured(u4+x,v4+y,P4Z+z,  u6+x,v6+y,P6Z+z,  u7+x,v7+y,P7Z+z, 100,300,300,100,100,100)
 triangle_textured(u4+x,v4+y,P4Z+z,  u5+x,v5+y,P5Z+z,  u6+x,v6+y,P6Z+z, 100,300,300,300,300,100)
  
  triangle_textured(u0+x,v0+y,P0Z+z,  u7+x,v7+y,P7Z+z,  u3+x,v3+y,P3Z+z, 100,300,300,100,100,100)
  triangle_textured(u0+x,v0+y,P0Z+z,  u4+x,v4+y,P4Z+z,  u7+x,v7+y,P7Z+z, 100,300,300,300,300,100)

;triangle(u0+x,v0+y,u2+x,v2+y,u3+x,v3+y)

  ;=a-0.9 

  StartDrawing(WindowOutput(#Win))   
    DrawImage(ImageID(#Win),0,0)
  StopDrawing() 
  

  Delay(10)
Until EventID = #PB_Event_CloseWindow  

End


 Procedure triangle(x1.f,y1.f,x2.f,y2.f,x3.f,y3.f)
 ;// this function draws a filled triangle 
 ;// by dividing it in half And stepping through 
 ;// each line 

 ;///// 
 Define x.l
 Define y.l         ;   //looping variables 
 Define height.l    ;   // the heights of the triangles 

 Define dx_right.f  ;   // the dx/dy ratio of the right edge of the line 
 Define dx_left.f   ;   // the dx/dy ratio of the left edge of the line 
 Define xs.f
 Define xe.f        ;   // the starting and ending points of the edges 


 ;// make sure points are in order 
 Define temp_x.l
 Define temp_y.l 



 If (y2 < y1) 
  temp_y = y1; 
  temp_x = x1; 
  y1 = y2; 
  x1 = x2; 
  y2 = temp_y; 
  x2 = temp_x; 
 EndIf

 If (y3 < y1) 
  temp_y = y1; 
  temp_x = x1; 
  y1 = y3; 
  x1 = x3; 
  y3 = temp_y; 
  x3 = temp_x; 
 EndIf 

 If (y3 < y2)  
  temp_y = y3; 
  temp_x = x3; 
  y3 = y2; 
  x3 = x2; 
  y2 = temp_y; 
  x2 = temp_x; 
 EndIf 

 Define right_x.l 
 Define left_x.l 

 left_x = x2; 
 right_x = x1 + ( (y2-y1)* (x3-x1)/ (y3-y1)); 

 If (right_x < left_x) ;// messes up If right is on left  
  temp_x = right_x; 
  right_x = left_x; 
  left_x = temp_x; 
 EndIf 




 ;/////!!DRAW TOP!!/////// 

 ;//draw the triangle top 
 If (y1 <> y2) ;(y1 != y2) 

  ;// compute height of subtriangle 
  height = y2 - y1; 

  ;// set starting points 
  xs =  x1;+ 0.999999; 
  xe =  x1; 

  ;// compute edge ratios 
  dx_left =  (left_x - x1) /  height; 
  dx_right =  (right_x - x1) /  height; 


   ;///DRAW IT ALREADY!!!! 
  StartDrawing(FastImageOutput(#Win))  
  For y = y1 To y2 
  If y=> 0 And y < #Ymax
   For x =  xs To xe  
    ;dest.PlotPixel(x, y, 50, 50, 200); 
    If x=> 0 And x< #Xmax
    Plot(x,y,RGB(100,100,100))
    EndIf
   Next 
  EndIf
   ;//adjust starting And ending point 
   xs + dx_left; 
   xe + dx_right; 
  Next
  StopDrawing()

 EndIf 


 If (y2 <> y3) ;(y2 != y3) 

  ;//now recompute slope of shorter edge To finish triangle bottom 

  ;// recompute slopes 

  height = y3 - y2; 
  dx_right =  (x3 - right_x) /  (height); 
  dx_left =  (x3 - left_x) /  (height); 
  xs =  left_x; 
  xe =  right_x; 

  ;// draw the rest of the triangle 
  StartDrawing(FastImageOutput(#Win)) 
  For y = y2 To y3; y++) 
  If y=> 0 And y < #Ymax
    For x =  xs To xe; x++) 
      ;dest.PlotPixel(x, y, 50, 50, 200); 
      If x=> 0 And x< #Xmax
      Plot(x,y,RGB(100,100,100))
      EndIf
    Next 
  EndIf
    ;//adjust starting And ending point 
    xs + dx_left; 
    xe + dx_right; 

  Next ;//End For 
  StopDrawing()

  
 EndIf 
EndProcedure


 Procedure triangle_textured(x1.f,y1.f,z1.f,x2.f,y2.f,z2.f,x3.f,y3.f,z3.f,tx1.f=0,ty1.f=0,tx2.f=0,ty2.f=0,tx3.f=0,ty3.f=0)
  ;// this function draws a filled triangle 
 ;// by dividing it in half And stepping through 
 ;// each line 

 ;///// 
 Define x.l         ;   //looping variables
 Define y.l 
 Define height.f    ;.l   // the heights of the triangles 

 Define dx_right.f  ;   // the dx/dy ratio of the right edge of the line 
 Define dx_left.f   ;   // the dx/dy ratio of the left edge of the line 
 Define xs.f        ;   // the starting and ending points of the edges 
 Define xe.f        
 
 ;//TEXTURE VARIABLES/////////////// 
 Define tx.f
 Define ty.f       ;//current texture coordinates 
 Define tz.f
 
 Define tys.f
 Define txs.f      ;// starting texture coordinates for each line 
 Define tzs.f

 Define constant_tx.f
 Define constant_ty.f
 Define constant_tz.f
 
 Define left_tx.f 
 Define left_ty.f 
 Define left_tz.f 
 
 Define right_tx.f    ; // edge ratio 
 Define right_ty.f 
 Define right_tz.f
 
 Define tx_left.f 
 Define ty_left.f 
 Define tz_left.f
 
  ;// make sure points are in order 
 Define temp_tx.f
 Define temp_ty.f;  
 
 Define temp_x.f
 Define temp_y.f 
 Define temp_z.f
 Define temp_tz.f

 Define new_tx1.f
 Define new_tx2.f
 Define new_tx3.f
 Define new_ty1.f
 Define new_ty2.f
 Define new_ty3.f

 Define new_z1.f
 Define new_z2.f
 Define new_z3.f
 

new_tx1 = tx1/z1
new_tx2 = tx2/z2
new_tx3 = tx3/z3
new_ty1 = ty1/z1
new_ty2 = ty2/z2
new_ty3 = ty3/z3


new_z1 = 1.0/z1
new_z2 = 1.0/z2
new_z3 = 1.0/z3

 If (y2 < y1) 

  Swap x1,x2
  Swap y1,y2
  Swap z1,z2
  Swap tx1,tx2
  Swap ty1,ty2
  Swap new_tx1, new_tx2
  Swap new_ty1, new_ty2
  Swap new_z1, new_z2

 EndIf 

 If (y3 < y1) 

  Swap x1,x3
  Swap y1,y3
  Swap z1,z3
  Swap tx1,tx3
  Swap ty1,ty3
  Swap new_tx1,new_tx3
  Swap new_ty1,new_ty3
  Swap new_z1,new_z3
  
 EndIf 

 If (y3 < y2) 

  Swap x2,x3
  Swap y2,y3
  Swap z2,z3
  Swap tx2,tx3
  Swap ty2,ty3
  Swap new_tx2,new_tx3
  Swap new_ty2,new_ty3
  Swap new_z2,new_z3

 EndIf


  
 ;// COMPUTE INCREMENTAL RATIO //////////// 
 Define right_x.f 
 Define left_x.f 

 If y3=y1
  
  left_tx   = new_tx2
  right_tx  = new_tx1 
  left_ty   = new_ty2
  right_ty  = new_ty1
  left_tz   = new_z2
  right_tz  = new_z1
 
 Else
 
  left_x = x2; 
  right_x = x1 + ((y2-y1)*(x3-x1)/(y3-y1)); 

  ;//COMPUTE TEXTURE INCREMENTAL RATIO ///// 
  
  left_tz   = new_z2;   //      texture 
  right_tz  = new_z1  + ((y2-y1)*(new_z3-new_z1)/(y3-y1))  
  left_tx   = new_tx2;  //      texture 
  right_tx  = new_tx1 + ((y2-y1)*(new_tx3-new_tx1)/(y3-y1)); 
  left_ty   = new_ty2;  //      texture 
  right_ty  = new_ty1 + ((y2-y1)*(new_ty3-new_ty1)/(y3-y1)); 
 
 EndIf

 If (right_x < left_x) ;// messes up If right is on left 

  Swap right_x,left_x; 
  Swap right_tx,left_tx; 
  Swap right_ty,left_ty; 
  Swap right_tz,left_tz; 
 
 EndIf 
 

 ;///////////////////////////////////////// 
  Define otx.f
  Define oty.f
  Define *pt_point.fpoint
  Define *pt_plot.fplot
  
  Define *Buffer
  Define Pitch
  
  *Buffer = DrawingBuffer() 
  Pitch   = DrawingBufferPitch() 

 ;/////!!DRAW TOP!!/////// 



 ;//draw the triangle top 
 If (y1 <> y2) 

  ;// compute height of subtriangle 
  height = y2 - y1; 

  ;// set starting points 
  xs = x1+0.999999
  xe = x1; 

  ;// compute edge ratios 
  dx_left  = (left_x - x1) / height; 
  dx_right = (right_x - x1) / height;
  
  tx_left = (left_tx - new_tx1) / height; 
  ty_left = (left_ty - new_ty1) / height; 
  tz_left = (left_tz - new_z1) / height;
  
  constant_tx = (right_tx - left_tx) / (right_x - left_x); 
  constant_ty = (right_ty - left_ty) / (right_x - left_x); 
  constant_tz = (right_tz - left_tz) / (right_x - left_x);  
  
  txs = new_tx1; 
  tys = new_ty1
  tzs = new_z1

  StartDrawing(FastImageOutput(#Win)) 

    For y = Int(y1) To Int(y2); y++) 

      tx = txs
      ty = tys
      tz = tzs
    
      If y >= #Ymin And y < #Ymax 
 
        For x = Int(xs) To Int(xe); x++) 
          ;f x>#Xmax : x=Int(xe): EndIf

          otx=tx/tz
          oty=ty/tz          
           
          If x    >= #Xmin And x    < #Xmax
          If otx  >= #Xmin And otx  < #Xmax 
          If oty  >= #Ymin And oty  < #Ymax 

          *pt_point.fpoint=*Buffer+Pitch*Int(oty)+Int(otx)*4
          *pt_plot.fplot=*Buffer+Pitch*y+x*4         
          *pt_plot\fplot=*pt_point\fpoint
           
          EndIf
          EndIf
          EndIf
    

          tx + constant_tx; 
          ty + constant_ty;
          tz + constant_tz

      
        Next 
       EndIf
      ;//adjust starting And ending point 
      xs + dx_left; 
      xe + dx_right; 

      txs + tx_left; 
      tys + ty_left; 
      tzs + tz_left;

    Next 
  StopDrawing()
 EndIf 


 ;////////DRAW BOTTOM!!!!/////////// 

 If (y2 <> y3) 

 ; //now recompute slope of shorter edge To finish triangle bottom 

  ;// recompute slopes 

  height = y3 - y2; 
  dx_right = (x3 - right_x) / (height); 
  dx_left = (x3 - left_x) / (height); 
  xs = left_x + 0.999999; 
  xe = right_x; 

  tx_left = (new_tx3 - left_tx) / height; 
  ty_left = (new_ty3 - left_ty) / height; 
  tz_left = (new_z3  - left_tz) / height;
    
  constant_ty = (right_ty - left_ty) / (right_x - left_x); 
  constant_tx = (right_tx - left_tx) / (right_x - left_x); 
  constant_tz = (right_tz - left_tz) / (right_x - left_x);

  txs = left_tx
  tys = left_ty
  tzs = left_tz


  ;// draw the rest of the triangle 
  StartDrawing(FastImageOutput(#Win)) 
    For y = Int(y2) To Int(y3); y++) 
  
      tx = txs; 
      ty = tys;
      tz = tzs
      
      If y >= #Ymin And y < #Ymax

      For x = Int(xs) To Int(xe); x++) 
        ;f x>#Xmax : x=Int(xe): EndIf 
         
        otx=tx/tz       
        oty=ty/tz
           
        If x >= #Xmin And x < #Xmax  
        If otx >= #Xmin And otx < #Xmax 
        If oty >= #Ymin And oty < #Ymax 
        *pt_point.fpoint=*Buffer+Pitch*Int(oty)+Int(otx)*4
        *pt_plot.fplot=*Buffer+Pitch*y+x*4 
        *pt_plot\fplot=*pt_point\fpoint

        EndIf
        EndIf
        EndIf
    
        tx + constant_tx  
        ty + constant_ty 
        tz + constant_tz 

      Next 
    
      
      EndIf
    ;//adjust starting And ending point 
    xs + dx_left; 
    xe + dx_right; 

    txs + tx_left; 
    tys + ty_left;
    tzs + tz_left;
    Next
  StopDrawing() 
 EndIf 
 
EndProcedure



 Procedure CreatebackImage()
  UseJPEGImageDecoder()
  Define pic
  pic=LoadImage(#PB_Any,"DSC00684.JPG")
If pic
  StartDrawing(ImageOutput(0))
    DrawImage(ImageID(pic), 0, 0) 
  StopDrawing() 
Else
  StartDrawing(ImageOutput(0)) 
    Define aa
    Define bb
    For aa=0 To 500
      For bb=0 To 500
       Plot(aa,bb,255-(aa % 255)+bb*255) 
     Next 
    Next
  StopDrawing()
EndIf

  StartDrawing(ImageOutput(#Win))
    DrawImage(ImageID(0), 0, 0) 
  StopDrawing() 
EndProcedure




;- 

Procedure ___ReleaseFastImageOutput() 
  If FastImgOutputID\DC:DeleteDC_(FastImgOutputID\DC):FastImgOutputID\DC=0:EndIf ; free the created memory DC 
EndProcedure 

Procedure ___StopDirectAccess() 
  ProcedureReturn FastImgOutputID\DC 
EndProcedure 

Procedure ___StartDirectAccess() 
  GetPixel_(FastImgOutputID\DC,0,0) ; make sure all GDI operations are finished 
  ProcedureReturn FastImgOutputID\PixelBuffer 
EndProcedure 

; FastImageOutput() provides a faster pixel access for 32-,24- and 15 bit images(DIBSesctions). 
; However, for now only plot(x,y,color) works faster. (point(x,y) seems to be not optimized for direct memory access at the moment. You can use the PointFast() command from the E2D Userlib to get a faster point command.) 
Procedure FastImageOutput(Image) 
Define ds.DIBSECTION
Define MemDC

  If GetObject_(ImageID(Image),SizeOf(DIBSECTION),ds.DIBSECTION)=0 
    ProcedureReturn 0 ; no DIBSECTION 
  EndIf 

  FastImgOutputID\Type=7 ; allows direct memory access 
  FastImgOutputID\ReleaseProcedure=@___ReleaseFastImageOutput() 
  FastImgOutputID\PixelBuffer=ds\dsBm\bmBits+ds\dsBm\bmWidthBytes*(ds\dsBm\bmHeight-1) ;needed because the image if top down 
  FastImgOutputID\Pitch=-ds\dsBm\bmWidthBytes 
  FastImgOutputID\Width=ds\dsBm\bmWidth 
  FastImgOutputID\Height=ds\dsBm\bmHeight 
  FastImgOutputID\Depth=ds\dsBm\bmBitsPixel 

  Select FastImgOutputID\Depth 
    Case 32 
      FastImgOutputID\PixelFormat=#PB_PixelFormat_32Bits_BGR 
    Case 24 
      FastImgOutputID\PixelFormat=#PB_PixelFormat_24Bits_BGR  
    Case 16 
      FastImgOutputID\Depth=15 
      FastImgOutputID\PixelFormat=#PB_PixelFormat_15Bits      
    Default 
      ProcedureReturn 0 ; only 32-,24- and 15bit DIBSections are supported 
  EndSelect 

  MemDC=CreateCompatibleDC_(0) 
  If MemDC=0:ProcedureReturn 0:EndIf ; the memory DC cannot be created 
  SelectObject_(MemDC,ImageID(Image)) 
  FastImgOutputID\DC=MemDC 

  FastImgOutputID\StopDirectAccess=@___StopDirectAccess() 
  FastImgOutputID\StartDirectAccess=@___StartDirectAccess()  
  ProcedureReturn FastImgOutputID 
EndProcedure 



[/list]