Ищем примеры кода для тесселяции Direct3D - PullRequest
0 голосов
/ 21 июля 2010

Я пытаюсь узнать, как использовать функцию Direct3D D3DXTessellateRectPatch: msdn.microsoft.com/en-us/library/bb205471(v=VS.85).aspx

Я нашел документацию MSDN весьма полезной и смог реализовать тесселяцию одиночный прямоугольный патч.

Сейчас я пытаюсь создать мозаику из сетки, состоящей из тридцати двух бикубических трехмерных патчей Безье (чайник Юты).

Я попробовал простой подход - тесселяция каждой кривой Безье по отдельности, затем объединение вершин и соответствующие индексы с учетом смещения вершин для создания мозаичной объединенной сетки.

Однако, похоже, это не дает желаемого результата.

Если у кого-то есть подсказки по этой проблеме или, что еще лучше, примеры кода, мы будем очень благодарны.

В частности, я проверил: Www.directxtutorial.com http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160/

И еще одна ссылка на Direct3D, а также Google.

Спасибо и с нетерпением ждем ваших советов / указателей.

Yours Миша

1 Ответ

0 голосов
/ 22 июля 2010

Тим С Шредер очень помог мне и предложил использовать ID3DXPatchMesh. Вот пример кода, который генерирует тесселированный чайник (место в файле tester.cpp):

// Main D3DX framework from www.directxtutorial.com (free section) 
#include <assert.h>
#include <stdio.h>

// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>

// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

// global declarations
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPD3DXMESH mesh = NULL;    // define the mesh pointer

// function prototypes
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void init_graphics(void);

struct vertex_data 
{
    D3DXVECTOR3 position;
    DWORD color;
};
#define FVF_VERTEX_DATA (D3DFVF_XYZ | D3DFVF_DIFFUSE)

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "WindowClass";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL, "WindowClass", "Our Direct3D Program",
                          WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                          NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);

    initD3D(hWnd);

    MSG msg;

    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if(msg.message == WM_QUIT)
            break;

        render_frame();
    }

    cleanD3D();

    return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = SCREEN_WIDTH;
    d3dpp.BackBufferHeight = SCREEN_HEIGHT;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);

    init_graphics();

    d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);    // turn off the 3D lighting
    d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);    // turn off culling
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
}

// this is the function used to render a single frame
void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    d3ddev->BeginScene();

    d3ddev->SetFVF(FVF_VERTEX_DATA);

    // set the view transform
    D3DXMATRIX matView;    // the view transform matrix
    D3DXMatrixLookAtLH(&matView,
    &D3DXVECTOR3 (0.0f, 8.0f, 25.0f),    // the camera position
    &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),      // the look-at position
    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView

    // set the projection transform
    D3DXMATRIX matProjection;    // the projection transform matrix
    D3DXMatrixPerspectiveFovLH(&matProjection,
                               D3DXToRadian(45),    // the horizontal field of view
                               (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
                               1.0f,   // the near view-plane
                               100.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection

    // set the world transform
    static float index = 0.0f; index+=0.03f; // an ever-increasing float value
    D3DXMATRIX matRotateY;    // a matrix to store the rotation for each triangle
    D3DXMatrixRotationY(&matRotateY, index);    // the rotation matrix
    d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));    // set the world transform

    if (mesh) mesh->DrawSubset(0);     

    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL);
}

// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
    if (mesh) mesh->Release();
    d3ddev->Release();
    d3d->Release();
}

#define MAX_PATCHES 1000
#define POINTS_PER_PATCH 16
int num_patches = -1;
int patches[MAX_PATCHES][POINTS_PER_PATCH];

