Browse Source

Fehler beim Freigeben der Ressourcen eines Threads auf UNIX Systemen behoben, der zu enormen Memory Leaks geführt hat.

Kolja Strohm 8 years ago
parent
commit
0e8d05d6aa
16 changed files with 501 additions and 84 deletions
  1. 2 2
      Array.h
  2. 1 0
      Betriebssystem.h
  3. 7 3
      Bildschirm.cpp
  4. 26 11
      Global.cpp
  5. 14 8
      Globals.h
  6. 18 1
      Kam3D.cpp
  7. 1 0
      Kam3D.h
  8. 147 0
      Mat4.h
  9. 14 1
      MausEreignis.h
  10. 0 3
      Text.cpp
  11. 76 12
      Thread.cpp
  12. 22 12
      Thread.h
  13. 161 27
      Welt3D.cpp
  14. 9 1
      Welt3D.h
  15. 1 1
      Zeichnung3D.cpp
  16. 2 2
      Zeichnung3D.h

+ 2 - 2
Array.h

@@ -282,7 +282,7 @@ namespace Framework
                 err += __LINE__;
                 err += " Index: ";
                 err += i;
-                throw std::out_of_range( err );
+                throw std::out_of_range( (char*)err );
             }
             ArrayEintrag< TYP > *e = einträge;
             for( int a = 0; a < i && e; ++a )
@@ -295,7 +295,7 @@ namespace Framework
             err += __LINE__;
             err += " Index: ";
             err += i;
-            throw std::out_of_range( err );
+            throw std::out_of_range( (char*)err );
         }
 
         // Überprüft, ob ein Element in der Liste enthalten ist

+ 1 - 0
Betriebssystem.h

@@ -28,6 +28,7 @@
 
 #define WIN32_LEAN_AND_MEAN
 #include <Windows.h>
+#define pthread_t                      void*
 
 #else
 

+ 7 - 3
Bildschirm.cpp

@@ -935,9 +935,12 @@ void Bildschirm3D::render() // Zeichnet das Bild
         // Clear the back buffer.
         if( rend3D || !testRend || rend )
         {
-            d3d11Context->ClearRenderTargetView( rtview, color );
-            // Clear the depth buffer.
-            d3d11Context->ClearDepthStencilView( dsView, D3D11_CLEAR_DEPTH, 1, 0 );
+            if( füll )
+            {
+                d3d11Context->ClearRenderTargetView( rtview, color );
+                // Clear the depth buffer.
+                d3d11Context->ClearDepthStencilView( dsView, D3D11_CLEAR_DEPTH, 1, 0 );
+            }
             // Bind the render target view and depth stencil buffer to the output render pipeline.
             d3d11Context->OMSetRenderTargets( 1, &rtview, dsView );
 
@@ -946,6 +949,7 @@ void Bildschirm3D::render() // Zeichnet das Bild
 
             for( auto i = kameras->getArray(); i.set; i++ )
                 i.var->render( renderObj );
+            rend3D = 0;
         }
         // Set the depth stencil state.
         d3d11Context->OMSetDepthStencilState( depthDisabledStencilState, 1 );

+ 26 - 11
Global.cpp

@@ -3,20 +3,21 @@
 #include <Windows.h>
 #include <GdiPlus.h>
 #pragma comment( lib, "gdiplus.lib" )
+#include "Fenster.h"
+#include "Maus.h"
+#include "Model3DList.h"
+#include "TexturList.h"
 
 #endif
 #define Global
-#include "Fenster.h"
-#include "Maus.h"
 #include "Globals.h"
 #include "Thread.h"
-#include "Model3DList.h"
-#include "TexturList.h"
 
 void Framework::initFramework()
 {
     if( istInitialisiert )
         return;
+#ifdef WIN32
     Gdiplus::GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;
     Gdiplus::GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, 0 );
@@ -26,26 +27,43 @@ void Framework::initFramework()
         TastenStand[ i ] = 0;
     for( int i = 0; i < 3; ++i )
         MausStand[ i ] = 0;
-    thRegister = new ThreadRegister();
     Model3DList::init();
     m3dRegister = new Model3DList();
     TexturList::init();
     texturRegister = new TexturList();
+#endif
     istInitialisiert = 1;
+    thRegister = new ThreadRegister();
 }
 
 void Framework::releaseFramework()
 {
     if( !istInitialisiert )
         return;
+    thRegister->cleanUpClosedThreads();
     delete thRegister;
+#ifdef WIN32
     m3dRegister->release();
     Model3DList::destroy();
     texturRegister->release();
     TexturList::destroy();
+#endif
     istInitialisiert = 0;
 }
 
