2D Drawing bug

Everything else that doesn't fall into one of the other PB categories.
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

2D Drawing bug

Post by va!n »

i changed the topic, because its not a problem with point() - its a problem when using box() command!

seems there is a bug in the point() command !? just check following small and easy example! When moving the mouse (blue box) on the red floor, no green box for collision shoud appear! The green box should only be drawn when the mouse (blue box) is outsite the red floor ;-) Tested with 16 and 32 bit screenmode!

Code: Select all


InitSprite()
InitMouse()
InitKeyboard()

OpenScreen(640,480,16," --- Bug in Point() command!? --- ")
MouseLocate(0,0)

Repeat
  ClearScreen( RGB(0,0,0) )                     ; Clear background black

  ExamineKeyboard()
  ExamineMouse()
  
  lPlayerPosX.l = MouseX()                      ; Get players position X
  lPlayerPosY.l = MouseY()                      ; Get players position Y

  StartDrawing(ScreenOutput())
     Box(  0,0,100,400, RGB(255,0,0) )          ; Draw playfield in red
     Box(100,0,100, 70, RGB(255,0,0) )          ; Draw playfiled in red
 
     lCheckWall.l = Point(lPlayerPosX,lPlayerPosY)
     
     If lCheckWall = $0                         ; If $0 then we touched the wall
       Box(220,220,40,40,RGB(0,255,0))          ; Draw green box when wall touched!
     EndIf
     
     Box(lPlayerPosX,lPlayerPosY,2,2, RGB(0,0,255) ) 
     
    ; -------- Debug related stuff --------
     
     DrawingMode(1)
     FrontColor(RGB(255,255,255))
     DrawText(500,20,"PosX: "+Str(lPlayerPosX))
     DrawText(500,40,"PosY: "+Str(lPlayerPosY))
     DrawText(500,60,"Wall: "+Str(lCheckWall))
     
     ; -------- End debug section --------
     
  StopDrawing()  


  FlipBuffers(1) : Delay(2)

