Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Rendering context opengl (https://www.delphipraxis.net/44658-rendering-context-opengl.html)

Arnulf 22. Apr 2005 12:08


Rendering context opengl
 
Hi
Hat schon mal jemand versucht dirrekt den frontbuffer einer fremden opengl anwendung zu bekommen?
Ich würde gerne mit
glReadPixels
einen screenshot machen - oder vielleicht sogar ein video.

Dazu bräuchte ich aber den rendering context des programms.
Wenn ich mir den dc hol und einen neuen RC erstelle, dann rendere ich leider nicht in der laufenden anwendung zwar am gleichen fenster aber hald eine neue grafik :(.

Damit kann ich dann natürlich auch keinen screenshot machen..
vielleicht weiß hier jemand rat?

Danke
Arnulf

c113plpbr 24. Apr 2005 01:25

Re: Rendering context opengl
 
Zitat:

Zitat von Arnulf
Hat schon mal jemand versucht dirrekt den frontbuffer einer fremden opengl anwendung zu bekommen?

Ich denke ja ... ich hab das schon öfter versucht und auch durchgeführt, allerdings immer mit dem "fertigen" Backbuffer (text vor dem zeichnen eines neuen frames hinzufügen), was aber eigentlich aufs gleiche rauskommt ^^ ...
Zitat:

Zitat von Arnulf
Ich würde gerne mit
glReadPixels
einen screenshot machen - oder vielleicht sogar ein video.

Da kann ich dir nicht weiter helfen (ich bin OGL-noob ^^, und bin froh, wenn ich verstehe wie ein polygon gezeichnet wird ...)
Zitat:

Zitat von Arnulf
Dazu bräuchte ich aber den rendering context des programms.

API-Hooking ist da dein bester, und warscheinlich auch einziger Freund: Da du warscheinlich das fertige Bild brauchst, müsstest du die "SwapBuffers"-Funktion abfangen, und deinen Screenshot anhand des übergebenen DC Handles erstellen.
Für's API-Hooking verwende und empfehle ich meist die MadCodeHook Library. Bei Fragen zum Thema API-Hooking kann ich dir weiterhelfen, allerdings nicht bei OpenGL Fragen.

ciao, Philipp

Speedmaster 24. Apr 2005 10:00

Re: Rendering context opengl
 
Guckst du hier!!!

Arnulf 24. Apr 2005 12:01

Re: Rendering context opengl
 
Zitat:

API-Hooking ist da dein bester, und warscheinlich auch einziger Freund:
Oje Oje - hooking versteh ich nicht im gerningsten.
Ja ich könnte madcodehook verwenden - und mir einen hook basteln (schaut ja nicht schwer aus).
Aber ich denke ich versteh da die basis nicht.

Ich müsste also eine funktion in der libary opengl32.dll hooken?
Das bedeutet ich muß die libary mit load libary laden und versuchen den handle für die .dll zu bekommen um die Procedure SwapBuffers abzufangen.

Oder ich lagere meine screenshot funktion in eine .dll aus und injiziere die dann?
Dann wüsste ich aber immer noch nicht wie ich die libary schreiben sollte. weil ich keine ahnung hab wie ich von meiner injizierten libary auf den backbuffer zugreife.

Einen text in den backbuffer zu rendern und dann zu warten bis swapbuffer aufgerufen wird ist vermutlich besser als zu versuchen auf den frontbuffer zuzugreifen - hab noch garnich daran gedacht.
Somal ich auch keine ahnung hab wie ich den front buffer bekomme :).

hm... - einen hook zu schreiben würde ich vielleich schaffen, aber ich denke ich versteh die theorie nicht dahinter und das machts mir schwer.
Auch eine procedure in einer anderen libary abzufangen ist mir schleierhaft.

Ich weiß es gibt einige tutorials dazu wie man das macht, aber das verständniss fehlt mir ein bisschen dafür.

Wäre super wenn mir jemand helfen könnte genau das zu machen. - Also auf den Backbuffer eines programms zuzugreifen und einen screenshot rauszuholen.
glReadpixel bekomm ich hin - abgesehen von dem beispiel das Speedmaster hier angeführt hat :)

nur den hook schaff ich nicht.
Danke auf jeden fall.
War schon mal ein hinweis wie das gehen könnte :)

Arnulf

sniper_w 24. Apr 2005 12:23

Re: Rendering context opengl
 
swapbuffers() befindet sich im gdi32.dll. Du solltest die ganze dll kapseln, damit du weist wann die swapbuffers aufgerufen wird...
Danachh rufst du glReadPixels.....denke ich zu mindest....such mal in Google "Fraps"