+bool Framework::istThreadOk( Thread *t )
+{
+    return thRegister->isThread( t );
+}
+
+// Gibt das Thread Register des Frameworks zurück
+Framework::ThreadRegister *Framework::getThreadRegister()
+{
+    return thRegister;
+}
+
+#ifdef WIN32
+
 const Framework::Punkt &Framework::getMausPos()
 {
     return mausPos;
@@ -66,11 +84,6 @@ bool Framework::getTastenStand( unsigned char taste )
     return TastenStand[ taste ];
 }
 
-bool Framework::istThreadOk( Thread *t )
-{
-    return thRegister->isThread( t );
-}
-
 // Gibt das Model3DData Register des Frameworks ohne erhöhten reference Counter zurück
 Framework::Model3DList *Framework::zM3DRegister()
 {
@@ -81,4 +94,6 @@ Framework::Model3DList *Framework::zM3DRegister()
 Framework::TexturList *Framework::zTexturRegister()
 {
     return texturRegister;
-}
+}
+
+#endif

+ 14 - 8
Globals.h

@@ -9,10 +9,11 @@
 
 namespace Framework
 {
+    class ThreadRegister; // Thread.h
+    class Thread; // Thread.h
+#ifdef WIN32
     class Maus; // Maus.h
     class WFensterArray; // Fenster.h
-    class Thread; // Thread.h
-    class ThreadRegister; // Thread.h
     class Model3DList; // Model3DList.h
     class TexturList; // TexturList.h
 
@@ -21,13 +22,15 @@ namespace Framework
     Global bool MausStand[ 3 ];
     Global bool TastenStand[ 255 ];
     Global Maus MausZeiger;
-    Global bool istInitialisiert;
     Global bool msgExit;
     Global Punkt mausPos;
-    Global ThreadRegister *thRegister;
     Global Model3DList *m3dRegister;
     Global TexturList *texturRegister;
+#endif
+    Global bool istInitialisiert;
+    Global ThreadRegister *thRegister;
 
+#ifdef WIN32
     // Gibt die Koordinaten der Maus auf dem Bildschirm zurück
     __declspec( dllexport ) const Punkt &getMausPos();
     // Gibt zurück, ob eine Taste der Maus momentan gedrückt wird
@@ -43,6 +46,11 @@ namespace Framework
     //  taste: Die Taste, deren Status gesetzt werden soll
     //  st: Ob die Taste momentan gedrückt wird. (true), wenn ja. (false) sonnst.
     __declspec( dllexport ) void setTastenStand( unsigned char taste, bool st );
+    // Gibt das Model3DData Register des Frameworks ohne erhöhten reference Counter zurück
+    __declspec( dllexport ) Model3DList *zM3DRegister();
+    // Gibt das Textur Register des Frameworks ohne erhöhten reference Counter zurück
+    __declspec( dllexport ) TexturList *zTexturRegister();
+#endif
     // Initialisiert das Framework
     // Wird in der (WinMain) des Frameworks automatisch aufgerufen
     __declspec( dllexport ) void initFramework();
@@ -53,10 +61,8 @@ namespace Framework
     //  t: Der zeiger, der überprüft werden soll
     //  return: 1, falls der Zeiger in Ordnung ist. 0, falls der Zeiger auf kein existentes Thread Objekt zeigt
     __declspec( dllexport ) bool istThreadOk( Thread *t );
-    // Gibt das Model3DData Register des Frameworks ohne erhöhten reference Counter zurück
-    __declspec( dllexport ) Model3DList *zM3DRegister();
-    // Gibt das Textur Register des Frameworks ohne erhöhten reference Counter zurück
-    __declspec( dllexport ) TexturList *zTexturRegister();
+    // Gibt das Thread Register des Frameworks zurück
+    __declspec( dllexport ) ThreadRegister *getThreadRegister();
 }
 
 #endif

+ 18 - 1
Kam3D.cpp

@@ -4,6 +4,7 @@
 #include "Shader.h"
 #include "TastaturEreignis.h"
 #include "Globals.h"
+#include "MausEreignis.h"
 #include <d3d11.h>
 #include <DirectXMath.h>
 
@@ -177,7 +178,23 @@ bool Kam3D::tick( double tv )
 //  me: Das Mausereignis, das verarbeitet werden soll
 void Kam3D::doMausEreignis( MausEreignis &me )
 {
-
+    if( me.verarbeitet )
+        return;
+    if( me.mx > viewport->TopLeftX && me.my > viewport->TopLeftY && me.mx < viewport->TopLeftX + viewport->Width && me.my < viewport->TopLeftY + viewport->Height )
+    {
+        MausEreignis3D me3d;
+        me3d.id = me.id;
+        me3d.verarbeitet = me.verarbeitet;
+        Vec3< float > mausP = Vec3< float >( ( me.mx - viewport->TopLeftX ) / ( 0.5f * viewport->Width ) - 1, ( me.my - viewport->TopLeftY ) / ( 0.5f * viewport->Height ) - 1, 0 );
+        Vec3< float > mausT = Vec3< float >( mausP.x, mausP.y, 1 );
+        Mat4< float > mat = proj * view;
+        mat = mat.getInverse();
+        mausP = mat * mausP;
+        mausT = mat * mausT;
+        me3d.pos = mausP;
+        me3d.dir = mausT - mausP;
+        me.verarbeitet = 1;
+    }
 }
 
 // Verarbeitet ein Tastaturereignis

