Direct3D成长日记(04):深度缓存测试

本教程介绍如何使用Direct3D进行深度缓存测试,通过F1键切换深度缓存的启用与禁用状态。代码实现了基本的窗口创建、Direct3D初始化、图形渲染流程,并演示了如何设置和使用顶点缓存。

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

Direct3D成长日记(04):深度缓存测试

源程序:

//////////////////////////////////////////////////////////////////////////
//文件名称    :Direct3D成长日记(04):深度缓存测试。
//作者        :shenzi
//完成时间    :2009.05.07
//描述        :通过F1控制启动深度缓存与否。
//////////////////////////////////////////////////////////////////////////

//包含头文件,相应库:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

//全局变量声明:
LPDIRECT3D9            g_pD3D = NULL;        //Direct3D接口指针
LPDIRECT3DDEVICE9    g_pD3DDevice = NULL;//Direct3D设备指针
LPDIRECT3DVERTEXBUFFER9        g_pVBuffer = NULL; //顶点缓存

#define WINDOW_CLASS_NAME    L"Direct3D"
#define WINDOW_NAME            L"Direct3DBasics Tutorial"

#define SCREEN_WIDTH    800
#define SCREEN_HEIGHT    600
BOOL    g_bEnableZBuf = TRUE;

//顶点结构
struct CUSTOMVERTEX
{
    FLOAT X, Y ,Z;
    DWORD COLOR;
};

#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)

//函数声明:
HRESULT InitD3D( HWND);            //初始化Direct3D
void RenderFrame( void);        //场景渲染
void CleanD3D( void);            //释放资源
HRESULT InitGraphics(void);        //初始化图形
void SetupMatrices(void);            //模型视图投影矩阵设置

//WINDOWS 消息处理函数:
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM);

//WinMain函数:
int WINAPI WinMain( HINSTANCE hInstance,
                   HINSTANCE hprevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    //变量声明:
    HWND hwnd;
    MSG msg;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    //创建窗口类
    wc.cbClsExtra        = 0;
    wc.cbSize            = sizeof(WNDCLASSEX);
    wc.cbWndExtra        = 0;
    wc.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.hCursor            = LoadCursor( NULL, IDC_ARROW);
    wc.hIcon            = LoadIcon( NULL, IDI_APPLICATION);
    wc.hInstance        = hInstance;
    wc.lpfnWndProc        = WndProc;
    wc.lpszClassName    = WINDOW_CLASS_NAME;
    wc.lpszMenuName        = NULL;
    wc.style            = CS_HREDRAW | CS_VREDRAW;

    //注册窗口类
    RegisterClassEx(&wc);

    //初始化窗口
    hwnd = CreateWindowEx(    NULL,
        WINDOW_CLASS_NAME,
        WINDOW_NAME,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        NULL, NULL, hInstance, NULL);

    //显示,更新窗口:
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    InitD3D(hwnd);


    ZeroMemory(&msg, sizeof(MSG));

    //消息循环:
    while( msg.message != WM_QUIT )
    {
        if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
            RenderFrame();
    }

    UnregisterClass( WINDOW_CLASS_NAME, wc.hInstance );
    return 0;

}

LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_DESTROY:
        CleanD3D();
        PostQuitMessage( 0 );
        return 0;
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_F1:
            if (g_bEnableZBuf)
            {
                g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
            }
            else
                g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);

            g_bEnableZBuf = !g_bEnableZBuf;
            return 0;
        }
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

HRESULT InitD3D(HWND hwnd)
{
    //创建D3D对象:
    if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
    {
        return E_FAIL;
    }

    //定义窗口的显示信息:
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp));

    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.EnableAutoDepthStencil = TRUE;
    

    //创建D3D设备:
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,   
        D3DDEVTYPE_HAL,
        hwnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp,
        &g_pD3DDevice)))
    {
        return E_FAIL;
    }

    InitGraphics();

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

    return S_OK;
}
void RenderFrame(void)
{
    if(NULL == g_pD3DDevice)
        return;
    //清空背景缓冲区:
    g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);


    if(SUCCEEDED(g_pD3DDevice->BeginScene()))
    {
        //渲染场景:
        //设置顶点结构:
        g_pD3DDevice->SetFVF(CUSTOMFVF);

        SetupMatrices();

        //选取要显示的顶点
        g_pD3DDevice->SetStreamSource(0, g_pVBuffer, 0, sizeof(CUSTOMVERTEX));

        D3DXMATRIX matWorld;
        D3DXMATRIX matTanslate;
        D3DXMATRIX matScale;
        D3DXMATRIX matRotY;

        static FLOAT angle = 0.0f;

        angle += 0.05f;
        D3DXMatrixTranslation(&matTanslate, 0.0f, 0.0f, 0.0f);

        g_pD3DDevice->SetTransform(D3DTS_WORLD, &matTanslate);

        //绘制图元
        g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);

        D3DXMatrixTranslation(&matTanslate, 1.5f, 0.0f, -0.0f);
        D3DXMatrixRotationY(&matRotY, angle);

        matWorld =   matRotY * matTanslate ;

        g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

        g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);

        g_pD3DDevice->EndScene();
    }
    //把渲染的场景显示在窗口:
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

}
void CleanD3D(void)
{
    //释放资源
    if (NULL != g_pVBuffer)
    {
        g_pVBuffer->Release();
    }
    if(NULL != g_pD3DDevice)
        g_pD3DDevice->Release();
    if(NULL != g_pD3D)
        g_pD3D->Release();

    g_pVBuffer = NULL;
    g_pD3DDevice = NULL;
    g_pD3D = NULL;
}