void B_patch(int ii, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p)
{
    assert(ii < MAX_PATCHES);
    patches[ii][0] = a-1;
    patches[ii][1] = b-1;
    patches[ii][2] = c-1;
    patches[ii][3] = d-1;
    patches[ii][4] = e-1;
    patches[ii][5] = f-1;
    patches[ii][6] = g-1;
    patches[ii][7] = h-1;
    patches[ii][8] = i-1;
    patches[ii][9] = j-1;
    patches[ii][10] = k-1;
    patches[ii][11] = l-1;
    patches[ii][12] = m-1;
    patches[ii][13] = n-1;
    patches[ii][14] = o-1;
    patches[ii][15] = p-1;
    assert(POINTS_PER_PATCH==16);
}

#define MAX_POINTS 1000
int num_points = -1;
D3DXVECTOR3 points[MAX_POINTS];

void B_point(int ii, double x, double y, double z)
{
    ii--;
    assert(ii < MAX_POINTS);
    points[ii].x = x;
    /*** Y AND Z FLIPPED ***/
    points[ii].y = z;
    points[ii].z = y;
}

// BEGIN http://www.sjbaker.org/teapot/teaset.tgz

/*
 *  The file input.c  -- Juhana Kouhia, jk87377@cs.tut.fi, Oct. 25, 1991
 *
 *  Load_patch(filename, patches, vertices);
 *    char *filename; int *patches, *vertices;  
 *    A sample program to read Bezier patches in.
 *    Returns count of patches and vertices.
 *  User defined subroutines:
 *    B_patch(ii, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
 *      int ii, a, b, ..., p;
 *      Defines one Bezier patch with index number ii,
 *      indexes to points are in a, b, c, ..., p.
 *    B_point(ii, x, y, z);
 *      int ii; double x, y, z;
 *      Defines one point with index number ii.
 */

#include <stdio.h>