+ 1 - 0
Kam3D.h

@@ -10,6 +10,7 @@ struct D3D11_VIEWPORT;
 
 namespace Framework
 {
+    struct MausEreignis; // MausEreignis.h
     class Render3D; // Render3D.h
     class Welt3D; // Welt3D.h
 

+ 147 - 0
Mat4.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "Vec3.h"
+#include <iostream>
 
 namespace Framework
 {
@@ -65,6 +66,152 @@ namespace Framework
             result.z = elements[ 2 ][ 0 ] * r.x + elements[ 2 ][ 1 ] * r.y + elements[ 2 ][ 2 ] * r.z + elements[ 2 ][ 3 ];
             return  result;
         }
+        // Berechnet die inverse Matrix
+        Mat4 getInverse()
+        {
+            Mat4 ret;
+            ret.elements[ 0 ][ 0 ] = 
+                elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 2 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 2 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 3 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] -
+                elements[ 3 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ];
+
+            ret.elements[ 1 ][ 0 ] = 
+                -elements[ 1 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 1 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] +
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ];
+
+            ret.elements[ 2 ][ 0 ] = 
+                elements[ 1 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 3 ] -
+                elements[ 1 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 1 ] -
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 3 ] +
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 1 ] +
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] -
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 1 ];
+
+            ret.elements[ 3 ][ 0 ] = 
+                -elements[ 1 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 2 ] +
+                elements[ 1 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 1 ] +
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 2 ] -
+                elements[ 2 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 1 ] -
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] +
+                elements[ 3 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 1 ];
+
+            ret.elements[ 0 ][ 1 ] = 
+                -elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 2 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 2 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 3 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] +
+                elements[ 3 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ];
+
+            ret.elements[ 1 ][ 1 ] = 
+                elements[ 0 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 0 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ];
+
+            ret.elements[ 2 ][ 1 ] = 
+                -elements[ 0 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 3 ] +
+                elements[ 0 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 1 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 3 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 1 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 1 ];
+
+            ret.elements[ 3 ][ 1 ] = 
+                elements[ 0 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 2 ] -
+                elements[ 0 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 1 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 2 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 1 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 1 ];
+
+            ret.elements[ 0 ][ 2 ] = 
+                elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 1 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 1 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 3 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] -
+                elements[ 3 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
+
+            ret.elements[ 1 ][ 2 ] = 
+                -elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] +
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
+
+            ret.elements[ 2 ][ 2 ] = 
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 3 ] -
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 1 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 3 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 1 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 1 ];
+
+            ret.elements[ 3 ][ 2 ] = 
+                -elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 2 ] +
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 1 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 2 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 1 ] -
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] +
+                elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 1 ];
+
+            ret.elements[ 0 ][ 3 ] = 
+                -elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] +
+                elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ] +
+                elements[ 1 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] -
+                elements[ 1 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ] -
+                elements[ 2 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] +
+                elements[ 2 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
+
+            ret.elements[ 1 ][ 3 ] = 
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] -
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
+
+            ret.elements[ 2 ][ 3 ] = 
+                -elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] +
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 1 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 1 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 1 ];
+
+            ret.elements[ 3 ][ 3 ] = 
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] -
+                elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 1 ] -
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] +
+                elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 1 ] +
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] -
+                elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 1 ];
+
+            T det = elements[ 0 ][ 0 ] * ret.elements[ 0 ][ 0 ] + elements[ 0 ][ 1 ] * ret.elements[ 1 ][ 0 ] + elements[ 0 ][ 2 ] * ret.elements[ 2 ][ 0 ] + elements[ 0 ][ 3 ] * ret.elements[ 3 ][ 0 ];
+
+            if( det == 0 )
+            {
+                std::cout << "Fehler beim erstellen der Inversen Matrix";
+                return ret;
+            }
+            det = 1.0f / det;
+
+            for( int i = 0; i < 16; i++ )
+                ret.elements[ i / 4 ][ i % 4 ] = ret.elements[ i / 4 ][ i % 4 ] * det;
+
+            return ret;
+        }
         // Erzeugt eine Matrix, die einen Vektor um die Z Achse dreht, wenn sie mit ihm multipliziert wird
         //  radian: Der Winkel in Bogenmas
         static Mat4 rotationZ( T radian )

