JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=51b410330d742066f3637dcc49e99e62Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Grafik-API mit Pixelzugriff
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
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

BeitragVerfasst am: 12.07.2006, 17:58    Titel: Grafik-API mit Pixelzugriff Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
Kovok
Mini JLI'ler


Alter: 36
Anmeldedatum: 06.07.2006
Beiträge: 8
Wohnort: Bonn
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 18:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden AIM-Name MSN Messenger
manu
Super JLI'ler


Alter: 35
Anmeldedatum: 09.03.2006
Beiträge: 327
Wohnort: allgäu (DE)
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 19:03    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 19:05    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 20:54    Titel: Antworten mit Zitat

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 thinking .
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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
Christian Rousselle
Site Admin


Alter: 48
Anmeldedatum: 19.07.2002
Beiträge: 1630

Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 21:47    Titel: Antworten mit Zitat

Ich denke, dass deine D3D Texture-Idee schnell genug sein sollte.Texturegröße von 768x512 sollte reichen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 22:17    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 12.07.2006, 23:15    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 13.07.2006, 08:46    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
AFE-GmdG
JLI MVP
JLI MVP


Alter: 45
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 13.07.2006, 08:52    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
magynhard
Super JLI'ler



Anmeldedatum: 26.04.2003
Beiträge: 461
Wohnort: Wild durch die Welt ;-)
Medaillen: Keine

BeitragVerfasst am: 13.07.2006, 13:36    Titel: Antworten mit Zitat

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. Rolling Eyes
_________________
Niemand ist hoffnungsloser versklavt als der, der fälschlich glaubt frei zu sein. [J. W. Goethe]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 13.07.2006, 15:58    Titel: Antworten mit Zitat

Ich habe zwar übewrhaupt keien Ahnung von OGL, aber sind Mipmaps nciht schwachsinnig?
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Kovok
Mini JLI'ler


Alter: 36
Anmeldedatum: 06.07.2006
Beiträge: 8
Wohnort: Bonn
Medaillen: Keine

BeitragVerfasst am: 17.07.2006, 12:43    Titel: Antworten mit Zitat

Jonathan_Klein hat Folgendes geschrieben:
Ich habe zwar übewrhaupt keien Ahnung von OGL, aber sind Mipmaps nciht schwachsinnig?


wieso das?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden AIM-Name MSN Messenger
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 17.07.2006, 13:04    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 17.07.2006, 13:30    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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

Impressum