HRESULT InitGraphics(void)
{
    //定义顶点数组
    CUSTOMVERTEX vertices[] =
    {
        {  -2.0f, -2.0f, 0.0f, 0xffff0000,},
        {   0.0f,  2.0f, 0.0f, 0xff00ff00,},
        {   2.0f, -2.0f, 0.0f, 0xff0000ff,},
    };

    //建立顶点缓存
    if (FAILED(g_pD3DDevice->CreateVertexBuffer(sizeof(vertices),
        0,
        CUSTOMFVF,
        D3DPOOL_MANAGED,
        &g_pVBuffer,
        NULL)))
    {
        return E_FAIL;
    }

    //通过Lock,Unlock 为顶点缓存填充数据(顶点信息):
    VOID * pV;

    if(FAILED(g_pVBuffer->Lock(0,
        sizeof(vertices),
        (void**)&pV,
        0)))
    {
        return E_FAIL;
    }
    memcpy(pV, vertices, sizeof(vertices));

    g_pVBuffer->Unlock();

}

void SetupMatrices(void)
{
    //投影变换
    D3DXMATRIX matProjection;

    D3DXMatrixPerspectiveFovLH(&matProjection,
        D3DX_PI/4,
        (FLOAT)SCREEN_WIDTH/(FLOAT)SCREEN_HEIGHT,
        0.1f,
        100.0f);
    g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);

    //视图变换
    D3DXMATRIX matView;

    D3DXVECTOR3 pEye(-5.0f, 0.0f, -5.0f);
    D3DXVECTOR3 pAt (0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 pUp (0.0f, 1.0f, 0.0f);

    D3DXMatrixLookAtLH(&matView,
        &pEye,
        &pAt,
        &pUp);

    g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);

}

结果:

Direct3D成长日记(04):深度缓存测试。


资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 无锡平芯微半导体科技有限公司生产的A1SHB三极管(全称PW2301A)是一款P沟道增强型MOSFET,具备低内阻、高重复雪崩耐受能力以及高效电源切换设计等优势。其技术规格如下:最大漏源电压(VDS)为-20V,最大连续漏极电流(ID)为-3A,可在此条件下稳定工作;栅源电压(VGS)最大值为±12V,能承受正反向电压;脉冲漏极电流(IDM)可达-10A,适合处理短暂高电流脉冲;最大功率耗散(PD)为1W,可防止器件过热。A1SHB采用3引脚SOT23-3封装,小型化设计利于空间受限的应用场景。热特性方面,结到环境的热阻(RθJA)为125℃/W,即每增加1W功率损耗,结温上升125℃,提示设计电路时需考虑散热。 A1SHB的电气性能出色,开关特性优异。开关测试电路及波形图(图1、图2)展示了不同条件下的开关性能,包括开关上升时间(tr)、下降时间(tf)、开启时间(ton)和关闭时间(toff),这些参数对评估MOSFET在高频开关应用中的效率至关重要。图4呈现了漏极电流(ID)与漏源电压(VDS)的关系,图5描绘了输出特性曲线,反映不同栅源电压下漏极电流的变化。图6至图10进一步揭示性能特征:转移特性(图7)显示栅极电压(Vgs)对漏极电流的影响;漏源开态电阻(RDS(ON))随Vgs变化的曲线(图8、图9)展现不同控制电压下的阻抗;图10可能涉及电容特性,对开关操作的响应速度和稳定性有重要影响。 A1SHB三极管(PW2301A)是高性能P沟道MOSFET,适用于低内阻、高效率电源切换及其他多种应用。用户在设计电路时,需充分考虑其电气参数、封装尺寸及热管理,以确保器件的可靠性和长期稳定性。无锡平芯微半导体科技有限公司提供的技术支持和代理商服务,可为用户在产品选型和应用过程中提供有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值