+ 14 - 1
MausEreignis.h

@@ -1,7 +1,7 @@
 #ifndef MausEreignis_H
 #define MausEreignis_H
 
-#include "Betriebssystem.h"
+#include "Vec3.h"
 
 namespace Framework
 {
@@ -42,6 +42,19 @@ namespace Framework
         bool verarbeitet;
     };
 
+    // Speichert eine bestimmte Mauseingabe des Nutzers
+    struct MausEreignis3D
+    {
+        // Art der Eingabe
+        int id;
+        // Die Position der Maus in der Welt
+        Vec3< float > pos;
+        // Die Richtung, in die die Kamera zeigt
+        Vec3< float > dir;
+        // Speichert, ob die Eingabe bereits verarbeitet wurde
+        bool verarbeitet;
+    };
+
     // Standart Maus Ereinis Rückruffunktion
     //  param: Ein beliebiger Parameter
     //  obj: Die Zeichnung, welches diese Funktion aufruft

+ 0 - 3
Text.cpp

@@ -1,9 +1,6 @@
 //---Include---
 #include "Text.h"
 #include <sstream>
-#include <string>
-#include <stdlib.h>
-#include <stdio.h>
 #include <iomanip>
 #ifndef WIN32
 #include <string.h>

+ 76 - 12
Thread.cpp

@@ -7,11 +7,10 @@ using namespace Framework;
 // Konstruktor 
 Thread::Thread()
 {
-    thRegister->add( this );
-#ifdef WIN32
+    threadHandleSys = 0;
     threadHandle = 0;
     threadId = 0;
-#endif
+    thRegister->add( this );
     run = 0;
 }
 
@@ -68,6 +67,11 @@ void Thread::ende() // beendet den Thread
 #pragma warning(suppress: 6258)
         TerminateThread( threadHandle, 0 );
 #else
+        if( pthread_self() == threadHandle )
+        {
+            thRegister->addClosedThread( threadHandle );
+            run = 0;
+        }
         pthread_cancel( threadHandle );
 #endif
     }
@@ -88,7 +92,7 @@ bool Thread::l
     return run;
 }
 
-int Thread::warteAufThread( int zeit ) const // wartet zeit lang auf den Thread
+int Thread::warteAufThread( int zeit ) // wartet zeit lang auf den Thread
 {
 #ifdef WIN32
     if( !run )
@@ -99,16 +103,28 @@ int Thread::warteAufThread( int zeit ) const // wartet zeit lang auf den Thread
 #else
     if( !run )
         return 0;
-    return pthread_join( threadHandle, 0 );
+    if( pthread_self() == threadHandle )
+        return 0;
+    if( threadHandleSys )
+        *threadHandleSys = threadHandle;
+    int ret = pthread_join( threadHandle, 0 );
+    threadHandle = 0;
+    return ret;
 #endif
 }
 
-#ifdef WIN32
-void *Thread::getThreadHandle() const
+// Legt einen Frameworkpointer auf ein Threadhandle fest, der auf 0 gesetzt wird, falls die Ressourcen des Threads bereits follstänfig aufgeräumt wurden
+//  ths: Ein Zeiger auf ein Threadhandle, das verändert werden soll
+void Thread::setSystemHandlePointer( pthread_t *ths )
+{
+    threadHandleSys = ths;
+    *threadHandleSys = threadHandle;
+}
+
+pthread_t Thread::getThreadHandle() const
 {
     return threadHandle;
 }
-#endif
 
 // funktionen 
 #ifdef WIN32
@@ -123,26 +139,74 @@ unsigned long __stdcall Framework::threadStart( void *param )
 #else
 void *Framework::threadStart( void *param )
 {
+    pthread_t handle = 0;
     pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, 0 );
-    ( (Thread *)param )->thread();
-    ( (Thread *)param )->threadEnd();
+    if( istThreadOk( (Thread *)param ) )
+    {
+        ( (Thread *)param )->setSystemHandlePointer( &handle );
+        ( (Thread *)param )->thread();
+    }
+    if( istThreadOk( (Thread *)param ) )
+        ( (Thread *)param )->threadEnd();
+    thRegister->addClosedThread( handle );
     pthread_exit( 0 );
     return 0;
 }
 #endif
 
