从零开始写光栅化渲染器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            = 1;
    d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality         = 0;
    d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow              = hWnd;
    d3dpp.Windowed                   = true;
    d3dpp.EnableAutoDepthStencil     = true;
    d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
    d3dpp.Flags                      = 0;
    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, 0);

    return true;
}

void DirectX::lockSurface()
{
    // 创建并初始化锁定区域,LockRect为D3DLOCKED_RECT类型的成员变量
    memset(&LockRect, 0, 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 >> 2)] = 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:绘制一个像素点_第1张图片

3.项目完整地址:

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

你可能感兴趣的:(从零开始写软件光栅化渲染器)