D3D画文字

#include <Windows.h>
#include <D3D9.h>
#include <D3dx9tex.h>
#pragma comment(lib, "D3D9.lib")
#pragma  comment(lib, "D3dx9.lib")

const TCHAR *kClassName = L"Rectangle_D3D";

IDirect3D9 *d3d9 = nullptr;
IDirect3DDevice9 *device9 = nullptr;
IDirect3DVertexBuffer9 *vectex_buffer9 = nullptr; 
D3DPRESENT_PARAMETERS params;

BOOL window_mode = TRUE;
HINSTANCE kInstance = nullptr;

#define D3D_FVF_VECTOR (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2)
const int kWndWidth = 640;
const int kWndHeight = 480;
const int kTextureWidth = 256;
const int kTextureHeight = 256;

struct Vector {
    Vector(float v_x, float v_y, float v_z, DWORD c, float v_u, float v_v, float v_u2, float v_v2)
        : x(v_x),
          y(v_y),
          z(v_z),
          color(c),
          u(v_u),
          v(v_v),
          text_u(v_u2),
          text_v(v_v2) {
        rhw = 1.0f;
    }
    float x, y, z, rhw;
    DWORD color;
    float u, v;
    float text_u, text_v;//文字纹理
};

LRESULT CALLBACK WindowProc(
    _In_ HWND   hwnd,
    _In_ UINT   uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    );

bool InitD3D(HWND hwnd);//初始化
bool Done();//完成
bool ReDrawRectangle();
void DrawTextTexture(HWND hwnd);
void DrawPicTexture(HWND hwnd);

int CALLBACK WinMain(
    _In_ HINSTANCE hInstance,
    _In_ HINSTANCE hPrevInstance,
    _In_ LPSTR     lpCmdLine,
    _In_ int       nCmdShow
    ) {

    kInstance = hInstance;
    //init app
    WNDCLASSEX wndclassex;
    wndclassex.cbSize = sizeof(WNDCLASSEX);
    wndclassex.style = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc = WindowProc;
    wndclassex.cbClsExtra = 0;
    wndclassex.cbWndExtra = 0;
    wndclassex.hInstance = hInstance;
    wndclassex.hIcon = nullptr;
    wndclassex.hCursor = LoadCursor(hInstance, IDC_ARROW);
    wndclassex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndclassex.lpszMenuName = nullptr;
    wndclassex.lpszClassName = kClassName;
    wndclassex.hIconSm = nullptr;
    RegisterClassEx(&wndclassex);

    HWND  hwnd = CreateWindowEx(0, kClassName, L"斧王报道,中路英雄失踪", WS_OVERLAPPEDWINDOW, 100, 100, 640, 480, nullptr, nullptr, hInstance, nullptr);

    ShowWindow(hwnd, nCmdShow);

    InitD3D(hwnd);
    UpdateWindow(hwnd);
    MSG msg;
    while (true) {
        if (PeekMessage(&msg,nullptr, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT) {
                break;
            }
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }
    Done();
    return 0;
}

LRESULT CALLBACK WindowProc(
    _In_ HWND   hwnd,
    _In_ UINT   uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    ) {
       
      PAINTSTRUCT ps;
      HDC hdc;
      if (uMsg == WM_PAINT) {
          hdc = BeginPaint(hwnd, &ps);
            ReDrawRectangle();
          EndPaint(hwnd, &ps);
      } else if (uMsg == WM_KEYDOWN) {
          if (wParam == VK_SPACE) {
              //空格键
              //全屏模式<-->窗口模式之间切换
              window_mode = !window_mode;
              D3DDISPLAYMODE mode;
              if (!window_mode) {
                  UINT adapter_mode_count = d3d9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
                  for (UINT adapter_mode = 0; adapter_mode < adapter_mode_count; ++adapter_mode) {
                      d3d9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, adapter_mode, &mode);
                      if (mode.Width == kWndWidth && mode.Height == kWndHeight) {
                          break;
                      }
                  }
              }
              if (!window_mode && (mode.Width != kWndWidth || mode.Height != kWndHeight)) {
                  return DefWindowProc(hwnd, uMsg, wParam, lParam);
              }
              if (nullptr != device9) {
                  params.BackBufferWidth = window_mode ? kWndWidth : mode.Width;
                  params.BackBufferHeight = window_mode ? kWndHeight : mode.Height;
                  params.Windowed = window_mode;
                  HRESULT  hr = device9->Reset(¶ms);
                  if (FAILED(hr)) {
                      int i = 0;
                  }
              }
          }
      }else if (uMsg == WM_DESTROY) {
          PostMessage(hwnd, WM_QUIT, 0, 0);
      }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

bool InitD3D(HWND hwnd) {
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
    if (nullptr == d3d9) {
        return false;
    }

    params.BackBufferWidth = kWndWidth;
    params.BackBufferHeight = kWndHeight;
    params.BackBufferFormat = D3DFMT_X8R8G8B8;
    params.BackBufferCount = 1;
    params.MultiSampleType = D3DMULTISAMPLE_NONE;
    params.MultiSampleQuality = 0;
    params.SwapEffect = D3DSWAPEFFECT_COPY;
    params.hDeviceWindow = hwnd;
    params.Windowed = window_mode;
    params.EnableAutoDepthStencil = FALSE;
    params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
    params.Flags = 0;
    params.FullScreen_RefreshRateInHz = 0;
    params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    HRESULT hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, &device9);
    if (FAILED(hr)) {
        return false;
    }

    device9->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    device9->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    device9->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    device9->SetRenderState(D3DRS_LIGHTING, false);
    hr = device9->CreateVertexBuffer(12 * sizeof(Vector), 0, D3D_FVF_VECTOR, D3DPOOL_SYSTEMMEM, &vectex_buffer9, nullptr);
    if (FAILED(hr)) {
        return false;
    }
    
   // DrawText2(hwnd);
    
    Vector *vectors; 
    vectex_buffer9->Lock(0, 0, (void**)&vectors, 0);
    //创建Rectangle
    vectors[0] = Vector(220, 340, 0, 0xffFFFFFF, 0, 1, 0, 1);
    vectors[1] = Vector(220, 140, 0, 0xffFFFFFF, 0, 0, 0, 0);
    vectors[2] = Vector(420, 140, 0, 0xffFFFFFF, 1, 0, 1, 0);
    vectors[3] = Vector(220, 340, 0, 0xffFFFFFF, 0, 1, 0, 1);
    vectors[4] = Vector(420, 140, 0, 0xffFFFFFF, 1, 0, 1, 0);
    vectors[5] = Vector(420, 340, 0, 0xffFFFFFF, 1, 1, 1, 1);
    vectex_buffer9->Unlock();

    DrawPicTexture(hwnd);
    DrawTextTexture(hwnd);
    device9->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
    return true;
}