+// Konstruktor
+ThreadRegister::ThreadRegister()
+{
+    InitializeCriticalSection( &cs );
+}
+
+// Destruktor
+ThreadRegister::~ThreadRegister()
+{
+    DeleteCriticalSection( &cs );
+}
+
 // Inhalt der ThreadRegister Klasse aus Thread.h
 void ThreadRegister::add( Thread *t )
 {
+    EnterCriticalSection( &cs );
     threads.add( t );
+    LeaveCriticalSection( &cs );
 }
 
 void ThreadRegister::remove( Thread *t )
 {
+    EnterCriticalSection( &cs );
     threads.lösche( threads.getWertIndex( t ) );
+    LeaveCriticalSection( &cs );
+}
+
+bool ThreadRegister::isThread( Thread *t )
+{
+    EnterCriticalSection( &cs );
+    bool ret = threads.hat( threads.getWertIndex( t ) );
+    LeaveCriticalSection( &cs );
+    return ret;
+}
+
+void ThreadRegister::addClosedThread( pthread_t handle )
+{
+    EnterCriticalSection( &cs );
+    if( handle )
+        closedThreads.add( handle );
+    LeaveCriticalSection( &cs );
 }
 
-bool ThreadRegister::isThread( Thread *t ) const
+// Löscht die bereits beendetetn Threads und gibt ihre Reccourcen wieder frei
+void ThreadRegister::cleanUpClosedThreads()
 {
-    return threads.hat( threads.getWertIndex( t ) );
+    EnterCriticalSection( &cs );
+    while( closedThreads.getEintragAnzahl() > 0 )
+    {
+#ifndef WIN32
+        pthread_join( closedThreads.get( 0 ), 0 );
+#endif
+        closedThreads.lösche( 0 );
+    }
+    LeaveCriticalSection( &cs );
 }

+ 22 - 12
Thread.h

@@ -10,20 +10,18 @@ namespace Framework
     // Ein neuer Thread wie die Thread Klasse aus Java
     class Thread
     {
+    private:
+        pthread_t *threadHandleSys;
     protected:
-#ifdef WIN32
-        void *threadHandle;
         unsigned long threadId;
-#else
         pthread_t threadHandle;
-#endif
         bool run;
 
     public:
         // Konstruktor 
         __declspec( dllexport ) Thread();
         // Destruktor 
-        __declspec( dllexport ) ~Thread();
+        __declspec( dllexport ) virtual ~Thread();
         // Startet den neuen Thread 
         __declspec( dllexport ) void start();
 #ifdef WIN32
@@ -43,12 +41,13 @@ namespace Framework
         //         false, wenn der Thread beendet, pausiert oder noch nicht gestartet wurde.
         __declspec( dllexport ) bool läuft() const;
         // wartet zeit lang auf den Thread
-        // zeit: Die Zeit, die auf den Thread gewartet werden soll. 1000 = 1 Sekunde
-        __declspec( dllexport ) int warteAufThread( int zeit ) const;
-#ifdef WIN32
-        // Gibt ein Handle auf den Thread zurück (Nur für Windows)
-        __declspec( dllexport ) void *getThreadHandle() const;
-#endif
+        //  zeit: Die Zeit, die auf den Thread gewartet werden soll. 1000 = 1 Sekunde
+        __declspec( dllexport ) int warteAufThread( int zeit );
+        // Legt einen Frameworkpointer auf ein Threadhandle fest, der auf 0 gesetzt wird, falls die Ressourcen des Threads bereits follstänfig aufgeräumt wurden
+        //  ths: Ein Zeiger auf ein Threadhandle, das verändert werden soll
+        void setSystemHandlePointer( pthread_t *ths );
+        // Gibt ein Handle auf den Thread zurück
+        __declspec( dllexport ) pthread_t getThreadHandle() const;
     };
 
 #ifdef WIN32
@@ -64,8 +63,14 @@ namespace Framework
     {
     private:
         Array< Thread* > threads;
+        CRITICAL_SECTION cs;
+        Array< pthread_t > closedThreads;
 
     public:
+        // Konstruktor
+        ThreadRegister();
+        // Destruktor
+        ~ThreadRegister();
         // Fügt einen neuen Thread hinzu
         //  t: Der Thread, der hinzugefügt werden soll
         void add( Thread *t );
@@ -74,7 +79,12 @@ namespace Framework
         void remove( Thread *t );
         // Überprüft, ob ein Zeiger auf ein gültiges Thread Objekt zeigt, oder ob es schon gelöscht wurde
         //  t: Der Zeiger, der geprüft werden soll
-        bool isThread( Thread *t ) const;
+        bool isThread( Thread *t );
+        // Setzt Wird automatisch aufgerufen, wenn ein Thread beendet wird. Die Reccourcen werden daraufhin in cleanUpClosedThreads freigegeben.
+        //  handle: Das Handle des Threads
+        void addClosedThread( pthread_t handle );
+        // Löscht die bereits beendetetn Threads und gibt ihre Reccourcen wieder frei
+        __declspec( dllexport ) void cleanUpClosedThreads();
     };
 }
 

+ 161 - 27
Welt3D.cpp

