#include <main.h>
#include <Fenster.h>
#include <Bildschirm.h>
#include <RenderThread.h>
#include <Welt3D.h>
#include <Cube.h>
#include <Kam3D.h>
#include <Bild.h>
#include <Rahmen.h>
#include <Textur.h>
#include <Model3D.h>
#include <Model3DList.h>
#include <DXBuffer.h>
#include <DateiSystem.h>
#include <M3Datei.h>

using namespace Framework;

class TreppeOben : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    TreppeOben()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 48 + 11 * 24 ];
        for( int i = 0; i < 48 + 11 * 24; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        makeQuader( vertecies, 24, Vec3< float >( -5, -stdSize / 2, -5 ), Vec3< float >( 10, stdSize + 20, 10 ) );
        float last = -5;
        for( int i = 0; i < 11; i++ )
        {
            float fullRad = PI;
            float curr = ( fullRad / 10 ) * i;
            Mat4< float > rotation = Mat4< float >::rotationY( curr );
            Mat4< float > rotation2 = Mat4< float >::rotationY( fullRad / 10 );
            Vec3< float > test( stdSize / 2, -stdSize / 2 + i * 10 + 10, 0 );
            Vec3< float > diff = rotation2 * test;
            float length = diff.z;
            Vec3< float > rtf( stdSize / 2, -stdSize / 2 + i * 10 + 20, -diff.z / 2 );
            Vec3< float > rtb( stdSize / 2, -stdSize / 2 + i * 10 + 20, diff.z / 2 );
            Vec3< float > rbf( stdSize / 2, -stdSize / 2 + i * 10 + 10, -diff.z / 2 );
            Vec3< float > rbb( stdSize / 2, -stdSize / 2 + i * 10 + 10, diff.z / 2 );
            Vec3< float > ltf( 0, -stdSize / 2 + i * 10 + 20, 5 );
            Vec3< float > ltb( 0, -stdSize / 2 + i * 10 + 20, -5 );
            Vec3< float > lbf( 0, -stdSize / 2 + i * 10 + 10, 5 );
            Vec3< float > lbb( 0, -stdSize / 2 + i * 10 + 10, -5 );
            rtf = rotation * rtf;
            rtb = rotation * rtb;
            rbf = rotation * rbf;
            rbb = rotation * rbb;
            ltf = rotation * ltf;
            ltb = rotation * ltb;
            lbf = rotation * lbf;
            lbb = rotation * lbb;
            makeQuader( vertecies, 48 + i * 24, ltf, rtf, lbf, rbf, ltb, rtb, lbb, rbb );
        }
        model->setVertecies( vertecies, 48 + 11 * 24 );

        M3Datei dat;
        dat.setPfad( "3d.m3" );
        dat.leseDaten();
        dat.saveModel( model, "treppe" );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class TreppeUnten : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    TreppeUnten()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 48 + 11 * 24 ];
        for( int i = 0; i < 48 + 11 * 24; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, stdSize / 2 + 10, 0 ), Vec3< float >( stdSize, 10, stdSize / 2 ) );
        makeQuader( vertecies, 24, Vec3< float >( -5, -stdSize / 2, -5 ), Vec3< float >( 10, stdSize + 20, 10 ) );
        float last = -5;
        for( int i = 0; i < 11; i++ )
        {
            float fullRad = PI;
            float curr = ( fullRad / 10 ) * i;
            Mat4< float > rotation = Mat4< float >::rotationY( curr );
            Mat4< float > rotation2 = Mat4< float >::rotationY( fullRad / 10 );
            Vec3< float > test( stdSize / 2, -stdSize / 2 + i * 10 + 10, 0 );
            Vec3< float > diff = rotation2 * test;
            float length = diff.z;
            Vec3< float > rtf( stdSize / 2, -stdSize / 2 + i * 10 + 20, -diff.z / 2 );
            Vec3< float > rtb( stdSize / 2, -stdSize / 2 + i * 10 + 20, diff.z / 2 );
            Vec3< float > rbf( stdSize / 2, -stdSize / 2 + i * 10 + 10, -diff.z / 2 );
            Vec3< float > rbb( stdSize / 2, -stdSize / 2 + i * 10 + 10, diff.z / 2 );
            Vec3< float > ltf( 0, -stdSize / 2 + i * 10 + 20, 5 );
            Vec3< float > ltb( 0, -stdSize / 2 + i * 10 + 20, -5 );
            Vec3< float > lbf( 0, -stdSize / 2 + i * 10 + 10, 5 );
            Vec3< float > lbb( 0, -stdSize / 2 + i * 10 + 10, -5 );
            rtf = rotation * rtf;
            rtb = rotation * rtb;
            rbf = rotation * rbf;
            rbb = rotation * rbb;
            ltf = rotation * ltf;
            ltb = rotation * ltb;
            lbf = rotation * lbf;
            lbb = rotation * lbb;
            makeQuader( vertecies, 48 + i * 24, ltf, rtf, lbf, rbf, ltb, rtb, lbb, rbb );
        }
        model->setVertecies( vertecies, 48 + 11 * 24 );

        M3Datei dat;
        dat.setPfad( "3d.m3" );
        dat.leseDaten();
        dat.saveModel( model, "treppe" );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class Mauer : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    Mauer()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 48 ];
        for( int i = 0; i < 48; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        makeQuader( vertecies, 24, Vec3< float >( -stdSize / 2, -stdSize / 2, -5 ), Vec3< float >( stdSize, stdSize + 10, 10 ) );
        model->setVertecies( vertecies, 48 );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class MauerEcke : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    MauerEcke()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 72 ];
        for( int i = 0; i < 72; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        makeQuader( vertecies, 24, Vec3< float >( 0, -stdSize / 2, -5 ), Vec3< float >( stdSize / 2, stdSize + 10, 10 ) );
        makeQuader( vertecies, 48, Vec3< float >( -5, -stdSize / 2, 0 ), Vec3< float >( 10, stdSize + 10, stdSize / 2 ) );
        model->setVertecies( vertecies, 72 );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class MauerKreuz : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    MauerKreuz()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 72 ];
        for( int i = 0; i < 72; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        makeQuader( vertecies, 24, Vec3< float >( -stdSize / 2, -stdSize / 2, -5 ), Vec3< float >( stdSize, stdSize + 10, 10 ) );
        makeQuader( vertecies, 48, Vec3< float >( -5, -stdSize / 2, -stdSize / 2 ), Vec3< float >( 10, stdSize + 10, stdSize ) );
        model->setVertecies( vertecies, 72 );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class Boden : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    Boden()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 24 ];
        for( int i = 0; i < 24; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        model->setVertecies( vertecies, 24 );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

class Held : public Model3D
{
    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > ltf, Vec3< float > rtf, Vec3< float > lbf, Vec3< float > rbf, Vec3< float > ltb, Vec3< float > rtb, Vec3< float > lbb, Vec3< float > rbb )
    {
        vertecies[ startIndex ].pos = ltf;
        vertecies[ startIndex ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 1 ].pos = rtf;
        vertecies[ startIndex + 1 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 2 ].pos = lbf;
        vertecies[ startIndex + 2 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 3 ].pos = rbf;
        vertecies[ startIndex + 3 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 4 ].pos = ltb;
        vertecies[ startIndex + 4 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 5 ].pos = rtb;
        vertecies[ startIndex + 5 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 6 ].pos = lbb;
        vertecies[ startIndex + 6 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 7 ].pos = rbb;
        vertecies[ startIndex + 7 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 8 ].pos = ltf;
        vertecies[ startIndex + 8 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 9 ].pos = rtf;
        vertecies[ startIndex + 9 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 10 ].pos = lbf;
        vertecies[ startIndex + 10 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 11 ].pos = rbf;
        vertecies[ startIndex + 11 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 12 ].pos = ltb;
        vertecies[ startIndex + 12 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 13 ].pos = rtb;
        vertecies[ startIndex + 13 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 14 ].pos = lbb;
        vertecies[ startIndex + 14 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 15 ].pos = rbb;
        vertecies[ startIndex + 15 ].tPos = Vec2< float >( 1.0f, 1.0f );

        vertecies[ startIndex + 16 ].pos = ltf;
        vertecies[ startIndex + 16 ].tPos = Vec2< float >( 0.f, 1.f );
        vertecies[ startIndex + 17 ].pos = rtf;
        vertecies[ startIndex + 17 ].tPos = Vec2< float >( 1.f, 1.f );
        vertecies[ startIndex + 18 ].pos = lbf;
        vertecies[ startIndex + 18 ].tPos = Vec2< float >( 0.f, 0.f );
        vertecies[ startIndex + 19 ].pos = rbf;
        vertecies[ startIndex + 19 ].tPos = Vec2< float >( 1.f, 0.f );
        vertecies[ startIndex + 20 ].pos = ltb;
        vertecies[ startIndex + 20 ].tPos = Vec2< float >( 0.0f, 0.0f );
        vertecies[ startIndex + 21 ].pos = rtb;
        vertecies[ startIndex + 21 ].tPos = Vec2< float >( 1.0f, 0.0f );
        vertecies[ startIndex + 22 ].pos = lbb;
        vertecies[ startIndex + 22 ].tPos = Vec2< float >( 0.0f, 1.0f );
        vertecies[ startIndex + 23 ].pos = rbb;
        vertecies[ startIndex + 23 ].tPos = Vec2< float >( 1.0f, 1.0f );

        // front side
        Polygon3D* p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0;
        p->indexList[ 1 ] = startIndex + 2;
        p->indexList[ 2 ] = startIndex + 3;
        p->indexList[ 3 ] = startIndex + 0;
        p->indexList[ 4 ] = startIndex + 3;
        p->indexList[ 5 ] = startIndex + 1;
        model->addPolygon( p );
        // back side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4;
        p->indexList[ 1 ] = startIndex + 7;
        p->indexList[ 2 ] = startIndex + 6;
        p->indexList[ 3 ] = startIndex + 4;
        p->indexList[ 4 ] = startIndex + 5;
        p->indexList[ 5 ] = startIndex + 7;
        model->addPolygon( p );
        // right side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 1 + 8;
        p->indexList[ 1 ] = startIndex + 3 + 8;
        p->indexList[ 2 ] = startIndex + 7 + 8;
        p->indexList[ 3 ] = startIndex + 1 + 8;
        p->indexList[ 4 ] = startIndex + 7 + 8;
        p->indexList[ 5 ] = startIndex + 5 + 8;
        model->addPolygon( p );
        // left side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 0 + 8;
        p->indexList[ 1 ] = startIndex + 6 + 8;
        p->indexList[ 2 ] = startIndex + 2 + 8;
        p->indexList[ 3 ] = startIndex + 0 + 8;
        p->indexList[ 4 ] = startIndex + 4 + 8;
        p->indexList[ 5 ] = startIndex + 6 + 8;
        model->addPolygon( p );
        // top side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 4 + 16;
        p->indexList[ 1 ] = startIndex + 0 + 16;
        p->indexList[ 2 ] = startIndex + 1 + 16;
        p->indexList[ 3 ] = startIndex + 4 + 16;
        p->indexList[ 4 ] = startIndex + 1 + 16;
        p->indexList[ 5 ] = startIndex + 5 + 16;
        model->addPolygon( p );
        // down side
        p = new Polygon3D();
        p->indexAnz = 6;
        p->indexList = new int[ p->indexAnz ];
        p->indexBuffer->setLength( p->indexAnz * 4 );
        p->indexBuffer->setData( p->indexList );
        p->indexList[ 0 ] = startIndex + 6 + 16;
        p->indexList[ 1 ] = startIndex + 3 + 16;
        p->indexList[ 2 ] = startIndex + 2 + 16;
        p->indexList[ 3 ] = startIndex + 6 + 16;
        p->indexList[ 4 ] = startIndex + 7 + 16;
        p->indexList[ 5 ] = startIndex + 3 + 16;
        model->addPolygon( p );
    }

    void makeQuader( Vertex3D* vertecies, int startIndex, Vec3< float > pos, Vec3< float > size )
    {
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = pos.x;
        // Calculate the screen coordinates of the right side of the bitmap.
        right = pos.x + size.x;
        // Calculate the screen coordinates of the top of the bitmap.
        top = pos.y + size.y;
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = pos.y;
        float front = pos.z + size.z;
        float back = pos.z;

        makeQuader( vertecies, startIndex, Vec3< float >( left, top, front ), Vec3< float >( right, top, front ), Vec3< float >( left, bottom, front ), Vec3< float >( right, bottom, front ),
                    Vec3< float >( left, top, back ), Vec3< float >( right, top, back ), Vec3< float >( left, bottom, back ), Vec3< float >( right, bottom, back ) );
    }
public:
    // Konstruktor
    //  size: Die Größe des Würfels
    Held()
    {
        model = new Model3DData();
        float stdSize = 100;
        float left, right, top, bottom;
        // Calculate the screen coordinates of the left side of the bitmap.
        left = (float)( ( stdSize / 2.0 ) * -1 );
        // Calculate the screen coordinates of the right side of the bitmap.
        right = left + (float)stdSize;
        // Calculate the screen coordinates of the top of the bitmap.
        top = (float)( stdSize / 2.0 );
        // Calculate the screen coordinates of the bottom of the bitmap.
        bottom = top - (float)stdSize;
        float front = -stdSize / 2;
        float back = front + stdSize;

        Vertex3D * vertecies = new Vertex3D[ 24 ];
        for( int i = 0; i < 24; i++ )
            vertecies[ i ].knochenId = 0;
        makeQuader( vertecies, 0, Vec3< float >( -stdSize / 2, -stdSize / 2, -stdSize / 2 ), Vec3< float >( stdSize, 10, stdSize ) );
        model->setVertecies( vertecies, 24 );

        textur = new Model3DTextur();
    }
    // Setzt die Textur des Würfels, so dass sie an allen Seiten gleich ist
    //  textur: Die Textur als Bild
    void setTextur( Bild * textur )
    {
        Textur* t = new Textur();
        t->setBildZ( textur );
        int anz = model->getPolygonAnzahl();
        for( int i = 0; i < anz; i++ )
            this->textur->setPolygonTextur( i, t->getThis() );
        t->release();
        rend = 1;
    }
};

