Wiki Page Content

Differences between revisions 5 and 6
Revision 5 as of 2014-01-22 05:53:02
Size: 37424
Editor: norbert
Comment: Tiny fix.
Revision 6 as of 2014-02-13 03:42:24
Size: 120
Editor: RyanGordon
Comment: Removed Dutch translation, due to various concerns.
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#pragma section-numbers off
#pragma camelcase off

= SDL 1.2 naar 2.0 migratiehandleiding =

||<tablestyle="text-align:center; width: 90%">This is a translation of the original [[MigrationGuide|English version]]. Dit is een vertaling van de originele [[MigrationGuide|Engelstalige versie]].||

<<TableOfContents()>>

== Vertalingen ==

 * Une traduction de cette page par Developpez.com est disponible [[http://jeux.developpez.com/tutoriels/sdl-2/guide-migration/|ici]].
 * Als u deze pagina wil vertalen naar andere talen, laat Ryan dit dan weten: icculus@icculus.org

== Introductie ==

Na vele jaren in ontwikkeling te zijn geweest, is SDL 2.0 eindelijk uitgebracht!

We zijn nogal trots erop, en we willen graag dat spellen die SDL 1.2 gebruiken onmiddellijk de overstap maken. Aangezien dit kan aanvoelen als een afschrikwekkende taak, bevat dit document simpele, stapsgewijze instructies over hoe te migreren naar de nieuwe library. We denken dat u zult zien dat het niet zo moeilijk is als u denkt, en u zult veelal ofwel functie-aanroepen vervangen met directe equivalenten of enige hacks in uw brontekst om om te gaan met 1.2 tekortkomingen ongedaan maken.

We denken dat u zeer tevreden zult zijn met SDL 2.0, zowel met de nieuwe mogelijkheden als de betere ervaring dan met SDL 1.2. Dit document probeert niet te omvatten al de geweldige nieuwe dingen in SDL2--dat zijn er vele--maar enkel de dingen die u moet doen om het ''direct'' draaiende te krijgen. Als u uw brontekst eenmaal omgezet hebt, raadpleeg dan zeker de nieuwe dingen; u zult waarschijnlijk ook een deel ervan willen toevoegen aan uw applicatie.

=== Overzicht van nieuwe mogelijkheden ===
Dit zijn de meest belangrijke nieuwe mogelijkheden van SDL 2.0:

 * Volledige 3D apparatuuracceleratie
 * Ondersteuning voor OpenGL 3.0+ voor diverse profielen (kern, compatibiliteit, foutopsporing, robuustheid, enz)
 * Ondersteuning voor OpenGL ES
 * Ondersteuning voor meerdere vensters
 * Ondersteuning voor meerdere schermen
 * Ondersteuning voor meerdere geluidsapparaten
 * Android en iOS ondersteuning
 * Simpele 2D render API die, achter de schermen, Direct3D, OpenGL, OpenGL ES, of software-rendering kan gebruiken
 * Haptische terugkoppeling beschikbaar onder Windows, Mac OS X en Linux
 * XInput en XAudio2 ondersteuning voor Windows
 * Atomaire operaties
 * Energiebeheer (vaststellen resterende batterijduur, enz)
 * Aangepaste venstervormen
 * 32-bit geluid (int en float)
 * Vereenvoudigde spelbesturingsapparaat API (de joystick API is nog immer beschikbaar!)
 * Ondersteuning voor aanraakschermen (multi-touch, veegbewegingen, enz)
 * Betere fullscreen ondersteuning
 * Betere toetsenbord ondersteuning (scancodes vs toetscodes, enz).
 * Berichtvensters
 * Klembord ondersteuning
 * Simpele slepen-en-neerzetten ondersteuning
 * Fatsoenlijke unicode invoer en IME ondersteuning
 * [[CategoryAssertions|Een zeer krachtige assert-macro]]
 * zlib licentie in plaats van LGPL.
 * Veel van de oude ergernissen van 1.2 zijn verdwenen
 * Vele andere dingen!

De [[Introduction|Introductie]] pagina heeft een meer omvangrijke lijst van welke mogelijkheden SDL in zijn algemeenheid biedt (inclusief oude 1.2 mogelijkheden).

=== Op zoek naar meer informatie ===

De beste plekken met informatie zijn:
 * deze wiki :)
 * de testen meegeleverd met SDL, in de {{{test/}}} directory ([[http://hg.libsdl.org/SDL/file/default/test|blader online]])
 * de SDL [[http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org|mailinglijst]]


== Overstappen van SDL 1.2 naar 2.0 ==

=== Enkele algemene waarheden ===

Er is geen compatibiliteitslaag ingebouwd in SDL2. Als een API veranderde voor 2.0, hebben we de oude functies veranderd of verwijderd waar dit logisch is. Als u uw 1.2 programma laat wijzen naar de 2.0 headerbestanden, zal het waarschijnlijk niet willen compileren. Dit document zal proberen u te leiden langs de meest belangrijke wijzigingen, en degenen die het meest waarschijnlijk zijn u te laten struikelen.

Er is geen SDL_main! Nou, oké, er ''is'', en het doet nu wat het altijd bedoeld was te doen: een klein stukje brontekst zijn dat het verschil verbergt tussen `main()` en `WinMain()` onder Windows. Er is geen initialisatie-brontekst erin, en het is volkomen optioneel. Dit betekent dat u SDL kunt gebruiken zonder dat u het overneemt in uw 'hoofdlijn', wat mooi is voor invoegtoepassingen die SDL gebruiken, of scripttalen met een SDL module. Al de dingen waarvoor u de 1.2 SDL_main zou willen zijn nu in SDL_Init() waar ze thuishoren.

Er is geen SDL parachute meer. Wat 1.2 `SDL_INIT_NOPARACHUTE` noemde is nu de standaard en enige toestand. Dit zou problemen veroorzaken als iets anders dan de hoofd-thread crashte, en het zou belemmeren dat toepassingen hun eigen signaal/uitzondering handlers instellen. Aan de negatieve kant, sommige platformen ruimen fullscreen video niet goed op na crashes. U moet uw eigen crash handler installeren, of [[SDL_Quit]]() aanroepen in een `atexit()` functie of iets dergelijks als u zich hierover bezorgd maakt. Merk op dat op Unix platformen, SDL nog immer `SIGINT` afvangt en koppelt aan een [[SDL_EventType|SDL_QUIT]] event.


=== Video ===
==== Het instellen van een spel met de nieuwe video API ====

De video API is het meest drastisch gewijzigd van 1.2. Behoeften zijn heel erg veranderd sinds SDL's API was ontworpen eind jaren 1990. Om met moderne apparatuur en OS mogelijkheden om te gaan, hebben we de oude 1.2 video API bijna compleet vervangen.

Maak u geen zorgen, de nieuwe is tamelijk geweldig, en als u eenmaal begrijpt wat is veranderd, zult u zeer tevreden zijn met de nieuwe mogelijkheden die het kan brengen voor uw 1.2 spel. We zullen die later bespreken.

Het goede nieuws: als uw spel OpenGL gebruikte, hoeft u waarschijnlijk niet veel te doen: verander een handvol functie-aanroepen naar hun SDL2 equivalenten, en u bent klaar.

Voor 2D graphics bood SDL 1.2 een concept genaamd "oppervlakken," dat waren geheugenbuffers van pixels. Het scherm zelf was een "oppervlak," als u aan 2D software rendering deed, en we verschaften functies om pixels te kopiëren ("blitten") tussen oppervlakken, onderwijl formaten omzettende waar nodig. U was bijna altijd aan het werk op de CPU en in systeem RAM, niet op de GPU en in het videogeheugen. SDL 2.0 verandert dit; u krijgt nu bijna altijd apparatuuracceleratie, en de API is dienovereenkomstig aangepast.

Als u een 2D spel hebt, is de kans groot dat u een van drie benaderingen hebt genomen om te renderen. Ze zullen die allemaal langsgaan, maar eerst, laten we praten over inleidende dingen.

Herinnert u zich SDL_SetVideoMode()? Dat is volledig verdwenen. SDL 2.0 staat u toe meerdere vensters te hebben, dus de oude functie was niet logisch meer.

U had wellicht iets als dit:

{{{#!highlight cpp
SDL_WM_SetCaption("Mijn spelvenster", "spel");
SDL_Surface *scherm = SDL_SetVideoMode(640, 480, 0, SDL_FULLSCREEN | SDL_OPENGL);
}}}

Wat nu dit is:

{{{#!highlight cpp
SDL_Window *scherm = SDL_CreateWindow("Mijn spelvenster",
                          SDL_WINDOWPOS_UNDEFINED,
                          SDL_WINDOWPOS_UNDEFINED,
                          640, 480,
                          SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
}}}

U kunt zien dat dit gelijkenis toont aan 1.2. Het verschil is dat u meerdere vensters kunt hebben (als u wilt), en u hebt meer controle over ze. `SDL_WM_SetCaption` is weg, want we willen toestaan dat elk venster zijn eigen titel heeft (u kunt het later veranderen met [[SDL_SetWindowTitle]]()), en we willen u een vensterpositie laten opgeven (of, in dit geval, '''SDL_WINDOWPOS_UNDEFINED''' laten gebruiken aangezien het ons niet uitmaakt waar het systeem het plaatst. '''SDL_WINDOWPOS_CENTERED''' is ook een goede keuze).

U krijgt extra krediet als u gebruikers een beeldscherm laat opgeven voor het venster: SDL2 laat u ook systemen met meerdere monitoren beheren. Maakt u zich op dit moment echter geen zorgen daarover.

Nu uw venster terug is op het scherm, is het tijd om over uw strategie te spreken. SDL2 heeft nog steeds [[SDL_Surface]], maar wat u wilt, waar mogelijk, is het nieuwe [[SDL_Texture]]. Oppervlakken zijn nu altijd in systeem RAM, en worden altijd bewerkt door de CPU, dus daaraan willen we ontsnappen. SDL2 heeft een nieuwe rendering API. Het is bedoeld voor gebruik door simpele 2D spellen, maar met name, het is bedoeld om al het software-renderen in video RAM te krijgen en naar de GPU. En zelfs als u het enkel wilt gebruiken om het werk van uw software-renderer naar het scherm te krijgen, brengt het enige zeer mooie voordelen: waar mogelijk, zal het OpenGL of Direct3D gebruiken achter de schermen, wat betekent dat u gratis snellere blits, een werkende Steam Overlay, en schaalbaarheid krijgt.

Het is als volgt ingericht.

`SDL_SetVideoMode()` wordt [[SDL_CreateWindow]](), zoals we eerder besproken. Maar hoe regelen we de resolutie? Als uw spel hard-gecodeerd was op 640x480, bijvoorbeeld, liep u waarschijnlijk aan tegen monitoren die dat niet op fullscreen-resolutie aankonden op dat moment, en in venstermodus zag uw spel er waarschijnlijk uit als een geanimeerde postzegel op zeer high-end monitoren. Er is een betere oplossing in SDL2.

We roepen `SDL_ListModes()` niet meer aan. Er is een equivalent in SDL2 (roep [[SDL_GetDisplayMode]]() aan in een lus, [[SDL_GetNumDisplayModes]]() keer), maar in plaats daarvan gaan we een nieuwe mogelijkheid gebruiken genaamd "fullscreen desktop," die SDL zegt "geef me het hele scherm en wijzig de resolutie niet." Voor ons hypothetische 640x480 spel, kan dit er zo uitzien:

{{{#!highlight cpp
SDL_Window *sdlVenster = SDL_CreateWindow(titel,
                             SDL_WINDOWPOS_UNDEFINED,
                             SDL_WINDOWPOS_UNDEFINED,
                             0, 0,
                             SDL_WINDOW_FULLSCREEN_DESKTOP);
}}}

Merk op dat we niet specificeerden 640 of 480...fullscreen desktop geeft u het hele scherm en negeert elke afmeting die u opgeeft. Het spelvenster zou direct moeten verschijnen, zonder te hoeven wachten op het verspringen van het scherm in een nieuwe resolutie, en we zullen de GPU gebruiken om te verschalen naar de bureaubladgrootte, wat de neiging heeft sneller en netter ogend te zijn dan als een LCD een lagere resolutie nabootst. Bijkomend voordeel: geen van uw achtergrondvensters verschalen zichzelf op dit moment.

Nu hebben we een renderingskader nodig.

{{{#!highlight cpp
SDL_Renderer *renderer = SDL_CreateRenderer(sdlVenster, -1, 0);
}}}

Een renderer verbergt de details van hoe we tekenen in het venster. Dit zou achter de schermen Direct3D kunnen gebruiken, OpenGL, OpenGL ES, of software-oppervlakken, afhankelijk van wat het systeem biedt; uw brontekst blijft onveranderd, ongeacht wat SDL kiest (hoewel u welkom ''bent'' om één of andere soort renderer af te dwingen). Als u wilt proberen om sync-naar-vblank af te dwingen om scheuren te verminderen, kunt u '''SDL_RENDERER_PRESENTVSYNC''' gebruiken in plaats van nul voor de derde parameter. U moet hier geen venster creëren met de '''SDL_WINDOW_OPENGL''' vlag. Als [[SDL_CreateRenderer]]() beslist dat het OpenGL wil gebruiken, zal dat het venster naar behoren voor u bijwerken.

Nu dat u begrijpt hoe dit werkt, kunt u dit ook allemaal doen in één stap met [[SDL_CreateWindowAndRenderer]](), als u niet iets bijzonders wilt:

{{{#!highlight cpp
SDL_Window *sdlVenster;
SDL_Renderer *sdlRenderer;
SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, &sdlVenster, &sdlRenderer);
}}}

Ervan uitgaande dat deze functies niet mislukten (controleer altijd op NULLs!), bent u klaar om te starten met tekenen op het scherm. Laten we om te beginnen het scherm opschonen naar zwart.

{{{#!highlight cpp
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
SDL_RenderClear(sdlRenderer);
SDL_RenderPresent(sdlRenderer);
}}}

Dit werkt zoals u zou denken; teken in zwart (r,g,b allen nul, volledig alfa), schoon het hele venster op, plaats het opgeschoonde venster op het scherm. Jazeker, als u `SDL_UpdateRect()` gebruikte of `SDL_Flip()` om uw bits op het scherm te krijgen, gebruikt de render API [[SDL_RenderPresent]]().

Er is hier één extra algemeen ding om in te stellen. Aangezien we '''SDL_WINDOW_FULLSCREEN_DESKTOP''' gebruiken, ''weten'' we niet daadwerkelijk de hoeveelheid scherm waarnaar we moeten tekenen. Gelukkig hoeven we dat niet te weten. Een van de mooie dingen van 1.2 is dat u kon zeggen "Ik wil een 640x480 venster en het maakt me niet uit hoe je dat gedaan krijgt," zelfs als het gedaan krijgen betekende het venster centreren in een hogere resolutie ten behoeve van uw applicatie.

Voor 2.0, de render API laat u dit doen...

{{{#!highlight cpp
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "lineair"); // maak de verschaalde rendering gladder ogend.
SDL_RenderSetLogicalSize(sdlRenderer, 640, 480);
}}}

...en het zal het juiste ding doen voor u. Dit is fijn aangezien u de logische rendergrootte kunt wijzigen om verschillende effecten te bereiken, maar het primaire gebruik is dit: in plaats van te proberen het systeem te laten werken met uw rendergrootte, kunnen we nu uw rendergrootte laten werken met het systeem. Op mijn 1920x1200 beeldscherm denkt deze applicatie nu te praten tegen een 640x480 resolutie, maar SDL gebruikt de GPU om op te schalen om al die pixels te gebruiken. Merk op dat 640x480 en 1920x1200 niet dezelfde beeldverhoudingen zijn: SDL draagt ook daar zorg voor, verschaalt zo veel mogelijk en letterboxt het verschil.

Nu zijn we echt klaar om te beginnen met tekenen.


==== Als uw spel alleen maar volledig gerenderde frames naar het scherm wil krijgen ====

Een speciaal geval zijn oldschool, met software gerenderde spellen: de applicatie wil zelf elke pixel tekenen en de uiteindelijke verzameling pixels efficiënt naar het scherm krijgen in één grote blit. Een voorbeeld van zo'n spel is ''Doom'', of ''Duke Nukem 3D'', of vele andere.

Hiervoor zult u een enkele SDL_Texture willen die het scherm zal representeren. Laten we er nu een creëren voor ons 640x480 spel:

{{{#!highlight cpp
sdlTexture = SDL_CreateTexture(sdlRenderer,
                               SDL_PIXELFORMAT_ARGB8888,
                               SDL_TEXTUREACCESS_STREAMING,
                               640, 480);
}}}

Dit komt neer op een texture op de GPU. De strategie is om elk frame te voltooien middels het uploaden van pixels naar deze texture, het texture te tekenen naar het venster, en deze flipt de tekening op het scherm. '''SDL_TEXTUREACCESS_STREAMING''' vertelt SDL dat de inhoud van deze texture regelmatig zal wijzigen.

Voorheen had u waarschijnlijk een [[SDL_Surface]] voor het scherm waarop uw applicatie tekende, vervolgens riep u `SDL_Flip()` aan om naar het scherm te schrijven. Nu kunt u een [[SDL_Surface]] creëren die altijd in RAM is in plaats van datgene gebruiken wat u zou hebben gekregen van `SDL_SetVideoMode()`, of enkel een blok met pixels malloc()en om naar te schrijven. Idealiter schrijft u naar een buffer met RGBA pixels, maar als u een conversie moet uitvoeren, dat is ook goed.

{{{#!highlight cpp
extern Uint32 *mijnPixels; // misschien is dit een oppervlak->pixels, of een malloc()'d buffer, of wat dan ook.
}}}

Aan het einde van het frame, willen we als volgt uploaden naar het texture:

{{{#!highlight cpp
SDL_UpdateTexture(sdlTexture, NULL, mijnPixels, 640 * sizeof (Uint32));
}}}

Dit zal uw pixels uploaden naar het GPU geheugen. Die NULL kan een subregio zijn als u wilt prutsen met 'vuile rechthoeken', maar de kans is groot dat moderne apparatuur gewoon de hele framebuffer kan verwerken zonder veel moeite. Het laatste argument is de hoogte--het aantal bytes vanaf de start van een rij tot de volgende--en aangezien we een lineaire RGBA buffer hebben in dit voorbeeld, is het enkel 640 keer 4 (r,g,b,a).

Om nu dat texture op het scherm te krijgen:

{{{#!highlight cpp
SDL_RenderClear(sdlRenderer);
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
SDL_RenderPresent(sdlRenderer);
}}}

Dat is alles. [[SDL_RenderClear]]() veegt de bestaande video framebuffer uit (in het geval, zeg, de Steam Overlay het laatste frame overschreef), [[SDL_RenderCopy]]() verplaatst de inhoud van de texture naar de video framebuffer (en dankzij [[SDL_RenderSetLogicalSize]](), zal het zijn verschaald/gecentreerd alsof het beeldscherm 640x480 was), en [[SDL_RenderPresent]]() plaatst het op het scherm.


==== Als uw spel oppervlakken wil blitten naar het scherm ====

In dit scenario laadt uw SDL 1.2 spel een stel afbeeldingen van schijf naar een stel [[SDL_Surface]]s, mogelijk probeerde u ze in video RAM te krijgen met `SDL_HWSURFACE`. U laadt deze eenmaal, en u blit ze telkens weer naar de framebuffer indien nodig, maar afgezien daarvan veranderen ze nooit. Een simpel 2D platformspel zou dit kunnen doen. Als u geneigd bent te denken over uw oppervlakken als "sprites," en niet buffers van pixels, dan is het volgende waarschijnlijk geschikt voor u.

U kunt individuele textures bouwen (oppervlakken die leven in het GPU geheugen) zoals we deden voor die ene grote texture:

{{{#!highlight cpp
sdlTexture = SDL_CreateTexture(sdlRenderer,
                               SDL_PIXELFORMAT_ARGB8888,
                               SDL_TEXTUREACCESS_STATIC,
                               mijnWijdte, mijnHoogte);
}}}

Dat doet wat je zou verwachten. We gebruiken '''SDL_TEXTUREACCESS_STATIC''', want we gaan onze pixels eenmaal uploaden in plaats van telkens weer. Maar een gemakkelijkere oplossing is wellicht:

{{{#!highlight cpp
sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, mijnOppervlak);
}}}

Gebruik dit, en u laadt uw [[SDL_Surface]] zoals gebruikelijk, maar dan aan het einde maakt u een texture ervan. Heeft u eenmaal een [[SDL_Texture]], dan kunt u de originele oppervlakken vrij maken.

Op dat moment had uw 1.2 spel een aantal [[SDL_Surface]]s, welke het zou [[SDL_BlitSurface]]()en naar het schermoppervlak om de uiteindelijke framebuffer samen te stellen, en tenslotte `SDL_Flip()t` naar het scherm. Voor SDL 2.0, hebt u een aantal [[SDL_Texture]]s, die u zult [[SDL_RenderCopy]]()en naar uw Renderer om de uiteindelijke framebuffer samen te stellen, en tenslotte [[SDL_RenderPresent]]() naar het scherm. Zo simpel is het. Als deze textures nooit aangepast hoeven te worden, zult u mogelijk ondervinden dat uw framesnelheid zojuist ook door het dak is gegaan.


==== Als uw spel beide wil doen ====

Dingen worden ietwat gecompliceerder als u oppervlakken wilt blitten ''en'' individuele pixels wilt wijzigen in de framebuffer. Rondreizen--het teruglezen van gegevens van textures--kan pijnlijk kostbaar zijn; doorgaans wilt u altijd gegevens in één richting duwen. U bent waarschijnlijk het beste af, in dit geval, als u alles in software houdt tot de laatste push naar het scherm, dus we zullen de twee vorige technieken combineren.

Het goede nieuws: de 1.2 [[SDL_Surface]] API bestaat grotendeels nog steeds. Dus wijzig uw schermoppervlak van dit:

{{{#!highlight cpp
SDL_Surface *scherm = SDL_SetVideoMode(640, 480, 32, 0);
}}}

...naar dit...

{{{#!highlight cpp
// als al deze hex u afschrikt, raadpleeg SDL_PixelFormatEnumToMasks()!
SDL_Surface *scherm = SDL_CreateRGBSurface(0, 640, 480, 32,
                                        0x00FF000,
                                        0x0000FF00,
                                        0x000000FF,
                                        0xFF000000);
SDL_Texture *sdlTexture = SDL_CreateTexture(sdlRenderer,
                                            SDL_PIXELFORMAT_ARGB8888,
                                            SDL_TEXTUREACCESS_STREAMING,
                                            640, 480);
}}}

...en blijf dingen blitten en pixels afstellen als voorheen, uw definitieve framebuffer samenstellende in deze [[SDL_Surface]]. Zodra u klaar bent om die pixels op het scherm te krijgen, doet u dit net als in ons eerste scenario:

{{{#!highlight cpp
SDL_UpdateTexture(sdlTexture, NULL, scherm->pixels, scherm->hoogte);
SDL_RenderClear(sdlRenderer);
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
SDL_RenderPresent(sdlRenderer);
}}}

Merk op dat een texture creëren zowel kostbaar als een beperkte hulpbron kan zijn: roep niet voor elk frame [[SDL_CreateTextureFromSurface]]() aan. Stel een texture in en een oppervlak, en werk eerstgenoemde met laatstgenoemde bij.

De Render API heeft meer mogelijkheden, waarvan sommige mogelijk in staat zijn brontekst van uw applicatie te vervangen: verschalen, lijntekenen, enz. Als u dit gedeelte leest omdat u simpele behoeften hebt die verder gaan dan oppervlakken blitten, bent u mogelijk in staat te stoppen met het porren van individuele pixels en kunt u alles verplaatsen naar de GPU, wat uw programma een significante snelheidsverhoging zal geven en waarschijnlijk uw brontekst zeer vereenvoudigt.

==== Andere Renderer API aandachtspunten ====

U kunt enkele simpele effecten bewerkstelligen met de render API zonder aan de slag te hoeven gaan met directe pixel manipulatie. Enkele van deze waren beschikbaar voor 1.2 oppervlakken.

 * Kleur alfa: [[SDL_Color]] bevat nu een vierde, '''alfa''' element. Uw 1.2 brontekst die zich bezighoudt met SDL_Colors kopieerde/zette die waarde mogelijk niet (die was genaamd `unused`). In 2.0 moet u dit wel doen.
 * Afa-vermenging: gebruik [[SDL_SetSurfaceAlphaMod]] en [[SDL_SetTextureAlphaMod]] in plaats van `SDL_SetAlpha()`. Alfa-vermenging op oppervlakken kan worden uitgeschakeld via [[SDL_SetSurfaceBlendMode]]() en op textures met [[SDL_SetTextureBlendMode]]().
 * Kleursleutel: Als u [[SDL_SetColorKey]]() aanroept, moet u `SDL_TRUE` meegeven in plaats van `SDL_SRCCOLORKEY`.
 * Kleurmodulering: Sommige renderers ondersteunen nu een globale kleurwijziging ({{{brnC = brnC * kleur}}}), bekijk [[SDL_SetTextureColorMod]]() voor meer informatie.

=== OpenGL ===

Als u OpenGL al rechtstreeks gebruikte, is uw migratie vrij simpel. Verander uw `SDL_SetVideoMode()` aanroep in [[SDL_CreateWindow]]() gevolgd door [[SDL_GL_CreateContext]](), en uw `SDL_GL_SwapBuffers()` aanroep in [[SDL_GL_SwapWindow]](venster). Al de daadwerkelijke aanroepen in de GL zijn precies hetzelfde.

Als u [[SDL_GL_SetAttribute]](SDL_GL_SWAP_CONTROL, x) gebruikte, dit is veranderd. Er is nu een [[SDL_GL_SetSwapInterval]](x) aanroep, zodat u dit kunt veranderen op een bestaande GL context.

Merk op dat SDL 2.0 kan schakelen tussen venstermodus en fullscreen met OpenGL vensters zonder de GL context te verliezen (hoera!). Gebruik [[SDL_SetWindowFullscreen]]() hiervoor.


=== Invoer ===

Het goede nieuws is dat SDL 2.0 Unicode invoer mogelijk heeft gemaakt. Het slechte nieuws is dat het enkele kleine veranderingen zal behoeven in uw applicatie.

In 1.2 riepen veel applicaties die zich enkel druk maakten over VS Engels nog immer `SDL_EnableUNICODE(1)` aan, omdat het nuttig was om het teken te krijgen dat was verbonden met een toetsaanslag. Dit werkte niet goed zodra men zich buiten het Engels begaf, en het werkte al ''helemaal niet'' zodra men te maken kreeg met Aziatische talen.

Het blijkt dat i18n moeilijk is.

SDL heeft dit veranderd. `SDL_EnableUNICODE()` is verdwenen, en evenzo is [[SDL_Keysym]]'s `unicode` veld. U krijgt niet langer tekeninvoer van [[SDL_EventType|SDL_KEYDOWN]] events. Gebruik [[SDL_EventType|SDL_KEYDOWN]] nu om het toetsenbord te behandelen als een 101-knops joystick. Tekstinvoer komt ergens anders vandaan.

Het nieuwe event is [[SDL_EventType|SDL_TEXTINPUT]]. Dit wordt teweeggebracht telkens als er nieuwe tekst is ingevoerd door de gebruiker. Merk op dat deze tekst misschien komt van toetsaanslagen, of het misschien komt van een soort van IME (dat is een chique manier om ingewikkelde, multi-teken tekst in te voeren). Dit event geeft volledige strings terug, die misschien één teken lang zijn, of verscheidene codeposities met multi-tekengegevens. Deze string is altijd in UTF-8 gecodeerd.

Als alles wat u belangrijk vindt is of de gebruiker een bepaalde toets indrukte, dat is nog altijd [[SDL_EventType|SDL_KEYDOWN]], maar we hebben dit systeem gesplitst in twee delen vanaf 1.2: toetscodes en scancodes.

Scancodes zijn bedoeld om lay-out onafhankelijk te zijn. Beschouw dit als "de gebruiker drukte de Q toets in als het zou zijn op een VS QWERTY toetsenbord" ongeacht of dit daadwerkelijk een Europees toetsenbord is of een Dvorak toetsenbord of wat dan ook. De scancode is altijd dezelfde toetspositie.

Toetscodes zijn bedoeld om lay-out afhankelijk te zijn. Beschouw dit als "de gebruiker drukte de toets met het label 'Q' op zijn specifieke toetsenbord in."

Bijvoorbeeld, als u de toets indrukte die twee toetsen rechts is van CAPS LOCK op een VS QWERTY toetsenbord, zal het een scancode rapporteren van SDL_SCANCODE_S en een toetscode van SDLK_S. Dezelfde toets op een Dvorak toetsenbord zal een scancode rapporteren van SDL_SCANCODE_S en een toetscode van SDLK_O.

Merk op dat zowel toetscodes als scancodes nu 32 bits zijn, en een breed scala aan nummers gebruiken. Er is geen `SDLK_LAST` meer. Als uw programma een opzoektabel had met SDLK_LAST elementen, om te laveren tussen SDL toetsen en hetgeen uw applicatie intern wilde, dat is niet meer mogelijk. Gebruik in plaats daarvan een hashtabel. Een `std::map` bijvoorbeeld. Als u werkt met scancodes in plaats van toetscodes, is er '''SDL_NUM_SCANCODES''', dat u kunt gebruiken voor matrixgrenzen. Diens waarde is momenteel 512.

`SDLMod` is nu [[SDL_Keymod]] en diens "META" toetsen (de "Windows" toetsen) worden nu de "GUI" toetsen genoemd.

`SDL_GetKeyState()` is hernoemd naar [[SDL_GetKeyboardState]](). De resulterende matrix zou nu geïndexeerd moeten zijn op SDL_SCANCODE_* waarden (zie [[SDL_Scancode]]) in plaats van [[SDL_Keysym]] waarden.

Nu dan, wat betreft muisinvoer.

De eerste verandering, eenvoudigweg, is dat het muiswiel niet langer een knop is. Dit was een historische fout die we hebben gecorrigeerd in SDL 2.0. Kijk of er [[SDL_EventType|SDL_MOUSEWHEEL]] events zijn. Wij ondersteunen zowel verticale als horizontale wieltjes, en sommige platformen kunnen tevens twee-vinger scrollen op een trackpad afhandelen als wielinvoer. U zult niet langer [[SDL_EventType|SDL_BUTTONDOWN]] events ontvangen voor muiswieltjes, en knoppen 4 en 5 zijn nu echte muisknoppen.

Als uw spel de muis voor altijd moet rollen in één richting, bijvoorbeeld om een speler in een FPS rond te laten draaien zonder de muis de rand van het scherm te laten raken en te stoppen, verborg u waarschijnlijk de muiscursor en greep u de invoer:

{{{#!highlight cpp
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
}}}

In SDL2 werkt dit ietwat anders. U roept aan...

{{{#!highlight cpp
SDL_SetRelativeMouseMode(SDL_TRUE);
}}}

...en SDL doet de rest.


=== Events ===

[[SDL_PushEvent]]() geeft nu `1` terug bij succes in plaats van `0`.

Events mask worden nu gespecificeerd middels bereiken:

{{{#!highlight cpp
SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN));
}}}

