opengl Engine vom Programmierneuling! oder: kann man das so machen?



  • Hi erstmal !
    Nachdem ich in den letzten Wochen etwas mit Direct X und OpenGl rumexperimentiert hatte und auch Engines wie Irrlicht und Ogre mal getestet hatte wollte ich die WinApi und den ganzen OpenGL kram in Klassen auslagern. Also sozusagen ne kleine Engine entwerfen. Als Ausgangsprojekt habe ich ein Tutorial von "NeHe" genommen und das dann in eine Klasse gepackt. Die "Engine" sollte also das Fenster erstellen und eine Pyramide und einen Würfel darstellen können. Das Auslagern der Funktionen war anfangs gar nicht so schwer, erst mit der WndProc begann es kompliziert zu werden. Nach jeder menge Kaffee und mindestens genausovielen Tipps aus dem Internet hatte ich es endlich geschafft! Da ich aber anfänger bin und von OOP nicht allzuviel verstehe (deshalb mache ich das. Will OOP verstehen!!!) habe ich jetzt keine Ahnung ob das so wie ich es geschrieben habe "guter Stil" ist. Oder anders gesagt so einfach wie ich es geschrieben habe kann das nicht wirklich guter stil sein 🤡. Bevor ich jetzt anfange meine "Engine" auszubauen wollte ich mir hier rat suchen. Ich Poste mal meine klasse und hoffe mir kann jemand tipps geben wie es "besser" geht. Auch über Erklärungen weshalb man etwas so und nicht so macht wären echt klasse, bin absoluter Programmieranfänger und hatte bis vor 2 Wochen nur C++/CLI genutzt. Gerade was also die WinApi anbelangt bin ich also nicht allzu fit. So, hier erstmal der Code:

    //klassen.h
    #include <Windows.h>
    #include <gl\GL.h>
    #include <gl\GLU.h>
    
    class ladeObjekt {
    //Funktionen für die Erstellung von 3D-Objekten
     public :
    	 static void ladePyramide(void);
    	 static void ladeWuerfel(void); 
    };
    
    class ogl {
    //-------------------------------------------------------------------------------------
    	private:
    HINSTANCE hInstance;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;
    
    public:
    
    	ogl(HINSTANCE hInstance);
    virtual ~ogl();
    
    static LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    bool handleMessages();
    
    static GLvoid ReSizeGLScene(GLsizei width, GLsizei height);		// verändert die Größe und initialisiert das GL-Fenster 
    static GLvoid KillGLWindow(bool fullscreen, HGLRC hRC,HDC hDC, HWND hWnd, HINSTANCE hInstance );		// Entferne das Fenster korrekt 
    static int InitGL(GLvoid);	
    bool createWindow(char* title, int width, int height, int bits, bool fullscreenflag);
    static int DrawGLScene(GLfloat rtri, GLfloat rquad );// Hier kommt der ganze Zeichnen-Kram hin 
    void swap();
    
    //---------------------------------------------------------------------------------------
    
    };
    
    //klassen.cpp
    #include "resource.h"
    #include "klassen.h"
    
    //-----------------------------------------------------------------------------------------------------------
    //
    //Farben und Vertices der Pyramide
    //-----------------------------------------------------------------------------------------------------------
    void ladeObjekt::ladePyramide(void) {
    //Hier sind nur vertices und farben drin also eher uninteressant...
    	....
    }
    
    //-----------------------------------------------------------------------------------------------------------
    //
    //Farben und Vertices des Würfels
    //-----------------------------------------------------------------------------------------------------------
    void ladeObjekt::ladeWuerfel(void) {
    	//Hier sind nur vertices und farben drin also eher uninteressant...
    	....
    	//
    
    	}
    
    //-----------------------------------------------------------------------------------------------------------
    //
    //Konstruktor
    //-----------------------------------------------------------------------------------------------------------
    ogl::ogl(HINSTANCE hInstance)
    {
    this->hInstance = hInstance;
    
    hWnd = NULL;
    hDC = NULL;
    hRC = NULL;
    }
    
    //-----------------------------------------------------------------------------------------------------------
    //
    //Destruktor
    //----------------------------------------------------------------------------------------------------------
    ogl::~ogl() {
    if(hRC)
    {
      wglMakeCurrent(NULL, NULL);
      wglDeleteContext(hRC);
    }
    if(hWnd && hDC)
    {
      ReleaseDC(hWnd, hDC);
    }
    
    if(hWnd)
    {
      DestroyWindow(hWnd);
    }
    }
    
    //--------------------------------------------------------------------------------------------------------------
    //
    //Window Process kümmert sich um Nachrichten wie Tastatur und Mausereignisse aber auch Systemereignisse
    //--------------------------------------------------------------------------------------------------------------
    LRESULT CALLBACK ogl::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch(msg)
        {
    		case WM_SYSCOMMAND: 
    
    			switch (wParam) 
    			{ 
    			//Screensaver unterdrücken 
    			case SC_SCREENSAVE:   
    				return 0; 
    			//Stand-By unterdrücken
    			case SC_MONITORPOWER:
    				return 0;
    		} 
    		break;       
      case WM_KEYDOWN:
    	  switch (wParam) {
      case VK_ESCAPE:
    	  PostQuitMessage(0);
    	  break;
      case VK_F1:
    	  ShowCursor(true);
    	  MessageBox(NULL,"Nachricht wurde von WndProc empfangen\nund verarbeitet. Test wird beendet!", "Programm wird beendet !",MB_OK|MB_ICONINFORMATION);
    	  PostQuitMessage(0);
    	  break;
      case WM_CLOSE:
       DestroyWindow(hWnd);
       break;
      case WM_DESTROY:
       PostQuitMessage(0);
       break;
    	  }
      default:
       return DefWindowProc(hWnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    //-----------------------------------------------------------------------------------------------------------------
    //
    //halte Ausschau nach und behandle Nachrichten 
    //-----------------------------------------------------------------------------------------------------------------
    bool ogl::handleMessages()
    { 
    MSG msg = {0};
    
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
      if(msg.message == WM_QUIT)
      {
       return false;
      }
    
      TranslateMessage(&msg);
      DispatchMessage(&msg);
        }
    return true;
    }
    
    //------------------------------------------------------------------------------------------------------------------------
    //
    //Ändere die Fenstergröße
    //------------------------------------------------------------------------------------------------------------------------
    GLvoid ogl::ReSizeGLScene(GLsizei width, GLsizei height)		// verändert die Größe und initialisiert das GL-Fenster 
    {
    	if (height==0)										// Verhindere eine Division durch 0, indem 
    	{
    		height=1;										// die Höhe auf 1 gesetzt wird 
    	}
    
    	glViewport(0,0,width,height);						// Resette die aktuelle Ansicht (Viewport) 
    
    	glMatrixMode(GL_PROJECTION);						// wähle die Projektions-Matrix aus 
    	glLoadIdentity();									// Resette die Projection Matrix
    
    	// Calculate The Aspect Ratio Of The Window
    	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
    
    	glMatrixMode(GL_MODELVIEW);							// Wähle die Modelview Matrix aus 
    	glLoadIdentity();									// Resette die Modelview Matrix
    }
    
    //-------------------------------------------------------------------------------------------------------------------------
    //
    //Zerstöre das Fenster
    //-------------------------------------------------------------------------------------------------------------------------
    GLvoid ogl::KillGLWindow(bool fullscreen,
    						   HGLRC hRC,
    						   HDC hDC,
    						   HWND hWnd, 
    						   HINSTANCE hInstance )		// Entferne das Fenster korrekt 
    {
    	if (fullscreen)										// Sind wir im Fullscreen Modus? 
    	{
    		ChangeDisplaySettings(NULL,0);					// Wenn ja, wechsle zurück zum Desktop 
    		ShowCursor(TRUE);								// Zeige den Maus-Zeiger 
    	}
    
    	if (hRC)											// Haben wir einen Rendering Context? 
    	{
    		if (!wglMakeCurrent(NULL,NULL))					// Können wir den DC und RC Kontext freigeben? 
    		{
    			MessageBox(NULL,"Freigabe des DC und RC Kontextes nicht gelungen!","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		}
    
    		if (!wglDeleteContext(hRC))						// Können wir den RC löschen? 
    		{
    			MessageBox(NULL,"Freigabe des Rendering Context nicht gelungen!","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		}
    		hRC=NULL;										// Setze RC auf NULL 
    	}
    
    	if (hDC && !ReleaseDC(hWnd,hDC))					// Können wir DC freigeben?
    	{
    		MessageBox(NULL,"Freigabe des Device Context nicht gelungen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		hDC=NULL;										// Setze DC auf NULL 
    	}
    
    	if (hWnd && !DestroyWindow(hWnd))					// Können wir das Fenster zerstören? 
    	{
    		MessageBox(NULL,"Konnte hWnd nicht zerstören.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		hWnd=NULL;										// Setze hWnd auf NULL
    	}
    
    	if (!UnregisterClass("OpenGL",hInstance))			// Können wir die Klasse de-registrieren? 
    	{
    		MessageBox(NULL,"Konnte Klasse nicht de-registrieren","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		hInstance=NULL;									// Setze hInstance auf NULL 
    	}
    }
    
    //---------------------------------------------------------------------------------------------------------------
    //
    //initialisiere OpenGl
    //---------------------------------------------------------------------------------------------------------------
    int ogl::InitGL(GLvoid)							// Der ganze Setup Kram für OpenGL kommt hier rein 
    {
    	glShadeModel(GL_SMOOTH);							// aktiviert weiches Shading (Smooth Shading) 
    	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Schwarzer Hintergrund
    	glClearDepth(1.0f);									// Depth Buffer Setup
    	glEnable(GL_DEPTH_TEST);							// aktiviert Depth Test
    	glDepthFunc(GL_LEQUAL);								// Die Art des auszuführenden Depth Test 
    	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// wirklich nette Perspektiven Berechnungen
    	return TRUE;										// Initialisierung war OK 
    }
    
    //----------------------------------------------------------------------------------------------------------
    //
    //erstelle das Fenster
    //----------------------------------------------------------------------------------------------------------
    	bool ogl::createWindow(char* title, int width, int height, int bits, bool fullscreenflag)
    {
    	GLuint		PixelFormat;			// Enthält die Ergebnisse nachdem nach was passendem gesucht wurde 
    	WNDCLASS	wc;						// Fenster Klassen Struktur 
    	DWORD		dwExStyle;				// erweiterter Fenster-Stil 
    	DWORD		dwStyle;				// Fenster-Stil 
    	RECT		WindowRect;				// Enthält die obere linke / untere rechte Eckwerte des Rechtecks 
    	WindowRect.left=(long)0;			// Setze linken Wert auf 0 
    	WindowRect.right=(long)width;		// Setze rechten Wert auf die gewünschte Breite 
    	WindowRect.top=(long)0;				// Setze den oberen Wert auf 0 
    	WindowRect.bottom=(long)height;		// Setze unteren Wert auf die gewünschte Höhe 
    
    	bool fullscreen=fullscreenflag;			// Setze das globale Fullscreen Flag 
    
    	hInstance			= GetModuleHandle(NULL);				// Ermittle die Instanz für unser Fenster 
    	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Zeichne neu beim bewegen und eigener DC für's Fenster 
    	wc.lpfnWndProc		= (WNDPROC) WinProc;					// WndProc behandelt die Nachrichten 
    	wc.cbClsExtra		= 0;									// Keine extra Fenster-Daten 
    	wc.cbWndExtra		= 0;									// Keine extra Fenster-Daten 
    	wc.hInstance		= hInstance;							// Setze die Instanz 
    	wc.hIcon			= LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));	// Lade mein eigenes Icon 
    	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Lade den Pfeil-Zeiger 
    	wc.hbrBackground	= NULL;									// es wird kein Hintergrund für GL benötigt 
    	wc.lpszMenuName		= NULL;									// Wir wollen kein Menü 
    	wc.lpszClassName	= "OpenGL";								// Setze den Klassen-Namen 
    
    	if (!RegisterClass(&wc))									// Versuche die Fenster-Klasse zu registrieren 
    	{
    		MessageBox(NULL,"Fehler bei der registrierung der Fenster-Klasse!","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;											// beende und gebe FALSE zurück 
    	}
    
    	if (fullscreen)												// Vollbild-Modus? 
    	{
    		DEVMODE dmScreenSettings;								// Device Modus 
    		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Stelle sicher, dass der Speicher geleert ist 
    		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Größe der Devmode Struktur 
    		dmScreenSettings.dmPelsWidth	= width;				// ausgewählte Screen Breite 
    		dmScreenSettings.dmPelsHeight	= height;				// ausgewählte Screen Höhe 
    		dmScreenSettings.dmBitsPerPel	= bits;					// ausgewählte Bits Per Pixel 
    		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
    
    		// Versuche gewählten Modus zu setzen und Ergebnisse zurückliefern. ANMERKUNG: CDS_FULLSCREEN lässt die Start-Leiste nicht anzeigen. 
    		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
    		{
    			// Wenn der Modus fehl schlägt, biete zwei Optionen an. Beenden oder im Fenster-Modus laufen lassen. 
    			if (MessageBox(NULL," Der Vollbildmodus wird von Ihrer Videokarte nicht unterstützt. Benutzen sie bitte den Fenstermodus!","Achtung!",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
    			{
    				fullscreen=FALSE;			// wähle Fenster-Modus aus (Fullscreen=FALSE) 
    			}
    			else
    			{
    				// Message Box anzeigen, die den Benutzer wissen lässt, dass das Programm geschlossen wird. 
    				MessageBox(NULL,"Programm wird jetzt geschlossen.","Fehler",MB_OK|MB_ICONSTOP);
    				return FALSE;									// beende und gebe FALSE zurück 
    			}
    		}
    	}
    
    	if (fullscreen)												// Sind wir immer noch im Fullscreen Modus? 
    	{
    		dwExStyle=WS_EX_APPWINDOW;								// erweiterter Fenster-Stil 
    		dwStyle=WS_POPUP;										// Fenster-Stil 
    		ShowCursor(FALSE);										// verstecke Maus-Zeiger
    	}
    	else
    	{
    		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// erweiterter Fenster-Stil 
    		dwStyle=WS_OVERLAPPEDWINDOW;							// Fenster-Stil 
    	}
    
    	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// justiere das Fenster der angeforderten Größe entsprechend 
    
    	// Create The Window
    	if (!(hWnd=CreateWindowEx(	dwExStyle,							// erweiterter Stil für das Fenster 
    								"OpenGL",							// Klassen Name 
    								title,								// Fenster Titel 
    								dwStyle |							// ausgewählter Fenster Stil  
    								WS_CLIPSIBLINGS |					// benötigter Fenster-Stil 
    								WS_CLIPCHILDREN,					// benötigter Fenster-Stil
    								0, 0,								// Fenster Position 
    								WindowRect.right-WindowRect.left,	// berechne die justierte Fenster-Breite 
    								WindowRect.bottom-WindowRect.top,	// berechne die justierte Fenster-Höhe 
    								NULL,								// Kein Parent Fenster
    								NULL,								// Kein Menü
    								hInstance,							// Instanz 
    								NULL)))								// Leite nichts an WM_CREATE weiter 
    	{
    		ogl::KillGLWindow(fullscreenflag,hRC,hDC,hWnd,hInstance);								// Resette die Ansicht
    		MessageBox(NULL,"Fehler bei der Fenstererstellung.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;									// beende und gebe FALSE zurück 
    	}
    
    	//-----------------------------------------------------------------------------------------------------------
    	//
    	//Pixelformardescritor
    	//-----------------------------------------------------------------------------------------------------------
    	static	PIXELFORMATDESCRIPTOR pfd=				// pfd teilt Windows mit, wie wir die Dinge haben wollen 
    	{
    		sizeof(PIXELFORMATDESCRIPTOR),				// Größe des Pixel Format Descriptors 
    		1,											// Versions Nummer 
    		PFD_DRAW_TO_WINDOW |						// Format muss Fenster unterstützen
    		PFD_SUPPORT_OPENGL |						// Format muss OpenGL unterstützen
    		PFD_DOUBLEBUFFER,							// Muss Double Buffering unterstützen 
    		PFD_TYPE_RGBA,								// Fordere ein RGBA Format an 
    		bits,										// wähle unsere Farbtiefe aus 
    		0, 0, 0, 0, 0, 0,							// Color Bits werden ignoriert 
    		0,											// Kein Alpha Buffer 
    		0,											// Shift Bit wird ignoriert 
    		0,											// Kein Accumulation Buffer
    		0, 0, 0, 0,									// Accumulation Bits ignorieren
    		16,											// 16Bit Z-Buffer (Depth Buffer)   
    		0,											// Kein Stencil Buffer
    		0,											// Kein Auxiliary Buffer
    		PFD_MAIN_PLANE,								// Haupt-Zeichen-Schicht 
    		0,											// Reserviert
    		0, 0, 0										// Layer Masken werden ignoriert 
    	};
    
    	if (!(hDC=GetDC(hWnd)))							//Haben wir einen Device Kontext erhalten? 
    	{
    		ogl::KillGLWindow(fullscreenflag,hRC,hDC,hWnd,hInstance);								// Resette die Anzeige 
    		MessageBox(NULL,"Konnte keinen GL Device Kontext erstellen.","Fehler!",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück 
    	}
    
    	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// Hat Windows ein passendes Pixel Format gefunden? 
    	{
    		ogl::KillGLWindow(fullscreenflag,hRC,hDC,hWnd,hInstance);								// Resette die Anzeige 
    		MessageBox(NULL,"Kein passendes PixelFormat vorhanden.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück 
    	}
    
    	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// Können wir das Pixel Format setzen? 
    	{
    		ogl::KillGLWindow(fullscreenflag,hRC,hDC,hWnd,hInstance);								// Resette die Anzeige
    		MessageBox(NULL,"Kann PixelFormat nicht setzen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück
    	}
    
    	if (!(hRC=wglCreateContext(hDC)))				// Können wir einenRendering Kontext kriegen? 
    	{
    		ogl::KillGLWindow(fullscreenflag,hRC,hDC,hWnd,hInstance);							// Resette die Anzeige
    		MessageBox(NULL,"Erhalte keinen GL Rendering Kontext.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück
    	}
    
    	if(!wglMakeCurrent(hDC,hRC))					// Versuche den Rendering Kontext zu aktivieren 
    	{
    		ogl::KillGLWindow(fullscreen,hRC,hDC,hWnd,hInstance);								// Resette die Anzeige
    		MessageBox(NULL,"Kann den GL Rendering Kontext nicht erstellen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück
    	}
    
    	ShowWindow(hWnd,SW_SHOW);						// Zeige das Fenster 
    	SetForegroundWindow(hWnd);						// Etwas höhere Priorität 
    	SetFocus(hWnd);									// Setze den Tastatur-Fokus auf das Fenster 
    	ogl::ReSizeGLScene(width, height);					// Initialisiere unseren perspektivischen GL-Screen 
    
    	if (!ogl::InitGL())									// Initialisiere unser neu erzeugtes GL Fenster
    	{
    		ogl::KillGLWindow(fullscreen,hRC,hDC,hWnd,hInstance);								// Resette die Anzeige
    		MessageBox(NULL,"Initialisation nicht gelungen .","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;								// Gebe FALSE zurück
    	}
    
    	return TRUE;									// Erfolg
    }
    
     //-----------------------------------------------------------------------------------------------------------------
    //
    //Zeichne die OpenGl Scene
    //------------------------------------------------------------------------------------------------------------------
    int ogl::DrawGLScene(GLfloat rtri, GLfloat rquad )
    {
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Lösche den Bildschirm und den Depth-Buffer 
    	glLoadIdentity();									// Resettet die aktuelle Modelview Matrix 
    	glTranslatef(-1.5f,0.0f,-6.0f); // Sicht ausrichten
    	glRotatef(rtri,1.0f,1.0f,0.0f);	// Dreieck um X und Y-Achse rotieren
    	glBegin(GL_TRIANGLES);			// Beginne Primitive Dreieck zu zeichnen
    	ladeObjekt::ladePyramide();// Koordinaten und Farben der Pyramide laden
    	glEnd();						// Fertig gezeichnet
    	glLoadIdentity(); // Resette die aktuelle Modelview Matrix 
    	glTranslatef(1.5f,0.0f,-6.0f); // 1.5 Einheiten nach links und dann 6 Einheiten in den Bildschirm hinein 
    	glRotatef(rquad,1.0f,0.0f,1.0f); // Rotiere den Würfel auf der X und Z-Achse  
    	glBegin(GL_QUADS);				// Beginne Primitive Rechteck zu zeichnen
    	ladeObjekt::ladeWuerfel();					// Koordinaten und Farben des Würfels laden
    	glEnd();						// Fertig gezeichnet					
    	return TRUE;										// Alles war OK 
    }
    
    //------------------------------------------------------------------------------------------------------------------
    //
    //Wechsle zwischen den Puffern
    //------------------------------------------------------------------------------------------------------------------
    void ogl::swap()
    {
    SwapBuffers(hDC);
    }
    

    😮
    Recht langer Post geworden, gebe mir aber Mühe das in Zukunft kürzer zu halten.
    Gruß littles



  • littles schrieb:

    Da ich aber anfänger bin und von OOP nicht allzuviel verstehe (deshalb mache ich das. Will OOP verstehen!!!) habe ich jetzt keine Ahnung ob das so wie ich es geschrieben habe "guter Stil" ist.

    Code wird nicht dadurch objektorientiert, wenn man alles in eine Klasse packt.

    Als erstes könntest Du versuchen das Single responsibility principle anzuwenden. Deine ogl-Klasse übernimmt zu viele verschiedene Aufgaben.

    http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

    Nachtrag:
    Und eine Engine ist was anderes. Ich warne Dich nur vor, weil hier manche Leute allergisch auf sowas reagieren 😉



  • Danke für den link! Werde noch den GL kram und den WinApi kram trennen. Das ist jetzt sozusagen der erste Ansatz gewesen der sich Compilieren ließ und auch lief. Wieso muss ich eigentlich die ganzen statics einsetzen? ginge das, abgesehen von WinProc nicht auch ohne?

    Naja, ne Engine ist das nicht, ganz klar, aber es soll als "Hello World" für den Start einer Engine dienen. Also sozusagen der Startpunkt um eine Engine aufzubauen. Daher auch die "" bei dem Begriff Engine 😉





  • wie ich ja schon erwähnte arbeite ich eigentlich mit CLI (und das auch erst seit 6 Monaten). Da gibt es aber nix gescheites (oder hab nix gefunden) um Komplexere Grafiken zu verwenden. Deshalb wollte ich dafür was eigenes entwickeln um Daten zu Visualisieren (z.B. Darstellung einer Beinprothese und die möglichkeit den Bewegunsablauf zur laufzeit zu optimieren). Da ich aber in anderen Projekten dann nicht wieder bei null anfangen will wollte ich mir die Arbeit machen eine "Engine" (wenn auch eine abgespeckte) für weitere Projekte zu erstellen. Falls mein Ansatz oder der Begriff "Engine" falsch sein sollten könnt ihr mir da natürlich gerne tipps geben wie man das richtig macht. Aber bevor wir jetzt mit der Definition der Engine bzw nicht Engine weiter machen würde ich lieber etwas zum Code erfahren. 😃



  • Nenn's einfach Framework. Engine impliziert irgendwie, dass sie sehr abstrakt für alle möglichen Dinge eingesetzt werden kann. Soll heißen du baust 10 verschiedene Kameratypen ein, obwohl du für deine Anwendung eigentlich nur einen brauchst. Nach

    Also sozusagen der Startpunkt um eine Engine aufzubauen.

    war ich aber auch schon kurz davor den Link zu posten.

    Zum Code:
    Bitte mal durchgängig richtig einrücken und farbig machen (cpp-Tags, nicht code-Tags), dann ist das auch etwas einfacher zu lesen.
    Ansonsten kann ich mich meinem Vorredner nur anschließen, eine Klasse sollte eine Aufgabe haben, nicht 100. statische Funktionen kann man meistens vermeiden. (Freie Funktionen und OOP sind keine Gegensätze.)
    Du kannst ja mal versuchen, mehr in die Konstruktoren/Destruktoren zu verlagern. Funktionen wie "InitGL", "killGLWIndow", "createWindow", etc. sind ein Zeichen für schlechtes Design.



  • Okay, mit Framework kann ich mich anfreunden 😉
    Danke für den Hinweis. Werde mich gleich mal ranmachen. Ist ja echt super, so schnell hatte ich nicht mit so vielen Statements gerechnet.


Log in to reply