天天看點

從零開始寫光栅化渲染器1:繪制一個像素點

1.準備工作

光栅化渲染器的第一步就是繪制一個像素點,然後再進行線,三角形的繪制,這裡主要通過directx9(具體哪個版本不重要,主要是用來繪制,也可以通過其它方式)進行像素點的繪制。

//DirectX是自己定義的一個類,主要負責DirectX裝置的建立,以及圖形的繪制
bool DirectX::initialDirectX(HINSTANCE hInstance, HWND hWnd, int width, int height)
{
    //1.建立接口
    IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    //2.擷取硬體資訊,确定頂點處理方式
    D3DCAPS9 caps;
    int vertexProcessing;
    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);    //(目前顯示卡,硬體裝置)
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
    {
        vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    }
    else
    {
        vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    //3.填寫D3D參數
    D3DPRESENT_PARAMETERS d3dpp;
    d3dpp.BackBufferWidth            = width;
    d3dpp.BackBufferHeight           = height;
    d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
    d3dpp.BackBufferCount            = ;
    d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality         = ;
    d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow              = hWnd;
    d3dpp.Windowed                   = true;
    d3dpp.EnableAutoDepthStencil     = true;
    d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
    d3dpp.Flags                      = ;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

    //4.建立裝置,pD3DXDevice是IDirect3DDevice9*類型的成員變量
    d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, vertexProcessing, &d3dpp, &pD3DXDevice);
    d3d9->Release();
    //建立一個繪制表面,pD3DSurface是IDirect3DSurface9*類型的成員變量
    pD3DXDevice->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pD3DSurface, );

    return true;
}

void DirectX::lockSurface()
{
    // 建立并初始化鎖定區域,LockRect為D3DLOCKED_RECT類型的成員變量
    memset(&LockRect, , sizeof(LockRect));
    // 鎖定
    pD3DSurface->LockRect(&LockRect,NULL,D3DLOCK_DISCARD);

}

void DirectX::unlockSurface()
{
    // 解鎖
    pD3DSurface->UnlockRect();
}

void DirectX::drawPixel(int x,int y, AColor color,float depth)
{
    /* 像素着色
    Pointer to the locked bits. If a RECT was provided to the LockRect call, 
    pBits will be appropriately offset from the start of the surface.*/

    DWORD* pBits = (DWORD*)LockRect.pBits;      //擷取像素數組,并進行着色
    pBits[x + y * (LockRect.Pitch >> )] = ARGB( color.a_ , color.r_ , color.g_ , color.b_ ); 
}
           

2.調用繪制

/************************************************************************/
/* 1.繪制一個像素                                                         */
/************************************************************************/
void draw_pixel()
{
    //繪制了100*100的像素
    for (int i=0;i<100;++i)
    {
        for (int j=0;j<100;++j)
        {
            g_directX.drawPixel(i,j,AColor(0,255,0,0));
        }
    }
}
           

效果圖如下

從零開始寫光栅化渲染器1:繪制一個像素點

3.項目完整位址:

3DRender: https://github.com/zhanghuanzj/3DRender.git

繼續閱讀