@@ -1,6 +1,7 @@
 #include "Welt3D.h"
 #include "Zeichnung3D.h"
 #include "Render3D.h"
+#include "MausEreignis.h"
 
 using namespace Framework;
 
@@ -8,18 +9,22 @@ using namespace Framework;
 // Konstructor
 Welt3D::Welt3D()
 {
+    InitializeCriticalSection( &cs );
     arraySize = 100;
     arraySizeAlpha = 100;
     members = new Zeichnung3D*[ arraySize ];
     membersAlpha = new Zeichnung3D*[ arraySizeAlpha ];
-    used = new bool[ arraySizeAlpha ];
-    distSq = new float[ arraySizeAlpha ];
-    alphaVS = new Zeichnung3D*[ arraySizeAlpha ];
+    distSq = new float[ arraySizeAlpha + arraySize ];
+    distSqSort = new float[ arraySizeAlpha + arraySize ];
+    alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
+    elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
     for( int i = 0; i < arraySize; i++ )
         members[ i ] = 0;
     for( int i = 0; i < arraySizeAlpha; i++ )
         membersAlpha[ i ] = 0;
     ref = 1;
+    rend = 0;
+    upd = 1;
 }
 
 // Destruktor
@@ -27,15 +32,18 @@ Welt3D::~Welt3D()
 {
     delete[] members;
     delete[] membersAlpha;
-    delete[] used;
     delete[] distSq;
+    delete[] distSqSort;
     delete[] alphaVS;
+    delete[] elementsSort;
+    DeleteCriticalSection( &cs );
 }
 
 // Fügt der Welt ein Objekt hinzu
 //  obj: Das Objekt, was hinzugefügt werden soll
 void Welt3D::addZeichnung( Zeichnung3D *obj )
 {
+    EnterCriticalSection( &cs );
     Zeichnung3D **tmp = members;
     int max = arraySize;
     if( obj->hatAlpha() )
@@ -48,10 +56,12 @@ void Welt3D::addZeichnung( Zeichnung3D *obj )
         if( !*tmp )
         {
             *tmp = obj;
+            LeaveCriticalSection( &cs );
             return;
         }
         tmp++;
     }
+    rend = 1;
     if( obj->hatAlpha() )
     {
         arraySizeAlpha += 100;
@@ -61,12 +71,15 @@ void Welt3D::addZeichnung( Zeichnung3D *obj )
         delete[] membersAlpha;
         membersAlpha = nm;
         membersAlpha[ arraySizeAlpha - 100 ] = obj;
-        delete[] used;
         delete[] distSq;
+        delete[] distSqSort;
         delete[] alphaVS;
-        used = new bool[ arraySizeAlpha ];
-        distSq = new float[ arraySizeAlpha ];
-        alphaVS = new Zeichnung3D*[ arraySizeAlpha ];
+        delete[] elementsSort;
+        distSq = new float[ arraySizeAlpha + arraySize ];
+        distSqSort= new float[ arraySizeAlpha + arraySize ];
+        alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
+        elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
+        LeaveCriticalSection( &cs );
         return;
     }
     arraySize += 100;
@@ -76,12 +89,22 @@ void Welt3D::addZeichnung( Zeichnung3D *obj )
     delete[] members;
     members = nm;
     members[ arraySize - 100 ] = obj;
+    delete[] distSq;
+    delete[] distSqSort;
+    delete[] alphaVS;
+    delete[] elementsSort;
+    distSq = new float[ arraySizeAlpha + arraySize ];
+    distSqSort = new float[ arraySizeAlpha + arraySize ];
+    alphaVS = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
+    elementsSort = new Zeichnung3D*[ arraySizeAlpha + arraySize ];
+    LeaveCriticalSection( &cs );
 }
 
 // Entfernt ein Objekt aus der Welt
 //  obj: Das Objekt, das entwernt werden soll
 void Welt3D::removeZeichnung( Zeichnung3D *obj )
 {
+    EnterCriticalSection( &cs );
     int index = 0;
     if( !obj->hatAlpha() )
     {
@@ -90,9 +113,12 @@ void Welt3D::removeZeichnung( Zeichnung3D *obj )
             if( *i == obj )
             {
                 *i = 0;
+                rend = 1;
+                LeaveCriticalSection( &cs );
                 return;
             }
         }
+        LeaveCriticalSection( &cs );
         return;
     }
     for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
@@ -100,17 +126,79 @@ void Welt3D::removeZeichnung( Zeichnung3D *obj )
         if( *i == obj )
         {
             *i = 0;
+            rend = 1;
+            LeaveCriticalSection( &cs );
             return;
         }
     }