// Aktion beim schließen des Fensters
void schließen( void* p, void* f )
{
    // Stoppe Nachrichten Loop
    StopNachrichtenSchleife( ( (WFenster*)f )->getFensterHandle() );
}

int __stdcall Framework::Start( Startparam p )
{
    // Fenster erstellen
    WNDCLASS wc = F_Normal( p.hinst );
    wc.lpszClassName = "3D Creator";

    WFenster* f = new WFenster();
    f->erstellen( WS_OVERLAPPEDWINDOW, wc );
    f->setVSchließAktion( schließen );
    f->setAnzeigeModus( SW_SHOWNORMAL );
    f->setSize( 1300, 820 );
    f->setPosition( Punkt( 100, 100 ) );

    // 3D Umgebung erstellen
    Bildschirm3D* b = new Bildschirm3D( f->getThis() );
    f->setBildschirm( b->getThis() );
    b->setFillFarbe( 0 );
    b->setTestRend( 0 );

    Welt3D* welt = new Welt3D();
    TreppeUnten* test = new TreppeUnten();

    LTDBDatei* assets = new LTDBDatei();
    assets->setDatei( new Text( "assets.ltdb" ) );
    assets->leseDaten( 0 );
    Bild* b1 = assets->laden( 0, new Text( "ground.png" ) );
    assets->release();
    test->setTextur( b1->getThis() );
    test->setPosition( 0, 0, 0 );
    welt->addZeichnung( test );
    TreppeOben* test2 = new TreppeOben();
    test2->setTextur( b1->getThis() );
    test2->setPosition( 150, 0, 0 );
    welt->addZeichnung( test2 );
    Mauer* test3 = new Mauer();
    test3->setTextur( b1->getThis() );
    test3->setPosition( 150, 0, 150 );
    welt->addZeichnung( test3 );
    MauerEcke* test4 = new MauerEcke();
    test4->setTextur( b1->getThis() );
    test4->setPosition( -150, 0, 0 );
    welt->addZeichnung( test4 );
    MauerKreuz* test5 = new MauerKreuz();
    test5->setTextur( b1->getThis() );
    test5->setPosition( 0, 0, 150 );
    welt->addZeichnung( test5 );
    Boden* test6 = new Boden();
    test6->setTextur( b1->getThis() );
    test6->setPosition( -150, 0, 150 );
    welt->addZeichnung( test6 );

    b1->release();

    Kam3D* kamA = new Kam3D();
    kamA->setBildschirmPosition( 10, 10 );
    kamA->setBildschirmSize( 385, 385 );
    kamA->setPosition( Vec3<float>( -1000, 0, 0 ) );
    kamA->setAusrichtung( Vec3<float>( 0, 0, 0 ) );
    kamA->setWelt( welt->getThis() );
    b->addKamera( kamA );

    Kam3D* kamB = new Kam3D();
    kamB->setBildschirmPosition( 10, 405 );
    kamB->setBildschirmSize( 385, 385 );
    kamB->setPosition( Vec3<float>( 0, -1000, 0 ) );
    kamB->setAusrichtung( Vec3<float>( 0, 0, 0 ) );
    kamB->setWelt( welt->getThis() );
    b->addKamera( kamB );

    Kam3D* kamC = new Kam3D();
    kamC->setBildschirmPosition( 405, 10 );
    kamC->setBildschirmSize( 385, 385 );
    kamC->setPosition( Vec3<float>( 0, 0, -1000 ) );
    kamC->setAusrichtung( Vec3<float>( 0, 0, 0 ) );
    kamC->setWelt( welt->getThis() );
    b->addKamera( kamC );

    Kam3D * kamD = new Kam3D();
    kamD->setStyle( Kam3D::Style::Movable | Kam3D::Style::Rotatable | Kam3D::Style::Tick );
    kamD->setBildschirmPosition( 405, 405 );
    kamD->setBildschirmSize( 385, 385 );
    kamD->setPosition( Vec3<float>( 0, 0, -1000 ) );
    kamD->setAusrichtung( Vec3<float>( 0, 0, 0 ) );
    kamD->setWelt( welt->getThis() );
    b->addKamera( kamD );

    LRahmen * kamAR = new LRahmen();
    kamAR->setPosition( 10, 10 );
    kamAR->setFarbe( 0xFFFFFFFF );
    kamAR->setRamenBreite( 1 );
    kamAR->setSize( 385, 385 );
    b->addMember( kamAR );
    LRahmen * kamBR = new LRahmen();
    kamBR->setPosition( 404, 10 );
    kamBR->setFarbe( 0xFFFFFFFF );
    kamBR->setRamenBreite( 1 );
    kamBR->setSize( 385, 385 );
    b->addMember( kamBR );
    LRahmen * kamCR = new LRahmen();
    kamCR->setPosition( 10, 405 );
    kamCR->setFarbe( 0xFFFFFFFF );
    kamCR->setRamenBreite( 1 );
    kamCR->setSize( 385, 385 );
    b->addMember( kamCR );
    LRahmen * kamDR = new LRahmen();
    kamDR->setPosition( 405, 405 );
    kamDR->setFarbe( 0xFFFFFFFF );
    kamDR->setRamenBreite( 1 );
    kamDR->setSize( 385, 385 );
    b->addMember( kamDR );

    // Render Loop starten
    RenderTh * r = new RenderTh();
    r->setBildschirm( b->getThis() );
    r->setTickFunktion( [ test, b, kamD ]( void*, void*, double t )
    {
        //test->setDrehung( test->getDrehung() + Vec3<double>( t, t, t ) );
        if( Framework::getTastenStand( T_Enter ) )
        {
            kamD->setAusrichtung( Vec3<float>( 0, 0, 0 ) );
        }
    } );
    r->beginn();

    // Nachrichten Loop starten und warten
    StartNachrichtenSchleife();

    // Speicher Freigeben
    r->beenden();
    r->release();
    b->release();
    f->setBildschirm( 0 );
    f->zerstören();
    f->release();
    welt->release();

    return 0;
}