Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Ich wollte mit folgenden Code einen Teil des PBuffers in eine Textur laden.
Code:
wglMakeCurrent(pbuffer.dc, PBuffer.rc);
glBindTexture(GL_TEXTURE_2D,PBuffer.TextureID);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
0,
0,
X,
Y,
Width,
Height);
wglMakeCurrent(glwindow.dc, glwindow.rc);
Aber leider kopierte er nicht einen Teil aus dem PBuffer in die gesammte Textur,
sonder er kopierte den gesammten PBuffer in einen kleinen Bereich der Textur.
Meine Frage jetzt:
Gibt es eine andere Funktion dafür, oder wisst ihr eine Lösung für das Problemm?
Ziel der ganzen Sache ist es, den Boden von meinem Level erst zu Rendern, und ihn im Arbeitsspeicher lagern zu lassen.
Der aktuell gebrauchte Ausschnitt wird, wenn er gebraucht wird in eine Textur kopiert und ausgegeben.
Rendern des Boden dauert zu lange um es wärend des Spieles zu laden.
Und natürlich möchte ich auch den Speicher von meiner Grafikkarte schonen.
MfG
IFlo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Man kopiert eigentlich nicht aus dem PBuffer in eine Texture, sondern bindet den PBuffer mit wglBindTexImage an ein Texture Object und kann dann direkt aus dem PBuffer rendern.
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Als du mir damals erklärtes wie es geht, haben die von dir genannten Funktionen gar nichts in meinem Projekt bewirkt.
Da aber das Haupt-Problemm war und ist das das eigentliche Rendern des Boden so lange braucht, und ich keine Lösung dafür hatte, habe ich es sein lassen.(Sorry Lars das ich dir kein Feedback gab)
Als ich mir es heute nochmal anschaute kamm ich auf die oben genannte Idee, welche aber an dieser Kopier-Funktion scheiterte.
MfG
IFlo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Guck mal ins Shaderforum. Dort hab ich ne Cel-Shading-Demo mit Quellcode gepostet, die ne Klasse zur Kapselung eines PBuffers mitbringt und ausserdem auch zeigt wie man dieses direkte in den Puffer (ohne glTexCopy) nutzt. Evtl. hilft dir das ja weiter.
Man muß den PBuffer mit anderen Attributen erstellen, wenn man ihn nacher an eine Texture binden will. Das ganze System ist sehr anfällig und wenn da ein Parameter nicht stimmt, geht es nicht oder nur sehr langsam. Ein PBuffer der für Texturen erstellt wurde kann eventuell nacher nur noch schlecht für die Benutzung von glCopyTexImage verwendet werden. Die Sache mit dem Contextwechsel ist auch nicht unbedingt geschwindigkeitsförderlich. Der ATI Treiber hat(te) mal einen Fehler, daß Occlusion Query Handles nicht gemeinsam von mehreren RC benutzt werden konnten. Da ich keine Texture rendern muß, die größer als der Bildschirm ist oder mehr als 32Bit pro Texel benötigt, bin ich wieder zurück zu dem ganz normalen glCopyTexSubImage, weil mir das robuster erscheint. Eine Delphi3D.Net Demo zeigt, daß der Geschwindigkeitsunterschied vernachlässigbar ist.
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Zitat:
die ne Klasse zur Kapselung eines PBuffers mitbringt
Eine Klasse habe ich mir ja schon erstellt, nur leider funktionierte es nicht ohne die Kopier-Funktion. Ich habe mir gerade mal den Code runtergeladen und schaue ihn mir mal an.(Die Anwendung kann ich ja wohl schlecht mit einer Geforce 2mx laufen lassen
Zitat:
Man muß den PBuffer mit anderen Attributen erstellen, wenn man ihn nacher an eine Texture binden will
Das habe ich so weit ich dich richtig verstanden habe gemacht, aber ich habe irgendetwas habe ich wohl dann doch falsch gemacht.
Vielleicht poste ich ja nochmal meine PBuffer-Klasse, damit wir rausfinden können wo der Fehler liegt.
MfG
IFlo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
var //Funktionen für die einfache Verwendung als Textur wglBindTexImageARB: function(hPbuffer: HPBUFFERARB; iBuffer: TGLint): Boolean; {$IFDEF Win32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF} wglReleaseTexImageARB: function(hPbuffer: HPBUFFERARB; iBuffer: TGLint): Boolean; {$IFDEF Win32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF} implementation type TPFB =array [0..18]of Integer ; const cPixelFormatBuffer:TPFB = (WGL_SUPPORT_OPENGL_ARB, 1, // pbuffer will be used with gl WGL_COLOR_BITS_ARB,32, // 32 bits for color buffer WGL_DEPTH_BITS_ARB, 24, // 24 bits for depth buffer WGL_DRAW_TO_PBUFFER_ARB, 1, // enable render to pbuffer WGL_PIXEL_TYPE_ARB,WGL_TYPE_RGBA_ARB, //RGBA mode WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,// ? WGL_BIND_TO_TEXTURE_RGBA_ARB, 1, // pbuffer will be used as a texture WGL_TEXTURE_FORMAT_ARB,WGL_TEXTURE_RGBA_ARB, // ? WGL_TEXTURE_TARGET_ARB,WGL_TEXTURE_2D_ARB, // ? 0 );// zero terminates the list
Constructor TpBuffer.Create(const WindowDC:HDC;const WindowRC:HGLRC;const Width,Height:Integer); var PFB:TPFB;//Das wunsch PixelFormat für das Buffer Count:Integer; pfbID:Integer; //Das PixelFormat welches wir erhalten haben EmptyInt:Integer; begin if not LoadFunctions then Exception.Create('Für den pBuffer benötigte Funktionen konnten nicht geladen werden'); EmptyInt := 0; FWidth := Width; FHeight:= Height; FWindowDC := WindowDC; FWindowRC := WindowRC;
PFB := cPixelFormatBuffer; Count := 0; // choose a pixel format that meets our minimum requirements wglChoosePixelFormatARB(Windowdc,@PFB, @EmptyInt, 1,@pfbID,@count); if Count = 0 then raise Exception.Create('P-buffer: Unable to find an acceptable pixel format'); // allocate the pbuffer FHandle := wglCreatePbufferARB(Windowdc, pfbID, width, height, @EmptyInt ); FDC := wglGetPbufferDCARB(FHandle); FRC := wglCreateContext(FDC); if FHandle = 0 then raise Exception.Create('P-buffer: Unable to create P-buffer'); // make a texture object for binding the pbuffer to
procedure TpBuffer.RenderMode(On:Boolean); begin if On then begin wglMakeCurrent(FDC, FRC); wglReleaseTexImageARB(FHandle,WGL_FRONT_LEFT_ARB); end else begin {$IFDEF COPYMODE} glBindTexture(GL_TEXTURE_2D, TextureID); //Bild nur übertragen(Nicht erstellen) glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, FWidth, FHeight); {$ENDIF} wglMakeCurrent(Fwindowdc, Fwindowrc);
end; end;
function TpBuffer.LoadFunctions:Boolean; begin result := false; wglBindTexImageARB := wglGetProcAddress('wglBindTexImageARB'); wglReleaseTexImageARB := wglGetProcAddress('wglReleaseTexImageARB'); //Überprüfen ob es Funktionen gibt die nicht geladen werden konnten. if @wglReleaseTexImageARB =nil then exit; if @wglBindTexImageARB = nil then exit; if @wglChoosePixelFormatARB = nil then exit; if @wglCreatePbufferARB = nil then exit; if @wglGetPbufferDCARB = nil then exit; if @wglReleasePbufferDCARB = nil then exit; if @wglDestroyPbufferARB = nil then exit; if @wglQueryPbufferARB = nil then exit; result := true; end;
end.
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Es gibt zwei Arten von Attributen. Die eine Liste ist für das Pixelformat und die andere für den PBuffer. Die PBuffer Attibute setzt man mit
wglSetPBufferAttribARB nach dem Erstellen des PBuffers. Bei mri funktioniert folgende Konfiguration:
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Poste doch auch mal den Code in dem man sieht wie du deinen PBuffer benutzt. Ich schätze mal du machst einen Fehler mit wglBindTexImageARB bzw. wglReleaseTexImageARB, aber da du letzteres über einen Parameter steuerst (On : Boolean) kann man ja schlecht sagen das es daran liegt.
Normalerweise geht das bei direktem RTT nämlich so :
Code:
PixelBuffer.Enable;
// Szene rendern (->PBuffer)
PixelBuffer.Disable;
...
wglBindTexImageARB...
// Quad mit PBufferinhalt rendern
wglReleaseTexImageARB
Wenn du jetzt z.B. am Ende das wglReleaseTexImageARB vergisst, oder am Anfang das wglBindTexImageARB dann klappts natürlich nicht.
P.S. : Hast du mal meine Unit ausprobiert? Wenn nicht, dann schau dir wenigstens den Source davon an, denn die funktioniert ja tadellos.
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Ich glaube jetzt weis ich warum es nicht funktioniert:
Code:
if not wglSetPBufferAttribARB(FHandle,@BufferAttrib) then Exception.Create('Unable tu set pBuffer Attrib');
Seht ihr den Fehler? Ich habe hier das raise vergessen. Das verhinderte das ich hier informiert wurde das es nicht geklappt hat.
Auch das Reduzieren der Attribute auf nur
Code:
,WGL_BIND_TO_TEXTURE_RGBA_ARB , GL_TRUE
half nichts.
Scheinbar unterstützt meine Grafikkarte dieses Feature nicht, oder ich muss mein OpenGL erneuern(allerdings kann ich das ja nicht umbedingt von den Anwendern meines Programmes erwarten ).
MfG
IFlo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Um die Theorie zu überprüfen habe ich mal wie in Sos pBuffer Tutorial die Attribute beim Erstellen gleich mitgegeben.
Und siehe da ich erhalte wie vermutet keinen PBuffer.
MfG
IFlo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.