+    LeaveCriticalSection( &cs );
+}
+
+// Verarbeitet ein Mausereignis
+//  me: Das Mausereignis, das verarbeitet werden soll
+void Welt3D::doMausEreignis( MausEreignis3D &me )
+{
+    //EnterCriticalSection( &cs );
+    //int anz = 0;
+    //int index = 0;
+    //for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
+    //{
+    //    if( *i )
+    //    {
+    //        distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() );
+    //        alphaVS[ anz ] = *i;
+    //        anz++;
+    //    }
+    //}
+    //index = 0;
+    //for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
+    //{
+    //    if( *i )
+    //    {
+    //        distSq[ anz ] = me.pos.abstandSq( ( *i )->getPos() );
+    //        alphaVS[ anz ] = *i;
+    //        anz++;
+    //    }
+    //}
+    //float maxEntf;
+    //int ind;
+    //do
+    //{
+    //    maxEntf = -1;
+    //    ind = -1;
+    //    for( int i = 0; i < anz; i++ )
+    //    {
+    //        if( !used[ i ] && distSq[ i ] > maxEntf )
+    //        {
+    //            maxEntf = distSq[ i ];
+    //            ind = i;
+    //        }
+    //    }
+    //    if( ind >= 0 )
+    //    {
+    //        alphaVS[ ind ]->doMausEreignis( me );
+    //        if( me.verarbeitet )
+    //        {
+    //            LeaveCriticalSection( &cs );
+    //            return;
+    //        }
+    //        used[ ind ] = 1;
+    //    }
+    //} while( ind >= 0 );
+    //LeaveCriticalSection( &cs );
 }
+
 // Verarbeitet die vergangene Zeit
 //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
 //  return: true, wenn sich das Objekt verändert hat, false sonnst.
 bool Welt3D::tick( double tickval )
 {
+    if( !upd )
+        return rend;
+    rend = 0;
+    upd = 0;
     int index = 0;
-    bool ret = 0;
+    EnterCriticalSection( &cs );
     for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
     {
         if( *i && ( *i )->hatAlpha() )
@@ -119,12 +207,12 @@ bool Welt3D::tick( double tickval )
             *i = 0;
             continue;
         }
-        ret |= *i ? ( *i )->tick( tickval ) : 0;
+        rend |= *i ? ( *i )->tick( tickval ) : 0;
     }
     index = 0;
     for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
     {
-        ret |= *i ? ( *i )->tick( tickval ) : 0;
+        rend |= *i ? ( *i )->tick( tickval ) : 0;
         if( *i && !( *i )->hatAlpha() )
         {
             addZeichnung( *i );
@@ -132,21 +220,22 @@ bool Welt3D::tick( double tickval )
             continue;
         }
     }
-    return ret;
+    LeaveCriticalSection( &cs );
+    return rend;
 }
 
 // Zeichnet einen ausschnitt der Welt
 //  zRObj: Enthällt alle Werkzeuge, die zum Zeichnen verwendet werden
 void Welt3D::render( Render3D *zRObj )
 {
+    upd = 1;
     int index = 0;
+    EnterCriticalSection( &cs );
     for( Zeichnung3D **i = members; index < arraySize; i++, index++ )
     {
         if( *i && zRObj->isInFrustrum( ( *i )->getPos(), ( *i )->getRadius() ) )
             ( *i )->render( zRObj );
     }
-    memset( used, 0, arraySizeAlpha * sizeof( bool ) );
-    memset( alphaVS, 0, arraySizeAlpha * sizeof( Zeichnung3D * ) );
     index = 0;
     int index2 = 0;
     for( Zeichnung3D **i = membersAlpha; index < arraySizeAlpha; i++, index++ )
@@ -154,29 +243,74 @@ void Welt3D::render( Render3D *zRObj )
         if( *i && zRObj->isInFrustrum( ( *i )->getPos(), ( *i )->getRadius(), &distSq[ index2 ] ) )
         {
             alphaVS[ index2 ] = *i;
+            elementsSort[ index2 ] = *i;
+            distSqSort[ index2 ] = distSq[ index2 ];
             index2++;
         }
     }
