码迷,mamicode.com
首页 > 其他好文 > 详细

hge source explor 0xC graphics Ⅲ

时间:2016-05-28 09:58:24      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

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

内部调用接口

  内部接口主要完成:关于固定流水线的设置;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 Ⅲ

标签:

原文地址:http://www.cnblogs.com/yoru/p/5515666.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!