DirectX Overlay mit PB programmieren

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

KeyKon hat geschrieben:Kommt man da nicht anders ran? (Hab nähmlich Demo, und warte noch auf weihnachten :roll: )

KeyKon
???
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Da kann er keine WinAPI benutzen und kann das Beispiel somit nicht kompilieren, das ist es wohl, was er damit sagen wollte.
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

hmm, mich wundert, dass das bei mir nicht funktioniert.

Ich habe ne Geforce4 Mx440 Grafikkarte, und ich dachte schon, dass die sowas unterstützen müsste. Kann es sein, dass ich meine WinXP / DirectX Settings verbockt habe?
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Beitrag von Stefan »

Hallo

@KeyKon
Ich hab dir die Funktion mal nachprogrammiert:

Code: Alles auswählen

Procedure IsSprite(Sprite)
!extrn _PB_Sprite_ObjectsArea
!MOV Eax,[Esp]
!LEA Eax,[Eax+Eax*2];IMUL Eax,24
!SAL Eax,3 
!ADD Eax,[_PB_Sprite_ObjectsArea]
ProcedureReturn 
EndProcedure
Funktioniert das Beispiel jetzt ?

@bluejoke
An deinem Grafikchip kann es nicht liegen.
Ich hab auch ne GeForce4 MX 440.
Hast du vielleicht die Hardwarebeschleunigung deaktiviert ?