-    float maxEntf;
-    int ind;
-    do
+    int K;
+    int L = 1;
+    while( L < index2 )
     {
-        maxEntf = -1;
-        ind = -1;
-        for( int i = 0; i < index2; i++ )
+        K = 0;
+        while( K + 2 * L - 1 < index2 )
         {
-            if( !used[ i ] && distSq[ i ] > maxEntf )
+            //merge
+            int I = K;
+            int J = K + L;
+            int N = K;
+            while( I < K + L || J < K + 2 * L )
             {
-                maxEntf = distSq[ i ];
-                ind = i;
+                if( J == K + 2 * L || ( I < K + L && distSq[ I ] < distSq[ J ] ) )
+                {
+                    distSqSort[ N ] = distSq[ I ];
+                    elementsSort[ N ] = alphaVS[ I ];
+                    I++;
+                }
+                else
+                {
+                    distSqSort[ N ] = distSq[ J ];
+                    elementsSort[ N ] = alphaVS[ J ];
+                    J++;
+                }
+                N++;
             }
+            K += 2 * L;
         }
-        if( ind >= 0 )
+        if( K + L - 1 < index2 - 1 )
         {
-            alphaVS[ ind ]->render( zRObj );
-            used[ ind ] = 1;
+            //merge
+            int I = K;
+            int J = K + L;
+            int N = K;
+            while( I < K + L || J < index2 - 1 )
+            {
+                if( J == index2 || ( I < K + L && distSq[ I ] < distSq[ J ] ) )
+                {
+                    distSqSort[ N ] = distSqSort[ I ];
+                    elementsSort[ N ] = alphaVS[ I ];
+                    I++;
+                }
+                else
+                {
+                    distSqSort[ N ] = distSq[ J ];
+                    elementsSort[ N ] = alphaVS[ J ];
+                    J++;
+                }
+                N++;
+            }
         }
-    } while( ind >= 0 );
+        float *tmpF = distSq;
+        distSq = distSqSort;
+        distSqSort = tmpF;
+        Zeichnung3D **tmpZ = alphaVS;
+        alphaVS = elementsSort;
+        elementsSort = tmpZ;
+        L *= 2;
+    }
+    for( int i = index2 - 1; i >= 0; i-- )
+        alphaVS[ i ]->render( zRObj );
+    LeaveCriticalSection( &cs );
 }
 
 // Erhöht den Reference Counting Zähler.

+ 9 - 1
Welt3D.h

@@ -7,6 +7,7 @@ namespace Framework
     class Zeichnung3DArray; // Zeichnung3D.h
     class Zeichnung3D; // Zeichnung.h
     class Render3D; // Render3D.h
+    struct MausEreignis3D; // MausEreignis.h
 
     // Speichert alle 3D Zeichnungen einer Szene ab
     class Welt3D
@@ -14,11 +15,15 @@ namespace Framework
     private:
         Zeichnung3D **members;
         Zeichnung3D **membersAlpha;
-        bool *used;
         float *distSq;
+        float *distSqSort;
         Zeichnung3D **alphaVS;
+        Zeichnung3D **elementsSort;
         int arraySize;
         int arraySizeAlpha;
+        bool rend;
+        bool upd;
+        CRITICAL_SECTION cs;
         int ref;
 
     public:
@@ -32,6 +37,9 @@ namespace Framework
         // Entfernt ein Objekt aus der Welt
         //  obj: Das Objekt, das entwernt werden soll
         __declspec( dllexport ) void removeZeichnung( Zeichnung3D *obj );
+        // Verarbeitet ein Mausereignis
+        //  me: Das Mausereignis, das verarbeitet werden soll
+        __declspec( dllexport ) void doMausEreignis( MausEreignis3D &me );
         // Verarbeitet die vergangene Zeit
         //  tickval: Die zeit in sekunden, die seit dem letzten Aufruf der Funktion vergangen ist
         //  return: true, wenn sich das Objekt verändert hat, false sonnst.

+ 1 - 1
Zeichnung3D.cpp

@@ -122,7 +122,7 @@ int Zeichnung3D::errechneMatrizen( Mat4< float > &viewProj, Mat4< float > *matBu
 
 // Verarbeitet ein Mausereignis
 //  me: Das Mausereignis, das verarbeitet werden soll
-void Zeichnung3D::doMausEreignis( MausEreignis &me )
+void Zeichnung3D::doMausEreignis( MausEreignis3D &me )
 {}
 
 // Verarbeitet ein Tastaturereignis

+ 2 - 2
Zeichnung3D.h

@@ -4,7 +4,7 @@
 
 namespace Framework
 {
-    struct MausEreignis;
+    struct MausEreignis3D;
     struct TastaturEreignis;
     class Render3D; // Render3D.h
 
@@ -66,7 +66,7 @@ namespace Framework
         __declspec( dllexport ) virtual int errechneMatrizen( Mat4< float > &viewProj, Mat4< float > *matBuffer );
         // Verarbeitet ein Mausereignis
         //  me: Das Mausereignis, das verarbeitet werden soll
-        __declspec( dllexport ) virtual void doMausEreignis( MausEreignis &me );
+        __declspec( dllexport ) virtual void doMausEreignis( MausEreignis3D &me );
         // Verarbeitet ein Tastaturereignis
         //  te: das Tastaturereignis, das verarbeitet werden soll
         __declspec( dllexport ) virtual void doTastaturEreignis( TastaturEreignis &te );