Sfoglia il codice sorgente

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

Kolja Strohm 10 anni fa
parent
commit
0e8d05d6aa
16 ha cambiato i file con 501 aggiunte e 84 eliminazioni
  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 );