hge source explor 0xD graphics Ⅳ

Posted YORU

tags:

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

外部接口

  这里的接口提供给用户进行固定的步骤:BeginScene;自己的渲染;EndScene。

  接下来从教程2的渲染顺序来看函数

 Gfx_BeginScene(HTARGET targ)

在渲染前的准备工作

  • TestCooperativeLevel 测试设备是否可用
  • 如果在窗口模式下要检测BackBufferFormat,并更新BPP
  • _GfxRestore 重设dx
  • 检测顶点缓存:如果顶点缓存为不为0,则还未调用EndScene
  • 在当前渲染对象并非参数中的渲染对象时:设置表面、渲染对象、设置渲染参数、设置投影矩阵、设置视图矩阵
  • 设置为当前渲染对象
  • IDirect3DDevice::BeginScene
  • 锁定顶点缓存:等待顶点
bool CALL HGE_Impl::Gfx_BeginScene(HTARGET targ)
{
    LPDIRECT3DSURFACE8 pSurf=0, pDepth=0;
    D3DDISPLAYMODE Mode;
    CRenderTargetList *target=(CRenderTargetList *)targ;

    HRESULT hr = pD3DDevice->TestCooperativeLevel();
    if (hr == D3DERR_DEVICELOST) return false;
    else if (hr == D3DERR_DEVICENOTRESET)
    {
        if(bWindowed)
        {
            if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) 
            {
                _PostError("Can\'t determine desktop video mode");
                return false;
            }

            d3dppW.BackBufferFormat = Mode.Format;
            if(_format_id(Mode.Format) < 4) nScreenBPP=16;
            else nScreenBPP=32;
        }

        if(!_GfxRestore()) return false; 
    }
    
    if(VertArray)
    {
        _PostError("Gfx_BeginScene: Scene is already being rendered");
        return false;
    }
    
    if(target != pCurTarget)
    {
        if(target)
        {
            target->pTex->GetSurfaceLevel(0, &pSurf);
            pDepth=target->pDepth;
        }
        else
        {
            pSurf=pScreenSurf;
            pDepth=pScreenDepth;
        }
        if(FAILED(pD3DDevice->SetRenderTarget(pSurf, pDepth)))
        {
            if(target) pSurf->Release();
            _PostError("Gfx_BeginScene: Can\'t set render target");
            return false;
        }
        if(target)
        {
            pSurf->Release();
            if(target->pDepth) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); 
            else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); 
            _SetProjectionMatrix(target->width, target->height);
        }
        else
        {
            if(bZBuffer) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); 
            else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
            _SetProjectionMatrix(nScreenWidth, nScreenHeight);
        }

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

        pCurTarget=target;
    }

    pD3DDevice->BeginScene();
    pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );

    return true;
}
Gfx_BeginScene

 

 Gfx_Clear(DWORD color)

清理背景的工作

  • 清理背景为指定的颜色
void CALL HGE_Impl::Gfx_Clear(DWORD color)
{
    if(pCurTarget)
    {
        if(pCurTarget->pDepth)
            pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
        else
            pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
    }
    else
    {
        if(bZBuffer)
            pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
        else
            pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
    }
}
Gfx_Clear

 

 Gfx_RenderQuad(const hgeQuad *quad)

渲染矩形的准备工作

  • 判断是否锁定顶点缓冲区

  • 当前的渲染图元类型是否为矩阵 || 顶点是否超过 || 当前的纹理是否相同 || 渲染模式是否相同 : 只要一项不同,就先渲染当前的所有顶点,在渲染完后设置元数=0
  • 将矩形的顶点导入顶点缓存

  • 图元数增长
void CALL HGE_Impl::Gfx_RenderQuad(const hgeQuad *quad)
{
    if(VertArray)
    {
        if(CurPrimType!=HGEPRIM_QUADS || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_QUADS || CurTexture!=quad->tex || CurBlendMode!=quad->blend)
        {
            _render_batch();

            CurPrimType=HGEPRIM_QUADS;
            if(CurBlendMode != quad->blend) _SetBlendMode(quad->blend);
            if(quad->tex != CurTexture)
            {
                pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)quad->tex );
                CurTexture = quad->tex;
            }
        }

        memcpy(&VertArray[nPrim*HGEPRIM_QUADS], quad->v, sizeof(hgeVertex)*HGEPRIM_QUADS);
        nPrim++;
    }
}
Gfx_RenderQuad

 

 Gfx_RenderTriple(const hgeTriple *triple)

渲染三角形的准备工作

  • 类似矩形
void CALL HGE_Impl::Gfx_RenderTriple(const hgeTriple *triple)
{
    if(VertArray)
    {
        if(CurPrimType!=HGEPRIM_TRIPLES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_TRIPLES || CurTexture!=triple->tex || CurBlendMode!=triple->blend)
        {
            _render_batch();

            CurPrimType=HGEPRIM_TRIPLES;
            if(CurBlendMode != triple->blend) _SetBlendMode(triple->blend);
            if(triple->tex != CurTexture) {
                pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)triple->tex );
                CurTexture = triple->tex;
            }
        }

        memcpy(&VertArray[nPrim*HGEPRIM_TRIPLES], triple->v, sizeof(hgeVertex)*HGEPRIM_TRIPLES);
        nPrim++;
    }
}
Gfx_RenderTriple

 

 Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z)

渲染直线的准备工作

  • 判断是否锁定顶点缓冲区
  • 当前的渲染图元类型是否为矩阵 || 顶点是否超过 || 当前的纹理是否相同 || 渲染模式是否相同 : 只要一项不同,就先渲染当前的所有顶点,在渲染完后设置元数=0
  • 直线顶点导入顶点缓存
  • 图元数增长