// Modified to work with g++
void Load_patch(char *filename, int *patches, int *vertices)
{
  int ii;
  float x,y,z;
  int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;

  FILE *fp;

  if (!(fp = fopen(filename,"r"))) {
    fprintf(stderr,"Load_patch: Can't open %s\n",filename);
    exit(1);
  }

  (void)fscanf(fp,"%i\n",patches);
  for (ii = 0; ii < *patches; ii++) {
    (void)fscanf(fp,"%i, %i, %i, %i,",&a,&b,&c,&d);
    (void)fscanf(fp,"%i, %i, %i, %i,",&e,&f,&g,&h);
    (void)fscanf(fp,"%i, %i, %i, %i,",&i,&j,&k,&l);
    (void)fscanf(fp,"%i, %i, %i, %i\n",&m,&n,&o,&p);
    B_patch(ii, a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
  }
  (void)fscanf(fp,"%i\n",vertices);
  for (ii = 1; ii <= *vertices; ii++) {
    (void)fscanf(fp,"%f, %f, %f\n",&x,&y,&z);
    B_point(ii, (double)x,(double)y,(double)z);
  }
}

// END http://www.sjbaker.org/teapot/teaset.tgz

// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
    // load patch
    char filename[255];
    sprintf(filename,"teapot");
    Load_patch(filename,&num_patches,&num_points);
    printf("Loaded patch %s with %d patches and %d vertices.\n",
           filename,num_patches,num_points);

    // create declarator from FVF
    D3DVERTEXELEMENT9 inDecl[MAX_FVF_DECL_SIZE];
    if (!SUCCEEDED(D3DXDeclaratorFromFVF(FVF_VERTEX_DATA,inDecl)))
        assert(FALSE);    

    // create patch mesh
    LPD3DXPATCHMESH p_mesh;
    D3DXPATCHINFO info;
    info.PatchType = D3DXPATCHMESH_RECT;
    info.Degree = D3DDEGREE_CUBIC;
    info.Basis = D3DBASIS_BEZIER;

    if (!SUCCEEDED(D3DXCreatePatchMesh(&info,num_patches,num_points,0,inDecl,d3ddev,&p_mesh)))
        assert(FALSE);
    assert(p_mesh->GetControlVerticesPerPatch()==POINTS_PER_PATCH);

    // copy vertices
    LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
    if (!SUCCEEDED(p_mesh->GetVertexBuffer(&v_buffer))) 
        assert(FALSE);
    struct vertex_data* vertex_data = NULL;
    DWORD number_of_vertices=p_mesh->GetNumVertices();
    assert(number_of_vertices==num_points);
    if (!SUCCEEDED(v_buffer->Lock(0,number_of_vertices*sizeof(struct vertex_data),(void **)&vertex_data,D3DLOCK_DISCARD)))
        assert(FALSE);
    for (int i=0; i<num_points; i++)
    {
        vertex_data[i].position.x = points[i].x;
        vertex_data[i].position.y = points[i].y;
        vertex_data[i].position.z = points[i].z;
        vertex_data[i].color = D3DCOLOR_XRGB(255,0,0);
    }
    v_buffer->Unlock();
    v_buffer->Release();    

    // copy indices
    LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;
    if (!SUCCEEDED(p_mesh->GetIndexBuffer(&i_buffer))) 
        assert(FALSE);
    D3DINDEXBUFFER_DESC i_buffer_desc;
    if (!SUCCEEDED(i_buffer->GetDesc(&i_buffer_desc)))
        assert(FALSE);
    assert(i_buffer_desc.Size==num_patches*POINTS_PER_PATCH*sizeof(WORD));
    WORD* index_data = NULL;
    if (!SUCCEEDED(i_buffer->Lock(0,0,(void **)&index_data,D3DLOCK_DISCARD)))
        assert(FALSE);
    int idx=0;
    for (int i=0; i<num_patches; i++)
    {
        for (int j=0; j<POINTS_PER_PATCH; j++)
        {
            index_data[idx] = patches[i][j];
            idx++;
        }
    }
    i_buffer->Unlock();
    i_buffer->Release();    

    // create mesh for tesselation
    FLOAT fTessLevel=1.0f;
    DWORD Adaptive=FALSE;
    DWORD NumTriangles,NumVertices;
    if (!SUCCEEDED(p_mesh->GetTessSize(fTessLevel,Adaptive,&NumTriangles,&NumVertices)))
        assert(FALSE);
    if (!SUCCEEDED(D3DXCreateMeshFVF(NumTriangles,NumVertices,D3DXMESH_MANAGED,FVF_VERTEX_DATA,d3ddev,&mesh)))
        assert(FALSE);

    // tesselate
    assert(Adaptive==FALSE);
    if (!SUCCEEDED(p_mesh->Tessellate(fTessLevel,mesh)))
        assert(FALSE);
    printf("Generated tesselated mesh with %d triangles, %d vertices\n",NumTriangles,NumVertices);

    p_mesh->Release();
}

