|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 12.07.2006, 17:58 Titel: Grafik-API mit Pixelzugriff |
|
|
Hi allerseits,
mein Problem in aller Kürze: Ich benötige eine Grafik-API, welche mir die Manipulation jedes einzelnen Pixels gestattet, welche später auf dem Screen erscheinen sollen und das sollte auch noch möglichst performant geschehen. Unter "performant" verstehe ich >100 FPS bei einer Auflösung von 640x480 Pixel und einer Farbtiefe von 16 Bit auf einem low-end-System wie dem Meinigen (P4 1,7GHz, 512MB RAM, Radeon 9200 mit 64MB). Diese Werte sollten aber eher als Richtlinie dienen, 8 Bit würden mir gegebenenfalls sogar reichen - vielleicht sogar der gute alte ModeX, aber ich glaube, das geht zuweit.
Als ersten Gedanken hatte ich natürlich DirectDraw, aber ich musste mit Schrecken feststellen, dass es recht lahm ist damit 640x480 Pixel einzeln zusetzen (ca. 50 FPS im Fullscreen), eigentlich auch logisch, da DirectDraw ja afaik nicht mehr direkt auf Graka-Unterstützung bauen kann.
Das heißt aber auch, das ich irgendeine Alternative finden müsste, ein Gedanke den ich noch hatte, wäre die Funktion 'glDrawPixels', welche OGL bietet, aber nach ersten Recherchen scheint diese Funktion auch sehr langsam zu sein.
Noch ein Gedanke war, irgendwie in jedem Frame eine Textur aus einem Datenblock zu erzeugen und einfach über ein bildschirmgroßes Quad zu rendern. Ich kann mir aber irgendwie nicht vorstellen, dass das sonderlich performant wäre, da die Textur ja bei einer Auflösung von 640x480 Pixeln immerhin 1024x1024 Pixel groß sein müsste und das Ding in jedem Frame über den Bus zu jagen... adieu ihr schönen FPS. Ich hatte in dem Zusammenhang noch den Gedanken eventuell "dynamische" Texturen zu verwenden, OGL bietet ja die Möglichkeit dynamische VBOs auf der Grafikkarte zu speichern, welche gelockt und verändert werden können, warum sollte so etwas also nicht auch mit Texturen gehen? Gibt es da etwas in der Art? Kennt da vielleicht jemand eine passende Extension, welche auch schon seit geraumer Zeit existiert, wegen meinen Ansprüchen an die Hardware?
Vielleicht reicht auch die GDI vollkommen aus?
Bietet D3D etwas Vergleichbares zu 'glDrawPixels'?
Hat jemand vielleicht noch 'ne komplett andere Idee, kennt irgendein tolles SDK oder dergleichen? Oder will mich unwissenden Naivling vielleicht aus dem Irrglauben erlösen, dass es mit DD doch noch irgendwie schneller geht?
P.S.: Plattformunabhängigkeit wäre ein nettes Feature, aber kein Must-have. |
|
Nach oben |
|
|
Kovok Mini JLI'ler
Alter: 36 Anmeldedatum: 06.07.2006 Beiträge: 8 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 12.07.2006, 18:41 Titel: |
|
|
schau dir mal das buch an, der Autor macht genau dies. Ansonsten mach es selbst. Directx 7 nehmen und alles was du brauchst ist direkten zugriff auf Pixelspeicher, alles andere machste von hand |
|
Nach oben |
|
|
manu Super JLI'ler
Alter: 35 Anmeldedatum: 09.03.2006 Beiträge: 327 Wohnort: allgäu (DE) Medaillen: Keine
|
Verfasst am: 12.07.2006, 19:03 Titel: |
|
|
Vielleicht kann dir ja die SDL da alles bieten, was du brauchst. Ich kenne mich zwar nicht besonders gut mit der SDL aus, aber der direkte Zugriff auf Pixel ist so viel ich weiß schon möglich.
offizielle seite:
http://www.libsdl.org/tutorials.php
vllt. ist das ganz nützlich:
http://sol.gfxile.net/gp/ch04.html |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 12.07.2006, 19:05 Titel: |
|
|
dynamische Texturen werden nur ein wenig bringen. Fakt ist doch, das der Prozesor die Pixel berechnen soll, und die Graka die anzeigen sollen. Daher müssen auf jedne Fall alle auf die Garifkkarte kopiert werden.
Ich schätze aber mal, das es schneller gehen dürfte alle zusammen zu kopieren, statt jedne einzelnt. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Dr. Best Senior JLI'ler
Alter: 34 Anmeldedatum: 17.06.2004 Beiträge: 269 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 12.07.2006, 20:54 Titel: |
|
|
Du könntest mal ausprobieren dir in D3D per IDirect3DDevice::GetBackBuffer einen pointer auf das backbuffer surface zu holen und den dann zu locken. Ich weiß nicht ob das möglich ist aber wenn es geht dürfte es doch eigentlich halbwegs effizient sein .
Ansonsten fiele mir da auch noch die Funktion IDirect3DDevice8::CopyRects ein. Die dürfte zumindest effizienter sein als alles in eine überdimensionierte Textur zu speichern und die dann zu rendern.
Edit:
P.S. Die "realtime"-raytracing Fraktion in diesem Forum müsste doch eigentlich wissen wie das am effizientesten geht. |
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 12.07.2006, 21:47 Titel: |
|
|
Ich denke, dass deine D3D Texture-Idee schnell genug sein sollte.Texturegröße von 768x512 sollte reichen. |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 12.07.2006, 22:17 Titel: |
|
|
Ah, schon soviele Antworten, das ist toll. 8)
Kovok hat Folgendes geschrieben: | schau dir mal das buch an, der Autor macht genau dies. Ansonsten mach es selbst. Directx 7 nehmen und alles was du brauchst ist direkten zugriff auf Pixelspeicher, alles andere machste von hand |
Der LaMothe soll sowieso ziemlich klasse sein, wenn es darum geht ein tiefgehendes Verständnis für die Materie zu entwickeln, werde ich mir sicher demnächst mal zu Gemüte führen. Danke für den Hinweis. Über DirectX (ich nehme an, du meinst DD in der Version 7), und direktem Zugriff auf die Daten eines Surfaces hatte ich es schon getestet, leider mit durchwachsenen Ergebnissen.
manu hat Folgendes geschrieben: | Vielleicht kann dir ja die SDL da alles bieten, was du brauchst. Ich kenne mich zwar nicht besonders gut mit der SDL aus, aber der direkte Zugriff auf Pixel ist so viel ich weiß schon möglich. |
Gut, SDL bietet natürlich die Funktionalität, aber die baut unter Windows auch auf DD auf, womit wir wieder beim Knackpunkt wären. ;)
Jonathan_Klein hat Folgendes geschrieben: | dynamische Texturen werden nur ein wenig bringen. Fakt ist doch, das der Prozesor die Pixel berechnen soll, und die Graka die anzeigen sollen. Daher müssen auf jedne Fall alle auf die Garifkkarte kopiert werden.
Ich schätze aber mal, das es schneller gehen dürfte alle zusammen zu kopieren, statt jedne einzelnt. |
Jo, wenn das schnell genug von statten geht, ist das soweit auch kein Problem, ich werd's einfach mal testen. ;)
Dr. Best hat Folgendes geschrieben: | Du könntest mal ausprobieren dir in D3D per IDirect3DDevice::GetBackBuffer einen pointer auf das backbuffer surface zu holen und den dann zu locken. Ich weiß nicht ob das möglich ist aber wenn es geht dürfte es doch eigentlich halbwegs effizient sein :think: .
Ansonsten fiele mir da auch noch die Funktion IDirect3DDevice8::CopyRects ein. Die dürfte zumindest effizienter sein als alles in eine überdimensionierte Textur zu speichern und die dann zu rendern. |
Daran hatte ich auch schonmal gedacht, aber ich hab' mir sagen lassen, dass die D3D-Surfaces wohl auch nicht die Schnellsten sind, lasse mich aber auch gerne eines Besseren belehren. ;)
Achja, D3D hat immer noch den Haken, dass ich mich damit nicht sonderlich gut auskenne, aber ich denke das sollte kein Hindernis sein, gibt sicher sogar was äquivalentes für OpenGL.
Christian Rousselle hat Folgendes geschrieben: | Ich denke, dass deine D3D Texture-Idee schnell genug sein sollte.Texturegröße von 768x512 sollte reichen. |
Das wäre natürlich klasse. Werde ich jetzt einfach mal als erstes testen, muss nochmal schauen, ob OGL nicht-quadratische Texturen unterstützt... Ansonsten wäre D3D sicher eine gute Alternative, hat das OGL in dieser Hinsicht eventuell etwas vorraus? In OGL klappt das zumindest per Extension.
Danke für eure Tipps/Hinweise Jungs, ich werde glaube ich als erstes mal die Variante über die Textur testen. ;) |
|
Nach oben |
|
|
Dr. Best Senior JLI'ler
Alter: 34 Anmeldedatum: 17.06.2004 Beiträge: 269 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 12.07.2006, 23:15 Titel: |
|
|
768 als Dimension einer Textur? Hört sich für mich nicht gut an. In der D3DCAPS9 Struktur findet man unter TextureCaps die Capability D3DPTEXTURECAPS_POW2 die festlegt ob eine Grafikkarte dazu in der Lage ist bei Texturen Dimensionen zu verwenden die keine Potenzen von 2 sind. Und afaik ist das bei den meisten Grafikkarten nicht möglich.
Oder stellt 768 eine Ausnahme da?
Keine Ahnung wie sich das bei OGL verhält. |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 13.07.2006, 08:46 Titel: |
|
|
Das hatte mich auch etwas verwundert, das Problem ist, das ich von ziemlich antiquierter Zielhardware ausgehen muss, also nehme ich einfach mal an, dass es definitiv nicht unterstützt wird. ;) Bringt mich aber gerade auf die Idee, das man eventuell 2 kleinere Texturen verwenden könnte, um sich der gewünschten Auflösung anzunähern (z.B.: 512x512 und 512x256). |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 13.07.2006, 08:52 Titel: |
|
|
768 als Dimension für die Textur würde ich auch als unsinnig Ansehen, aber was möglich und Sinnig wäre ist eventuell 2 Texturen zu verwenden, eine 512x512 und eine 128x512.
Diese Texturen Packst du am besten mit FVF_XYZRHW|FVF_TEXTURED auf den Screen.
Ich denke dass sollte mit DX9 kein Problem darstellen. Langsamer als andere Varianten sollte es nicht sein und du kannst hierbei sehr schön die Direct3DFunktionen zum Blenden, Rotieren und Skalieren nutzen (einfach passende Koordinaten für die Eckpunkte aussuchen ^^; )
Was du noch machen kannst, ist die Auflösung 512x384 zu nutzen, das ist zwar ein kleines bisschen kleiner als 640x480 aber passt auf eine 512x512 Textur. _________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
magynhard Super JLI'ler
Anmeldedatum: 26.04.2003 Beiträge: 461 Wohnort: Wild durch die Welt ;-) Medaillen: Keine
|
Verfasst am: 13.07.2006, 13:36 Titel: |
|
|
GreveN hat Folgendes geschrieben: | Werde ich jetzt einfach mal als erstes testen, muss nochmal schauen, ob OGL nicht-quadratische Texturen unterstützt... |
Also beim Laden von Texturen gings, wenn ich anstatt
glTexImage2D(...) // (nur 2^X)
einfach
gluBuild2DMipmaps(...)
hernahm.
Ob Du überhaupt das gesucht hast, weiß ich nicht - aber vielleicht ein Denkanstoß. Bin kein OpenGL-Freak. _________________ Niemand ist hoffnungsloser versklavt als der, der fälschlich glaubt frei zu sein. [J. W. Goethe]
|
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 13.07.2006, 15:58 Titel: |
|
|
Ich habe zwar übewrhaupt keien Ahnung von OGL, aber sind Mipmaps nciht schwachsinnig? _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Kovok Mini JLI'ler
Alter: 36 Anmeldedatum: 06.07.2006 Beiträge: 8 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 17.07.2006, 12:43 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Ich habe zwar übewrhaupt keien Ahnung von OGL, aber sind Mipmaps nciht schwachsinnig? |
wieso das? |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 17.07.2006, 13:04 Titel: |
|
|
Ich hab die "Hardcore"-Variante über eine Textur, die in jedem Frame verändert und auf die Karte geschoben wird mal ausgetestet, die Ergebnisse waren nicht überwältigend, ~60 FPS bei 512x512 Pixeln und 24 Bit. Hier einmal der Testsource, vielleicht hab ich auch nur einen grob fahrlässigen Fehler gemacht, kA:
CPP: | unsigned char* pixels = new unsigned char[786432];
::ZeroMemory(pixels, sizeof(pixels));
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
glClear(GL_COLOR_BUFFER_BIT);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, -1.0f);
glEnd();
SwapBuffers (hDC);
}
}
delete[] pixels; |
(FPS gemessen mit Fraps)
Ich hab mich natürlich mal noch ein bisschen erkundigt, scheinbar sperren "moderne" Grafikkarten den Videospeicher für die CPU, es ist also nicht mehr ohne Weiteres möglich direkt auf den Grafikspeicher zu zugreifen, nur noch über die Grafikkarte, und dafür verwendet man natürlich D3D, DD, OGL usw. Ich hab natürlich auch mal geschaut wie verschiedene Software-Renderer das machen, der Irrlicht-Software-Renderer will z.B. einen "Presenter" übergeben haben, welcher das eigentliche Anzeigen übernimmt, läuft also im Endeffekt auch auf DD oder Ähnliches hinaus. Die Meisten Raytracer bauen auch auf DD. So richtig glücklich bin ich damit aber nicht, weil DD eben scheinbar so langsam ist, gibt's da nicht irgendwelche "Tricks"? Vielleicht per Assembler? Wie machen die Jungs aus der Demoszene das? Die werden doch kaum D3D und Co. zurückgreifen, oder? |
|
Nach oben |
|
|
Dr. Best Senior JLI'ler
Alter: 34 Anmeldedatum: 17.06.2004 Beiträge: 269 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 17.07.2006, 13:30 Titel: |
|
|
Eine Optimierung hätt ich für deinen Code. Wenn du die OpenGL Entsprechung zu D3DRS_ZENABLE auf false setzt müsstest du dir das Clearen eigentlich sparen können. Das dürfte eine merkliche Verbesserung mit sich bringen. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|