@real
Sorry,hab keine Ahnung wie man das Problem lösen kann. :(

Gruß
Stefan
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Beitrag von Stefan »

@KeyKon

Hier noch der ganze Code für die Demoversion:

Code: Alles auswählen

;Achtung: 
;Nicht jede Grafikkarte unterstüzt Overlays. 

Procedure IsSprite_(Sprite)
!extrn _PB_Sprite_ObjectsArea
!MOV Eax,[Esp]
!LEA Eax,[Eax+Eax*2];IMUL Eax,24
!SAL Eax,3 
!ADD Eax,[_PB_Sprite_ObjectsArea]
ProcedureReturn 
EndProcedure


#DDOVER_SHOW=16384 
#DDSCAPS_OVERLAY=128    
#DDSCAPS_VIDEOMEMORY=16384 
#DDSD_PIXELFORMAT=4096 
#DDSD_CAPS=1 
#DDSD_HEIGHT=2 
#DDSD_WIDTH=4 
#DDPF_RGB=64 
#DDPF_FOURCC=4 
#DDLOCK_WAIT=1 

Structure DDPIXELFORMAT 
  dwSize.l 
  dwFlags.l 
  dwFourCC.l 
  dwRGBBitCount.l 
  dwRBitMask.l 
  dwGBitMask.l 
  dwBBitMask.l 
  dwRGBAlphaBitMask.l 
EndStructure 

Structure DDCOLORKEY 
  dwColorSpaceLowValue.l 
  dwColorSpaceHighValue.l 
EndStructure 

Structure DDSCAPS2 
  dwCaps.l 
  dwCaps2.l 
  dwCaps3.l 
  dwCaps4.l 
EndStructure 

Structure DDSURFACEDESC2 
  dwSize.l 
  dwFlags.l 
  dwHeight.l 
  dwWidth.l 
  lPitch.l 
  dwBackBufferCount.l 
  dwRefreshRate.l 
  dwAlphaBitDepth.l 
  dwReserved.l 
  lpSurface.l 
  ddckCKDestOverlay.DDCOLORKEY 
  ddckCKDestBlt.DDCOLORKEY 
  ddckCKSrcOverlay.DDCOLORKEY 
  ddckCKSrcBlt.DDCOLORKEY 
  ddpfPixelFormat.DDPIXELFORMAT 
  ddsCaps.DDSCAPS2 
  dwTextureStage.l 
EndStructure 

Structure PB_Sprite 
  Sprite.l 
  Width.w 
  Height.w 
  Depth.w 
  Mode.w 
  FileName.l 
  RealWidth.w 
  RealHeight.w 
  ClipX.w 
  ClipY.w 
EndStructure 


Procedure CreateOverlayFromSprite(Sprite) 
  *Sprite.PB_Sprite=IsSprite_(Sprite) 
  
  *SrcDDS.IDirectDrawSurface7=*Sprite\Sprite 
  *SrcDDS\GetDDInterface(@*DD.IDirectDraw7) 
  
  Width=*Sprite\RealWidth 
  Height=*Sprite\RealHeight 
  
  ddsd.DDSURFACEDESC2 
  ddsd\dwSize=SizeOf(DDSURFACEDESC2) 
  ddsd\ddsCaps\dwCaps=#DDSCAPS_OVERLAY|#DDSCAPS_VIDEOMEMORY 
  ddsd\dwFlags=#DDSD_CAPS|#DDSD_HEIGHT|#DDSD_WIDTH|#DDSD_PIXELFORMAT 
  ddsd\dwWidth=Width 
  ddsd\dwHeight=Height 
  
  
  ddsd\ddpfPixelFormat\dwSize=SizeOf(DDPIXELFORMAT) 
  ddsd\ddpfPixelFormat\dwFlags=#DDPF_RGB 
  ddsd\ddpfPixelFormat\dwRGBBitCount=16 
  ddsd\ddpfPixelFormat\dwRBitMask=$F800 
  ddsd\ddpfPixelFormat\dwGBitMask=$07E0 
  ddsd\ddpfPixelFormat\dwBBitMask=$001F 
  Result=*DD\CreateSurface(ddsd,@*DDS.IDirectDrawSurface7,0) 
  Format=1 
  
  If Result 
    ddsd\ddpfPixelFormat\dwRBitMask=$7C00 
    ddsd\ddpfPixelFormat\dwGBitMask=$03E0 
    ddsd\ddpfPixelFormat\dwBBitMask=$001F 
    Result=*DD\CreateSurface(ddsd,@*DDS.IDirectDrawSurface7,0) 
    Format=1 
  EndIf 
  
  If Result 
    ddsd\ddpfPixelFormat\dwRGBBitCount=0 
    ddsd\ddpfPixelFormat\dwRBitMask=0 
    ddsd\ddpfPixelFormat\dwGBitMask=0 
    ddsd\ddpfPixelFormat\dwBBitMask=0 
    ddsd\ddpfPixelFormat\dwFlags=#DDPF_FOURCC 
    ddsd\ddpfPixelFormat\dwFourCC=PeekL(@"UYVY") 
    Result=*DD\CreateSurface(ddsd,@*DDS.IDirectDrawSurface7,0) 
    Format=2 
  EndIf 
  
  If Result 
    ddsd\ddpfPixelFormat\dwFourCC=PeekL(@"YUY2") 
    Result=*DD\CreateSurface(ddsd,@*DDS.IDirectDrawSurface7,0) 
    Format=3 
  EndIf 
  
  If Result:MessageRequester("Error","Can't create Surface !"):End:EndIf 
  
  SrcDC=StartDrawing(SpriteOutput(Sprite)) 
  
  If Format=1 
    
    *DDS\GetDC(@DC) 
    
    OpenLibrary(1,"GDI32.dll")
    CallFunction(1,"BitBlt",DC,0,0,Width,Height,SrcDC,0,0,13369376) 
    CloseLibrary(1)
    *DDS\ReleaseDC(DC) 
    
  Else 
    *DDS\Lock(0,ddsd,#DDLOCK_WAIT,0) 
    
    Addr=ddsd\lpSurface 
    Pitch=ddsd\lPitch 
    
    For y=0 To Height-1 
      For x=0 To Width-1 Step 2 
        
        C1=Point(x,y) 
        C2=Point(x+1,y) 
        
        Y0=     ( Red(C1)*29 +Green(C1)*57 +Blue(C1)*14)/100 
        U0=128 +(-Red(C1)*14 -Green(C1)*29 +Blue(C1)*43)/100 
        V0=128 +( Red(C1)*36 -Green(C1)*29 -Blue(C1)*07)/100 
        
        Y1=     ( Red(C2)*29 +Green(C2)*57 +Blue(C2)*14)/100 
        U1=128 +(-Red(C2)*14 -Green(C2)*29 +Blue(C2)*43)/100 
        V1=128 +( Red(C2)*36 -Green(C2)*29 -Blue(C2)*07)/100 
        
        Select Format 
          Case 2 
            PokeL(Addr,Y1<<24+((V0+V1)/2)<<16+Y0<<8+(U0+U1)/2):Addr+4 
          Case 3 
            PokeL(Addr,((V0+V1)/2)<<24+Y1<<16+((U0+U1)/2)<<8+Y0):Addr+4 
        EndSelect 
        
      Next 
      Addr+(Pitch-Width*2) 
    Next 
    
    *DDS\UnLock(0) 
  EndIf 
  
  StopDrawing() 
  
  ProcedureReturn *DDS 
EndProcedure 



Procedure ShowOverlay(*DDS.IDirectDrawSurface7,x,y,Width,Height) 
  re.RECT 
  re\left=x 
  re\right=x+Width 
  re\top=y 
  re\bottom=y+Height  
  
  *DDS\GetDDInterface(@*DD.IDirectDraw7) 
  *DD\GetGDISurface(@*GDI.IDirectDrawSurface7) 
  
  *DDS\UpdateOverlay(0,*GDI,re,#DDOVER_SHOW,0) 
EndProcedure 

Procedure FreeOverlay(*DDS.IDirectDrawSurface7) 
  *DDS\Release() 
EndProcedure 


  
InitSprite() 
OpenWindow(1,0,0,200,100,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Overlay-Test") 
OpenWindowedScreen(WindowID(),0,0,320,200,0,0,0) 

  
CreateSprite(1,256,64);Breite muss durch 2 teilbar sein. 

StartDrawing(SpriteOutput(1)) 
For x=0 To 255 
  For y=0 To 63 
    Plot(x,y,RGB(255-x,y*4,x)) 
  Next 
Next 
DrawingFont(LoadFont(1,"Arial",32)) 
DrawingMode(1) 
Locate(3,3) 
FrontColor(0,0,0) 
DrawText("Hallo Welt !!!") 
FrontColor(255,255,255) 
Locate(0,0) 
DrawText("Hallo Welt !!!") 
CloseFont(1) 
StopDrawing() 


Overlay=CreateOverlayFromSprite(1);Bei mir wird nur ein Overlay unterstützt. 

OpenLibrary(1,"user32.dll")
DesktopWidth=CallFunction(1,"GetSystemMetrics",16) 
DesktopHeight=CallFunction(1,"GetSystemMetrics",17) 
CloseLibrary(1)

Repeat 
  
  FlipBuffers() 
  
  Angle.f+0.02 
  
  x=Sin(Angle)*(DesktopWidth-256)/2+(DesktopWidth-256)/2 
  y=Cos(Angle)*(DesktopHeight-64)/2+(DesktopHeight-64)/2 
  
  ShowOverlay(Overlay,x,y,256,64) 
  
Until WindowEvent()=#PB_Event_CloseWindow 

FreeOverlay(Overlay) 


Gruß
Stefan
Benutzeravatar
KeyKon
Beiträge: 1412
Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM
PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM
Win10 x64 Home/Prof
PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:

Beitrag von KeyKon »

Ja! Danke :allright:
P.S.:Cooler Effekt

KeyKon
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

Was ich nicht verstehe: es wird ein Overlay-Surface erstellt. Dieses Surface sollte eigentlich andere Surfaces überlagern. Warum kann ich es dann nicht sehen, wenn ich während eines DirectX-Spiels mittels (globalem) Keyboard-Hook das Overlay anzeigen lasse (bzw. es versuche)?
Andreas21
Beiträge: 390
Registriert: 30.08.2004 09:05
Computerausstattung: Desktop
Windows 10 Pro x64
CPU: AMD Ryzen 5 2600 3.40 GHz
Ram: 16GB RAM
Grafik: NVIDA Geforce 1060
PB: 5.72 X86/X64
Wohnort: Heidelberg

Beitrag von Andreas21 »

Der Code geht super^^
Aber mich würde intressieren ob man es auch auf andere Fenster anzeigenlassen kann und nicht nur auf dem Desktop.

Ich meine auf anderen Directx Fenstern.

Ich hab versuch mit dem Code bisel zu spielen aber habs nicht hin bekommen. p.p
Windows 10 x64 Pro - PB 5.61 X64 / x32 - PB 4.6 x32
Benutzeravatar
coder
Beiträge: 204
Registriert: 25.09.2005 17:53
Computerausstattung: Intel Core2Quad Q8200 @ 2.33GHz
ASUS P5Q3, 2GB DDR3-1066 RAM, ATi Raedeon HD 4850
Wohnort: Deutschland
Kontaktdaten:

Beitrag von coder »

real hat geschrieben:Leider... :( Hast Du schon Ansätze (vielleicht in anderen Programmiersprachen)? Bei http://www.angelcode.com/dev/overlay/ gibt es ein Bsp. !
Hat schon mal jemand versucht den Code zu übersetzen..?
Windows 7 x64 | PureBasic 4.60 4.50 4.02
Ja verdammt, meine Eltern wohnen immer noch bei mir!
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Hat es mittlerweile schon jemand geschafft, ein Sprite auf einem anderem
Screen darzustellen (DirectX ... Spiel) ?

Mich würde interessieren, wo man denn angeben könnte, welcher Screen benutzt werden soll.
Eine Anzeige innerhalb eines Spiels a'la Steam oder XFire könnt ich gut gebrauchen ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Antworten