void DrawPicTexture(HWND hwnd) {
    //加载图片
    HDC mem_dc = CreateCompatibleDC(NULL);
    HBITMAP hbitmap = static_cast<HBITMAP>(::LoadImage(kInstance, L"texture.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
    HBITMAP old_bitmap = static_cast<HBITMAP>(SelectObject(mem_dc, hbitmap));
    BITMAP bmp;
    GetObject(hbitmap, sizeof(BITMAP), (LPBYTE)&bmp);
    IDirect3DSurface9 *surface9 = nullptr;
   HRESULT hr = device9->CreateOffscreenPlainSurface(bmp.bmWidth, bmp.bmHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface9, nullptr);
    if (FAILED(hr)) {
        return;
    }
    DWORD pixel_pos;
    D3DLOCKED_RECT lock_rect;
    surface9->LockRect(&lock_rect, nullptr, 0);
    BYTE* surface_buffer = static_cast<BYTE*>(lock_rect.pBits);
    for (int h = 0; h < bmp.bmHeight; ++h) {
        for (int w = 0; w < bmp.bmWidth; ++w) {
            COLORREF color = GetPixel(mem_dc, w, h);
            DWORD red = GetRValue(color);
            DWORD green = GetGValue(color);
            DWORD blue = GetBValue(color);
            red <<= 16;
            green <<= 8;
            DWORD dwColor = red | green | blue;
            pixel_pos = h * lock_rect.Pitch + w * 4;
            memcpy(&surface_buffer[pixel_pos], &dwColor, 4);
        }
    }
    surface9->UnlockRect();
    SelectObject(mem_dc, old_bitmap);
    ReleaseDC(hwnd, mem_dc);

    device9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    device9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    //    创建纹理
    IDirect3DTexture9 *texture9 = nullptr;
    hr = device9->CreateTexture(kTextureWidth, kTextureHeight, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture9, 0);
    if (FAILED(hr)) {
        surface9->Release();
        return;
    }
    IDirect3DSurface9 *texture_surface9 = nullptr;
    texture9->GetSurfaceLevel(0, &texture_surface9);
    RECT src;
    ::SetRect(&src, 0, 0, kTextureWidth, kTextureHeight);
    POINT dest;
    dest.x = 0;
    dest.y = 0;
    hr = device9->UpdateSurface(surface9, &src, texture_surface9, &dest);
    texture_surface9->Release();
    if (FAILED(hr)) {
        surface9->Release();
        return;
    }
    device9->SetTexture(0, texture9);

    surface9->Release();
}

void DrawTextTexture(HWND hwnd) {
    HDC hDc = ::CreateCompatibleDC(NULL);                    // 通过当前桌面创建设备内容HDC
    SetTextColor(hDc, RGB(255, 255, 255));                          // 设置背景颜色和文字的颜色
    SetBkColor(hDc, 0xFFFF0000);

    LOGFONT lf;
    ZeroMemory(&lf, sizeof(LOGFONT));
    lf.lfHeight = 25;
    lf.lfWidth = 0;
    HFONT   hFont = CreateFontIndirect(&lf);              // 创建大小为72的字体

    SelectObject(hDc, hFont);
    SIZE sz;
    GetTextExtentPoint32(hDc, L"斧王报道,中路英雄失踪", lstrlen(L"斧王报道,中路英雄失踪"), &sz);

    DWORD* pBitmapBits;                                                        //  创建一个位图
    BITMAPINFO bitmapInfo;
    ZeroMemory(&bitmapInfo.bmiHeader, sizeof(BITMAPINFOHEADER));
    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfo.bmiHeader.biWidth = kTextureWidth;
    bitmapInfo.bmiHeader.biHeight = kTextureHeight;
    bitmapInfo.bmiHeader.biPlanes = 1;
    bitmapInfo.bmiHeader.biCompression = BI_RGB;
    bitmapInfo.bmiHeader.biBitCount = 32;

    HBITMAP hBitmap = CreateDIBSection(hDc, &bitmapInfo, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
    SelectObject(hDc, hBitmap);                            // 将位图与HDC关联,这样文字时间上就保存在hBitmap里面了

    TextOut(hDc, 6, 100, L"斧王报道,中路英雄失踪", lstrlen(L"斧王报道,中路英雄失踪"));
    BITMAP bmp;
    GetObject(hBitmap, sizeof(BITMAP), &bmp);

    IDirect3DSurface9 *surface9 = nullptr;
   HRESULT hr = device9->CreateOffscreenPlainSurface(kTextureWidth, kTextureHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface9, nullptr);
    if (FAILED(hr)) {
        return;
    }
    DWORD pixel_pos;
    D3DLOCKED_RECT lock_rect;
    surface9->LockRect(&lock_rect, nullptr, 0);
    BYTE* surface_buffer = static_cast<BYTE*>(lock_rect.pBits);
    for (int h = 0; h < kTextureHeight; ++h) {
        for (int w = 0; w < kTextureWidth; ++w) {
            COLORREF color = GetPixel(hDc, w, h);
            DWORD red = GetRValue(color);
            DWORD green = GetGValue(color);
            DWORD blue = GetBValue(color);
            red <<= 16;
            green <<= 8;
            DWORD dwColor = red | green | blue;
            pixel_pos = h * lock_rect.Pitch + w * 4;
            memcpy(&surface_buffer[pixel_pos], &dwColor, 4);
        }
    }
    surface9->UnlockRect();

    //创建纹理
    IDirect3DTexture9 *texture9x = nullptr;
    hr = device9->CreateTexture(kTextureWidth, kTextureHeight, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture9x, 0);
    if (FAILED(hr)) {
        surface9->Release();
        return;
    }
    IDirect3DSurface9 *texture_surface9 = nullptr;
    texture9x->GetSurfaceLevel(0, &texture_surface9);
    RECT src;
    ::SetRect(&src, 0, 0, kTextureWidth, kTextureHeight);
    POINT dest;
    dest.x = 0;
    dest.y = 0;
    hr = device9->UpdateSurface(surface9, &src, texture_surface9, &dest);
    texture_surface9->Release();
    if (FAILED(hr)) {
        surface9->Release();
        return;
    }
    hr = device9->SetTexture(1, texture9x);

    surface9->Release();

    DeleteObject(hFont);
    DeleteObject(hBitmap);
    DeleteDC(hDc);

 //   surface9->Release();
    

}

bool ReDrawRectangle() {
    if (nullptr == device9) {
        return false;
    }
    device9->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 255, 255, 255), 0.0f, 0);
    device9->SetStreamSource(0, vectex_buffer9, 0, sizeof(Vector));
    device9->SetFVF(D3D_FVF_VECTOR);
    device9->BeginScene();
    device9->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
    device9->EndScene();
    device9->Present(0, 0, 0, 0);
    return true;
}

bool Done() {
    if (nullptr != vectex_buffer9) {
        vectex_buffer9->Release();
    }
    if (nullptr != device9) {
        device9->Release();
    }
    if (nullptr != d3d9) {
        d3d9->Release();
    }
    return true;
}


效果图如下:


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值