void CALL HGE_Impl::Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z)
{
    if(VertArray)
    {
        if(CurPrimType!=HGEPRIM_LINES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_LINES || CurTexture || CurBlendMode!=BLEND_DEFAULT)
        {
            _render_batch();

            CurPrimType=HGEPRIM_LINES;
            if(CurBlendMode != BLEND_DEFAULT) _SetBlendMode(BLEND_DEFAULT);
            if(CurTexture) { pD3DDevice->SetTexture(0, 0); CurTexture=0; }
        }

        int i=nPrim*HGEPRIM_LINES;
        VertArray[i].x = x1; VertArray[i+1].x = x2;
        VertArray[i].y = y1; VertArray[i+1].y = y2;
        VertArray[i].z     = VertArray[i+1].z = z;
        VertArray[i].col   = VertArray[i+1].col = color;
        VertArray[i].tx    = VertArray[i+1].tx =
        VertArray[i].ty    = VertArray[i+1].ty = 0.0f;

        nPrim++;
    }
}
Gfx_RenderLine

 

 Gfx_EndScene()

渲染工作结束

  • 对顶点缓存中的所有顶点进行渲染;设置参数为true,在渲染结束之后顶点缓存vertarry=0
  • IDirect3DDevice::EndScene
  • IDirect3DDevice::Present 清理
void CALL HGE_Impl::Gfx_EndScene()
{
    _render_batch(true);
    pD3DDevice->EndScene();
    if(!pCurTarget) pD3DDevice->Present( NULL, NULL, NULL, NULL );
}
Gfx_EndScene

 

 Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim)

批量渲染前的工作

  • 获取顶点缓冲,并将原来的顶点渲染
  • 设置当前的渲染图元、当前渲染混合模式、当前纹理
  • 得到最大能渲染的个数
  • 返回顶点缓存地址:准备载入顶点
hgeVertex* CALL HGE_Impl::Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim)
{
    if(VertArray)
    {
        _render_batch();

        CurPrimType=prim_type;
        if(CurBlendMode != blend) _SetBlendMode(blend);
        if(tex != CurTexture)
        {
            pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)tex );
            CurTexture = tex;
        }

        *max_prim=VERTEX_BUFFER_SIZE / prim_type;
        return VertArray;
    }
    else return 0;
}
Gfx_StartBatch

 

 Gfx_FinishBatch(int nprim)

批量渲染前准备工作结束

  • 设置需要渲染的图元的个数
void CALL HGE_Impl::Gfx_FinishBatch(int nprim)
{
    nPrim=nprim;
}
Gfx_FinishBatch

 

 Gfx_SetClipping(int x, int y, int w, int h)

设置裁剪

  • 设置一个视口,并且设置视口的长、宽
  • 然后将现有的顶点缓冲中的顶点渲染
  • 设置视口
  • 重新设置投影矩阵
void CALL HGE_Impl::Gfx_SetClipping(int x, int y, int w, int h)
{
    D3DVIEWPORT8 vp;
    int scr_width, scr_height;

    if(!pCurTarget) {
        scr_width=pHGE->System_GetStateInt(HGE_SCREENWIDTH);
        scr_height=pHGE->System_GetStateInt(HGE_SCREENHEIGHT);
    }
    else {
        scr_width=Texture_GetWidth((HTEXTURE)pCurTarget->pTex);
        scr_height=Texture_GetHeight((HTEXTURE)pCurTarget->pTex);
    }

    if(!w) {
        vp.X=0;
        vp.Y=0;
        vp.Width=scr_width;
        vp.Height=scr_height;
    }
    else
    {
        if(x<0) { w+=x; x=0; }
        if(y<0) { h+=y; y=0; }

        if(x+w > scr_width) w=scr_width-x;
        if(y+h > scr_height) h=scr_height-y;

        vp.X=x;
        vp.Y=y;
        vp.Width=w;
        vp.Height=h;
    }

    vp.MinZ=0.0f;
    vp.MaxZ=1.0f;

    _render_batch();
    pD3DDevice->SetViewport(&vp);

    D3DXMATRIX tmp;
    D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
    D3DXMatrixTranslation(&tmp, -0.5f, +0.5f, 0.0f);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
    D3DXMatrixOrthoOffCenterLH(&tmp, (float)vp.X, (float)(vp.X+vp.Width), -((float)(vp.Y+vp.Height)), -((float)vp.Y), vp.MinZ, vp.MaxZ);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
    pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
Gfx_SetClipping

 

 Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale)

设置移动变换

  • 通过参数对视图矩阵进行变换
  • 渲染顶点缓冲中的所有顶点
  • 重设投影矩阵
void CALL HGE_Impl::Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale)
{
    D3DXMATRIX tmp;

    if(vscale==0.0f) D3DXMatrixIdentity(&matView);
    else
    {
        D3DXMatrixTranslation(&matView, -x, -y, 0.0f);
        D3DXMatrixScaling(&tmp, hscale, vscale, 1.0f);
        D3DXMatrixMultiply(&matView, &matView, &tmp);
        D3DXMatrixRotationZ(&tmp, -rot);
        D3DXMatrixMultiply(&matView, &matView, &tmp);
        D3DXMatrixTranslation(&tmp, x+dx, y+dy, 0.0f);
        D3DXMatrixMultiply(&matView, &matView, &tmp);
    }

    _render_batch();
    pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
}
Gfx_SetTransform

 

图形模块 结束了!

以上是关于hge source explor 0xD 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