windows direct 3d 编程总结

本文概述了Direct3D的底层关键技术,包括创建D3D对象、设备配置、状态设定、画布创建、批量渲染模式、绘画层概念、3D矩阵、结果集提交、设备丢失与重建工作等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

--------------------------------------------------------------------------------
author: hjjdebug
date: 2012-07-04
--------------------------------------------------------------------------------
该文档不是一个入门教程。 而是一个描述D3D 底层关键技术的概要文档。
但尽量使得它通俗易懂。 具体的实现细节,你可能需要阅读代码或其它文献。

1. 创建d3d 对象和 获得d3d 设备能力
    CComPtr<IDirect3D9> d3d(Direct3DCreate9(D3D_SDK_VERSION));
    hr=d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &dc);
2. 创建d3d 设备 (独占模式,窗口模式),适配器模式(长,宽等)设备参数等在m_d3dpp 中
    FAIL_RET(m_d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,m_hWnd,vertexProcessing,&m_d3dpp,&m_pD3DDev.p));
3. 设定d3d 状态
    //设置剔出模式为不剔出任何面,显示正面和反面
    //关闭光照处理, 默认情况下启用光照处理
    // 不打开Z buffer缓存
    // 不打开模板缓冲
    //设置着色模式
    //设置填充模式
    //设置纹理寻址模式
    //设置纹理过滤模式
    // 设置纹理混合层
    //指定alpha 资源
    // 启用alpha 混合模式
4. 创建d3d 画布 (关联3 个对象)
    
    if( SUCCEEDED( D3DXCreateTexture(m_pD3DDev,CANVAS_WIDTH,CANVAS_HEIGHT,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&m_pCanvTexture) ) )   // texture
    m_pCanvTexture->GetSurfaceLevel(0,&m_pCanvSurface); //surface
    D3DXCreateRenderToSurface(m_pD3DDev,CANVAS_WIDTH,CANVAS_HEIGHT,D3DFMT_A8R8G8B8,TRUE,D3DFMT_D24S8,&m_pCanvRS); //render

核心函数:DrawTexture
HRESULT CD3DCanvas::DrawTexture    (int x,int y,SIZE const *pDstSize,IDirect3DTexture9 *pTexture,RECT const *pTexRect,D3DCOLOR color)
HRESULT Dx2DDraw::DrawTexture(RECT const *pDstRect,IDirect3DTexture9 *pTexture, RECT const *pTexRect, D3DCOLOR color, U32 z)
    // 计算纹理坐标
    drawVertexs.v[0].tu
    drawVertexs.v[0].tv
    drawVertexs.v[1].tu
    drawVertexs.v[1].tv
    drawVertexs.v[2].tu
    drawVertexs.v[2].tv
    drawVertexs.v[3].tu
    drawVertexs.v[3].tv
    // 画..
    FAIL_RET(m_pD3Device->SetTexture( 0,pTexture));
    memcpy(&VertArray_[nPrim_*NSPRIM_QUADS],drawVertexs.v, sizeof(CUSTOMVERTEX)*NSPRIM_QUADS);
5. 批量渲染模式
HRESULT Dx2DDraw::CreateVertexAndIndex()  // 创建定点缓冲区和索引缓冲区
HRESULT Dx2DDraw::RenderBatch(bool EndScence)
hr=m_pD3Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, nPrim_<<2, 0, nPrim_<<1);

6. Draw Target: 分为设定层次,画模板,画图形操作
        case TARGET_GRAPH:
            DrawGraph();
            break;
        case TARGET_TEMPLATE_PUSH:
            templateDepth++;
            DrawTemplatePush();
            break;
        case TARGET_TEMPLATE_POP:
            templateDepth--;
            if(templateDepth < 0)
                printf("error template depth!\n");
            DrawTemplatePop();
            break;
        case TARGET_GRAPH_TEMPLATE:
            DrawClipGraph();

所有操作仅仅对应 m_pD3Device->SetRenderState(。。。)
例如DrawGraph() 对应
FAIL_RET(m_pD3Device->SetRenderState(D3DRS_ALPHABLENDENABLE, ALPHABLENDVALUE));
FAIL_RET(m_pD3Device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA));
FAIL_RET(m_pD3Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA));
FAIL_RET(m_pD3Device->SetRenderState( D3DRS_STENCILENABLE, false));

7. 设备丢失和重建工作...
8. 绘画层的概念(驱动层,非驱动层)及批量绘画概念(beginPaint, endPaint(render),drawCmds)
    #define    DCTY_INVALID            0
    #define DCTY_DCDRAWRESIMAGE        1
    //世界坐标变换
    #define TRTY_MATRIXWORLD        2
    // 绘画目标
    #define DCTY_DRAWTARGET            3
    #define DCTY_DCSETDRAWCOLOR        4
    #define DCTY_DCSETBKGNDCOLOR    5
    #define DCTY_DCDRAWTEXT            6

    DCTY_DCDRAWRESIMAGE 对应以下子类型
    union{
        DCDrawImage dcDrawImage;
        DCDrawText dcDrawText;
        DCSetDrawColor dcDrawColor;
        DCSetBkGndColor dcBkGndColor;
        DCDrawTarget dcDrawTarget;
    };

9. 结果集提交
    FAIL_RET(RenderLayerDrawCmds(target)); // --> 画布(surface)
    FAIL_RET(RenderCanvas());    // 到 backbuffer
    FAIL_RET(Present());        // backbuffer -> 屏幕
10. 3D 矩阵
    SetupViewMatrix();    //眼睛, 观察点(原点),上法线, 必须要恰当设置,否则图像或大,或小,或看不见
    SetupProjMatrix();    // 投射矩阵,三维向二维的转换。符合远小近大的视觉效果。(45度或90度)

    视口概念: 视口也是一个矩阵,他是把屏幕大小映射到(-1,1)的一个矩阵变换。

10.1 两个简单接口。 给定平面上两点, 计算夹角及缩放比例
    // 返回旋转参数, 角度的正负值已包含
    void GetRotateAngle2(Point2D u1, Point2D u2, Point2D v1, Point2D v2, float &angle)
    // 返回缩放系数
    void GetScaleEfficient(Point2D u1, Point2D u2, Point2D v1, Point2D v2, float &scale)

10.2: 折扇动画的底层支持
    bool Dx3DDraw::GetMatrixWolrd_FromPoint(TransPoints  &transPs, D3DXMATRIX &matWorld)
    注意:缩放是相对于屏幕中心点进行的,如果不是已以屏幕中心点为中心的矩形,三角形,线段,需要将中心点移回(底层考虑)。
    //折扇动画需要调用: (2维平面)
    // 输入:    起点矢量,终点矢量,
    // 输出: matrix
    // input transPs.u1, transPs.u2; transPs.v1, transPs.v2;
    // output transPs.retP matWorld;
    // 注:当一条与坐标轴平行的线仅做缩放时,将不能判断线在那个平面内 ?
    // 简单说, 三点决定一个平面,而两点不能决定一个平面,此时默认是 Y轴,Z轴,X轴

    核心运算:
    1. 转换屏幕坐标到d3d 坐标
    2. 获取缩放系数,
    3. 获取旋转系数
    4. 找到偏移
    4. 加入世界变换,
    6. 得到最终变换矩阵

over! thanks!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值