Данные чайника (место в чайнике файла): (от http://www.sjbaker.org/teapot/teaset.tgz):

32
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
4,17,18,19,8,20,21,22,12,23,24,25,16,26,27,28
19,29,30,31,22,32,33,34,25,35,36,37,28,38,39,40
31,41,42,1,34,43,44,5,37,45,46,9,40,47,48,13
13,14,15,16,49,50,51,52,53,54,55,56,57,58,59,60
16,26,27,28,52,61,62,63,56,64,65,66,60,67,68,69
28,38,39,40,63,70,71,72,66,73,74,75,69,76,77,78
40,47,48,13,72,79,80,49,75,81,82,53,78,83,84,57
57,58,59,60,85,86,87,88,89,90,91,92,93,94,95,96
60,67,68,69,88,97,98,99,92,100,101,102,96,103,104,105
69,76,77,78,99,106,107,108,102,109,110,111,105,112,113,114
78,83,84,57,108,115,116,85,111,117,118,89,114,119,120,93
121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136
124,137,138,121,128,139,140,125,132,141,142,129,136,143,144,133
133,134,135,136,145,146,147,148,149,150,151,152,69,153,154,155
136,143,144,133,148,156,157,145,152,158,159,149,155,160,161,69
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177
165,178,179,162,169,180,181,166,173,182,183,170,177,184,185,174
174,175,176,177,186,187,188,189,190,191,192,193,194,195,196,197
177,184,185,174,189,198,199,186,193,200,201,190,197,202,203,194
204,204,204,204,207,208,209,210,211,211,211,211,212,213,214,215
204,204,204,204,210,217,218,219,211,211,211,211,215,220,221,222
204,204,204,204,219,224,225,226,211,211,211,211,222,227,228,229
204,204,204,204,226,230,231,207,211,211,211,211,229,232,233,212
212,213,214,215,234,235,236,237,238,239,240,241,242,243,244,245
215,220,221,222,237,246,247,248,241,249,250,251,245,252,253,254
222,227,228,229,248,255,256,257,251,258,259,260,254,261,262,263
229,232,233,212,257,264,265,234,260,266,267,238,263,268,269,242
270,270,270,270,279,280,281,282,275,276,277,278,271,272,273,274
270,270,270,270,282,289,290,291,278,286,287,288,274,283,284,285
270,270,270,270,291,298,299,300,288,295,296,297,285,292,293,294
270,270,270,270,300,305,306,279,297,303,304,275,294,301,302,271
306
1.4,0.0,2.4
1.4,-0.784,2.4
0.784,-1.4,2.4
0.0,-1.4,2.4
1.3375,0.0,2.53125
1.3375,-0.749,2.53125
0.749,-1.3375,2.53125
0.0,-1.3375,2.53125
1.4375,0.0,2.53125
1.4375,-0.805,2.53125
0.805,-1.4375,2.53125
0.0,-1.4375,2.53125
1.5,0.0,2.4
1.5,-0.84,2.4
0.84,-1.5,2.4
0.0,-1.5,2.4
-0.784,-1.4,2.4
-1.4,-0.784,2.4
-1.4,0.0,2.4
-0.749,-1.3375,2.53125
-1.3375,-0.749,2.53125
-1.3375,0.0,2.53125
-0.805,-1.4375,2.53125
-1.4375,-0.805,2.53125
-1.4375,0.0,2.53125
-0.84,-1.5,2.4
-1.5,-0.84,2.4
-1.5,0.0,2.4
-1.4,0.784,2.4
-0.784,1.4,2.4
0.0,1.4,2.4
-1.3375,0.749,2.53125
-0.749,1.3375,2.53125
0.0,1.3375,2.53125
-1.4375,0.805,2.53125
-0.805,1.4375,2.53125
0.0,1.4375,2.53125
-1.5,0.84,2.4
-0.84,1.5,2.4
0.0,1.5,2.4
0.784,1.4,2.4
1.4,0.784,2.4
0.749,1.3375,2.53125
1.3375,0.749,2.53125
0.805,1.4375,2.53125
1.4375,0.805,2.53125
0.84,1.5,2.4
1.5,0.84,2.4
1.75,0.0,1.875
1.75,-0.98,1.875
0.98,-1.75,1.875
0.0,-1.75,1.875
2.0,0.0,1.35
2.0,-1.12,1.35
1.12,-2.0,1.35
0.0,-2.0,1.35
2.0,0.0,0.9
2.0,-1.12,0.9
1.12,-2.0,0.9
0.0,-2.0,0.9
-0.98,-1.75,1.875
-1.75,-0.98,1.875
-1.75,0.0,1.875
-1.12,-2.0,1.35
-2.0,-1.12,1.35
-2.0,0.0,1.35
-1.12,-2.0,0.9
-2.0,-1.12,0.9
-2.0,0.0,0.9
-1.75,0.98,1.875
-0.98,1.75,1.875
0.0,1.75,1.875
-2.0,1.12,1.35
-1.12,2.0,1.35
0.0,2.0,1.35
-2.0,1.12,0.9
-1.12,2.0,0.9
0.0,2.0,0.9
0.98,1.75,1.875
1.75,0.98,1.875
1.12,2.0,1.35
2.0,1.12,1.35
1.12,2.0,0.9
2.0,1.12,0.9
2.0,0.0,0.45
2.0,-1.12,0.45
1.12,-2.0,0.45
0.0,-2.0,0.45
1.5,0.0,0.225
1.5,-0.84,0.225
0.84,-1.5,0.225
0.0,-1.5,0.225
1.5,0.0,0.15
1.5,-0.84,0.15
0.84,-1.5,0.15
0.0,-1.5,0.15
-1.12,-2.0,0.45
-2.0,-1.12,0.45
-2.0,0.0,0.45
-0.84,-1.5,0.225
-1.5,-0.84,0.225
-1.5,0.0,0.225
-0.84,-1.5,0.15
-1.5,-0.84,0.15
-1.5,0.0,0.15
-2.0,1.12,0.45
-1.12,2.0,0.45
0.0,2.0,0.45
-1.5,0.84,0.225
-0.84,1.5,0.225
0.0,1.5,0.225
-1.5,0.84,0.15
-0.84,1.5,0.15
0.0,1.5,0.15
1.12,2.0,0.45
2.0,1.12,0.45
0.84,1.5,0.225
1.5,0.84,0.225
0.84,1.5,0.15
1.5,0.84,0.15
-1.6,0.0,2.025
-1.6,-0.3,2.025
-1.5,-0.3,2.25
-1.5,0.0,2.25
-2.3,0.0,2.025
-2.3,-0.3,2.025
-2.5,-0.3,2.25
-2.5,0.0,2.25
-2.7,0.0,2.025
-2.7,-0.3,2.025
-3.0,-0.3,2.25
-3.0,0.0,2.25
-2.7,0.0,1.8
-2.7,-0.3,1.8
-3.0,-0.3,1.8
-3.0,0.0,1.8
-1.5,0.3,2.25
-1.6,0.3,2.025
-2.5,0.3,2.25
-2.3,0.3,2.025
-3.0,0.3,2.25
-2.7,0.3,2.025
-3.0,0.3,1.8
-2.7,0.3,1.8
-2.7,0.0,1.575
-2.7,-0.3,1.575
-3.0,-0.3,1.35
-3.0,0.0,1.35
-2.5,0.0,1.125
-2.5,-0.3,1.125
-2.65,-0.3,0.9375
-2.65,0.0,0.9375
-2.0,-0.3,0.9
-1.9,-0.3,0.6
-1.9,0.0,0.6
-3.0,0.3,1.35
-2.7,0.3,1.575
-2.65,0.3,0.9375
-2.5,0.3,1.125
-1.9,0.3,0.6
-2.0,0.3,0.9
1.7,0.0,1.425
1.7,-0.66,1.425
1.7,-0.66,0.6
1.7,0.0,0.6
2.6,0.0,1.425
2.6,-0.66,1.425
3.1,-0.66,0.825
3.1,0.0,0.825
2.3,0.0,2.1
2.3,-0.25,2.1
2.4,-0.25,2.025
2.4,0.0,2.025
2.7,0.0,2.4
2.7,-0.25,2.4
3.3,-0.25,2.4
3.3,0.0,2.4
1.7,0.66,0.6
1.7,0.66,1.425
3.1,0.66,0.825
2.6,0.66,1.425
2.4,0.25,2.025
2.3,0.25,2.1
3.3,0.25,2.4
2.7,0.25,2.4
2.8,0.0,2.475
2.8,-0.25,2.475
3.525,-0.25,2.49375
3.525,0.0,2.49375
2.9,0.0,2.475
2.9,-0.15,2.475
3.45,-0.15,2.5125
3.45,0.0,2.5125
2.8,0.0,2.4
2.8,-0.15,2.4
3.2,-0.15,2.4
3.2,0.0,2.4
3.525,0.25,2.49375
2.8,0.25,2.475
3.45,0.15,2.5125
2.9,0.15,2.475
3.2,0.15,2.4
2.8,0.15,2.4
0.0,0.0,3.15
0.0,-0.002,3.15
0.002,0.0,3.15
0.8,0.0,3.15
0.8,-0.45,3.15
0.45,-0.8,3.15
0.0,-0.8,3.15
0.0,0.0,2.85
0.2,0.0,2.7
0.2,-0.112,2.7
0.112,-0.2,2.7
0.0,-0.2,2.7
-0.002,0.0,3.15
-0.45,-0.8,3.15
-0.8,-0.45,3.15
-0.8,0.0,3.15
-0.112,-0.2,2.7
-0.2,-0.112,2.7
-0.2,0.0,2.7
0.0,0.002,3.15
-0.8,0.45,3.15
-0.45,0.8,3.15
0.0,0.8,3.15
-0.2,0.112,2.7
-0.112,0.2,2.7
0.0,0.2,2.7
0.45,0.8,3.15
0.8,0.45,3.15
0.112,0.2,2.7
0.2,0.112,2.7
0.4,0.0,2.55
0.4,-0.224,2.55
0.224,-0.4,2.55
0.0,-0.4,2.55
1.3,0.0,2.55
1.3,-0.728,2.55
0.728,-1.3,2.55
0.0,-1.3,2.55
1.3,0.0,2.4
1.3,-0.728,2.4
0.728,-1.3,2.4
0.0,-1.3,2.4
-0.224,-0.4,2.55
-0.4,-0.224,2.55
-0.4,0.0,2.55
-0.728,-1.3,2.55
-1.3,-0.728,2.55
-1.3,0.0,2.55
-0.728,-1.3,2.4
-1.3,-0.728,2.4
-1.3,0.0,2.4
-0.4,0.224,2.55
-0.224,0.4,2.55
0.0,0.4,2.55
-1.3,0.728,2.55
-0.728,1.3,2.55
0.0,1.3,2.55
-1.3,0.728,2.4
-0.728,1.3,2.4
0.0,1.3,2.4
0.224,0.4,2.55
0.4,0.224,2.55
0.728,1.3,2.55
1.3,0.728,2.55
0.728,1.3,2.4
1.3,0.728,2.4
0.0,0.0,0.0
1.5,0.0,0.15
1.5,0.84,0.15
0.84,1.5,0.15
0.0,1.5,0.15
1.5,0.0,0.075
1.5,0.84,0.075
0.84,1.5,0.075
0.0,1.5,0.075
1.425,0.0,0.0
1.425,0.798,0.0
0.798,1.425,0.0
0.0,1.425,0.0
-0.84,1.5,0.15
-1.5,0.84,0.15
-1.5,0.0,0.15
-0.84,1.5,0.075
-1.5,0.84,0.075
-1.5,0.0,0.075
-0.798,1.425,0.0
-1.425,0.798,0.0
-1.425,0.0,0.0
-1.5,-0.84,0.15
-0.84,-1.5,0.15
0.0,-1.5,0.15
-1.5,-0.84,0.075
-0.84,-1.5,0.075
0.0,-1.5,0.075
-1.425,-0.798,0.0
-0.798,-1.425,0.0
0.0,-1.425,0.0
0.84,-1.5,0.15
1.5,-0.84,0.15
0.84,-1.5,0.075
1.5,-0.84,0.075
0.798,-1.425,0.0
1.425,-0.798,0.0

Наконец, для компиляции с использованием mingw в Ubuntu 10.04 amd64 с соответствующим установленным программным обеспечением:

#!/bin/bash
rm tester.exe > /dev/null 2>&1
i586-mingw32msvc-g++ tester.cpp -o tester.exe -fcheck-new -Idxsdk/DXSDK/Include -ld3d9 dxsdk/DXSDK/Lib/x86/d3dx9.lib
...