Arnulf 24. Apr 2005 12:54

Re: Rendering context opengl
 
ah i see.
fraps - genau das was ich machen will.
im prinzip - allerdings will ich das selbst machen in meiner eigenen anwendung.
gdi32.dll? - naja dann hätt ich sogar in der falschen libary gesucht :).

trotzdem - ich muß hier von grund auf ein paar dinge lernen.
was meinst du mit kapseln?
mein verständniss davon ist, daß ich zwei möglichkeiten hab.
1. ich injiziere eine .dll - die einen localen hook macht und mir den aufruf der procedure swapbuffer meldet.

2. ich versuch den handle der libary im speicher zu bekommen.

beides hab ich noch nie gemacht und ist für mich auch schwer zu verstehen.

Ich versuch mich da gerade einzulesen, deshalb mag das was ich sage auch keinen sinn ergeben :)
Vielleich könnte mir jemand sagen ob ich am richtigen weg bin? - oder wie man das theoretisch macht und ich versuch mir dann mal ein bisschen code zusammen zu basteln.
Damit bekomm ich wenigstens mal ein bisschen mehr verständnis für die materie .....

Das ist doch sehr neu für mich.
Aber irgendwie freuts mich mal wieder was neues zu machen lol

Danke
Arnulf

c113plpbr 24. Apr 2005 13:58

Re: Rendering context opengl
 
Das in deiner "eigenen" Anwendung zu machen, wird ein ding der unmöglichkeit sein, wenn du es mit OpenGL-Befehlen lösen willst.
Aber du könntest doch auch einfach einen "normalen" Screenshot machen, z.B. so wie das Windows macht, also [PrintScreen]-Tastenmäßig. Das sollte bei OpenGL Anwendungen (meistens) auch funktionieren.

Zu API-Hooking gibt es noch eine Alternative: einen DLL-Wrapper zu schreiben, wobei die bei der gdi32.dll warscheinlich in ein lebenswerk ausarten würde ... :zwinker:

Zur API-Hooking Methode:
Als erstes musst du sämtlichen Code, der zur Erstellung des Screenshots gehört, und alles drumherum in eine DLL verfrachten.
Desweiteren brauchst du eine Callback funktion der SwapBuffers-Funktion. Diese wird dann anstelle der originalen SwapBuffers-Funktion aufgerufen. In dieser Funktion machst du dann deinen Screenshot mithilfe des übergebenen DC's (aber natürlich nicht bei jedem aufruf! am besten eine taste abfragen). Da du das, was die Anwendung eigentlich anzeigen will ja nicht auf den Bildschirm bringst, musst du noch einen Prototypen einer SwapBuffers Next Funktion deklarieren, und diese dann immer aufrufen.
In der DLL-Main Funktion steht dann im normalfall der Code zum Hooken der Funktion. Diese weist dann der Next funktion einen Pointer auf die originalfunktion zu, und leitet den funktionsaufruf von SwapBuffers auf deine SwapBuffersCallback funktion um.

Soweit doch garnicht schwer, oder? :mrgreen:

(zum glück hast du dir opengl ausgesucht ... directx wäre wesentlich schwieriger)

ciao, Philipp

sniper_w 24. Apr 2005 14:06

Re: Rendering context opengl
 
Zitat:

einen DLL-Wrapper zu schreiben
Das meinte ich mit Dll - kapseln...

Zitat:

wobei die bei der gdi32.dll warscheinlich in ein lebenswerk ausarten würde ...
Einfach :mrgreen: . Tolle bemerkung, aber nicht ganz unmöglich.... :mrgreen:

Zitat:

(zum glück hast du dir opengl ausgesucht ... directx wäre wesentlich schwieriger)
Obwohl ich immer mit OpenGL arbeite, wenn es um die Grafik geht, da bin ich aber anderer Meinung.

c113plpbr 24. Apr 2005 14:22

Re: Rendering context opengl
 
Zitat:

Zitat von sniper_w
Das meinte ich mit Dll - kapseln...

Wie auch immer, nur was genau meinst du dann damit?
Zitat:

Zitat von sniper_w
Einfach :mrgreen: . Tolle bemerkung, aber nicht ganz unmöglich.... :mrgreen:

Natürlich ist es möglich, nur ich würde es keinem empfehlen ... ;)
Zitat:

Zitat von sniper_w
Zitat:

(zum glück hast du dir opengl ausgesucht ... directx wäre wesentlich schwieriger)
Obwohl ich immer mit OpenGL arbeite, wenn es um die Grafik geht, da bin ich aber anderer Meinung.

