Toon posts:

[MDX] Sprite verdwijnt wanneer ik m'n screen Clear()

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi,

Ben pas begonnen met wat aankloten met Managed DirectX. Erg leuk tot nu toe, ik kan al een hele driehoek renderen... juistem.

Maar nu ben ik bezig met mijn volgende obstakel: Sprites!

Het is me gelukt om een Sprite te renderen op de volgende manier:
C#:
1
2
3
localSprite.Begin(SpriteFlags.AlphaBlend);
localSprite.Draw2D(localTexture, new Rectangle(0, 0, 32, 32), new Rectangle(0, 0, 32, 32), new Point(0, 0), Color.White);
localSprite.End();


Maar, in mijn hoofd-loop voor het 'spel' heb ik een device.clear() functie aangeroepen, om het beeld te verversen. Maar als ik dat doe, dan verdwijnt mijn Sprite - terwijl deze wel weer wordt aangeroepen NA de Clear():

C#:
1
2
3
4
5
6
7
8
RenderDevice.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0); //clear

RenderDevice.BeginScene();
Player.Render();    //render player
RenderDevice.EndScene();
            
RenderDevice.Present();
this.Invalidate();


Dus het moment dat ik de RenderDevice.Clear() NIET aanroep, dan blijft m'n sprite staan in alle roem en glorie in welke hij is gemaakt.

Kan iemand me helpen? Ik heb al MDX documentatie doorgelezen maar deze zuigt echt enorm. Ook is er weinig te vinden op Google en alle voorbeeld codes die ik heb gezien gebruiken deze zelfde opzet.

Alvast bedankt!

[ Voor 6% gewijzigd door Verwijderd op 13-05-2006 17:17 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

zoek even op "Craig tutorial Direct3D"

btw: waarom doe je invalidate na de present ??

[ Voor 45% gewijzigd door H!GHGuY op 13-05-2006 18:37 ]

ASSUME makes an ASS out of U and ME


Verwijderd

Wanneer gebruik je nu precies je sprite render code? Ik weet niet wat player.Render() doet, maar als je je sprite binnen deze functie gebruikt zou het inderdaad goed moeten zijn. Zou je wat meer code kunnen laten zien, dan kan ik je misschien verder helpen?
waarom doe je invalidate na de present ??
Dit is nodig om een 'OnPaint' render loop aan de gang te houden. Een beter alternatief is de AppStillIdle loop, maar we kunnen misschien beter eerst even naar je sprite kijken ;)

[ Voor 3% gewijzigd door Verwijderd op 13-05-2006 19:05 ]


Verwijderd

Topicstarter
Sprite.Render() functie is bovenaan beschreven, aller eerste stukje code.

Anyway, ik heb 't opgelost min of meer, ik heb de Invalidate() weggehaald, toen bleef alles wel staan. Nou twijfel ik alleen eraan of mijn loop nog aan de gang gaat...

Verwijderd

Als je Invalidate weg laat, dan zou je loop idd moeten stoppen, dus in principe render je dan maar 1 frame en dat was het dan. Plaats eens een breakpoint in je OnPaint, dan kun je zien wat er precies gebeurt... Je rendering code (2e stukje) wordt toch wel in aangeroepen OnPaint, of niet?

[ Voor 3% gewijzigd door Verwijderd op 14-05-2006 11:51 ]


Verwijderd

Topicstarter
Ik zit meer met het probleem dat als ik Invalidate() weghaal, de loop stopt maar er wel een hele frame gerendered wordt. Maar als ik Invalidate() niet weghaal, dan gaat m'n loop door en verdwijnt alles. Hoe dat zo?

Verwijderd

Met Invalidate vraag je een repaint van je control aan, dus als je Sprite dan niet meer zichtbaar is, dan lijkt het erop dat je rendering code niet wordt uitgevoerd bij een repaint. Het probleem zit dus meer in hoe en of je render loop werkt. Daarom vroeg ik ook om wat meer code; als je rendering code door je OnPaint wordt aangeroepen, dan zou het moeten werken met die Invalidate.

Verwijderd

Topicstarter
Ok dit is mijn gameloop:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        protected override void OnPaint(PaintEventArgs e)
        {
            //clear screen, and lock GPU
            RenderDevice.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
            RenderDevice.BeginScene();

            //render player
            Player1.Render();
            Player2.Render();

            //unlock GPU and draw screen
            RenderDevice.EndScene();
             RenderDevice.Present();

            this.Invalidate();
        }


Dit is hoe mijn Player-class eruit ziet, hier wordt dus alles gerenderd en bla die bla:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    public class Player
    {
        private Microsoft.DirectX.Direct3D.Device localDevice;
        private Sprite localSprite;
        private Texture localTexture;
        private Bitmap PlayerBitmap = new Bitmap("player.png");
        public int PlayerX, PlayerY;
        private int PlayerSize;

        public Player(Microsoft.DirectX.Direct3D.Device device, int X, int Y, int pSize)
        {
            localDevice = device;
            localSprite = new Sprite(localDevice);
            localTexture = new Texture(device, PlayerBitmap, Usage.None, Pool.Managed);
            PlayerX = X;
            PlayerY = Y;
            PlayerSize = pSize;
        }

        public void Render()
        {
            localSprite.Begin(SpriteFlags.AlphaBlend);
            localSprite.Draw2D(localTexture, Rectangle.Empty, new Rectangle(0, 0, 32, 32), new Point(PlayerX, PlayerY), Color.White);
            localSprite.End();
        }
}


