hge source explor 0xC graphics Ⅲ

Posted YORU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hge source explor 0xC graphics Ⅲ相关的知识,希望对你有一定的参考价值。

  这里关于图形模块的内部接口部分

内部调用接口

  内部接口主要完成:关于固定流水线的设置;dx的初始化;dx的结束

  可以说内部接口已经完成了左右工作,只要进行组合调用即可

_GfxInit()

  DX的初始化函数

  • Direct3DCreate8 创建接口
  • GetAdapterIdentifier 获得设备信息,在这里可以查询设备能够做到什么
  • PRESENT_PARAMETER 参数的填写
  • CreateDevice 创建设备
  • _AdjustWindow 这个函数原来在window模块里已经考虑过,在这里之所以调用是因为DX要和窗口之间关联,所以DX变化,窗口也随着调整
  • _SetPorjectMatrix 设置投影矩阵
  • D3DXMatirxIdentity 标准化视图矩阵
  • _init_lost 在这个函数中完成顶点缓存、索引缓存、矩阵设置、渲染设置等
  • Gfx_Clear 将窗口清理干净
bool HGE_Impl::_GfxInit()
{
    static const char *szFormats[]={"UNKNOWN", "R5G6B5", "X1R5G5B5", "A1R5G5B5", "X8R8G8B8", "A8R8G8B8"};
    D3DADAPTER_IDENTIFIER8 AdID;
    D3DDISPLAYMODE Mode;
    D3DFORMAT Format=D3DFMT_UNKNOWN;
    UINT nModes, i;
    
// Init D3D
                            
    pD3D=Direct3DCreate8(120); // D3D_SDK_VERSION
    if(pD3D==NULL)
    {
        _PostError("Can\'t create D3D interface");
        return false;
    }

// Get adapter info

    pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &AdID);
    System_Log("D3D Driver: %s",AdID.Driver);
    System_Log("Description: %s",AdID.Description);
    System_Log("Version: %d.%d.%d.%d",
            HIWORD(AdID.DriverVersion.HighPart),
            LOWORD(AdID.DriverVersion.HighPart),
            HIWORD(AdID.DriverVersion.LowPart),
            LOWORD(AdID.DriverVersion.LowPart));

// Set up Windowed presentation parameters
    
    if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) 
    {
        _PostError("Can\'t determine desktop video mode");
        if(bWindowed) return false;
    }
    
    ZeroMemory(&d3dppW, sizeof(d3dppW));

    d3dppW.BackBufferWidth  = nScreenWidth;
    d3dppW.BackBufferHeight = nScreenHeight;
    d3dppW.BackBufferFormat = Mode.Format;
    d3dppW.BackBufferCount  = 1;
    d3dppW.MultiSampleType  = D3DMULTISAMPLE_NONE;
    d3dppW.hDeviceWindow    = hwnd;
    d3dppW.Windowed         = TRUE;

    if(nHGEFPS==HGEFPS_VSYNC) d3dppW.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
    else                      d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;

    if(bZBuffer)
    {
        d3dppW.EnableAutoDepthStencil = TRUE;
        d3dppW.AutoDepthStencilFormat = D3DFMT_D16;
    }