Naja, zum hooken ist DX schwieriger ... auf jeden fall ... denn der weg zur Present-Funktion, ist nicht gerade "eben" (nagut, kommt auch wieder draufan, wie man's macht ... ^^).

ciao, Philipp

Arnulf 24. Apr 2005 23:01

Re: Rendering context opengl
 
Naja gut daß ihr euch einig seids :) - oder auch nicht.

Jedenfalls ist das wirklich nicht leicht zu verstehen. - Bin hald ein anfänger in der Beziehung.

Abgesehen vom injizieren der .dll (das bring ich vielleicht mit codeschnipseln hin) ist ja das hooken von funktionen oder proceduren in der gdi32.dll das hauptproblem hier.

Leider finde ich zu dem thema nur cheats :( für irgendwelche spiele und damit eben für opengl32.dll.
Das interessiert mich ned besonders und hilft mir dabei auch nicht recht weiter, weil die scheinbar keinen eigenen code verwenden, sondern nur grafiken verschwinden lassen (wände oder sowas).

trotzdem frag ich mich ob das auch für gdi32.dll funktionieren würde?

jedenfalls nehm ich mal so einen cheat her und bau den für mich um.....
mal sehen ob mir dabei jemand zu meinem ziel verhelfen kann :).

Delphi-Quellcode:
begin
  if getmodulehandle(pchar('gdi32.dll')) > 0 then
  begin
    @oldldrgetprocaddress := getprocaddress(getmodulehandle(pchar('gdi32.dll')),pchar('LdrGetProcedureAddress'));
    hookit(@oldldrgetprocaddress, @myldrgetprocaddress, ldrgetprocaddresssave);
  end;
end.

Delphi-Quellcode:
function myldrgetprocaddress(h: integer; f: pmychar; o: integer; var p: pointer): integer; stdcall;
var buf: array[0..255] of char;
    i: integer;
    s: string;
    sp: tspeicher;
begin
  ldrgetprocaddresssave.address^ := ldrgetprocaddresssave.save;  // unhook orig function
  i := GetModuleFileName(h,@buf,sizeof(buf));
  if (i > 0) and (f <> nil) then
  begin
    s := f^.d+' ';
    if pos(uppercase('swapbuffers '),uppercase(s)) > 0 then
    begin
      p := getprocaddress(h,pchar('swapbuffers'));
      hookit(p,@myswapbuffers,sp);
      result := oldldrgetprocaddressh,f,o,@swapbuffers);
    end else result := oldldrgetprocaddress(h,f,o,p);
  ldrgetprocaddresssave.address^ := ldrgetprocaddresssave.hook;  // hook orig function
end;

procedure hookit(fromfkt, tofkt: Pointer; var save: tspeicher); // hook a function
var
  old: cardinal; // old protect in memory
  NewCode: tjumpcode;  // jump to my function
  jump: ^array7;       // array to save
begin
  virtualprotect(Fromfkt, 7, $40, @old);            // let me write in memory
  save.address := Fromfkt;                          // saves hooked address
  Move(Fromfkt^, save.save, 7);                     // saves 5 bytes of orig address
  NewCode.bla1 := $55;                               // asm hex code for a jump
  newcode.bla2 := $5d;
  NewCode.wo := integer(tofkt)-integer(fromfkt)-7; // calculate address
  newcode.jmp := $e9;
  jump := @newcode;                                 // for save the jump
  save.hook := jump^;                               // save jump
  Move(save.hook, Fromfkt^, 7);                    // write jump to orig address
end;

procedure myswapbuffers();
begin
///////// mein screenshot wenn taste gedrückt oder sowas!
end;
Also das ist schon ein krasser hack oder?
Ich hab versucht das mal so halbwegs hinzubasteln - der code ist weder von mir noch sonstwas.
Der Creator ist beim originalen code nicht angegeben - hat wohl seinen grund :).

Jedenfalls hoffe ich, ich habs so halbwegs kapiert worum es hier geht.
Selbst wenn ich es damit so halbwegs hinbekommen könnte, muß ich doch zugeben, daß ich nur eine ahnung hab was hier alles passiert.
Ich würde das aber gerne genau verstehen, sonst hab ich von dem ganzen nichts und hab nur code geklaut - was mir allerdings nicht besonders liegt.

Bin ich mit dem zusammengebastelten code auf der richtigen spur? oder ist das alles nur unsinn und ich hab nix verstanden lol.
Ist wirklich nicht leicht das thema - was vermutlich auch gut so ist aber trotzdem würde ich das gerne verstehen.

Und versteht mich nicht falsch - code für cheats hab ich bei meinen recherchen genug gefunden, aber leider gibts nicht viel sinnvolles zu dem thema ...

Arnulf


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz