DirectX入门之快速开发框架

本文介绍了一个用于简化Direct3D开发的实用框架,包括窗口创建、设备初始化及常用颜色和光照材料设置等功能。

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

在前两篇文章中,我向你简单介绍了如何创建windows窗口、如何初始化Direct3D。这篇文章将给你一个快速开发Direct3D的框架。

框架图

这里写图片描述

运行截图

这里写图片描述

完整代码

下载地址:框架我已上传至优快云或者找龙书(DirectX9.0 3D游戏开发)源码。

头文件:


//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: d3dUtility.h
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Provides utility functions for simplifying common tasks.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __d3dUtilityH__
#define __d3dUtilityH__

#include <d3dx9.h>
#include <string>

namespace d3d
{
    bool InitD3D(
        HINSTANCE hInstance,       // [in] Application instance.
        int width, int height,     // [in] Backbuffer dimensions.
        bool windowed,             // [in] Windowed (true)or full screen (false).
        D3DDEVTYPE deviceType,     // [in] HAL or REF
        IDirect3DDevice9** device);// [out]The created device.

    int EnterMsgLoop(
        bool(*ptr_display)(float timeDelta));

    LRESULT CALLBACK WndProc(
        HWND hwnd,
        UINT msg,
        WPARAM wParam,
        LPARAM lParam);

    template<class T> void Release(T t)
    {
        if (t)
        {
            t->Release();
            t = 0;
        }
    }

    template<class T> void Delete(T t)
    {
        if (t)
        {
            delete t;
            t = 0;
        }
    }

    const D3DXCOLOR      WHITE(D3DCOLOR_XRGB(255, 255, 255));
    const D3DXCOLOR      BLACK(D3DCOLOR_XRGB(0, 0, 0));
    const D3DXCOLOR        RED(D3DCOLOR_XRGB(255, 0, 0));
    const D3DXCOLOR      GREEN(D3DCOLOR_XRGB(0, 255, 0));
    const D3DXCOLOR       BLUE(D3DCOLOR_XRGB(0, 0, 255));
    const D3DXCOLOR     YELLOW(D3DCOLOR_XRGB(255, 255, 0));
    const D3DXCOLOR       CYAN(D3DCOLOR_XRGB(0, 255, 255));
    const D3DXCOLOR    MAGENTA(D3DCOLOR_XRGB(255, 0, 255));

    //
    // Lights
    //

    D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
    D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
    D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);

    //
    // Materials
    //

    D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);

    const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
    const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);
    const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
    const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
    const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);
}

#endif // __d3dUtilityH__

实现.cpp

#include "stdafx.h"
#include "d3dtool.h"
#include<timeapi.h>
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "dinput8.lib")   
#pragma comment(lib, "dxguid.lib")
//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: d3dUtility.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Provides utility functions for simplifying common tasks.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////



