zoukankan      html  css  js  c++  java
  • 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

    图形模块 结束了!

  • 相关阅读:
    python的深拷贝和浅拷贝
    jquery的each循环
    python开发要求
    Python的进程和线程(二)——IO密集型任务
    Python的进程和线程(一)——计算密集型任务
    Python常用模块(一)--argparse模块
    Chrome Headless模式(二)——Python+selenium+headerless
    beyond compare 命令行批量比对图片
    Chrome Headless模式(一)
    python实现在mac笔记本上更换桌面背景
  • 原文地址:https://www.cnblogs.com/yoru/p/5532065.html
Copyright © 2011-2022 走看看