坑爹的天空穹

29 篇文章 0 订阅
16 篇文章 0 订阅

前两天写了天空盒,感觉可以写一个天空穹。其实就是索引缓存的利用,没有什么优化,可是就是有一个隐藏的问题。现在也没有办法解决。实在不想搞了。先放着吧~

效果就是这个效果~

这里写图片描述

真的心里好难受,如果面设置的少了就会少画一些面。感觉太诡异了。

算了 把代码贴这里,等过些时间等我修养深了。再回来看看吧~

照样 windows dx框架代码

// skysphere.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "skysphere.h"

#include "GameApp.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
GameApp g_GameApp;

// 此代码模块中包含的函数的前向声明:
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(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此放置代码。
    MSG msg;
    HACCEL hAccelTable;

    // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_SKYSPHERE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

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

    // 主消息循环:
    ZeroMemory(&msg, sizeof(msg));
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            g_GameApp.Update();
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
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_SKYSPHERE));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_SKYSPHERE);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // 将实例句柄存储在全局变量中

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

   if (!hWnd)
   {
      return FALSE;
   }

   if (!g_GameApp.Init(hInstance, hWnd))
   {
       return false;
   }

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

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
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);
        // 分析菜单选择:
        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: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        g_GameApp.Release();
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// “关于”框的消息处理程序。
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;
}

这个是windows创建的程序 直接搭建的框架,还算比较好的感觉 呵呵 ,自我感觉良好

然后主要app类

#include "stdafx.h"
#include "GameApp.h"


GameApp::GameApp(void)
{
    m_pD3D = NULL;
    m_pDevice = NULL;

    m_pSky = NULL;
}


GameApp::~GameApp(void)
{
    Release();
}


bool GameApp::Init(HINSTANCE hInstance, HWND hWnd)
{
    m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if (!m_pD3D)
    {
        return false;
    }

    D3DCAPS9 caps;
    if (FAILED(m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
    {
        return false;
    }

    int vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
    {
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    }

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &m_pDevice)))
    {
        return false;
    }

    m_pSky = new Sky();
    if (!m_pSky->Init(m_pDevice, 900.0f))
    {
        return false;
    }
    if (!m_pSky->LoadTexture("sp.jpg"))
    {
        return false;
    }

    return true;
}


void GameApp::Update(void)
{
    D3DXMATRIX matView;
    D3DXVECTOR3 eye(0.0f, 100.0f, -50.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXVECTOR3 at(0.0f, 110.0f, 0.0f);
    D3DXMatrixLookAtLH(&matView, &eye, &at, &up);
    m_pDevice->SetTransform(D3DTS_VIEW, &matView);

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4.0f, 1.0f, 0.0f, 1000.0f);
    m_pDevice->SetTransform(D3DTS_PROJECTION, &matProj);

    D3DLIGHT9 light;
    ZeroMemory(&light, sizeof(light));
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Direction = D3DXVECTOR3(0.0f, 1.0f, 1.0f);
    light.Ambient = light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    light.Specular = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
    m_pDevice->SetLight(0, &light);
    m_pDevice->LightEnable(0, TRUE);
    m_pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255, 255, 255));

    D3DVIEWPORT9 viewPort;
    viewPort.X = 0;
    viewPort.Y = 0;
    viewPort.Width = 800;
    viewPort.Height = 600;
    viewPort.MinZ = 0.0f;
    viewPort.MaxZ = 1.0f;
    m_pDevice->SetViewport(&viewPort);

    m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, D3DCOLOR_XRGB(0, 0, 50), 1.0f, 0);
    if (SUCCEEDED(m_pDevice->BeginScene()))
    {
        m_pSky->Render();

        m_pDevice->EndScene();
        m_pDevice->Present(NULL, NULL, NULL, NULL);
    }
}


void GameApp::Release(void)
{
    if (m_pSky)
    {
        delete m_pSky;
        m_pSky = NULL;
    }

    if (m_pDevice)
    {
        m_pDevice->Release();
        m_pDevice = NULL;
    }

    if (m_pD3D)
    {
        m_pD3D->Release();
        m_pD3D = NULL;
    }
}

头文件可以有实现文件推理出来。我也就不在这嘚瑟了。

然后是天空穹实现文件 其实就是球面坐标的转换。纯属练习

#include "stdafx.h"
#include "Sky.h"

#include "mmsystem.h"


Sky::Sky(void)
{
    m_pDevice = NULL;
    m_fRedius = 0.0f;
    m_pVB = NULL;
    m_pIB = NULL;
    m_pTexture = NULL;
}


Sky::~Sky(void)
{
    Release();
}


