Archief - DirectDraw buffer zelf gebruiken

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Katana

Legacy Member
Hallo!!

Ik ben net begonnen met een hoop tutorials over DirectX te bekijken. Ik zou graag een 2D-spelletje maken. Nu, in al die tutorials wordt gezegd hoe je een bitmap moet blitten op het scherm, hoe met sprites werken enzovoort enzovoort.. (met DirectDraw)
(Met d3d9 kan ik nu ook driehoekjes enzovoort op het scherm toveren, maar dat heb ik niet onmiddellijk nodig)

Wat ik dus wél nodig heb, is de volledige controle over mijn scherm. Waarbij ik dus bijvoorbeeld de buffer van DirectDraw (het stuk in het videogeheugen dat in de backbuffer zit) rechtstreeks kan manipuleren om dan te flippen. Misschien dat ergens een beginadres van deze buffer gedefinieerd is waar ik niet van weet?
Ik heb een voorbeeld gezien waarbij PutPixel de pixels één voor één op het scherm zet met directx, maar vanaf dat je een scherm van 640*480 wil vullen, zit je al een halve seconde bezig, dus da's ook geen oplossing.

Iemand die hier een oplossing voor kent/heeft, of een alternatief dat mij ook toelaat rechtstreeks in het geheugen te schrijven?

Veel dank bij voorbaat!

Ollie

Legacy Member
Katana zei:
Iemand die hier een oplossing voor kent/heeft, of een alternatief dat mij ook toelaat rechtstreeks in het geheugen te schrijven?

Veel dank bij voorbaat!

Probeer ergens de docs van DX7 vast te krijgen, daarin staat alles wat je nodig hebt.

fretn

Legacy Member
render naar een texture, en bewerk die texture dan , en render die texture dan op uw scherm ?
(gokjeuuuh :D )

Vich

Legacy Member
Je kan ook gewoon BitBlt ("blitten") via de Windows API. Maar of het aan je snelheidsverwachting voldoet weet ik niet.

QplQyer

Legacy Member
Code:
lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
USHORT *video_buffer = (USHORT *)ddsd.lpSurface;

Moet je wel eerst een Direct Draw Surface Description struct opbouwen en die in de variabele ddsd stoppen, dan kan je dus via ddsd.lpSurface aan je pointer naar je surface (video geheugen) geraken.

wlibaers

Legacy Member
Reck zei:
de standaard OpenGL oplossing :p

Ook de standaard DirectX 9 oplossing (DirectDraw krijgt geen updates meer, DirectX Graphics is de enige grafische component van nieuwere DirectX versies, en is eigenlijk de opvolger van Direct3D). Je moet inderdaad terug naar DirectX 7 voor de oude stijl.


OpenGL heeft trouwens wel functies om direct van hoofd-RAM naar een back- of frontbuffer te kopiëren, maar die werden traditioneel nooit echt geoptimaliseerd in de drivers (toch niet op PC hardware, op SGI machines en in bepaalde software OpenGL renderers zijn de functies wel snel), daarom dat de kopie naar texture gevolgd door het gebruik van die texture standaard geworden is.

Katana

Legacy Member
QplQyer zei:
Code:
lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
USHORT *video_buffer = (USHORT *)ddsd.lpSurface;

Moet je wel eerst een Direct Draw Surface Description struct opbouwen en die in de variabele ddsd stoppen, dan kan je dus via ddsd.lpSurface aan je pointer naar je surface (video geheugen) geraken.

Ah bedankt! Ik zal het eens proberen.

En hoe werkt die oplossing in dx9 dan precies? Dan moet je op je texture schrijven, en hoe gebeurt dat precies? Ook via een adres naar de texture ofzo?

Bedankt alvast voor de replies!

Katana

Legacy Member
Yippie, na wat prutsen werkt het! Nu nog even uitzoeken of het snel genoeg gaat.
Ik moest wel nog die USHORT vervangen door een int, omdat een short toch niet groot genoeg is om een geheugenadres in op te slaan..?
En het alternatief in DX9 is nog steeds welkom, omdat ik nu met directdraw7 zit en dat wordt al een beetje verouderd niet? :p

Bedankt alvast!

QplQyer

Legacy Member
Die USHORT gaf geen problemen bij mij hoor ... zo staat het trouwens in het boek "Tricks of the windows game programming gurus" beschreven.

Katana

Legacy Member
QplQyer zei:
Die USHORT gaf geen problemen bij mij hoor ... zo staat het trouwens in het boek "Tricks of the windows game programming gurus" beschreven.

Bij mij crasht hij als ik het probeer met een ushort.. Vreemd :)


Amai, zo'n verschillen. Als ik het scherm gewoon vul met nulletjes haal ik zo'n 400 frames/seconde, vanaf dat ik zoiets doe:

unsigned int *p = video_buffer;

for( int i = 0; i < 600; i++ ) {
for( int j = 0; j < 800; j++ ) {
afstand = (int)sqrt( (double)i*i + j*j );
*p++ = 0xff000000 + (i%256) + (timer%256)<<8 + (afstand%256)<<16;

};
p+=(pitch_min_width);
};

(Met pitch_min_width de lengte van het stuk buffer dat niet gebruikt wordt.)

Dan heb ik nog maar 'n 30 frames meer over... En dan heb ik nog niet het spel zelf geprogrammeerd :s (alhoewel de 'body' van het spel hoeft maar een 4-tal keer per seconde aangeroepen te worden).
Is het videogeheugen sneller of trager dan het ram? Anders maak ik een gigantische buffer (1024x600) (1024 is de pitch van het scherm) in het ram aan en memcpy ik gewoon heel het boeltje in m'n draw-functie..

Nog iemand die zoiets kan doen in directx 9? Misschien dat dat iets sneller gaat?

wlibaers

Legacy Member
OK, stel dat je een 3GHz processor hebt.

Delen door 30 fps -> 1e8 kloktikken per frame.

Delen door 800*600 geeft iets meer dan 200 kloktikken per pixel.

Vermits je conversies van int naar double en terug doet (vooral terug van double naar int is nogal traag in C), en dan nog naar videogeheugen schrijft (toch een beetje trager dan naar gewoon RAM) is dat eigenlijk nog wel normaal.

Type pointer zal uiteraard afhangen van het type surface - 16 of 32 bits (of 8, als je dat zou willen).
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan