DirectX 画三角形 正交投影

来源:互联网 发布:手机淘宝视频自动播放 编辑:程序博客网 时间:2024/06/06 14:18





#include <d3d9.h>#include <d3dx9.h>#pragma comment(lib, "d3d9.lib")#pragma comment(lib, "d3dx9.lib")#define WINDOW_WIDTH    640#define WINDOW_HEIGHT   480PDIRECT3D9 g_D3D = nullptr; // D3D对象PDIRECT3DDEVICE9 g_D3DDevice = nullptr; // D3D设备对象D3DXMATRIX g_ortho; // 矩阵变量,用于正交投影变换bool InitializeD3D(HWND hWnd); // 初始化D3Dvoid ShutdownD3D(); // 退出窗口之前释放D3D对象和D3D设备对象void RenderScene(); // 渲染场景bool InitializeObjects();// 初始化3D图形对象// 顶点数据struct stD3DVertex{    float x, y, z; // 坐标值(屏幕坐标) (左手坐标系) rhw 标志    unsigned long color; // 漫射光颜色};// 顶点缓存PDIRECT3DVERTEXBUFFER9 g_VertexBuffer = nullptr;// 顶点格式#define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 窗口消息处理过程void MyCreateWindow(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd); // 创建窗口/************************************************************************//* Windows窗口程序入口函数                                               *//************************************************************************/int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd){    MyCreateWindow(hInstance, hPrevInstance, lpCmdLine, nShowCmd);    return 0;}/************************************************************************//* 创建窗口                                                                 *//************************************************************************/void MyCreateWindow(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd){    // 声明一个窗口类 包含创建一个窗口所需要的相关数据信息    WNDCLASSEX wc = {        sizeof(WNDCLASSEX), // 窗口类的内存空间大小(字节)        CS_CLASSDC, // 窗口风格        MsgProc, // 处理消息的函数指针        0, // 类额外信息        0, // 窗口额外信息        hInstance, // 句柄,可以看作是窗口的身份标识        nullptr, // 图标样式        nullptr, // 鼠标样式        nullptr, // 背景画刷 也可以设置为一个颜色值 调用UnregisterClass后由系统删除        nullptr, // 菜单        "AppClass", // 窗口类名         nullptr // 窗口小图标    };    // 注册窗口类    RegisterClassEx(&wc);    // 创建窗口    HWND hWnd = CreateWindow(        "AppClass", // 窗口类名        "Window Title", // 窗口标题        WS_OVERLAPPEDWINDOW, // 窗口风格 (可重叠)        100, // 窗口左上角在屏幕坐标中的X值        100, // 窗口左上角在屏幕坐标中的Y值        WINDOW_WIDTH, // 窗口宽度        WINDOW_HEIGHT, // 窗口高度        GetDesktopWindow(), // 窗口父类        nullptr, // 菜单        hInstance, // 句柄        nullptr        );    if (InitializeD3D(hWnd))    {        // 设置指定窗口为显示状态        ShowWindow(hWnd, SW_SHOWDEFAULT);        // 发送绘制消息给窗口        UpdateWindow(hWnd);        MSG msg;        ZeroMemory(&msg, sizeof(msg));        while (msg.message != WM_QUIT)        {            if (PeekMessage(                &msg, // 存储消息的结构体指针                nullptr, // 窗口消息和线程消息都会被处理                 0, // 消息过滤最小值; 为0时返回所有可用信息                0, // 消息过滤最大值; 为0时返回所有可用信息                PM_REMOVE // 指定消息如何处理; 消息在处理完后从队列中移除                ))            {                TranslateMessage(&msg); // 变换虚拟键消息到字符消息,字符消息被发送到调用线程的消息队列                DispatchMessage(&msg); // 派发消息到窗口过程            }            else            {                // 渲染场景                RenderScene();            }        }    }    // 释放D3D对象和D3D设备对象资源    ShutdownD3D();    // 注销窗口类,释放窗口所占用资源    UnregisterClass("AppClass", wc.hInstance);}/************************************************************************//* 窗口消息处理过程                                                                     *//************************************************************************/LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch (msg)    {    case WM_DESTROY:        PostQuitMessage(0);        return 0;        break;    default:        break;    }    // windows消息的默认处理函数    return DefWindowProc(hWnd, msg, wParam, lParam);}/************************************************************************//* 初始化D3D对象和D3D设备对象*//************************************************************************/bool InitializeD3D(HWND hWnd){    // 显示模式 (以像素为单位的屏幕宽高,刷新频率,surface formt)    D3DDISPLAYMODE displayMode;    // 创建D3D对象 获取主显卡硬件信息  最先被创建,最后被释放    g_D3D = Direct3DCreate9(D3D_SDK_VERSION);    if (g_D3D == nullptr)    {        return false;    }    // 获取显示模式    if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT/*查询主显卡*/, &displayMode)))    {        return false;    }    // D3D 显示参数    D3DPRESENT_PARAMETERS d3dpp;    ZeroMemory(&d3dpp, sizeof(d3dpp));    d3dpp.Windowed = true; // 是否窗口化    d3dpp.BackBufferFormat = displayMode.Format;  // D3DFMT_X8R8G8B8  表示为32位RGB像素格式 每种颜色用一个字节表示    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 帧缓冲区交换方式; 可能是COPY可能是FLIP,由设备来确定适合当前情况的方式    // 创建D3D设备对象 ---- 代表显卡    if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))    {        return false;    }    // 初始化图形对象需要的顶点数据    if (!InitializeObjects())    {        return false;    }    return true;}/************************************************************************//* 释放D3D对象及设备对象资源*//************************************************************************/void ShutdownD3D(){    if (g_D3DDevice != nullptr)    {        g_D3DDevice->Release(); // 释放设备对象        g_D3DDevice = nullptr;    }    if (g_VertexBuffer != nullptr)    {        g_VertexBuffer->Release(); // 释放顶点缓存        g_VertexBuffer = nullptr;    }    if (g_D3D != nullptr)    {        g_D3D->Release(); // 最行创建, 最后释放        g_D3D = nullptr;    }}/************************************************************************//* 渲染场景                                                             *//************************************************************************/void RenderScene(){    g_D3DDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    g_D3DDevice->BeginScene();    // 通知D3D设备对象数据源    g_D3DDevice->SetStreamSource(        0,        g_VertexBuffer, // 数据源地址        0, // 顶点缓存起始偏移        sizeof(stD3DVertex) // 每个顶点数据的大小        );    g_D3DDevice->SetFVF(D3DFVF_VERTEX);    // 绘制图元    g_D3DDevice->DrawPrimitive(        D3DPT_TRIANGLELIST,  // 图元类型; 三角形        0, // 要加载的第一个顶点的索引        1 // 图元数量, 由图元类型决定(一个三角形)        );    g_D3DDevice->EndScene();    // 显示backbuffer内容到屏幕    g_D3DDevice->Present(nullptr, nullptr, nullptr, nullptr);}/************************************************************************//* 初始化顶点数据                                                        *//************************************************************************/bool InitializeObjects(){    // 计算正交投影矩阵 左手坐标系    D3DXMatrixOrthoLH(        &g_ortho,        WINDOW_WIDTH,        WINDOW_HEIGHT,        0.1f, // 近裁剪面        1000.f // 远裁剪面        );        // 设置投影变换    g_D3DDevice->SetTransform(        D3DTS_PROJECTION, // 标识为投影变换        &g_ortho // 变幻矩阵        );        // 设置光照    g_D3DDevice->SetRenderState(        D3DRS_LIGHTING, // 渲染状态类型; 光照        FALSE // 不使用光照        );    // 裁剪 (背面剔除)    g_D3DDevice->SetRenderState(        D3DRS_CULLMODE,        D3DCULL_NONE // 不进行背面剔除        );    // 三角形顶点数据    stD3DVertex objData[] =     {        {-150.f, -150.f, 0.1f, D3DCOLOR_XRGB(255, 255, 0)}, // 本地坐标系,也称模型坐标        {150.f, -150.f, 0.1f, D3DCOLOR_XRGB(255, 0, 0)},        {0.f, 150.f, 0.1f, D3DCOLOR_XRGB(0, 0, 255)}    };    // 创建顶点缓存    if (FAILED(        g_D3DDevice->CreateVertexBuffer(            sizeof(objData), // 顶点缓冲区的大小            0, // 顶点缓存的处理取决于D3D设备和顶点缓冲区是如何创建的(硬处理 or 软处理) 创建的设备对象为 D3DCREATE_HARDWARE_VERTEXPROCESSING 则此值必须为0            D3DFVF_VERTEX, // 顶点格式            D3DPOOL_DEFAULT, // 默认使用显卡显存            &g_VertexBuffer, // 顶点缓存指针            nullptr // 保留值, 适用于Vista以上系统中资源分享            )))    {        return false;    }    void* ptr = nullptr; // 顶点缓存地址    // 在显存中获取一块显存空间用于存储顶点数据    if (FAILED(g_VertexBuffer->Lock(        0, // 全部缓存        sizeof(objData), // 顶点数据大小        (void**)&ptr, // 将顶点数据首地址返回给ptr指针        0 // 锁定标记        )))    {        return false;    }    // 将顶数数据复制到顶点缓存里(显存)    memcpy(ptr, objData, sizeof(objData));    g_VertexBuffer->Unlock(); // 解锁顶点缓存    return true;}




0 0