bool Sky::Init(LPDIRECT3DDEVICE9 pDevice, float redius)
{
    m_pDevice = pDevice;
    m_fRedius = redius;

    if (FAILED(m_pDevice->CreateVertexBuffer((SKYLNUM * SKYHNUM + 1) * sizeof(Vertex),D3DUSAGE_WRITEONLY, SKYFVF, D3DPOOL_MANAGED, &m_pVB, NULL)))
    {
        return false;
    }

    Vertex* pVertices = NULL;
    if (FAILED(m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD)))
    {
        return false;
    }
    D3DXVECTOR3 begin(0.0f, m_fRedius, 0.0f);
    D3DXVECTOR3 cur(0.0f, 0.0f, 0.0f);

    int curIdx = 0;

    pVertices[curIdx++] = Vertex(begin, D3DXVECTOR2(0.5f, 0.5f));

    float vBase = D3DX_PI/2.0f/(SKYHNUM * 1.0f);
    float hBase = D3DX_PI*2.0f/(SKYLNUM * 1.0f);

    D3DXMATRIX matRotatez;
    D3DXMATRIX matRotatey;
    D3DXMATRIX matRotate;

    for (int h = 1; h <= SKYHNUM; h++)
    {
        D3DXVECTOR2 uv(vBase * (h * 1.0f)/D3DX_PI, 0.0f);
        D3DXVECTOR2 cur_uv(0.0f, 0.0f);

        for (int l = 0; l < SKYLNUM; l++)
        {
            D3DXMatrixRotationYawPitchRoll(&matRotate, hBase * (l * 1.0f), 0, -vBase * (h * 1.0f));
            D3DXVec3TransformCoord(&cur, &begin, &matRotate);

            D3DXMatrixRotationZ(&matRotatez, hBase * (l * 1.0f));
            D3DXVec2TransformCoord(&cur_uv, &uv, &matRotatez);

            pVertices[curIdx++] = Vertex(cur, D3DXVECTOR2(0.5f + cur_uv.x, 0.5f + cur_uv.y));
        }
    }

    m_pVB->Unlock();

    if (FAILED(m_pDevice->CreateIndexBuffer((SKYLNUM * 3 + ((SKYHNUM - 1) * SKYLNUM) * 6) * sizeof(DWORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &m_pIB, NULL)))
    {
        return false;
    }

    DWORD* pIndices = NULL;
    if (FAILED(m_pIB->Lock(0, 0, (void**)&pIndices, D3DLOCK_DISCARD)))
    {
        return false;
    }

    curIdx = 0;
    for (int l = 0; l < SKYLNUM; l++)
    {
        if (l < SKYLNUM - 1)
        {
            pIndices[curIdx++] = 0;
            pIndices[curIdx++] = l + 2;
            pIndices[curIdx++] = l + 1;
        }
        else
        {
            pIndices[curIdx++] = 0;
            pIndices[curIdx++] = 1;
            pIndices[curIdx++] = l + 1;
        }
    }

    for (int h = 0; h < SKYHNUM - 1; h++)
    {
        for (int l = 0; l < SKYLNUM; l++)
        {
            if (l < SKYLNUM - 1)
            {
                pIndices[curIdx++] = 1 + SKYLNUM * h + l;
                pIndices[curIdx++] = 1 + SKYLNUM * h + l + 1;
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1) + l + 1;

                pIndices[curIdx++] = 1 + SKYLNUM * h + l;
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1) + l + 1;
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1) + l;
            }
            else
            {
                pIndices[curIdx++] = 1 + SKYLNUM * h + l;
                pIndices[curIdx++] = 1 + SKYLNUM * h;
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1);

                pIndices[curIdx++] = 1 + SKYLNUM * h + l;
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1);
                pIndices[curIdx++] = 1 + SKYLNUM * (h + 1) + l;
            }
        }
    }

    m_pIB->Unlock();

    return true;
}


bool Sky::LoadTexture(string szFile)
{
    if (FAILED(D3DXCreateTextureFromFileA(m_pDevice, szFile.c_str(), &m_pTexture)))
    {
        return false;
    }

    return true;
}

void Sky::Render(void)
{
    D3DXMATRIX worldMat;
    D3DXMatrixRotationY(&worldMat, timeGetTime()/1800.0f);
    m_pDevice->SetTransform(D3DTS_WORLD, &worldMat);

    D3DMATERIAL9 mtrl;
    ZeroMemory(&mtrl, sizeof(mtrl));
    mtrl.Ambient = mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    mtrl.Specular = mtrl.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
    m_pDevice->SetMaterial(&mtrl);

    m_pDevice->SetStreamSource(0, m_pVB,0, sizeof(Vertex));
    m_pDevice->SetFVF(SKYFVF);
    m_pDevice->SetIndices(m_pIB);
    m_pDevice->SetTexture(0, m_pTexture);

    m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 1, SKYLNUM * 3, SKYLNUM * (SKYHNUM - 1) * 6,SKYLNUM * 3, SKYLNUM * (SKYHNUM - 1) * 2);
}


void Sky::Release(void)
{
    m_pDevice = NULL;
    m_fRedius = 0.0f;

    if (m_pTexture)
    {
        m_pTexture->Release();
        m_pTexture = NULL;
    }

    if (m_pIB)
    {
        m_pIB->Release();
        m_pIB = NULL;
    }

    if (m_pVB)
    {
        m_pVB->Release();
        m_pVB = NULL;
    }
}

恩实现的就是这样子了。然后再来一个图吧,显得图文并茂。

这里写图片描述

总结一下:
还是顶点缓存和索引感觉不是很实在,数据都对竟然显示不正确

数学转换 d3d提供的api没有熟悉,一开始我是各种三角函数转换,可是发现繁琐死了,api也不熟悉更是悲剧

最后这个程序没有任何优化 就是为了显示而显示 可取之处聊胜于无,不过,我就是这样一点一点的练习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当当小螳螂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值