wordt:

{{{#!highlight cpp
SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN);
}}}


=== Geluid ===

Het goede nieuws voor geluid is dat, met één uitzondering, het volledig achterwaarts compatibel is met 1.2. Als u de nieuwe mogelijkheden wilt, ze zijn voor u beschikbaar, maar u zult waarschijnlijk gewoon zonder ze compileren en draaien.

Die ene heel belangrijke uitzondering: De geluid-callback begint NIET meer met een geheel geïnitialiseerde buffer. U '''''moet''''' in alle gevallen volledig schrijven naar de buffer. Als u niet genoeg geluid hebt, dan moet uw callback stilte schrijven. Als u dit nalaat zult u herhaald geluid horen, of wellicht verstoord geluid. Als u het oude gedrag wilt herstellen van onvoorwaardelijk initialiseren van de buffer, plaats dan gewoon een SDL_memset(stream, 0, len) bij aanvang van uw callback.


=== Joysticks ===

Joystick events verwijzen nu naar een SDL_JoystickID. Dit is omdat SDL 2.0 kan omgaan met het komen en gaan van joysticks, aangezien apparaten worden aangesloten en uitgetrokken gedurende de levensduur van uw spel, dus de inhoudsopgave in de apparatenlijst die 1.2 gebruikt zou zinloos zijn doordat de beschikbare apparatenlijst verandert.