bool d3d::InitD3D(
    HINSTANCE hInstance,
    int width, int height,
    bool windowed,
    D3DDEVTYPE deviceType,
    IDirect3DDevice9** device)
{
    //
    // Create the main application window.
    //

    WNDCLASS wc;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = 0;
    wc.lpszClassName = L"Direct3D9App";

    if (!RegisterClass(&wc))
    {
        ::MessageBox(0, L"RegisterClass() - FAILED", 0, 0);
        return false;
    }

    HWND hwnd = 0;
    hwnd = ::CreateWindow(L"Direct3D9App",L"Direct3D9App",
        WS_EX_TOPMOST,
        0, 0, width, height,
        0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

    if (!hwnd)
    {
        ::MessageBox(0, L"CreateWindow() - FAILED", 0, 0);
        return false;
    }

    ::ShowWindow(hwnd, SW_SHOW);
    ::UpdateWindow(hwnd);

    //
    // Init D3D: 
    //

    HRESULT hr = 0;

    // Step 1: Create the IDirect3D9 object.

    IDirect3D9* d3d9 = 0;
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    if (!d3d9)
    {
        ::MessageBox(0, L"Direct3DCreate9() - FAILED", 0, 0);
        return false;
    }

    // Step 2: Check for hardware vp.

    D3DCAPS9 caps;
    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

    int vp = 0;
    if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    else
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    // Step 3: Fill out the D3DPRESENT_PARAMETERS structure.

    D3DPRESENT_PARAMETERS d3dpp;
    d3dpp.BackBufferWidth = width;
    d3dpp.BackBufferHeight = height;
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    d3dpp.BackBufferCount = 1;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.Windowed = windowed;
    d3dpp.EnableAutoDepthStencil = true;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
    d3dpp.Flags = 0;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    // Step 4: Create the device.

    hr = d3d9->CreateDevice(
        D3DADAPTER_DEFAULT, // primary adapter
        deviceType,         // device type
        hwnd,               // window associated with device
        vp,                 // vertex processing
        &d3dpp,             // present parameters
        device);            // return created device

    if (FAILED(hr))
    {
        // try again using a 16-bit depth buffer
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

        hr = d3d9->CreateDevice(
            D3DADAPTER_DEFAULT,
            deviceType,
            hwnd,
            vp,
            &d3dpp,
            device);

        if (FAILED(hr))
        {
            d3d9->Release(); // done with d3d9 object
            ::MessageBox(0, L"CreateDevice() - FAILED", 0, 0);
            return false;
        }
    }

    d3d9->Release(); // done with d3d9 object

    return true;
}

int d3d::EnterMsgLoop(bool(*ptr_display)(float timeDelta))
{
    MSG msg;
    ::ZeroMemory(&msg, sizeof(MSG));

    static float lastTime = (float)timeGetTime();

    while (msg.message != WM_QUIT)
    {
        if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
        else
        {
            float currTime = (float)timeGetTime();
            float timeDelta = (currTime - lastTime)*0.001f;

            ptr_display(timeDelta);

            lastTime = currTime;
        }
    }
    return msg.wParam;
}

D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Direction = *direction;

    return light;
}

D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_POINT;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Position = *position;
    light.Range = 1000.0f;
    light.Falloff = 1.0f;
    light.Attenuation0 = 1.0f;
    light.Attenuation1 = 0.0f;
    light.Attenuation2 = 0.0f;

    return light;
}

D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_SPOT;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Position = *position;
    light.Direction = *direction;
    light.Range = 1000.0f;
    light.Falloff = 1.0f;
    light.Attenuation0 = 1.0f;
    light.Attenuation1 = 0.0f;
    light.Attenuation2 = 0.0f;
    light.Theta = 0.5f;
    light.Phi = 0.7f;

    return light;
}

D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
    D3DMATERIAL9 mtrl;
    mtrl.Ambient = a;
    mtrl.Diffuse = d;
    mtrl.Specular = s;
    mtrl.Emissive = e;
    mtrl.Power = p;
    return mtrl;
}

主函数

//win32_directx.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "win32_directx.h"
#include<d3d9.h>
#include<timeapi.h>
#include"d3dtool.h"
#include "targetver.h"

#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "dinput8.lib")   
#pragma comment(lib, "dxguid.lib")
//////////////////////////////////////////////////////////////////////////////////////////////////
// 
// File: d3dinit.cpp
// 
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
//
// Desc: Demonstrates how to initialize Direct3D, how to use the book's framework
//       functions, and how to clear the screen to black.  Note that the Direct3D
//       initialization code is in the d3dUtility.h/.cpp files.
//          
//////////////////////////////////////////////////////////////////////////////////////////////////


//
// Globals
//

IDirect3DDevice9* Device = 0;

//
// Framework Functions
//

bool Setup()
{
    // Nothing to setup in this sample.

    return true;
}

void Cleanup()
{
    // Nothing to cleanup in this sample.
}

bool Display(float timeDelta)
{
    if (Device) // Only use Device methods if we have a valid device.
    {
        // Instruct the device to set each pixel on the back buffer black -
        // D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on
        // the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.
        Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);

        // Swap the back and front buffers.
        Device->Present(0, 0, 0, 0);
    }
    return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        ::PostQuitMessage(0);
        break;

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            ::DestroyWindow(hwnd);
        break;
    }
    return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
    HINSTANCE prevInstance,
    PSTR cmdLine,
    int showCmd)
{
    if (!d3d::InitD3D(hinstance,
        640, 480, true, D3DDEVTYPE_HAL, &Device))
    {
        ::MessageBox(0, L"InitD3D() - FAILED", 0, 0);
        return 0;
    }

    if (!Setup())
    {
        ::MessageBox(0, L"Setup() - FAILED", 0, 0);
        return 0;
    }

    d3d::EnterMsgLoop(Display);

    Cleanup();

    Device->Release();

    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值