Dit is alles wat eraan is. Ik volg netjes tutorials maar dit gaat dus voor geen meter. En als ik mijn Invalidate() weghaal dan krijg ik 1 hele frame! :'(

[ Voor 6% gewijzigd door Verwijderd op 14-05-2006 12:59 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

ik denk niet dat het wenselijk is dat je je gameloop in de OnPaint() steekt...

maak liever een
while(run)
{
doeAlles()
Render()
}

ASSUME makes an ASS out of U and ME


Verwijderd

Topicstarter
Dat heb ik zojuist geprobeerd, dan zie ik helemaal niks en loopt m'n applicatie vast.

Verwijderd

Die OnPaint loop is zo erg nog niet, het is de makkelijkste manier om een oneindige lus te maken zonder dat je het afhandelen van Window Messages (input, repaint etc) blokkeert. Maar je zou het ook eens met HighGuys code kunnen proberen, alleen met de toevoeging van Application.DoEvents(); aan het einde van je loop (dus wel binnen je loop, maar na Render(); ).

Maar goed, ik kan in de code die je hebt gepost zo snel geen fout ontdekken.... Heb je de ControlStyle.AllPaintingInWMPaint al met SetStyle op je control ingesteld? Hierdoor voorkom je dat je control op eigen houtje de background over je sprite heen tekent. Het zou de eerste keer zijn dat ik hier zo'n probleem mee zie, maar het is een poging waard.

[ Voor 6% gewijzigd door Verwijderd op 14-05-2006 13:44 ]


Verwijderd

Topicstarter
Dit heb ik aan ControlStyles:
C#:
1
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);


Dat is goed neem ik aan? Als ik Opaque weghaal krijg ik geflikker bij het leven.

Ik zat trouwens te denken, heb ik misschien iets niet goed gedaan bij de D3D init?
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        public Microsoft.DirectX.Direct3D.Device SetRenderDevice(Control wnd, PresentParameters pp)
        {
            Microsoft.DirectX.Direct3D.Device RenderDevice = 
                new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, 
                wnd, CreateFlags.HardwareVertexProcessing, pp);
            return RenderDevice;
        }

        public PresentParameters SetPParams(bool wind, SwapEffect swap, Control control)
        {
            PresentParameters pp = new PresentParameters();
            pp.Windowed = wind;
            pp.SwapEffect = swap;
            pp.BackBufferHeight = control.Height;
            pp.BackBufferWidth = control.Width;
            pp.BackBufferCount = 2;

            if (wind)
            {
                pp.PresentationInterval = PresentInterval.Immediate;
            }

            return pp;
        }

///////////////// In mijn main.cs ///////////////
                GameWindow.presentParams = GameWindow.Engine.SetPParams(true, SwapEffect.Discard, GameWindow);
                GameWindow.RenderDevice = GameWindow.Engine.SetRenderDevice(GameWindow, GameWindow.presentParams);


Ik heb dit uit een tutorial gevolgd. Ik volg 't allemaal maar of het goed is...?

[ Voor 83% gewijzigd door Verwijderd op 14-05-2006 13:53 ]


Verwijderd

Het enige wat ik hieraan kan ontdekken is dat de PresentationInterval officieel niet aan de docs voldoet:
For a windowed swap chain, this value must be PresentInterval.Default (0). For a full-screen swap chain, it can be PresentInterval.Default or the value that corresponds exactly to one of the flags enumerated in Present.
Lijkt me sterkt dat dit er iets mee te maken heeft, want volgens mij is PresentInterval.Default juist gelijk aan PresentInterval.Immediate. Wat een vermoeiend probleem :+ Als je wilt kun je me je project eens doorsturen naar feedback(apestaartje)mdxinfo(punt)com, dan kan ik er eens aan knutselen om te zien of ik wat vind.

Verwijderd

Topicstarter
JIj werkt bij MDXInfo.com?? Ik zit nu op jullie IRC kanaal te praten met Kal_Torak

Verwijderd

Ik heb MDXInfo samen met Pieter opgericht om MDX wat bekender te maken en te proberen het tekort aan MDX tutorials en samples wat te verhelpen. Ik wist helemaal niet dat we al zo bekend waren :D

Op het IRC kanaal zit ik eigenlijk bijna nooit, want dan krijg ik helemaal niks meer gedaan. Enfin, als je er met Kal_Torak niet uit komt, dan zie ik wel een zip in de mail verschijnen ;)

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

pp.DeviceWindow = Control ??

ASSUME makes an ASS out of U and ME


Verwijderd

Had ik ook al eens uitgeprobeerd, maar dat maakte niks uit. Ik snap om eerlijk te zijn ook niet wat deze property in de PresentParameters class doet. Het idee is me wel duidelijk, maar de control/handle die je meegeeft in de device constructor blijft bepalend. Vreemd en weer goed gedocumenteerd :+

Maar goed, we zijn er in ieder geval wel uit gekomen. Wiegje gebruikte een oudere versie van de D3DX assembly en daarmee kreeg ik het ook niet aan de gang. Door de D3DX assembly uit de April 2006 SDK te gebruiken werkte het wel zoals verwacht, dus ik denk dat in die oude assembly gewoon een bug zat.

[ Voor 4% gewijzigd door Verwijderd op 14-05-2006 22:32 ]

Pagina: 1