Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (1 posts)

How to draw a half sphere in Direct3D? Thanks.

Last post 3/23/2017 8:07 AM by linuxfedora. 0 replies.
  • 3/23/2017 8:07 AM

    How to draw a half sphere in Direct3D? Thanks.

    I have an image which is a fisheye image with a circle on it, and i want to put it inside a half sphere by using texture and then control the camera to view the image on the half sphere.

    I am new to direct3d, just learnt the basic primitive and texture skill, and if just create a quad and texture the image on it, i can do it without problem, but i have no idea how to create a half sphere and texture on it. I have googled and cannot find any sample code for it.

    Could anyone give me some hint on how to do it?

    I can create a half sphere now, but do not know how to map the texture with a Cirucle into the centre of the half sphere, the code as below:


    // Direct3DTestWin32.cpp : Defines the entry point for the application.
    //

    #include "stdafx.h"
    #include "Direct3DTestWin32.h"
    #include <d3d9.h>
    #include <d3dx9.h>

    #define MAX_LOADSTRING 100

    // define the screen resolution
    #define SCREEN_WIDTH 1280
    #define SCREEN_HEIGHT 720

    // Global Variables:
    HINSTANCE hInst; // current instance
    TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name


    // global declarations
    LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
    LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
    LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;    // the pointer to the vertex buffer
    IDirect3DIndexBuffer9 *pIbuf;
    IDirect3DTexture9* texture = NULL;
    IDirect3DTexture9* texture2 = NULL;
    LPD3DXSPRITE sprite=NULL;

    // function prototypes
    void initD3D(HWND hWnd);    // sets up and initializes Direct3D
    void render_frame(void);    // renders a single frame
    void cleanD3D(void);    // closes Direct3D and releases memory
    void init_graphics(void);
    IDirect3DTexture9 *LoadTexture(LPCWSTR path);

    int mSlice = 20;
    int mStack = 20;
    int mR = 1;
    int mNumOfVertices = 0;
    int mNumOfTriangle = 0;

    struct CUSTOMVERTEX 
    {
        D3DXVECTOR3 position; // The position
        FLOAT       tu, tv;   // The texture coordinates
    };

    #define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_TEX1)

    // Forward declarations of functions included in this code module:
    ATOM MyRegisterClass(HINSTANCE hInstance);
    BOOL InitInstance(HINSTANCE, int);
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

      // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_DIRECT3DTESTWIN32, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
    return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DIRECT3DTESTWIN32));

    // Main message loop:
    while(TRUE)
    {
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

        if(msg.message == WM_QUIT)
    break;

    render_frame();
    }

    cleanD3D();

    return (int) msg.wParam;
    }

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

        D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information

        ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
        d3dpp.Windowed = TRUE;    // program windowed, not fullscreen
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
        d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D

    d3dpp.EnableAutoDepthStencil = TRUE;    // automatically run the z-buffer for us
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;    // 16-bit pixel format for the z-buffer

        // create a device class using this information and information from the d3dpp stuct
        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); //make triangle see in both side

    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer

    //d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

    //d3ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    //d3ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    //d3ddev->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

    // d3ddev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);

    }

    // this is the function used to render a single frame
    void render_frame(void)
    {
        // clear the window to a deep blue
        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();    // begins the 3D scene

        // select which vertex format we are using
        d3ddev->SetFVF(CUSTOMFVF);

    d3ddev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    d3ddev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    d3ddev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
        // SET UP THE PIPELINE
        D3DXMATRIX matTranslateA;    // a matrix to store the translation for triangle A
        //D3DXMATRIX matTranslateB;    // a matrix to store the translation for triangle B
        D3DXMATRIX matRotateY;    // a matrix to store the rotation for each triangle
        static float index = 0; index+=0.005f; // an ever-increasing float value

        // build MULTIPLE matrices to translate the model and one to rotate
        D3DXMatrixTranslation(&matTranslateA, 0.0f, 0.0f, 0.0f);
        //D3DXMatrixTranslation(&matTranslateB, 0.0f, 0.0f, -1.0f);
    D3DXMatrixRotationX(&matRotateY, index);    // the front side

        // tell Direct3D about each world transform, and then draw another triangle
        d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateA * matRotateY));

        D3DXMATRIX matView;    // the view transform matrix

        D3DXMatrixLookAtLH(&matView,
                           &D3DXVECTOR3 (0.0f, 0.0f, -8.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

        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

    d3ddev->SetTexture (0, texture);
        d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
    d3ddev->SetIndices(pIbuf);


        // copy the vertex buffer to the back buffer
    //d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 20);
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mNumOfVertices, 0,  mNumOfTriangle / 2);//mNumOfTriangle / 2);

        d3ddev->EndScene();    // ends the 3D scene

        d3ddev->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
    }


    // this is the function that cleans up Direct3D and COM
    void cleanD3D(void)
    {
    v_buffer->Release();
    pIbuf->Release();
        d3ddev->Release();    // close and release the 3D device
        d3d->Release();    // close and release Direct3D
    }

    void init_graphics(void)
    {
    mNumOfVertices = 2 + mSlice * (mStack - 2);
    mNumOfTriangle = 2 * mSlice + ((mStack - 2) * (2 * mSlice));

    float stackStep = D3DX_PI / mStack;
    float sliceStep = 2 * D3DX_PI / mSlice;

        // create the vertex and store the pointer into v_buffer, which is created globally
        d3ddev->CreateVertexBuffer(mNumOfVertices * sizeof(CUSTOMVERTEX),
                                   0,
                                   CUSTOMFVF,
                                   D3DPOOL_MANAGED,
                                   &v_buffer,
                                   NULL);

        CUSTOMVERTEX* pVertices;
        v_buffer->Lock(0, 0, (void**)&pVertices, 0); //lock the vertex buffer
    int verticeIdx = 1;

    //Create all the vertices here
    pVertices[0].position = D3DXVECTOR3(0, mR, 0); //North point at index 0
    for(int i=1;i<mStack-1;i++)
    {
    float stackAngle = i * stackStep;
    for(int j=0;j<mSlice;j++)
    {
    float sliceAngle = j * sliceStep;

    pVertices[verticeIdx++].position = D3DXVECTOR3(
    (mR*sin(stackAngle)*cos(sliceAngle)),
    (mR*cos(stackAngle)),
    (mR*sin(stackAngle)*sin(sliceAngle))
    );
    }
    }
    pVertices[verticeIdx].position = D3DXVECTOR3(0, -mR, 0); //South point at last index
        v_buffer->Unlock();    // unlock the vertex buffer

    //Create all the index buffer.
    d3ddev->CreateIndexBuffer(sizeof(short) * mNumOfTriangle * 3, 
    D3DUSAGE_WRITEONLY, 
    D3DFMT_INDEX16, 
    D3DPOOL_DEFAULT, 
    &pIbuf, 
    NULL);

    short *iBuffData;
    HRESULT hRes2 =  pIbuf->Lock(0, 0, (void**)&iBuffData, 0);

    //North ring index
    int iBufIndex = 0;
    for (int i = 1; i <= mSlice; i++) 
    {
    if(i + 1 > mSlice)
    {
    iBuffData[iBufIndex++] = 0;
    iBuffData[iBufIndex++] = 1;
    iBuffData[iBufIndex++] = i;
    }
    else
    {
    iBuffData[iBufIndex++] = 0;
    iBuffData[iBufIndex++] = (i + 1);
    iBuffData[iBufIndex++] = i;
    }
        }

    //Middle ring index
    int baseIndex = 1;
    int ringVertexCount = mSlice;// + 1;
    for (int i = 0; i < mStack - 2; i++)
    {
    for (int j = 0; j < mSlice; j++)
    {
    int currentStackStartIndex = i * ringVertexCount;
    int nextStackStartIndex = (i + 1) * ringVertexCount;

    int currentStackMax = (i + 1) * ringVertexCount;
    int nextStackMax = (i + 2) * ringVertexCount;

    iBuffData[iBufIndex++] = baseIndex + currentStackStartIndex + j;

    int idx = currentStackStartIndex + (j + 1);
    if(idx >= currentStackMax)
    {
    idx -= mSlice;
    }
    iBuffData[iBufIndex++] = baseIndex + idx;
    iBuffData[iBufIndex++] = baseIndex + (nextStackStartIndex + j);

    iBuffData[iBufIndex++] = baseIndex + (nextStackStartIndex + j);
    iBuffData[iBufIndex++] = baseIndex + idx;

    idx = nextStackStartIndex + (j + 1);
    if(idx >= nextStackMax)
    {
    idx -= mSlice;
    }
    iBuffData[iBufIndex++] = baseIndex + idx;
    }
    }

    //South ring index
    int southPoleIndex = mNumOfVertices - 1;
    baseIndex = southPoleIndex - ringVertexCount;
    for (int i = 1; i <= mSlice; i++) {
            iBuffData[iBufIndex++] = southPoleIndex;
    iBuffData[iBufIndex++] = baseIndex + i;
    iBuffData[iBufIndex++] = baseIndex + i + 1;
        }

    pIbuf->Unlock();
    }

    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DIRECT3DTESTWIN32));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_DIRECT3DTESTWIN32);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
    }

    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;

       hInst = hInstance; // Store instance handle in our global variable

       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

       if (!hWnd)
       {
          return FALSE;
       }

       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);

       initD3D(hWnd);

    LPCWSTR path1 = L"D:\\Project\\Direct3DTestWin32\\debug\\0.jpg";

       texture = LoadTexture(path1);

    if(!texture)
    {
    return FALSE;
    }

    LPCWSTR path2 = L"D:\\Project\\Direct3DTestWin32\\debug\\1.jpg";

       texture2 = LoadTexture(path2);

    if(!texture2)
    {
    return FALSE;
    }

    if (SUCCEEDED(D3DXCreateSprite(d3ddev,&sprite)))
    {

    }

       return TRUE;
    }

    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND - process the application menu
    //  WM_PAINT - Paint the main window
    //  WM_DESTROY - post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
    wmId    = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    // Parse the menu selections:
    switch (wmId)
    {
    case IDM_ABOUT:
    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    // TODO: Add any drawing code here...
    EndPaint(hWnd, &ps);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }

    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
    return (INT_PTR)TRUE;

    case WM_COMMAND:
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    {
    EndDialog(hDlg, LOWORD(wParam));
    return (INT_PTR)TRUE;
    }
    break;
    }
    return (INT_PTR)FALSE;
    }

    //Load texture from file with D3DX
    //Supported formats: BMP, PPM, DDS, JPG, PNG, TGA, DIB
    IDirect3DTexture9 *LoadTexture(LPCWSTR path)
    {
      IDirect3DTexture9 *d3dTexture;
      D3DXIMAGE_INFO SrcInfo;   //Optional

      //Use a magenta colourkey
      D3DCOLOR colorkey = 0xFFFF00FF;

      //TeleEye_63_cam_1.bmp
      // Load image from file
      if (FAILED(D3DXCreateTextureFromFileEx (d3ddev, path, 0, 0, 1, 0,
    D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,
    colorkey, &SrcInfo, NULL, &d3dTexture)))
      {
    return NULL;
      }

      //Return the newly made texture
      return d3dTexture;
    }

Page 1 of 1 (1 posts) Previous Discussion Next Discussion