Om een SDL_JoystickID te krijgen voor uw geopende SDL_Joystick*, roept u aan:

{{{#!highlight cpp
SDL_JoystickID mijnID = SDL_JoystickInstanceID(mijnGeopendeStick);
}}}

En vergelijk het joystick events' '''which''' veld met `mijnID`. Als u geen gebruik maakt van de gebeurteniswachtrij voor joysticks, werken [[SDL_JoystickGetAxis]]() en dergelijke net als bij SDL 1.2.

U moet ook de nieuwe [[CategoryGameController|Game Controller API]] raadplegen, aangezien die cool is, en wellicht sparde u veel met de 1.2 API dat deze nieuwe brontekst netter zou kunnen oplossen. U kunt het vinden in SDL_gamecontroller.h. De Game Controller API integreert heel mooi met Steam Big Picture Mode: u krijgt automatische configuratie van de meeste controllers, en een mooie UI als u het manueel moet configureren. In elk geval geeft Steam deze configuratie door aan uw SDL applicatie.

Ondersteuning voor de oudere joystick API (/dev/input/js*) voor Linux is geschrapt uit SDL2. SDL2 ondersteunt alleen de nieuwe events API (/dev/input/event*) voor joysticks. Deze events zijn doorgaans niet leesbaar voor normale gebruikersaccounts, dus zelfs als joysticks zijn aangesloten zult u er waarschijnlijk geen hebben gedetecteerd. Dit is iets dat eindgebruikers voor zichzelf moeten configureren.


=== Threads ===

`SDL_KillThread()` is verdwenen. Het was nimmer veilig of betrouwbaar. De beste vervanging is om een vlag te zetten die een thread vertelt dat het dient te stoppen. Die thread moeten met enige regelmaat de vlag controleren, en dan roept de "killing" thread [[SDL_WaitThread]]() aan om op te ruimen.

[[SDL_CreateThread]]() verwacht nu een extra parameter, een naam voor de thread, die kan worden gebruikt door debuggers om het te identificeren. Als het u niet kan schelen, voeg dan gewoon een extra NULL toe aan uw functie-aanroep.


=== Audio-cd's ===

De 1.2 cd API is volledig verdwenen. Er is geen vervanging. De kans is groot dat u op dit moment uw muziek niet verzendt als cd-audiosporen op een schijf, als u überhaupt een schijf verzendt. U kunt [[http://www.vorbis.com/|Ogg Vorbis]] gebruiken of een ander audiobestandsformaat voor muziek, waarvan er vele worden verstrekt door SDL_mixer.


=== Dode platformen ===

We hebben een stel oude platformen eruit gerukt, zoals OS/2 en Mac OS 9. Het is gemakkelijker om een overzicht te geven van degene die we nog ondersteunen: Windows (XP en nieuwer), Linux, Mac OS X, iOS, Android. In de traditie van SDL zijn er andere platformen die werken maar niet zwaar ondersteund worden, zoals Haiku en Sony PSP. We zullen elk platform toevoegen waarvoor iemand patches stuurt, maar het leek alsof het tijd was om afscheid te nemen van een aantal oude vrienden bij de verhuizing naar de nieuwe versie.


=== Mobiele platformen ===

Er zijn, jarenlang, onofficiële ports geweest van SDL 1.2 naar iOS en Android. SDL ondersteunt deze platformen nu rechtstreeks, en de 2.0 API is veel beter geschikt voor ze. De meeste adviezen die u elders in dit document kreeg zijn van toepassing, maar er is een aantal andere dingen vermeldenswaardig.

Om te beginnen, er zijn bepaalde events die alleen van toepassing zijn op mobiele apparaten, of beter gezegd, van toepassing zijn op de manier waarop OSen van mobiele apparaten neigen te werken in een post-iPhone wereld. Oorspronkelijk probeerden we deze te koppelen aan de bestaande SDL events (zoals "uw applicatie gaat naar de achtergrond" wordt behandeld als een bureaubladvenster dat focus verliest), maar er is een meer urgente zaak: de meeste van deze events behoeven een onmiddellijke reactie, en als de applicatie er geen geeft, zal het OS uw applicatie sluiten.

Derhalve hebben we nieuwe SDL events toegevoegd voor enkele Android en iOS bijzonderheden, maar u moet een SDL event filter instellen om ze te vangen zodra het OS ze meldt, want wachten op uw volgende [[SDL_PollEvent]]() lus zal te laat zijn.

Bijvoorbeeld, er is SDL_APP_WILLENTERBACKGROUND, dat is iOS's `applicationWillResignActive()`, en als u tekent naar het scherm nadat dit event binnenkomt, eindigt iOS uw proces. U wilt deze dus onmiddellijk afvangen:

{{{#!highlight cpp
int SDLCALL mijnEventFilter(void *gebruikersgegevens, SDL_Event * event)
{
    if (event->type == SDL_APP_WILLENTERBACKGROUND) {
        // resources vrijmaken, TEKEN NIET MEER totdat u weer in de voorgrond bent!
    }
    // enz
    return 1;
}

// ergens bij het opstarten...

// dit roep mijnEventFilter(gegevens, event) aan zodra event wordt gegenereerd.
SDL_AddEventWatch(mijnEventFilter, gegevens);
}}}

Ten tweede, er zijn nu echte touch events, in plaats van te proberen dit te koppelen aan muisinvoer. U kunt touches volgen, meerdere vingers, en zelfs ingewikkelde gebaren. U wilt die waarschijnlijk gebruiken. Raadpleeg SDL_touch.h voor een lijst met die functies, en zoek naar [[SDL_Finger]]* in SDL_events.h.

Er is een handvol andere mobiel-vriendelijke functies, zoals [[SDL_StartTextInput]](), die het virtueel toetsenbord zal tonen. Maak gebruik ervan.

Bovendien zijn er ook Android en iOS specifieke functies, om u toegang te geven tot platform-specifieke mogelijkheden die niet zinvol zouden zijn in een algemene API. Raadpleeg SDL_system.h voor een lijst van deze functies.


=== RWops ===

[[SDL_RWread]]() en [[SDL_RWwrite]]() geven nu `0` terug bij een fout in plaats van `-1`.

Als u uw eigen [[SDL_RWops]] implementatie schreef, de functie-signatures zijn veranderd. Functies gebruiken nu `Sint64` en `size_t` in plaats van `int` dus ze kunnen werken met grote bestanden. In veel gevallen kunt u gewoon uw functie-signatures actualiseren en blijven werken als voorheen, maar als u aanliep tegen deze beperkingen zou u blij kunnen zijn een oplossing te hebben. Aangeroepen applicaties moeten weten dat de geretourneerde waarden zijn veranderd.

Er is nu ook een '''size'''-methode voor RWops. Dit laat een RWops de grootte rapporteren van de stream zonder de applicatie te moeten laten zoeken naar nul bytes vanaf het einde; met andere woorden, u kunt een totale grootte rapporteren voor streams waarin niet gezocht kan worden. Voor streams waarbij zelfs voorgaande niet werkt, kunt u nog immer -1 teruggeven.


=== Add-on bibliotheken ===

De officiële extensies SDL_image, SDL_ttf, SDL_mixer en SDL_net hebben een versie die zich toelegt op SDL 2.0: SDL2_image, SDL2_ttf, SDL2_mixer en SDL2_net. Het kan nodig zijn om ze te downloaden van de [[http://hg.libsdl.org/|mercurial repository's]] voor de recente correcties. Vervolgens, vanzelfsprekend, zult u moeten linken bijv. SDL2_image, niet SDL_image, om uw programma te compileren.

Deze bibliotheken zullen 1.2 in de toekomst niet ondersteunen, en elke compatibiliteit met 1.2 zal waarschijnlijk op enig moment verdwijnen uit nieuwere versies.

[[http://www.ferzkopp.net/joomla/content/view/19/14/|SDL_gfx]] kan ook worden gecompileerd met 2.0 vanaf versie 2.0.21 (mei 2010).


=== Samenvatting van enkele hernoemde of vervangen dingen ===

Een kort spiekbriefje waar enkele van de oude functies en andere dingen heen zijn gegaan:
 * SDL_SetVideoMode(): gebruik [[SDL_CreateWindow]]() in de plaats (samen met [[SDL_CreateRenderer]]() als u klassieke 2D rendering wilt gebruiken en niet OpenGL)
 * SDL_ListModes(): gebruik [[SDL_GetDisplayMode]]()/[[SDL_GetNumDisplayModes]]() in de plaats
 * SDL_UpdateRect()/SDL_Flip(): gebruik [[SDL_RenderPresent]]() in de plaats
 * SDL_Surface/2D rendering: oppervlakken bestaan ​​nog steeds, maar het wordt aanbevolen dat u in plaats van SDL_Surfaces waar mogelijk [[SDL_Texture]]s gebruikt met een 2D geaccelereerde renderer ([[SDL_CreateRenderer]]())
 * SDL_VideoInfo: gebruik [[SDL_GetRendererInfo]]()/[[SDL_GetRenderDriverInfo]]() in de plaats
 * SDL_GetCurrentVideoDisplay(): gebruik [[SDL_GetWindowDisplayIndex]]() in de plaats
 * SDL_VIDEORESIZE event: het nieuwe equivalent is [[SDL_WindowEvent|SDL_WINDOWEVENT_RESIZE]]


=== Andere dingen ===

Er is een enorme hoeveelheid van nieuwe en interessante functionaliteiten in SDL 2.0 waarvan 1.2 niet eens kon dromen. We hebben hier alleen geprobeerd uit te leggen wat u mogelijk moet doen om uw 1.2 programma draaiend te krijgen met 2.0, maar u zou de documentatie moeten verkennen voor dingen die u misschien altijd wenste en waarmee u het, tot nu toe, zonder moest doen. Bijvoorbeeld, elk spel dat ik ooit omzette bevatte uiteindelijk een berichtvenster-functie die er als volgt uitzag:

{{{#!highlight cpp
#if GEBRUIK_SDL
fprintf(stderr, "BRTVENSTER: %s\n%s\n", titel, tekst); // ach ja.
#endif
}}}

Nu is er [[SDL_ShowSimpleMessageBox]](). Graag gedaan!

Als u vooruit sprong naar dit gedeelte, ga terug en bekijk al de nieuwe mogelijkheden [[#Overzicht van nieuwe mogelijkheden|in het overzicht]]!
This page has been removed. The original English version of the [[MigrationGuide|Migration Guide]] is still available.

This page has been removed. The original English version of the Migration Guide is still available.

None: Migratiehandleiding (last edited 2014-02-13 03:42:24 by RyanGordon)

(Page Info.)
Feedback
Please include your contact information if you'd like to receive a reply.
Submit