Until KeyboardPushed(#PB_Key_Escape)
End
Can someone confirm this problem?
Last edited by va!n on Fri Mar 10, 2006 5:06 am, edited 2 times in total.
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

i found the bug... seem to be a waitblt issue or something like this!? btw addign a delay(1) after the BOX() drawing commands, the point() result is always correct ...

Code: Select all


InitSprite()
InitMouse()
InitKeyboard()

OpenScreen(640,480,16," --- Bug in Point() command!? --- ")
MouseLocate(0,0)

Repeat
  ClearScreen( RGB(0,0,0) )                     ; Clear background black

  ExamineKeyboard()
  ExamineMouse()
  
  lPlayerPosX.l = MouseX()                      ; Get players position X
  lPlayerPosY.l = MouseY()                      ; Get players position Y

  StartDrawing(ScreenOutput())
     Box(  0,0,140,400, RGB(255,0,0) )          ; Draw playfield in red
     Box(100,0,100, 70, RGB(255,0,0) )          ; Draw playfiled in red
    
     Delay(1)   ; <<<<<< THIS WILL SOLVE THE PROBLEM !!!!
 
     lCheckWall.l = Point(lPlayerPosX,lPlayerPosY)
     
     If lCheckWall = $0                         ; If $0 then we touched the wall
       Box(220,220,40,40,RGB(0,255,0))          ; Draw green box when wall touched!
     EndIf
     
     Box(lPlayerPosX,lPlayerPosY,2,2, RGB(0,0,255) ) 
     
    ; -------- Debug related stuff --------
     
     DrawingMode(1)
     FrontColor(RGB(255,255,255))
     DrawText(500,20,"PosX: "+Str(lPlayerPosX))
     DrawText(500,40,"PosY: "+Str(lPlayerPosY))
     DrawText(500,60,"Wall: "+Str(lCheckWall))
     
     ; -------- End debug section --------
     
  StopDrawing()  


  FlipBuffers(1) : Delay(2)

Until KeyboardPushed(#PB_Key_Escape)
End
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

PB4 beta6:
The bug still exist!
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Please stop bumping that ! Do you see a 'fixed' somewhere ?
Lebostein
Addict
Addict
Posts: 841
Joined: Fri Jun 11, 2004 7:07 am

Post by Lebostein »

I can't confirm this. The code works. Whats the problem?
User avatar
IceSoft
Addict
Addict
Posts: 1698
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

Lebostein wrote:I can't confirm this. The code works. Whats the problem?
Remove the delay() and try it again.
(You should read the text too, not only test any code ;-)
Belive! C++ version of Puzzle of Mystralia
Bug Planet
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
User avatar
Maxus
User
User
Posts: 71
Joined: Thu Feb 16, 2006 9:35 am
Location: Russia
Contact:

Post by Maxus »

In the first example, I do not know as at you, and at me as soon as there is a point area of red color, the green box at once is drawn.
Lebostein
Addict
Addict
Posts: 841
Joined: Fri Jun 11, 2004 7:07 am

Post by Lebostein »

I'am stupid? The code works! :?
The cursor in the red box -> the green box is hide....

Code: Select all

InitSprite()
InitMouse()
InitKeyboard()

OpenScreen(640,480,16," --- Bug in Point() command!? --- ")
MouseLocate(0,0)

ClearScreen( RGB(0,0,0) )                     ; Clear background black
FlipBuffers()

  StartDrawing(ScreenOutput())
     Box(  0,0,100,400, RGB(255,0,0) )          ; Draw playfield in red
     Box(100,0,100, 70, RGB(255,0,0) )          ; Draw playfiled in red

    For y = 0 To 410
    For x = 0 To 210

    col = Point(x,y)                              ;create a copy of the red boxes in x+300
    If col: Plot(x + 300, y, $00FF00): EndIf

    Next x
    Next y
  StopDrawing()  

FlipBuffers()

Repeat
  ExamineKeyboard()
  ExamineMouse()
Until KeyboardPushed(#PB_Key_Escape)
End
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

There is something weird here. I've do the following test code, which is DX7 only (no PB libs) and i get the same bug (try to move the mouse inside the red area and look at the displayed box, it should be always 255 but sometimes it flickers and display another number, which is not correct). Did i miss something or the GetPixel() API with DX is broken ? I've a Radeon 9800. You will need the minidx header found in the advanced source/directx7 drawer.

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Raw DirectX 7 example using Interfaces
;
; ------------------------------------------------------------
;


#ScreenResX = 640
#ScreenResY = 480
#ScreenBits = 32

; Structures and Constants
;
IncludeFile "MiniDirectDraw.pb"

SurfaceDescriptor.DDSURFACEDESC2

If OpenLibrary(0,"ddraw.dll")
  If CallFunction(0,"DirectDrawCreateEx",0,@DirectDraw.IDirectDraw7,?IID_IDirectDraw7,0) <> #DD_OK
    MessageRequester("Warning:","Couldn't init DirectDraw",0)
    End
  EndIf
Else
  MessageRequester("Warning:","Couldn't init DirectDraw",0)
  End
EndIf

MessageRequester("PureBasic - DirectX", "Enjoy the full object oriented DirectX example"+Chr(10)+"Press ALT+F4 to quit !")

; Here, DirectDraw is correctly initialized. The real fun begins...
;

hWnd = OpenWindow(1, 100, 100, 300, 400, "PureBasic - Raw DirectX Test", #WS_POPUP)
SetFocus_(hWnd)

If DirectDraw\SetCooperativeLevel(hWnd, #DDSCL_EXCLUSIVE | #DDSCL_FULLSCREEN) = #DD_OK

  If DirectDraw\SetDisplayMode(#ScreenResX, #ScreenResY, #ScreenBits, 0, 0) = #DD_OK

    ;
    ; Double buffer
    ;
    SurfaceDescriptor\dwSize            = SizeOf(DDSURFACEDESC2)
    SurfaceDescriptor\dwFlags           = #DDSD_CAPS | #DDSD_BACKBUFFERCOUNT
    SurfaceDescriptor\ddsCaps\dwCaps    = #DDSCAPS_PRIMARYSURFACE | #DDSCAPS_FLIP | #DDSCAPS_COMPLEX
    SurfaceDescriptor\dwBackBufferCount = 1

    If DirectDraw\CreateSurface(SurfaceDescriptor, @PrimarySurface.IDirectDrawSurface7, 0) <> #DD_OK
      MessageRequester("Warning:","Couldn't create primary surface",0)
      End
    EndIf
    
    ddscaps.DDSCAPS2
    ;Get a pointer To the back buffer
    ddscaps\dwCaps = #DDSCAPS_BACKBUFFER;
    If PrimarySurface\GetAttachedSurface(ddscaps, @BackSurface.IDirectDrawSurface7) <> #DD_OK
      MessageRequester("Warning:","Couldn't create primary surface",0)
      End
    EndIf
    
    ;
    ; LOAD the image and create a surface
    ;
    
    ;// Create the offscreen surface, by loading our bitmap.
    hbm.l                   ;HBITMAP
    bm.BITMAP               ;BITMAP
    pdds.l;

    hbm = LoadImage_(0, "Sprite.bmp", #IMAGE_BITMAP, 0, 0, #LR_LOADFROMFILE | #LR_CREATEDIBSECTION);
    If hbm = 0
      MessageRequester("INFO","Couldn't load the Sprite",0)
      End
    EndIf

    Debug hbm
    
    GetObject_(hbm, SizeOf(BITMAP), bm)
    
    Debug bm\bmWidth
    Debug bm\bmHeight

    SurfaceDescriptor\dwSize         = SizeOf(DDSURFACEDESC2)
    SurfaceDescriptor\dwFlags        = #DDSD_CAPS | #DDSD_HEIGHT | #DDSD_WIDTH
    SurfaceDescriptor\ddsCaps\dwCaps = #DDSCAPS_OFFSCREENPLAIN
    SurfaceDescriptor\dwWidth        = bm\bmWidth
    SurfaceDescriptor\dwHeight       = bm\bmHeight
    If DirectDraw\CreateSurface(SurfaceDescriptor, @Sprite.IDirectDrawSurface7, 0) <> #DD_OK
      MessageRequester("Error","Couldn't create Sprite surface",0)
      End
    EndIf

    hdcImage.l
    hdc.l
    bm2.BITMAP;
    ddsd2.DDSURFACEDESC2;
    hr.l;

    hdcImage = CreateCompatibleDC_(0);
    If hdcImage = 0
      MessageRequester("INFO","createcompatible dc failed",0)
      End
    EndIf
    
    SelectObject_(hdcImage, hbm);
    GetObject_(hbm, SizeOf(BITMAP), bm2);
    dx = bm2\bmWidth
    dy = bm2\bmHeight
    ddsd2\dwSize = SizeOf(DDSURFACEDESC2);
    ddsd2\dwFlags = #DDSD_HEIGHT | #DDSD_WIDTH;
    Sprite\GetSurfaceDesc(@ddsd2)

    hr = Sprite\GetDC(@hdc)
    If hr = #DD_OK
        StretchBlt_(hdc, 0, 0, ddsd2\dwWidth, ddsd2\dwHeight, hdcImage, 0, 0, dx, dy, #SRCCOPY);
        Sprite\ReleaseDC(hdc)
    Else
      Beep_(1000,1000)
    EndIf
    DeleteDC_(hdcImage);
    DeleteObject_(hbm);
    Sprite.IDirectDrawSurface7 = Sprite

    If Sprite = 0
      MessageRequester("INFO","DDLoadBitmap FAILED",0)
      End
    EndIf

    ddck.DDCOLORKEY;
    ddck\dwColorSpaceLowValue  = 0
    ddck\dwColorSpaceHighValue = 0
    Sprite\SetColorKey(#DDCKEY_SRCBLT, ddck)
    
    ;
    ; OK, Image is now loaded (hopefully ;)
    ;

    ShowWindow_(hWnd, #SW_SHOW)
    ShowCursor_(0)
    
    ;
    ; Message-Loop
    ;
    Color.l = $00FFFF00

    Repeat
      EventID.l = WindowEvent()
      
      If EventID = #PB_Event_CloseWindow  ; If the user has pressed on the close button
        Quit = 1
      EndIf

      If GetFocus_() = hWnd

        PrimarySurface\Flip(0, #DDFLIP_WAIT)  ; Swap the 2 buffers (front and back)
                
        If BackSurface\GetDC(@DC) = #DD_OK
          Brush = CreateSolidBrush_(255)

          SetRect_(Rect.RECT, 0, 0, 100, 400)
          FillRect_(DC, Rect, Brush)

          SetRect_(Rect.RECT, 0, 0, 200, 100)
          FillRect_(DC, Rect, Brush)

          DeleteObject_(Brush)
          
          GetCursorPos_(Point.POINT)
          
          lCheckWall.l = GetPixel_(DC, Point\x, Point\y)
          
          a$ = LSet(Str(lCheckWall), 20)
          TextOut_(DC, 100, 400, a$, Len(a$))
          
          SetRect_(Rect.RECT, Point\x, Point\y, Point\x+2, Point\y+2)
          FillRect_(DC, Rect, GetStockObject_(#GRAY_BRUSH))
          
          BackSurface\ReleaseDC(DC)
        EndIf

      EndIf
      
    Until Quit = 1 

  Else
     MessageRequester("Warning:", "Couldn't set display mode", 0)
  EndIf
Else
  MessageRequester("Error:","Couldn't set DirectDraw cooperative level")
EndIf

End
 
DataSection
  IID_IDirectDraw7:
    Data.l $15e65ec0
    Data.w $3b9c, $11d2
    Data.b $b9, $2f, $00, $60, $97, $97, $ea, $5b
EndDataSection 
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

All codes are rock stable at 0, 0, 255 when the cursor is over the red area here.
Fred wrote:Probably a driver issue then.
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Thanks for the test, it's probably a driver issue, yes.
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

@Fred:
I have tried your example using latest drivers and i still have the same problem - problem still exist even with latest ATI drivers! Seems its not a bug of Point(), futuremore a possible bug of Box() - as i added (10-march) to my first posting.
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

You tried the DX only example ? There is no PB commands in it, so it's not a Box() problem. You can convert it in C if you want ;).
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

yes, i tried the API based DX only example! :wink:
Mhhh, i will try to find some infos about this mystic thing to help you to get this one fixed. Btw, any idea why a delay(1) seems to solve the problem? ^^ greetz
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
Fred
Administrator
Administrator
Posts: 18351
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

It's probably a timing issue (the FillRect() command isn't finished when the getpixel() is called, which should never happen). Tried gdiflush() and such without success.
Post Reply