// Set up Full Screen presentation parameters

    nModes=pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT);

    for(i=0; i<nModes; i++)
    {
        pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &Mode);
        if(Mode.Width != (UINT)nScreenWidth || Mode.Height != (UINT)nScreenHeight) continue;
        if(nScreenBPP==16 && (_format_id(Mode.Format) > _format_id(D3DFMT_A1R5G5B5))) continue;
        if(_format_id(Mode.Format) > _format_id(Format)) Format=Mode.Format;
    }

    if(Format == D3DFMT_UNKNOWN)
    {
        _PostError("Can\'t find appropriate full screen video mode");
        if(!bWindowed) return false;
    }

    ZeroMemory(&d3dppFS, sizeof(d3dppFS));

    d3dppFS.BackBufferWidth  = nScreenWidth;
    d3dppFS.BackBufferHeight = nScreenHeight;
    d3dppFS.BackBufferFormat = Format;
    d3dppFS.BackBufferCount  = 1;
    d3dppFS.MultiSampleType  = D3DMULTISAMPLE_NONE;
    d3dppFS.hDeviceWindow    = hwnd;
    d3dppFS.Windowed         = FALSE;

    d3dppFS.SwapEffect       = D3DSWAPEFFECT_FLIP;
    d3dppFS.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

    if(nHGEFPS==HGEFPS_VSYNC) d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    else                      d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    if(bZBuffer)
    {
        d3dppFS.EnableAutoDepthStencil = TRUE;
        d3dppFS.AutoDepthStencilFormat = D3DFMT_D16;
    }

    d3dpp = bWindowed ? &d3dppW : &d3dppFS;

    if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
    else nScreenBPP=32;
    
// Create D3D Device

    if( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                  d3dpp, &pD3DDevice ) ) )
    {
        _PostError("Can\'t create D3D device");
        return false;
    }

    _AdjustWindow();

    System_Log("Mode: %d x %d x %s\\n",nScreenWidth,nScreenHeight,szFormats[_format_id(Format)]);

// Create vertex batch buffer

    VertArray=0;
    textures=0;

// Init all stuff that can be lost

    _SetProjectionMatrix(nScreenWidth, nScreenHeight);
    D3DXMatrixIdentity(&matView);
    
    if(!_init_lost()) return false;

    Gfx_Clear(0);

    return true;
}
_GfxInit

 

_init_lost()    重要!重要!重要!

  在这个函数中实现:顶点缓存、索引缓存、矩阵设置、渲染设置

  • GetRenderTarget & GetDepthStencilSurface
  • 将渲染对象列表中的对象都导入:D3DXCreateTexture & CreateDepthStencilSurface
  • CreateVertexBuffer 创建顶点缓存
  • SetVertexShader 设置顶点格式
  • SetStreamSource 设置顶点缓存
  • CreateIndexBuffer 创建索引缓存
  • IDirect3DIndexBuffer9::Lock  锁定索引缓冲区
  • 初始化索引,这里设置为 {0,1,2 2,3,0}的方式两个两个三角形渲染
  • IDirect3DIndexBuffer9::Unlock 解除索引缓冲区的锁定
  • SetIndices 设定索引缓冲区 
  • 接下来设置渲染参数
  • SetRenderState: D3DRS_CULLMODE,D3DRS_LIGHTING,D3DRS_ALPHABLENDENABLE,D3DRS_SRCBLEND,D3DRS_DESTBLEND,D3DRS_ALPHATESTENABLE,D3DRS_ALPHAREF,D3DRS_ALPHAFUNC
  • SetTextureStageState: D3DTSS_COLOROP,D3DTSS_COLORARG1,D3DTSS_COLORARG1,D3DTSS_COLORARG2,D3DTSS_ALPHAOP,D3DTSS_ALPHAARG1,D3DTSS_ALPHAARG2,D3DTSS_MIPFILTER,D3DTSS_MAGFILTER,D3DTSS_MINFILTER
  • 设置当前的需要渲染的图元个数
  • 设置当前需要渲染的图元类型
  • 设置当前BlendMode
  • 设置当前的纹理
  • SetTransform: D3DTS_VIEW,D3DTS_PROJECTION
