Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hab grad was mit 3D-Texturen machen wollen, und bin dann auf ein Problem mit unserem Header gestossen, was sich auch nicht durch die Lösung von Mars beheben lässt, nämlich das glTexImage3D (mit ARB gehts!) auf NIL zeigt. Hab dann zu Testzwecken nen Log in die dglOpenGL.pas eingebaut, der mir folgendes anzeigt :
ProcAddress fo glBlendColor is NIL! ProcAddress fo glBlendEquation is NIL! ProcAddress fo glDrawRangeElements is NIL! ProcAddress fo glColorTable is NIL! ProcAddress fo glColorTableParameterfv is NIL! ProcAddress fo glColorTableParameteriv is NIL! ProcAddress fo glCopyColorTable is NIL! ProcAddress fo glGetColorTable is NIL! ProcAddress fo glGetColorTableParameterfv is NIL! ProcAddress fo glGetColorTableParameteriv is NIL! ProcAddress fo glColorSubTable is NIL! ProcAddress fo glCopyColorSubTable is NIL! ProcAddress fo glConvolutionFilter1D is NIL! ProcAddress fo glConvolutionFilter2D is NIL! ProcAddress fo glConvolutionParameterf is NIL! ProcAddress fo glConvolutionParameterfv is NIL! ProcAddress fo glConvolutionParameteri is NIL! ProcAddress fo glConvolutionParameteriv is NIL! ProcAddress fo glCopyConvolutionFilter1D is NIL! ProcAddress fo glCopyConvolutionFilter2D is NIL! ProcAddress fo glGetConvolutionFilter is NIL! ProcAddress fo glGetConvolutionParameterfv is NIL! ProcAddress fo glGetConvolutionParameteriv is NIL! ProcAddress fo glGetSeparableFilter is NIL! ProcAddress fo glSeparableFilter2D is NIL! ProcAddress fo glGetHistogram is NIL! ProcAddress fo glGetHistogramParameterfv is NIL! ProcAddress fo glGetHistogramParameteriv is NIL! ProcAddress fo glGetMinmax is NIL! ProcAddress fo glGetMinmaxParameterfv is NIL! ProcAddress fo glGetMinmaxParameteriv is NIL! ProcAddress fo glHistogram is NIL! ProcAddress fo glMinmax is NIL! ProcAddress fo glResetHistogram is NIL! ProcAddress fo glResetMinmax is NIL! ProcAddress fo glTexImage3D is NIL! ProcAddress fo glTexSubImage3D is NIL! ProcAddress fo glCopyTexSubImage3D is NIL! ProcAddress fo glActiveTexture is NIL! ProcAddress fo glClientActiveTexture is NIL! ProcAddress fo glMultiTexCoord1d is NIL! ProcAddress fo glMultiTexCoord1dv is NIL! ProcAddress fo glMultiTexCoord1f is NIL! ProcAddress fo glMultiTexCoord1fv is NIL! ProcAddress fo glMultiTexCoord1i is NIL! ProcAddress fo glMultiTexCoord1iv is NIL! ProcAddress fo glMultiTexCoord1s is NIL! ProcAddress fo glMultiTexCoord1sv is NIL! ProcAddress fo glMultiTexCoord2d is NIL! ProcAddress fo glMultiTexCoord2dv is NIL! ProcAddress fo glMultiTexCoord2f is NIL! ProcAddress fo glMultiTexCoord2fv is NIL! ProcAddress fo glMultiTexCoord2i is NIL! ProcAddress fo glMultiTexCoord2iv is NIL! ProcAddress fo glMultiTexCoord2s is NIL! ProcAddress fo glMultiTexCoord2sv is NIL! ProcAddress fo glMultiTexCoord3d is NIL! ProcAddress fo glMultiTexCoord3dv is NIL! ProcAddress fo glMultiTexCoord3f is NIL! ProcAddress fo glMultiTexCoord3fv is NIL! ProcAddress fo glMultiTexCoord3i is NIL! ProcAddress fo glMultiTexCoord3iv is NIL! ProcAddress fo glMultiTexCoord3s is NIL! ProcAddress fo glMultiTexCoord3sv is NIL! ProcAddress fo glMultiTexCoord4d is NIL! ProcAddress fo glMultiTexCoord4dv is NIL! ProcAddress fo glMultiTexCoord4f is NIL! ProcAddress fo glMultiTexCoord4fv is NIL! ProcAddress fo glMultiTexCoord4i is NIL! ProcAddress fo glMultiTexCoord4iv is NIL! ProcAddress fo glMultiTexCoord4s is NIL! ProcAddress fo glMultiTexCoord4sv is NIL! ProcAddress fo glLoadTransposeMatrixf is NIL! ProcAddress fo glLoadTransposeMatrixd is NIL! ProcAddress fo glMultTransposeMatrixf is NIL! ProcAddress fo glMultTransposeMatrixd is NIL! ProcAddress fo glSampleCoverage is NIL! ProcAddress fo glCompressedTexImage3D is NIL! ProcAddress fo glCompressedTexImage2D is NIL! ProcAddress fo glCompressedTexImage1D is NIL! ProcAddress fo glCompressedTexSubImage3D is NIL! ProcAddress fo glCompressedTexSubImage2D is NIL! ProcAddress fo glCompressedTexSubImage1D is NIL! ProcAddress fo glGetCompressedTexImage is NIL! ProcAddress fo glBlendFuncSeparate is NIL! ProcAddress fo glFogCoordf is NIL! ProcAddress fo glFogCoordfv is NIL! ProcAddress fo glFogCoordd is NIL! ProcAddress fo glFogCoorddv is NIL! ProcAddress fo glFogCoordPointer is NIL! ProcAddress fo glMultiDrawArrays is NIL! ProcAddress fo glMultiDrawElements is NIL! ProcAddress fo glPointParameterf is NIL! ProcAddress fo glPointParameterfv is NIL! ProcAddress fo glPointParameteri is NIL! ProcAddress fo glPointParameteriv is NIL! ProcAddress fo glSecondaryColor3b is NIL! ProcAddress fo glSecondaryColor3bv is NIL! ProcAddress fo glSecondaryColor3d is NIL! ProcAddress fo glSecondaryColor3dv is NIL! ProcAddress fo glSecondaryColor3f is NIL! ProcAddress fo glSecondaryColor3fv is NIL! ProcAddress fo glSecondaryColor3i is NIL! ProcAddress fo glSecondaryColor3iv is NIL! ProcAddress fo glSecondaryColor3s is NIL! ProcAddress fo glSecondaryColor3sv is NIL! ProcAddress fo glSecondaryColor3ub is NIL! ProcAddress fo glSecondaryColor3ubv is NIL! ProcAddress fo glSecondaryColor3ui is NIL! ProcAddress fo glSecondaryColor3uiv is NIL! ProcAddress fo glSecondaryColor3us is NIL! ProcAddress fo glSecondaryColor3usv is NIL! ProcAddress fo glSecondaryColorPointer is NIL! ProcAddress fo glWindowPos2d is NIL! ProcAddress fo glWindowPos2dv is NIL! ProcAddress fo glWindowPos2f is NIL! ProcAddress fo glWindowPos2fv is NIL! ProcAddress fo glWindowPos2i is NIL! ProcAddress fo glWindowPos2iv is NIL! ProcAddress fo glWindowPos2s is NIL! ProcAddress fo glWindowPos2sv is NIL! ProcAddress fo glWindowPos3d is NIL! ProcAddress fo glWindowPos3dv is NIL! ProcAddress fo glWindowPos3f is NIL! ProcAddress fo glWindowPos3fv is NIL! ProcAddress fo glWindowPos3i is NIL! ProcAddress fo glWindowPos3iv is NIL! ProcAddress fo glWindowPos3s is NIL! ProcAddress fo glWindowPos3sv is NIL!
Einige davon sind sicherlicht NIL weil sie nicht unterstütz werden, aber Sachen wie glClientActiveTexture oder glTexImage3D müssten doch auf jeden Fall nen gültigen Funktionszeiger haben, zumal ihre ARB/EXT-Pendants ohne Murren funktionieren.
Um den Sachverhalt zu verdeutlichen : Ich nutze jetzt statt GetProcAddress jetzt diese Routine die selbiges erledigen soll von Mars, aber es hat sich eigentlich nix geändert :
Code:
function glProcedure(ProcName :PChar):Pointer;
begin
Result :=NIL;
ifAddr(wglGetProcAddress) <> NILthen
Result := wglGetProcAddress(ProcName);
if result <> NILthen
exit;
Result := GetProcAddress(LibHandle, ProcName);
if Result =nilthen
Log.Add('ProcAddress fo '+ProcName+' is NIL!');
end;
Und natürlich lade ich ganz am Anfang der InitOpenGL-Routine auch wglGetProcAddress :
Da ich in Sachen Headerkonvertierung eher unerfahren bin (dglOpenGL.pas war meine erste), steht ich da grad vor ner Wand...wäre also nett wenn einer von euch da mal nachsehen könnte was schief läuft.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Das ist in der Tat ein Problem. Ich habe mir mal den Header geschnappt und habe mir den mal genau angesehen. Betroffen von dem Fehler beim Laden sind alle Methoden ab Version 1.2. Da diese nicht direkt von der OpenGL32.dll exportiert werden. Ist ja auch Logisch. An der Stelle schlägt (auch logischerweise) das GetProcAddress fehl. Weil sie ja nicht direkt exportiert werden. Und das wglGetProcAddress lieferte mir diese Adressen der Methoden zurück. Aber nicht bei dem ersten Aufruf. Sondern erst zu dem Zeitpunkt als ich ReadImplementedProperties aufgerufen hatte. In der Methode wird heimlich ja noch einmal das InitOpenGL aufgerufen (jedenfalls bei der Version die ich habe (ausm SDK)) und dann liefert wglGetProcAddress eine Adresse zurück. Und ich kann mir das nur erklären, dass es sich mit den Methoden ab Versionen 1.2 genau so verhält wie mit den Extensions. Die sind auch erst dann verfügbar sobald OpenGL initialisiert wurde.
Evtl. sollten wir auf Grund dieses Verhaltens die Methoden von 1.2 und aufwärts mit in die Methode ReadExtensions aufnehmen. Dann sollte das Problem gelöst sein.
SOS: kann das sein, dass du das eine InitOpenGL aus ReadImplementationProperties rausgeschmissen hattest? Wenn nicht kann das glaube ich rausfliegen. Ist ja eigentlich überflüssig. Und wenn jemand die versuchen sollte die Extensions auszulesen OHNE vorher mindestens OpenGL initialisiert zu haben dann gehört es auch abgestürzt.
PS: wo gibbet denn eigentlich die neuste Version mit glProcedure?
Und in dem Header steht ganz oben noch version 1.0 drin. In der History allerdings 1.1
Mal eine Frage, so rein prinzipieller Art: wglGetProcAddress ist IMO so elementar wie GetProcAdress. Was spricht also dagegen, direkt nach dem Laden der OpenGL32.dll den Pointer von wglGetProcAdress zu ermitteln? Dern Rest könnte man ja dann mit der genannten glProcedure durchführen, wobei ich die Funktion etwas ändern würde:
Code:
function glProcedure(ProcName :PChar):Pointer;
begin
Result := GetProcAddress(LibHandle, ProcName);
ifnotAssigned(Result)then
Result := wglGetProcAddress(ProcName);
{$IFDEF _DEBUG_}
// Log Ausgabe für Debug
ifnotAssigned(Result)then
Log.Add('ProcAddress fo '+ProcName+' is NIL!');
{$ENDIF}
end;
Assigned liefert True zurück, wenn der übergebene Wert <> nil ist. Funktioniert wunderbar (hab' ich schon öfters verwendet). Dadurch hat man eine feste Reihenfolge
1. Die Funktion aus der OpenGL32.dll holen
2. Wenn die Funktion dort nicht existieren, sie aus den Erweiterungen laden
3. Wenn Result immer noch nil, gibt's die Funktion wohl auch nicht.
_________________ Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Danke für den Denkanstoss Lossy...ich hab mir dann ganz einfach mal die Unit vom Lischke angesehen, und der hat da was geschrieben das man zu den Extensions erst nen gültigen Zeiger via wglGetProcAddress bekommt, wenn man nen gültigen Kontext hat. Hab das dann recht einfach im ActivateRenderingContext gelöst :
Wenn also zum ersten Mal ein Kontext aktiviert wird, wird auch gepürft, ob die Implementationseigenschaften gelesen wurden. Ist das nicht der Fall, wird ReadImplementationProperties aufgerufen und ImplementationRead dort auf TRUE gesetzt.
Hab das mit meinem 3D-Textur-Demo probiert, und glTexImage3D funzt jetzt ohne Probleme, genauso wie das z.B. glClientActiveTexture (ohne ARB) tun sollte. Werd dann später die gefixte Unit öffentlich machen und auch ne News verfassen, da die Unit ja jetzt zu 100% funzen dürfte.
Edit : Wenn die Unit sonst keine Probleme macht, dann wollt ich die eigentlich im Verlaufe des heutigen Tages auch mal auf opengl.org publik machen, kann nämlich sicherlich ned schaden.
Ausserdem wollt ich da früher oder später noch ein paar kleinere Hilfsfunktionen wie glGetErrorString oder glGetExtSupported reinbringen, die jeder braucht und einem das Leben ungemein erleichtern.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Man würde damit Probleme auf Linuxsystemen bekommen. Wie der Name von der wgl schon sagt ist dass eine Windowsspezifische Methode. Die leider nur unter Windows existiert. Aber die gesamten Lunixextensions sind auch noch gar nicht implementiert und bei 99% der Windows OpenGL programmierer erübrigt sich die Sache auch schon fast. Aber man müsste dann auf jeden Fall überprüfen ob die wglGetProcAddress nil oder nicht. Unter Linux müsste man dazu glxGetProcAddress aufrufen.
Und das nächste ist. Der Treiber liefert erst dann die Methoden zu den Extensions (OpenGL Version 1.2 und drüber sind in diesem Falle auch "Extensions") wenn OpenGL initialisiert wurde. Es besteht ja auch die Möglichkeit ein anderes PixelFormat zu wählen. Und dementsprechend hätte der Treiber auch die Möglichkeit zu sagen Extension Blah exisiert nur bei 32Bit Farbtiefe.
Allerdings verstehe ich deinen zweiten Punkt nicht ganz. Wie meinst du das mit "aus den erweiterungen laden"?
SOS: Gern geschehen. Allerdings habe ich was die Formatierung von den Methoden angeht leichte Kopfschmerzen. Ich bin aber auch ein Übersichtsfanatiker. Wenn interesse danan besteht könnte ich die auch in den nächsten Tagen mal formatieren. Ich dachte da eher an so was in der Art.
Code:
function glProcedure(ProcName :PChar):Pointer;
begin
Result :=NIL;
ifAddr(wglGetProcAddress) <> NIL
then Result := wglGetProcAddress(ProcName);
if result <> NIL
thenexit;
Result := GetProcAddress(LibHandle, ProcName);
{$IFDEF DEBUG}
if Result =nil
then Log.Add('ProcAddress to '+ProcName+' is NIL!');
{$ENDIF}
end;
Und das Log per Compilerschalter finde ich ne klasse Idee.
@Linux: für den Linux-Support der Header muss man sowieso ifdefs einbauen.l Was dann auch auf die wglGetProcAddress bzw glxGetProcAddress zutrifft.
@aus den Extensions laden: damit meinte ich die wglGetProcAddress funktion. Wollte mir die genauere Differenzierung sparen (-> schreibfaul ).
@Extensions & Farbtiefe: Ist mir soweit schon klar. Mann muss beim wechseln des Pixelformats die Funktion zum laden der Extensions erneut aufrufen. Sprichtja auch nix dagegen. Aber mit der reihenfolge, welche ich vorgeschlagen hab, ist die glProcedure-Funktion kleiner & übersichtlocher (man spart sich z.B. das Exit eine Result = nil Abfrage). Macht in der Funktion keinen unterschied. Iss eben halt kleiner.
_________________ Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hmm...hab jetzt bereits den neuen Header hochgeladen, aber ohne Debugausgabe. Werd dann wohl heute deinen Header mit dem neuen zusammenfassen, also schonmal danke im Voraus.
P.S. : Die Newsmeldung zu unserem Header an opengl.org ist raus. Bin da mal auf Feedback gespannt.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hab grad in den entsprechenden Threads (Deutsch und Englisch) die um deine Debug-Ausgabe per ifdefs erweiterte Version hochgeladen. Die Formatierungen hab ich dabei allerdings ned komplett wie in deinem Header abgeändert, irgendwie kann ichs nicht leiden wenn vor jeder Zeile noch einige Leerschritte sind...aber dafür interessieren sich eh die wenigsten Nutzer.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Jau. Das ist reine Geschmackssache. Ich hatte mir das irgendwann mal angewöhnt, weil ich so viel schneller die Zusammengehörigkeiten feststellen konnte. Aber die Meisten werden da eh keinen Blick reinwerfen. Warum auch wenn funktioniert.
Wäre es nicht für die User komfortabler, im Falle einer Delphi-Version < 7 einfach die RaiseLastWin32error-Funktion zu erwenden und adneren Falls die RaiseLastOsError? Mit Hilfe von IFDEFs könnte man das praktisch realisieren:
Code:
{$ifdef VER150}
SysUtils.RaiseLastOSError;
{$ELSEIF}
SysUtils.RaiseLastWin32Error;
{$ENDIF}
Man müsste das mit den Defines natürlich noch detailierter implementieren, so dass man sagen kann, bei Delphi 7 aufwärts das eine, sonst das andere verwenden. Nur so als Idee.
_________________ Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Danke für den Tipp. Das wollt ich eigentlich schon länger machen, aber habs irgendwie total verpennt. Dank ifdefs würde die Unit dann auf älteren Delphiversionen ohne Anpassungen laufen. Kommt also defintiv rein!
Mitglieder in diesem Forum: 0 Mitglieder und 13 Gäste
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.