Feste Spielgeschwindigkeit



  • Daran dass du nicht auf Integers rundest, und vermutlich deine Texturen gleich gross sind wie der Platz den sie am Bildschirm einnehmen.

    Entweder auf Integer runden, oder grössere Texturen verwenden.



  • Ich verwende garkeine Texturen bei dem Zeichencode steht ja auch nichts von glTexCoord2f oder so.
    Und wenn ich auf Inteher runde, ruckelt es mehr als das es zittert.



  • Hihi, OK, nicht weit genug mitgedacht.
    Allerdings... wenn direkt die Kanten/Linien unscharf werden, dann muss fast irgend eine Art Antialiasing aktiv sein. Mir fällt auf jeden Fall nichts ein was sonst dazu führen könnte (dürfte) dass Kanten unscharf werden.

    Wenn du es selbst nicht aktivierst, ... vielleicht die Default-Einstellung im Treiber?



  • Ich habe jetzt mal Antialiasing mit glDisable(GL_LINE_SMOOTH) und GL_POLYGON_SMOOTH ausgeschaltet. Etwas anderes wie ARB Multisampling etc. existiert im Code gar nicht. Aber das wäre auch nicht der Sinn der Sache, wenn ich Antialiasing auschalten müsste.
    Wie gesagt arbeite ich mich jetzt in Threads ein, und lasse die logischen Berechnung getrennt vom rendern mit festen Zeitschritten ablaufen. Aber was passiert dann eigentlich wenn der Computer nicht schnell genug ist, um z.B. alle 10 ms die logischen Schritte zu berechnen?



  • Pikkolini schrieb:

    Ich habe jetzt mal Antialiasing mit glDisable(GL_LINE_SMOOTH) und GL_POLYGON_SMOOTH ausgeschaltet. Etwas anderes wie ARB Multisampling etc. existiert im Code gar nicht. Aber das wäre auch nicht der Sinn der Sache, wenn ich Antialiasing auschalten müsste.

    Du hast erwähnt dass einige Bilder scharf und andere unscharf sind. Antialiasing macht "unscharfe" Bilder. Natürlich musst du es deswegen nicht ausschalten 😕

    Könnte natürlich auch sein dass einfach nur der Video-Codec schuld an den unscharfen Bildern ist.

    Wie gesagt arbeite ich mich jetzt in Threads ein, und lasse die logischen Berechnung getrennt vom rendern mit festen Zeitschritten ablaufen.

    Mach das ruhig, wird nur vermutlich nix bringen.

    Aber was passiert dann eigentlich wenn der Computer nicht schnell genug ist, um z.B. alle 10 ms die logischen Schritte zu berechnen?

    Na was soll passieren, dein Spiel läuft dann zu langsam.



  • hustbaer schrieb:

    Pikkolini schrieb:

    Wie gesagt arbeite ich mich jetzt in Threads ein, und lasse die logischen Berechnung getrennt vom rendern mit festen Zeitschritten ablaufen.

    Mach das ruhig, wird nur vermutlich nix bringen.

    Ein paar Seiten vorher wurde in dies noch als beste Methode angepriesen und du willst mir jetzt sagen das bringt nichts? 😕

    Aber was passiert dann eigentlich wenn der Computer nicht schnell genug ist, um z.B. alle 10 ms die logischen Schritte zu berechnen?

    Na was soll passieren, dein Spiel läuft dann zu langsam.

    Hmm hast rechts das tuts ja eig immer, wenn der PC zu langsam ist.



  • Pikkolini schrieb:

    hustbaer schrieb:

    Pikkolini schrieb:

    Wie gesagt arbeite ich mich jetzt in Threads ein, und lasse die logischen Berechnung getrennt vom rendern mit festen Zeitschritten ablaufen.

    Mach das ruhig, wird nur vermutlich nix bringen.

    Ein paar Seiten vorher wurde in dies noch als beste Methode angepriesen und du willst mir jetzt sagen das bringt nichts? 😕

    Nicht von mir.

    Grundsätzlich ist die Methode schon gut, nur ich bin mir sicher dass du die Probleme die man damit Lösen kann einfach nicht hast.



  • Also stehe ich hier vor einem unlösbaren Problem?
    Aber mittlwerweile ist es mir fast egal, da ich endlich mal weiter kommen will.



  • Pikkolini schrieb:

    Also stehe ich hier vor einem unlösbaren Problem?
    Aber mittlwerweile ist es mir fast egal, da ich endlich mal weiter kommen will.

    Ziemlich sicher nicht. Nur wie sollen wir dir sagen was du falsch machst wenn wir den Code nicht sehen?
    Hab ja schon vorgeschlagen dass du den Code irgendwo uppen könntest, dann könnten wir drüber gucken. Wesentlich effizienter als zu raten und kleine Informationsstücke jedes mal umständlich nachfragen zu müssen.



  • So ich habe jetzt mal den Sourcecode und die .exe hochgeladen.
    Link



  • OK.

    1. Du verwendest QueryPerformanceCounter(). Das funktioniert meistens recht gut, aber nicht auf allen Systemen, daher würde ich empfehlen besser timeGetTime() zu verwenden.

    2. Deine Zeitmessung ist ... nicht optimal. Das "Stoppen und wieder Starten" des Timers kann man "atomar" machen.

    3. Du hast VSync nicht an.

    4. Du bewegst dein Objekt mit ner Geschwindigkeit die nahe an 1 Pixel/Frame liegt, aber nicht genau 1 Pixel/Frame ist.

    1 & 2 sind vermutlich egal, aber ich hab's trotzdem mal umgebaut. Vermutlich geht's auch ohne.

    3 ist einfach zu machen und bringt schonmal was.

    Und 4 ... da wird's interessant.
    Nachdem nun VSync an ist erfolgt die Ausgabe mit ziemlich genau 60 fps (auf nem TFT).
    Nun könnte man annehmen dass 60 Pixel/Sekunde extrem smooth sein müssten. Ist aber nicht so, zumindest nicht wenn man mit einer vom Bildaufbau unabhängigen Clock arbeitet. Die Umstellung auf timeGetTime() hat das Ganze vermutlich sogar noch etwas verschlimmert, allerdings war es mir zu doof das wieder zurück zu bauen.

    Also als kruze Erklärung, warum das überhaupt zu einer "zittrigen" Bewegung führt: wenn du mit 100 Pixel/Sekunde bewegst, dann sind das pro Frame bei 60Hz 1.66666 Pixel.
    Das macht dann 0 - 1.66 - 3.33 - 5 - 6.66 - 8.33 - 10 ...
    Da kein Antialiasing an ist, wird der Wert auf Integer gerundet (*).
    Also 0 - 1 - 3 - 5 - 6 - 8 - 10 ...
    Differenz zum jeweils vorigen Frame ist dann 1 - 2 - 2 - 1 - 2 - 2 ...
    Und das sieht nunmal zittrig aus.

    Mögliche Lösungen:

    * Höhere Geschwindigkeit führt dazu dass die Unterschiede in der pro Frame zurückgelegten Distanz (relativ) kleiner werden. Max. ist es 1 Pixel, d.h. wenn sich das Ding sowieso schon mit 10 Pixel/Frame bewegt ist der max. Fehler nur mehr 10% statt 66%. Ist natürlich kein ernst gemeinter Vorschlag, denn die Geschwindigkeit wird von anderen Faktoren vorgegeben. Nur der Vollständigkeit halber.

    * Auflösung erhöhen. OK, geht natürlich nicht mehr als der Monitor kann.

    * Antialiasing (FSAA) aufdrehen. Das macht alles etwas unscharf, speziell mit der einfachen Grafik die du im Moment drinnen hast. Dafür sieht die Bewegung aber sauber aus.

    * Objekte verwenden die keine oder kaum Kanten die parallel zu den Bildschirmkanten verlaufen.

    * Billboards statt Geometrie verwenden + sicher stellen dass jede Billboard-Textur einen ausreichend grossen "durchsichtigen" Rand hat + mit new hübschen Textur-Interpolation (=wenigstens bilinear) rendern.

    Ich hab' mal Code eingebaut um FSAA zu aktivieren, kannst dir ja ansehen wie das wirkt.

    Game.zip

    p.S.: meine Änderungen sind lediglich ein "proof of concept" und entsprechend quick and dirty.

    EDIT: (*): natürlich wird auch ohne FSAA subpixel genau gerendert, bloss hilft das nix bei Objekten wo alle Kanten 100% parallel zur Projektionsfläche sind.



  • Danke für deine ganzen Tipps und Codeverbesserungen, aber ich habe da jetzt schon eine Menge Fragen, obwohl ich noch garnicht den ganzen Code durchgearbeitet habe (da sind ja wirklich viele Änderungen drin).

    1. Wieso schreibst du ::Sleep(1) und nicht Sleep(1)? Das müsste doch beides das gleiche Sein oder irre ich mich da?

    2. Wieso haste du das letzte Sleep in der Programmschleife entfernt? Dadurch wird mein Prozessor wieder mit 100% gebraten 😃

    3. Wieso haste du einige Variablen und Funktionen in einen namenslosen namespace gepackt?

    4. Durch das FSAA läuft es jetzt wirklich flüssig, allerdings habe ich jett eine Prozessorlast von 80% (Pentium 4 3.06 GHz). Auch wenn ich in den settings.ini den wert using_fsaa auf false setze, bleibt es anscheinend doch an. Alles läuft flüssig und der Prozessor wird immernoch übermäßig gegrillt.

    5. Wenn den Task Manager oder Fraps anhabe, stottert das Spiel nurnoch unschön, und Fraps zeigt auch nurnoch 15 FPS an. Die FPS ohne ein anderes Programm muss ich noch testen.

    6. Ich habe QueryPerformanceCounter() genommen, da dies angeblich genauer sein soll. Mit deiner Methode läuft aber trotzdem alles super 😃

    7. Meinst du mit "die Zeit atmoar messen", das was du in dem Code gemacht hast? Wenn ja, wozu benutzt du die Funktionen timeBeginPeriod etc. die MSDN konnte mir bis jetzt noch nicht wirklich helfen.

    8. Wie funktioniert VSync? Ich habe in dem Code nur isUsingVsync() gefunden, mehr aber nicht. Diese macht das hier:
    return init.swapInterval > 0;
    Was hat es mit dem > 0 am Ende auf sich. Was ist dieses Swap Interval?

    9. Was machen die ersten beiden Funktionen in GLExtensions.cpp?

    10. Wieso lässt du die Programmschleife eine Millisekunde sleepen, wenn kein VSync an ist?

    So dann werde ich mir den Code jetzt mal weiter anschauen, und hoffen, dass ich noch einges verstehen werde 😉



  • EDIT:
    11. Wenn ich den Depthbuffer von 16 auf 32 Bits stelle, habe ich alles Glasklar und scharf. Gibts dabei aber irgendwelche nachteile? Ein nennenswerten Performanceeinbruch habe ich nicht gesehen.

    2. EDIT:
    Das sollte wirklich ein edit werden und kein neuer Beitrag 🙄



    1. Bloss Gewohnheit. ::Sleep heisst Sleep NUR im globalen Namespace, sonst nix.

    2. Hab den Code grad net vor mir, vielleicht hab ich da Mist gebaut. Der Gedanke war: abarbeiten von normalen Window-Messages nicht verzögern. Also wenn PeekMessage ne Message geholt hat, dann nicht Sleep. Dafür Sleep im "else" Zweig, wo vorher keins war. Aber nur wenn VSync nicht an ist. Wenn VSync an ist, dann *sollte* das dafür sorgen dass an anderer Stelle irgendwas blockiert. Bei Direct3D ist das so, ob es bei OpenGL auch so ist... hm. Vermutlich nicht, das würde dann auch erklären dass du so ne hohe CPU Last hast 🙂

    3. Weil die da hin gehören. Dinge die nur in einem einzigen .cpp File verwendet werden steckt man in anonymen Namespaces. "static" (internal linkage) ist pufi, und external linkage ohne anonymen Namespace ist auch pfui, wenn die Funktion nur in einem File verwendet wird.

    4. FSAA hat mit der CPU Last nix zu tun, das macht nur die Arbeit der GPU schwerer, aber das schlägt sich ja nicht auf die CPU Auslastung nieder. Die kommt vermutlich von der Sleep-Änderung. Und FSAA aus hat bei mir glaub ich funktioniert. Sieht man ja sofort den Unterschied: schwammig (FSAA=an) oder scharf (FSAA=aus). Und bei mir läufts mit 100px/sec auch nicht 100% flüssig ohne FSAA.

    5. Müsste ich mir ansehen. Auf jeden Fall: nicht aus dem Visual-Studio starten, denn Visual-Studio macht komische Dinge 🙂

    6. Ja, liest man öfter die Empfehlung. Halte ich aber für nen Fehler. Es sollte sich mal jmd. hinsetzen und eine allgemein verwendbare Hybrid-Timer-Lib für Windows schreiben. Oder am Besten gleich für Windows/Linux/OS-X und evtl. BSD.

    7. Kurz: ja, ich meine das "reset + get in Einem" was ich in timer::reset mache. Mit timeBeginPeriod() erhöht man die Auflösung von timeGetTime (hat nämlich per Default nur ca. 15ms Genauigkeit, was viel zu wenig wäre).

    8. Guck mal in WindowGL::InitGL. Der Integer-Wert den man da setzt gibt an, alle wieviel Frames ein neues Bild auf dem Bildschirm angezeigt wird. Also wenn du da z.B. 10 rein schreibst, dann ruckelt alles ganz ganz böse, weil bloss alle 10 Frames (Bildaufbau vom Monitor) ein neues Bild angezeigt wird. Und bei 1 ist es eben synchronisiert, also 1 Frame am Monitor = 1 neues Bild.
      Da ich aber wie gesagt von OpenGL kaum Ahnung habe weiss ich nicht wie das bei OpenGL genau funktioniert. Frag mal Google, der hilft dir 😉

    9. Die "is-supported" Funktion braucht man um abzufragen ob eine OpenGL Extension vom System unterstützt wird. Die andere ist wenn ich mich recht erinnere die zum konfigurieren des Presentation-Intervals (-> VSync).

    10. Siehe (2) - damit dann nicht 100% CPU Leistung verbraten wird, aus dem gleichen Grund warum du es ursprünglich drin hattest. Mit VSync sollte es nicht nötig sein, wobei ich da vermutlich noch irgendwas fehlt.

    11. Vermutlich kann deine GraKa kein Pixelformat mit 32 Bit Depth-Buffer UND FSAA. Dann wird ohne FSAA gerendert, und alles ist scharf. Nur tuts dann wieder mehr zittern.

    2. EDIT) Macht ja nix 🙂

    p.S.: ich hab das alles relativ schnell zusammengehackt, ich bin nicht sicher ob bei der FSAA Geschichte überhaupt das von dir eingestellte Pixel-Format gesucht wird, und nicht einfach irgend eines.



  • hustbaer schrieb:

    1. Müsste ich mir ansehen. Auf jeden Fall: nicht aus dem Visual-Studio starten, denn Visual-Studio macht komische Dinge 🙂

    Ok ich nehm alles zurück, Visual Studio wars 😃
    Ich habs jetzt mal intern aus dem Programm getest und es besteht vielleicht ein unterschied von 5-10 FPS wobei die ziemlich variieren und ich da nicht viel sagen kann.

    hustbaer schrieb:

    1. FSAA hat mit der CPU Last nix zu tun, das macht nur die Arbeit der GPU schwerer, aber das schlägt sich ja nicht auf die CPU Auslastung nieder. Die kommt vermutlich von der Sleep-Änderung. Und FSAA aus hat bei mir glaub ich funktioniert. Sieht man ja sofort den Unterschied: schwammig (FSAA=an) oder scharf (FSAA=aus). Und bei mir läufts mit 100px/sec auch nicht 100% flüssig ohne FSAA.

    Die CPU Auslastung kam tatsächlich von irgendwo anders her, sehr wahrscheinlich wieder vom Visual Studio. Aber lagern ATI Karten nicht ein Teil ihrer arbeit auf die CPU aus, wenn die zu viel zu tun haben? Ich mein das irgendwo mal gelsen zu haben, und wie kann ich mir das sonst erklären, dass die CPU Last augenblicklich auf 100% steigt, sobald ich in einem normalen 3D Spiel mich auch nur wage AntiAliasing anzumachen?

    hustbaer schrieb:

    1. Vermutlich kann deine GraKa kein Pixelformat mit 32 Bit Depth-Buffer UND FSAA. Dann wird ohne FSAA gerendert, und alles ist scharf. Nur tuts dann wieder mehr zittern.

    Das wird es vermutlich sein. Kann man die Pixelformate der GraKa irgendwo nachgucken? Google und das Catalyst Control Center schweigen diesbezüglich. Ich habe eine Radeon X1650 series.

    Und zum Schluss habe ich aber noch eine Frage grundlegend zu C++, die mir in einem halben Jahr noch nicht begegnet ist. Und zwar hast du in den return Anweisungen manchmal folgendes stehen:

    return s_wglSwapIntervalEXT(interval) != 0;
    // oder
    return init.swapInterval > 0;
    

    Ist das != 0 oder > 0 eine Art if-Abfrage? Ich habe mal nach C++ return gegooglet, aber nichts brauchbares gefunden und ein anderer Suchbegriff ist mir nicht eingefallen.

    Ansonsten danke für deine Ausführliche hilfe, mir wurde jetzt einiges klarer und habe jetzt einige brauchbare Codeschnipsel 🙂

    EDIT:
    Sollte ich bei VSync nicht nur 60 FPS haben? Momentan liegen die zwischen 290 und 340.



  • Aber lagern ATI Karten nicht ein Teil ihrer arbeit auf die CPU aus, wenn die zu viel zu tun haben?

    Das wäre mir neu, allerdings bin ich auch nicht gerade Experte was aktuelle Grafikkarten angeht.

    Kann man die Pixelformate der GraKa irgendwo nachgucken? Google und das Catalyst Control Center schweigen diesbezüglich.

    Man kann die irgendwie mit OpenGL enumerieren. Nehe oder Google werden dir sagen wie 🙂

    Und zum Schluss habe ich aber noch eine Frage grundlegend zu C++, die mir in einem halben Jahr noch nicht begegnet ist. Und zwar hast du in den return Anweisungen manchmal folgendes stehen:

    return s_wglSwapIntervalEXT(interval) != 0;
    // oder
    return init.swapInterval > 0;
    

    Lies dich mal ein was Epressions und Operatoren in C++ angeht.
    a < b ist in C++ einfach nur ne Expression, (fast) egal wo es steht. Eine Expression hat einen Wert. Expression mit Vergleichsoperatoren haben einen Wert vom Typ bool , und sind true wenn die Bedingung erfüllt ist, und sonst false .
    Und mit if (Expression) kann man halt Code bedingt ausführen lassen, also nur wenn der Wert der Expression, nach bool konvertiert, true ergibt. (Die Expression muss nicht den Typ bool haben, es geht z.B. auch if (42) - 42 nach bool konvertiert ist true (alles was nicht 0 oder false ist ergibt true ), d.h. der Code im if-Block wird ausgeführt)
    Man kann diesen Wert allerdings nicht nur mit if (Expression) verwenden, sondern ihn z.B. genau so gut einer Variable zuweisen. Oder eben mit return zurückgeben.

    Also:

    return init.swapInterval > 0;
    

    macht das selbe wie

    if (init.swapInterval > 0)
        return true;
    else
        return false;
    

    nur halt ohne unnötigen "Umweg".

    EDIT:
    Sollte ich bei VSync nicht nur 60 FPS haben? Momentan liegen die zwischen 290 und 340.

    Ja, sollte es. Hat es bei mir auch.
    Hast du auch sicher

    swap_interval = 1
    

    im settings.ini File stehen?

    BTW: use_fsaa = false funktioniert bei mir auch wie erwartet.



  • hustbaer schrieb:

    Kann man die Pixelformate der GraKa irgendwo nachgucken? Google und das Catalyst Control Center schweigen diesbezüglich.

    Man kann die irgendwie mit OpenGL enumerieren. Nehe oder Google werden dir sagen wie 🙂

    NeHe gibt mir nur Seiten die nicht mehr existieren und google nach "OpenGL Pixelformate" oder ähnlichem hat auch nicht viel gebacht. Aber das ist jetzt eigentlich unwichtig.

    hustbaer schrieb:

    Und zum Schluss habe ich aber noch eine Frage grundlegend zu C++, die mir in einem halben Jahr noch nicht begegnet ist. Und zwar hast du in den return Anweisungen manchmal folgendes stehen:

    return s_wglSwapIntervalEXT(interval) != 0;
    // oder
    return init.swapInterval > 0;
    

    Lies dich mal ein was Epressions und Operatoren in C++ angeht.
    a < b ist in C++ einfach nur ne Expression, (fast) egal wo es steht. Eine Expression hat einen Wert. Expression mit Vergleichsoperatoren haben einen Wert vom Typ bool , und sind true wenn die Bedingung erfüllt ist, und sonst false .
    Und mit if (Expression) kann man halt Code bedingt ausführen lassen, also nur wenn der Wert der Expression, nach bool konvertiert, true ergibt. (Die Expression muss nicht den Typ bool haben, es geht z.B. auch if (42) - 42 nach bool konvertiert ist true (alles was nicht 0 oder false ist ergibt true ), d.h. der Code im if-Block wird ausgeführt)
    Man kann diesen Wert allerdings nicht nur mit if (Expression) verwenden, sondern ihn z.B. genau so gut einer Variable zuweisen. Oder eben mit return zurückgeben.

    Also:

    return init.swapInterval > 0;
    

    macht das selbe wie

    if (init.swapInterval > 0)
        return true;
    else
        return false;
    

    nur halt ohne unnötigen "Umweg".

    Ok, danke. Also war es doch das was ich geglaubt hatte 😃

    hustbaer schrieb:

    EDIT:
    Sollte ich bei VSync nicht nur 60 FPS haben? Momentan liegen die zwischen 290 und 340.

    Ja, sollte es. Hat es bei mir auch.
    Hast du auch sicher

    swap_interval = 1
    

    im settings.ini File stehen?

    Ja hatte ich, aber ich musste die fps-Messung noch anpassen, habe einmal einen falschen Paramter benutzt 🙄
    Jetzt hab ich da auch 60 FPS stehen 🙂

    hustbaer schrieb:

    BTW: use_fsaa = false funktioniert bei mir auch wie erwartet.

    Bei mir jetzt auch. Wie gesagt lag es am Depth Buffer und and Visual Studio, dass ich gedacht habe es wär noch an.

    So jetzt bin ich aber durch und habe keine Fragen mehr 🙂
    Jetzt ist auch schön in einem Thread alles zusammengefasst, welche Möglichkeiten es für eine feste Spielgeschwindigkeit gibt 🙂



    1. Guck mal in WindowGL::InitGL. Der Integer-Wert den man da setzt gibt an, alle wieviel Frames ein neues Bild auf dem Bildschirm angezeigt wird. Also wenn du da z.B. 10 rein schreibst, dann ruckelt alles ganz ganz böse, weil bloss alle 10 Frames (Bildaufbau vom Monitor) ein neues Bild angezeigt wird. Und bei 1 ist es eben synchronisiert, also 1 Frame am Monitor = 1 neues Bild.

    Korrektur:
    Wenn ich als swapInterval 10 angebe, werden 10 Frames für ein Bild am Monitor gerendert, aber höchstens so viel wie die Grafikkarte verträgt :p
    Also wenn ich jetzt z.B. 100 da eingeben würde, habe ich 600 FPS, wenn ich jetzt aber 15 oder so eingeben würde, macht meine GraKa schon bei 724 schluss und nicht erst bei 6000 😃



  • Bei mir ist das genau umgekehrt.
    Wenn ich da 10 einstelle, dann rendert er 6 Frames pro Sekunde (alle 10 Monitor-Frames ein neu gerendertes Frame).

    Vielleicht hat ATI das wiedermal verkackt 😃 (ich hab so ein NIVEA Ding, das is viel besser *hihi*)

    Sollte aber egal sein, wichtig ist dass 1 (VSync an) und 0 (VSync aus) funktionieren.



  • Hmm, irgendwie bin ich gerade am verzweifeln 😞
    Und zwar wollte ich eine Klasse GLExtensions machen die so aussieht:

    class GLExtensions {
    public:
    	GLExtensions();
    	bool WGLisExtensionSupported(const char *extension_name);
    	bool WGLSetSwapInterval(int interval);
    	bool WGLInitMultisample(HINSTANCE hInstance, HWND hWnd, PIXELFORMATDESCRIPTOR pfd);
    	bool arbMultisampleSupported(void);
    	int arbMultisampleFormat(void);
    private:
    	PFNWGLSWAPINTERVALEXTPROC			m_wglSwapIntervalEXT;
    	PFNWGLGETSWAPINTERVALEXTPROC		m_wglGetSwapIntervalEXT;
    	PFNWGLGETEXTENSIONSSTRINGEXTPROC	m_wglGetExtensionsStringEXT;
    	bool								m_arbMultisampleSupported;
    	int									m_arbMultisampleFormat;
    };
    

    Nur meckert der Debugger in der Funktion WGLisExtensionSupported in folgender Zeile immer irgendwas wegen Zugriffsverletzung rum:

    const char* const extensions = m_wglGetExtensionsStringEXT();
    

    m_wglGetExtensionsStringEXT ist kein Nullpointer und generell war die einzige Änderung nur, dass ich statt einem s_ jetzt ein m_ als Präfix habe und die Variable jetzt ein Klassenmember ist.

    Fehlermeldung ist dieser hier:

    Eine Ausnahme (erste Chance) bei 0xcdcdcdcd in Game.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcdcdcdcd.
    Unbehandelte Ausnahme bei 0xcdcdcdcd in Game.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcdcdcdcd.
    

Anmelden zum Antworten