bool HGE_Impl::_init_lost()
{
    CRenderTargetList *target=pTargets;

// Store render target

    pScreenSurf=0;
    pScreenDepth=0;

    pD3DDevice->GetRenderTarget(&pScreenSurf);
    pD3DDevice->GetDepthStencilSurface(&pScreenDepth);
    
    while(target)
    {
        if(target->pTex)
            D3DXCreateTexture(pD3DDevice, target->width, target->height, 1, D3DUSAGE_RENDERTARGET,
                              d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &target->pTex);
        if(target->pDepth)
            pD3DDevice->CreateDepthStencilSurface(target->width, target->height,
                                                  D3DFMT_D16, D3DMULTISAMPLE_NONE, &target->pDepth);
        target=target->next;
    }

// Create Vertex buffer
    
    if( FAILED (pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE*sizeof(hgeVertex),
                                              D3DUSAGE_WRITEONLY,
                                              D3DFVF_HGEVERTEX,
                                              D3DPOOL_DEFAULT, &pVB )))
    {
        _PostError("Can\'t create D3D vertex buffer");
        return false;
    }

    pD3DDevice->SetVertexShader( D3DFVF_HGEVERTEX );
    pD3DDevice->SetStreamSource( 0, pVB, sizeof(hgeVertex) );

// Create and setup Index buffer

    if( FAILED( pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE*6/4*sizeof(WORD),
                                              D3DUSAGE_WRITEONLY,
                                              D3DFMT_INDEX16,
                                              D3DPOOL_DEFAULT, &pIB ) ) )
    {
        _PostError("Can\'t create D3D index buffer");
        return false;
    }

    WORD *pIndices, n=0;
    if( FAILED( pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 ) ) )
    {
        _PostError("Can\'t lock D3D index buffer");
        return false;
    }

    for(int i=0; i<VERTEX_BUFFER_SIZE/4; i++) {
        *pIndices++=n;
        *pIndices++=n+1;
        *pIndices++=n+2;
        *pIndices++=n+2;
        *pIndices++=n+3;
        *pIndices++=n;
        n+=4;
    }

    pIB->Unlock();
    pD3DDevice->SetIndices(pIB,0);

// Set common render states

    //pD3DDevice->SetRenderState( D3DRS_LASTPIXEL, FALSE );
    pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
    
    pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE,   TRUE );
    pD3DDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
    pD3DDevice->SetRenderState( D3DRS_ALPHAREF,        0x01 );
    pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );

    pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

    pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
    pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

    pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);

    if(bTextureFilter)
    {
        pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
        pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
    }
    else
    {
        pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
        pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
    }

    nPrim=0;
    CurPrimType=HGEPRIM_QUADS;
    CurBlendMode = BLEND_DEFAULT;
    CurTexture = NULL;

    pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
    pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);

    return true;
}
_init_lost

 

_GfxDone()

  DX结束工作

  • 删除所有的渲染对象:纹理、表面、本身
  • 重新设置索引缓存,并释放现在的索引缓存
  • 解除对顶点缓存的锁定并释放顶点缓存
  • 释放D3D设备
  • 释放D3D接口
void HGE_Impl::_GfxDone()
{
    CRenderTargetList *target=pTargets, *next_target;
    
    while(textures)    Texture_Free(textures->tex);

    if(pScreenSurf) { pScreenSurf->Release(); pScreenSurf=0; }
    if(pScreenDepth) { pScreenDepth->Release(); pScreenDepth=0; }

    while(target)
    {
        if(target->pTex) target->pTex->Release();
        if(target->pDepth) target->pDepth->Release();
        next_target=target->next;
        delete target;
        target=next_target;
    }
    pTargets=0;

    if(pIB)
    {
        pD3DDevice->SetIndices(NULL,0);
        pIB->Release();
        pIB=0;
    }
    if(pVB)
    {
        if(VertArray) {    pVB->Unlock(); VertArray=0;    }
        pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
        pVB->Release();
        pVB=0;
    }
    if(pD3DDevice) { pD3DDevice->Release(); pD3DDevice=0; }
    if(pD3D) { pD3D->Release(); pD3D=0; }
}
_GfxDone

_GfxRestore()

  对于DX的复位操作 Reset

  • 将当前的所有的渲染对象的纹理、表面释放
  • 释放定点缓存和索引缓存
  • IDirect3DDevice8::Reset
  • _init_lost
