PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL-Extensions


Che
2002-10-28, 20:14:44
Das Problem ist einfach erklärt: Wie benutze ich die OpenGL-Extensions?
Den glext.h-Header habe ich schon, im Programm auch die Funktionen deklatriert, mit wglGetProcessAdress() diese Funktionen auch geladen(oder was immer wglGetProcess() sonst macht ->könnte mir das vielleicht wer erklären?), aber wenn ich das Programm starte:
"Diese Anwendung wird aufgrund eines ungültigen Vorgangs geschlossen." (grmpf!)

Ich weiß dass hier viele intelligente Leute sind, die sich auch ganz fürchterlich viel mit OpenGL beschäftigen (->zeckensack:wink: ) und hoffe dass ihr die Zeit findet mir zu helfen. Aber wie ich dieses Forum kenne, brauche ich auf Hilfe nicht lange zu warten:)

P.S: Es gibt keine dummen Fragen, nur dumme Antworten.

zeckensack
2002-10-28, 22:43:48
wglGetProcaddress holt sich die Funktionen aus der DLL, die - MS sei Dank - nicht in der Importlib verfügbar sind. Das nennt man dann dynamisches Binden, nur mal so nebenbei ;)

Also, wichtig zu beachten ist, daß das Importieren von Extensions erst klappt, wenn ein gültiger OpenGL-Kontext erstellt wurde. Wenn du dich an einem der gängigen Tutorials orientierst, dann heißt das daß man die Extensions erst dann 'laden' kann, nachdem wglMakeCurrent aufgerufen wurde.

Außerdem sollte man die erhaltenen Funktionszeiger prüfen. Wenn die Funktion nicht gefunden wurde, dann gibt GetProcAddress NULL zurück. Ein Aufruf dieses ungültigen Funktionszeigers führt dann auch wieder zu einer access violation, so wie in deinem Fall.

Und noch gaaanz wichtig: eine saubere App muß den Extension-String lesen, und darf nur Extensions verwenden die darin aufgelistet ist. Diesen String kriegt man mit glGetString(GL_EXTENSIONS). Wie dieser String aufgebaut ist steht in der Spec, hier mal ein Schnipsel von mir dazu:
const char* ext_string=NULL;

bool
is_supported(const char*const extension)
{
if (ext_string==NULL)
{
ext_string=(const char*)glGetString(GL_EXTENSIONS);
}

uint ext_string_length=strlen(ext_string);
uint ext_len=strlen(extension);

uint o=0;

while (o<ext_string_length)
{
//skip spaces
while ((o<ext_string_length)&&(ext_string[o]==' ')) ++o;
//check current extension identifier
if (strncmp(ext_string+o,extension,ext_len)==0)
{
//check if this was the end of the extension identifier (GL_ARB_mu vs GL_ARB_multitexture)
char lim=ext_string[o+ext_len];
//space or zero termination character are acceptable
if ((lim==' ')||(lim==0)) return(true);
}
//skip identifier (non-spaces)
while ((o<ext_string_length)&&(ext_string[o]!=' ')) ++o;
}
//didn't find it
return(false);
}

Auch dafür muß wieder ein passender GL-Kontext vorhanden sein. Man ruft die Funktion dann einfach ala
is_supported("GL_ARB_texture_compression")
auf und erhält true wenn die Extension unterstützt wird. Wenn nicht, dann darf man die dazugehörigen Funktionen keinesfalls benutzen.

Bitte beachten: ist nicht 100%ig idiotensicher. Wenn man den Kontext zerstört und wieder neu erstellt, muß man auch dafür sorgen, daß der Extension-String erneut abgeholt wird. Dafür muß man ext_string wieder auf NULL setzen.

Che
2002-10-29, 11:12:04
Erst mal danke für die Antwort und die Erklärung von wglGetProcAdress.

Von wegen 'laden erst nach wglMakeCurrent', das habe ich glatt vergessen. Fehler ist jetzt behoben, ich krieg noch immer keine Funktion:
Das alles passiert in WinMain:


if (!CreateOpenGLWindow(ResolutionX, ResolutionY, BitsPerPixel, fullscreen))
QuitProgram=true;


InitOpenGL(ResolutionX, ResolutionY);

Kamera.Init(0, 0, 0, ResolutionX, ResolutionY, 3);

LoadHeightMap("heightmap/Desert.tga");
MakeDisplayList();

glMultiTexCoord2fv=(PFNGLMULTITEXCOORD2FVPROC)wglGetProcAddress("glMultiTexCoord2fv");
glMultiTexCoord2f=(PFNGLMULTITEXCOORD2FPROC)wglGetProcAddress("glMultiTexCoord2f");
glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");

Anm.: wglMakeCurrent() wird in CreateOpenGLWindow() aufgerufen.