bool HGE_Impl::_GfxRestore()
{
    CRenderTargetList *target=pTargets;

    //if(!pD3DDevice) return false;
    //if(pD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST) return;

    if(pScreenSurf) pScreenSurf->Release();
    if(pScreenDepth) pScreenDepth->Release();

    while(target)
    {
        if(target->pTex) target->pTex->Release();
        if(target->pDepth) target->pDepth->Release();
        target=target->next;
    }

    if(pIB)
    {
        pD3DDevice->SetIndices(NULL,0);
        pIB->Release();
    }
    if(pVB)
    {
        pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
        pVB->Release();
    }

    pD3DDevice->Reset(d3dpp);

    if(!_init_lost()) return false;

    if(procGfxRestoreFunc) return procGfxRestoreFunc();

    return true;
}
_GfxRestore

_render_batch(bool bEndScene)

  批渲染,就是将在顶点缓存中的数据全部渲染

  • 如果有顶点缓存的情况下才进行下面的步骤
  • 对顶点缓存接触锁定
  • 如果有图元要渲染,根据图元来分别渲染
  • 渲染完图元之后通过参数判定是否要释放定点缓存
void HGE_Impl::_render_batch(bool bEndScene)
{
    if(VertArray)
    {
        pVB->Unlock();
        
        if(nPrim)
        {
            switch(CurPrimType)
            {
                case HGEPRIM_QUADS:
                    pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, nPrim<<2, 0, nPrim<<1);
                    break;

                case HGEPRIM_TRIPLES:
                    pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, nPrim);
                    break;

                case HGEPRIM_LINES:
                    pD3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, nPrim);
                    break;
            }

            nPrim=0;
        }

        if(bEndScene) VertArray = 0;
        else pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );
    }
}
_render_batch

_SetBlendMode(int blend)

  设置Blend Mode

  • 如果需要的模式和当前的模式不同则设置为参数形式:
  • BLEND_ALPHABLEND
  • BLEND_ZWRITE
  • BLEND_COLORADD
void HGE_Impl::_SetBlendMode(int blend)
{
    if((blend & BLEND_ALPHABLEND) != (CurBlendMode & BLEND_ALPHABLEND))
    {
        if(blend & BLEND_ALPHABLEND) pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
        else pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
    }

    if((blend & BLEND_ZWRITE) != (CurBlendMode & BLEND_ZWRITE))
    {
        if(blend & BLEND_ZWRITE) pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
        else pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
    }            
    
    if((blend & BLEND_COLORADD) != (CurBlendMode & BLEND_COLORADD))
    {
        if(blend & BLEND_COLORADD) pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
        else pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    }

    CurBlendMode = blend;
}
_SetBlendMode

_SetProjectionMatrix(int width, int height)

  设置投影矩阵

  • 通过矩阵操作设置投影矩阵
void HGE_Impl::_SetProjectionMatrix(int width, int height)
{
    D3DXMATRIX tmp;
    D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
    D3DXMatrixTranslation(&tmp, -0.5f, height+0.5f, 0.0f);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
    D3DXMatrixOrthoOffCenterLH(&tmp, 0, (float)width, 0, (float)height, 0.0f, 1.0f);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
}
_SetProjectionMatrix

_format_id(D3DFORMAT fmt)

  获得模式

  • 预定了几个模式,判断给定的模式是否在其中并返回
int HGE_Impl::_format_id(D3DFORMAT fmt)
{
    switch(fmt) {
        case D3DFMT_R5G6B5:        return 1;
        case D3DFMT_X1R5G5B5:    return 2;
        case D3DFMT_A1R5G5B5:    return 3;
        case D3DFMT_X8R8G8B8:    return 4;
        case D3DFMT_A8R8G8B8:    return 5;
        default:                return 0;
    }
}
_format_id

 

以上是关于hge source explor 0xC graphics Ⅲ的主要内容,如果未能解决你的问题,请参考以下文章

hge source explor 0x8 timer

hge source explor 0x4 input module

hge source explor 0x6 input module

hge source explor 0x3 windows module

hge source explor 0xB graphics Ⅱ

hge source explor 0x5 input module