Was mache ich da falsch? Den glext-Header habe ich #includiert, die Funktionen global deklariert:

#include "main.h"
#include "glext.h"

bool Taste[256];
KAMERA Kamera;
HEIGHTMAP map1;
TEXTURE Textur[2];

PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv=NULL;
PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f=NULL;
PFNGLACTIVETEXTUREPROC glActiveTexture=NULL;

Es will nicht funktionieren
??????

btw: In glext.h gibbet einmal sowas:

GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
typedef void (APIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);

und einmal sowas:

GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat);
typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);


Einmal mit ARB hinten dran, einmal ohne - wo ist da der Unterschied, und welche Funktion soll/muss ich benutzen? Thx im voraus für jede Hilfe.

P.S: Das mit dem extension string prüfen ist natürlich klar, ich wollte nur zuerst mal shen ob und wie die ganze Sache mit den Extensions funktioniert. Soblad alle Tests ;) abgeschlossen sind, wird die Sache natürlich 'richtig' implementiert - ich will doch ein braver Programmierer sein ;)

zeckensack
2002-10-29, 11:38:24
Ganz sicher, daß du einen HW-beschleunigten Kontext hast?

Also ein Format, daß von deinem Grafikkartentreiber unterstützt wird? Bestimmte Kombinationen aus Farbtiefe/Stencil/irgendwelche komischen Sachen wie Overlay planes und sowas werden von der Soft-Implementierung von MS übernommen, die ist dann erstens grottenlahm und zweitens unterstützt sie fast überhaupt keine Extensions (Multitexturing schonmal garnicht).

Oder mal andersrum: Welche Farbtiefe/Z/Stencil forderst du an (am besten gleich den Pixelformatdescriptor posten). Was für eine Graka/Treiberversion ist das bei dir?

Du kannst auch mal spaßeshalber ein kleines Logfile erzeugen, und nach der GL-Initialisierung sowas machen:char* vendor=glGetString(GL_VENDOR);
char* renderer=glGetString(GL_RENDERER);
char* version=glGetString(GL_VERSION);
char* extensions=glGetString(GL_EXTENSIONS);

fprintf(log_file,"Vendor=%s\nRenderer=%s\nVersion=%s\n\nExtensions: %s\n",vendor,renderer,version,extensions);

Bzgl ARB vs non-ARB:
Es werden immer mal wieder ein paar Extensions in der nächsten Version in die Corespec mit aufgenommen. Dh daß sie ab einer bestimmten GL-Version (glGetString(GL_VERSION)) verpflichtend unterstützt werden müssen.

Multitexture ist ab der Version 1.2 Teil der GL-Spezifikation, also gibt's das auch ohne ARB-Suffix. Die Funktion der beiden Varianten ist jedoch identisch. Die ARB-Version hat den Vorteil, daß sie auch auf HW/Treibern verfügbar ist, die aktuell waren bevor die 1.2er Version verabschiedet wurde. Aus Gründen der Abwärtskompatibilität zu alten Apps werden idR auch von neuen OpenGL-Treibern die Funktionen mit ARB-Anhängsel weiterhin angeboten.

Ist also eigentlich fast egal was man nimmt, die Version mit Anhängsel ist lediglich verträglicher mit uralten Treibern. Funktionell ist's das gleiche.

Xmas
2002-10-29, 11:45:21
Vermutlich isses sogar dieselbe Adresse ;)

Che
2002-10-29, 13:48:21
Mann, hier muss man wirklich nicht lange auf Antworten warten, gefällt mir hier :)

Ob ich einen HW-Context habe war doch das erste was ich überprüft habe :D
Hier mal ein paar Pixelformate, Zeckensacks kleines Log ist auch dabei:
(HW-Unterstützung wird überprüft mit der PFD_GENERIC_FORMAT-Flag: wenn gesetzt -> Software, sonst -> HW. stimmt doch so,oder?)

Index Rot Grün Blau Alpha Color Z-Buffer Stencil Buffered Support
1 8 8 8 8 32 24 8 Single Hardware
2 8 8 8 8 32 24 8 Double Hardware
3 8 8 8 8 32 24 8 Double Hardware
4 8 8 8 8 32 24 8 Double Hardware
5 8 8 8 0 32 32 8 Single Software
6 8 8 8 0 32 16 8 Single Software
7 8 8 8 0 32 32 8 Double Software
8 8 8 8 0 32 16 8 Double Software
9 8 8 8 0 32 32 8 Single Software
10 8 8 8 0 32 16 8 Single Software
11 8 8 8 0 32 32 8 Double Software
12 8 8 8 0 32 16 8 Double Software
13 8 8 8 0 24 32 8 Single Software
14 8 8 8 0 24 16 8 Single Software
Gewähltes Pixelformat: 2

Vendor=3Dfx Interactive Inc.
Renderer=3Dfx/Voodoo5 (tm)/2 TMUs/32 MB SDRAM/KNI/ICD (Nov 2 2000)
Version=1.1.0

Extensions: GL_ARB_multitexture GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_EXT_packed_pixels GL_EXT_point_parameters GL_EXT_stencil_wrap GL_EXT_texture_env_add GL_EXT_vertex_array GL_SGIS_texture_edge_clamp GL_EXT_texture_env_combine GL_S3_s3tc GL_ARB_texture_compression GL_3DFX_texture_compression_FXT1 GL_SGIS_multitexture WGL_EXT_extensions_string WGL_3DFX_gamma_control WGL_EXT_swap_control WGL_ARB_extensions_string GL_3DFX_multisample


Anm.: 'Gewähltes Pixelformat' ist dasjenige was ich von ChoosePixelFormat() bekomme.

Grafikkarte: Voodoo 5 5500 AGP
Treiber: 1.0.0.734 (laut GLinfo)

Passt alles, oder?
Vielleicht habe ich irgendwo einen logischen Fehler, also nochmal ganz langsam:
1 glext.h inkludieren
2 funktionen global deklarieren
3 (extension unterstützung prüfen - kommt noch)
4 funktionsadressen mit wglGetProcAdress holen (nach wglMakeCurrent)
5 funktionen verwenden

Stimmt so, oder? WARUM funktioniert's dann nicht? *grmpfl* ->Programmer's fate :D


Danke für Hilfe schonmal im Voraus.

zeckensack
2002-10-29, 14:00:39
Aha!

GL version 1.1

....


da müsstest du jetzt eigentlich selbst drauf kommen können, aber ich will mal nicht so sein:

PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB=NULL;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB=NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB=NULL;


glMultiTexCoord2fvARB=(PFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB");
glMultiTexCoord2fARB=(PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");

Che
2002-10-29, 15:28:48
Oh ich Idiot!!!

Multitexture ab V1.2 in Corespec! Vorher ARB_extension! Ich hab's gelesen, aber nicht geschnallt was das eigentlich heißt. Na dann, ARB drangehängt, compiliert, läuft wunderbar, alles locker...
Vielen Dank für eure Aufmerksamkeit und schnelle Hilfe ->am Mogen Problem gepostet, zu Mittag gelöst - das find ich gut :D

btw: Welche Grafikhardware ist eigentlich 'OpenGL 1.3 compliant' (oder gibbet schon 1.4?)? Ist NV_VERTX_PROGRAM (oder wie das heißt) schon verpflichtend?

zeckensack
2002-10-29, 16:00:51
Aktuelle ATI-Treiber sind auf Version 1.3, Version 1.4 gibt's auch schon, anscheinend wird das von NV ab Deto 40.xx geboten (obwohl AFAIK einige benötigte HW-Features fehlen).

Für eine detaillierte Übersicht, schau mal da:
http://www.delphi3d.net/hardware/index.php

Die OpenGL-Specs gibt's auf ... tada ... OpenGL.org (http://www.opengl.org/).

Version 1.4 sollte ursprünglich ARB_vertex_program integrieren, da MS da aber irgendwas von wegen intellectual property gefaselt hat, gibt's das im Moment nur als 'richtige' Extension.

Im Stickie hier im Progger-Forum stehen auch noch reichlich nützliche Links rund um OpenGL drin :)

BNO
2002-11-06, 20:21:01
[QUOTE][SIZE=1]Originally posted by zeckensack
Aktuelle ATI-Treiber sind auf Version 1.3, Version 1.4 gibt's auch schon, anscheinend wird das von NV ab Deto 40.xx geboten (obwohl AFAIK einige benötigte HW-Features fehlen).

Für eine detaillierte Übersicht, schau mal da:
http://www.delphi3d.net/hardware/index.php

Die OpenGL-Specs gibt's auf ... tada ... OpenGL.org (http://www.opengl.org/).

In den Aktuellen Treibern ist die Version 1.3.3 bei ATI implementiert.

zeckensack
2002-11-07, 15:34:16
Originally posted by BNO
In den Aktuellen Treibern ist die Version 1.3.3 bei ATI implementiert. Jein ;)
Die GL-Versionsnummer ist 1.3.
Was nach dem nächsten Punkt kommt, ist eine interne Version des Herstellers der Implementation (in diesem Fall natürlich ATI). Es gibt keine OGL1.3.irgendwas Spezifikation.

1.3.3150 ist lediglich ein neuerer OpenGL-Treiber als 1.3.3040 (nur ein Beispiel, die gibt's aber wirklich beide), beide implementieren aber die 1.3er Spezifikation.


PS: Wusel ?-)