zoukankan      html  css  js  c++  java
  • DirectX API 编程起步 #02 窗口的诞生

     在这篇文章里我们先用 windows API 制作一个窗口出来,以后再用 DirectX API 渲染的东西就会显示在这里,控制台那黑白的画面肯定是没法用的。

    每次的代码都会更新到Github 

    首先贴出来目前为止的文件结构图,由上到下表示#include“XXXXX”关系

    系统头文件的调用不包含在内

    由于.h和.cpp都是对应出现的,我就不写的那么详细了

    Main.cpp 是调用 SoftwareClass 类的主函数。

    那么我们从上往下开始吧。

    Main.cpp

    由于只用调用接下来的类成员函数就行,所以这个代码非常简单。

     1 ////////////////
     2 // Main.cpp //
     3 ////////////////
     4 #include"SoftwareClass.h"
     5 
     6 /*********************************
     7 这里是整个程序的入口函数
     8 WinMain
     9 仅适用于Win32编程
    10 **********************************/
    11 
    12 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR pScmdline,int nCmdshow)
    13 {
    14     //新建类指针
    15     SoftwareClass *Software;
    16     //new一个类出来
    17     Software = new SoftwareClass;
    18     //初始化、运行、结束该程序
    19     if (Software->Initialize())
    20     {
    21         Software->Run();
    22     }
    23     Software->Shutdown();
    24     //删除并清理类指针
    25     delete Software;
    26     Software = NULL;
    27     return 0;
    28 }

    SoftwareClass

    接下来就是重点的主要类SoftwareClass,它管理着这个程序的生杀大权,并调用InputClass(记录输入的类)和GraphicsClass(渲染图形的类)来完成更高级的操作。

     首先是他的header

    SoftwareClass.h

     1 ////////////////////////
     2 // SoftwareClass.h //
     3 ///////////////////////
     4 
     5 /*******************************
     6 该类包含整个程序运行所需的功能
     7 ********************************/
     8 
     9 #ifndef _SOFTWARECLASS_H_
    10 #define _SOFTWARECLASS_H_
    11 
    12 //////////////
    13 // include //
    14 //////////////
    15 #include<Windows.h>
    16 
    17 //////////////////
    18 // File include //
    19 //////////////////
    20 #include"InputClass.h"
    21 #include"GraphicsClass.h"
    22 
    23 /////////////////////////
    24 // Class Declaration //
    25 /////////////////////////
    26 class SoftwareClass
    27 {
    28 public:
    29     //默认构造,复制,析构函数
    30     SoftwareClass();
    31     SoftwareClass(const SoftwareClass&);
    32     ~SoftwareClass();
    33 
    34     bool Initialize();//初始化
    35     void Shutdown();//关闭
    36     void Run();//运行
    37 
    38     //主要消息处理函数
    39     //系统级消息丢给另外的一个WndProc
    40     //比如窗口的关闭等消息
    41     LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
    42 
    43 //以下为私有成员函数
    44 private:
    45     bool Frame();
    46     //创建窗口最重要的函数
    47     void InitializeWindows(int&, int&);
    48     void ShutdownWindows();
    49 //以下为私有数据成员
    50 private:
    51     //创建窗口程序需要的参数,无需过度关心
    52     LPCWSTR m_SoftwareName;
    53     HINSTANCE m_hinstance;
    54     HWND m_hwnd;
    55 
    56     //m_* 代表成员数据
    57     InputClass *m_Input;
    58     GraphicsClass *m_Graphics;
    59 };
    60 
    61 ////////////////////////
    62 // Static Function //
    63 ///////////////////////
    64 
    65 //次要消息处理函数
    66 //用于处理系统级消息
    67 static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    68 
    69 /////////////
    70 // Global //
    71 /////////////
    72 
    73 //用于消息处理函数的调用
    74 //因为我们有两个
    75 //所以需要这个静态变量指向该类
    76 static SoftwareClass *SoftwareHandle = NULL;
    77 
    78 #endif

    SoftwareClass.cpp

    接着是他的.cpp

      1 ///////////////////////////
      2 // SoftwareClass.cpp //
      3 //////////////////////////
      4 #include "SoftwareClass.h"
      5 
      6 //////////////////////////////////////////////////////////
      7 SoftwareClass::SoftwareClass()
      8 {
      9     m_hinstance = NULL;
     10     m_hwnd = NULL;
     11     m_SoftwareName = NULL;
     12 
     13     m_Input = NULL;
     14 }
     15 SoftwareClass::SoftwareClass(const SoftwareClass &other)
     16 {
     17 }
     18 SoftwareClass::~SoftwareClass()
     19 {
     20 }
     21 //////////////////////////////////////////////////////////
     22 
     23 bool SoftwareClass::Initialize()
     24 {
     25     int screenWidth, screenHeight;
     26     bool result;
     27 
     28     screenHeight = 0;
     29     screenWidth = 0;
     30     InitializeWindows(screenWidth, screenHeight);
     31 
     32     //new一个输入处理类
     33     m_Input = new InputClass;
     34     if (!m_Input)
     35     {
     36         return false;
     37     }
     38     m_Input->Initialize();
     39 
     40     //new一个图形处理类
     41     m_Graphics = new GraphicsClass;
     42     if (!m_Graphics)
     43     {
     44         return false;
     45     }
     46 
     47     //由于图形类涉及到窗口的创建
     48     //容易失败
     49     //因此测试一下new是否成功
     50     result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
     51     if (!result)
     52     {
     53         return false;
     54     }
     55 
     56     return true;
     57 }
     58 
     59 //先清除输入类和图形类
     60 //再关闭窗口程序
     61 void SoftwareClass::Shutdown()
     62 {
     63     if (m_Graphics)
     64     {
     65         m_Graphics->Shutdown();
     66         delete m_Graphics;
     67         m_Graphics = NULL;
     68     }
     69 
     70     if (m_Input)
     71     {
     72         delete    m_Input;
     73         m_Input = NULL;
     74     }
     75 
     76     ShutdownWindows();
     77 }
     78 
     79 //消息的翻译分配在此
     80 void SoftwareClass::Run()
     81 {
     82     MSG msg;
     83     bool done, result;
     84     done = false;
     85 
     86     ZeroMemory(&msg, sizeof(MSG));
     87 
     88     //程序的最主要循环
     89     //不停地渲染、输出画面
     90     while (!done)
     91     {
     92         //消息队列的查找
     93         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
     94         {
     95             TranslateMessage(&msg);
     96             DispatchMessage(&msg);
     97         }
     98         
     99         //这说明PostQuitMessage被调用了
    100         if (msg.message == WM_QUIT)
    101         {
    102             done = true;
    103         }
    104         else
    105         {
    106             result = Frame();
    107             if (!result)
    108             {
    109                 done = true;
    110             }
    111         }
    112     }
    113 }
    114 
    115 LRESULT SoftwareClass::MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    116 {
    117     switch (msg)
    118     {
    119     case WM_KEYDOWN:
    120         m_Input->KeyDown((unsigned int)wParam);
    121 
    122         //当ESC被按下时,退出程序
    123         if (wParam == VK_ESCAPE)
    124         {
    125             PostQuitMessage(0);
    126         }
    127         return 0;
    128     case WM_KEYUP:
    129         m_Input->KeyUp((unsigned int)wParam);
    130         return 0;
    131     default:
    132         return DefWindowProc(hwnd, msg, wParam, lParam);
    133     }
    134 }
    135 
    136 bool SoftwareClass::Frame()
    137 {
    138     bool result;
    139 
    140     result = m_Graphics->Frame();
    141     if (!result)
    142     {
    143         return false;
    144     }
    145     return true;
    146 }
    147 
    148 //窗口程序的创建,注册,显示
    149 void SoftwareClass::InitializeWindows(int &screenWidth, int &screenHeight)
    150 {
    151     WNDCLASSEX wc = {};
    152     DEVMODE dmScreenSettings;
    153     int posX, posY;
    154 
    155     //赋值那个静态变量
    156     //指向该类
    157     SoftwareHandle = this;
    158     //别管
    159     m_hinstance = GetModuleHandle(NULL);
    160     //由于Unicode的原因
    161     //所有字符串要用 TEXT() 括起来
    162     m_SoftwareName = TEXT("MyShabbyEngine");
    163 
    164     //填写对象wc的有关信息
    165     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    166     //该窗口的消息处理函数
    167     wc.lpfnWndProc = WndProc;
    168     //以下全部不用管
    169     wc.cbClsExtra = 0;
    170     wc.cbWndExtra = 0;
    171     wc.hInstance = m_hinstance;
    172     wc.hIcon = NULL;
    173     wc.hIconSm = NULL;
    174     wc.hCursor = NULL;
    175     wc.lpszMenuName = NULL;
    176     //设置程序窗口背景
    177     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    178     //类名,意义不明
    179     wc.lpszClassName = m_SoftwareName;
    180     //这步绝不能漏了
    181     wc.cbSize = sizeof(WNDCLASSEX);
    182 
    183     //向系统注册该窗口
    184     RegisterClassEx(&wc);
    185 
    186     //从系统得到显示的分辨率
    187     screenWidth = GetSystemMetrics(SM_CXSCREEN);
    188     screenHeight = GetSystemMetrics(SM_CYSCREEN);
    189 
    190     //如果GraphicsClass文件里设置为全屏
    191     if (FULL_SCREEN)
    192     {
    193         memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
    194         dmScreenSettings.dmSize = sizeof(dmScreenSettings);
    195         dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;
    196         dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
    197         dmScreenSettings.dmBitsPerPel = 32;
    198         dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
    199 
    200         ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
    201 
    202         posX = posY = 0;
    203     }
    204     else
    205     {
    206         screenWidth = 800;
    207         screenHeight = 600;
    208 
    209         posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;
    210         posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
    211     }
    212 
    213     //在显示屏创建窗口
    214     //无边框
    215     m_hwnd = CreateWindowEx(WS_EX_APPWINDOW,
    216         m_SoftwareName, m_SoftwareName,
    217         WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
    218         posX, posY, screenWidth, screenHeight,
    219         NULL, NULL, m_hinstance, NULL);
    220 
    221     //将窗口显示出来
    222     ShowWindow(m_hwnd, SW_SHOW);
    223     SetFocus(m_hwnd);
    224 
    225     ShowCursor(false);
    226 }
    227 
    228 void SoftwareClass::ShutdownWindows()
    229 {
    230     //显示鼠标指针
    231     ShowCursor(true);
    232 
    233     if (FULL_SCREEN)
    234     {
    235         ChangeDisplaySettings(NULL, 0);
    236     }
    237 
    238     DestroyWindow(m_hwnd);
    239     m_hwnd = NULL;
    240 
    241     UnregisterClass(m_SoftwareName, m_hinstance);
    242     m_hinstance = NULL;
    243 
    244     SoftwareHandle = NULL;
    245 }
    246 
    247 LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    248 {
    249     switch (Msg)
    250     {
    251     case WM_DESTROY:
    252     case WM_CLOSE:
    253         PostQuitMessage(0);
    254         return 0;
    255     default:
    256         return SoftwareHandle->MessageHandler(hWnd, Msg, wParam, lParam);
    257     }
    258 }

    InputClass

    该类监控并记录哪些键被按下

    InputClass.h

     1 ////////////////////
     2 // InputClass.h //
     3 ///////////////////
     4 
     5 /******************************
     6 该类包含记录输入按键的功能
     7 ******************************/
     8 
     9 #ifndef _INPUTCLASS_H_
    10 #define _INPUTCLASS_H_
    11 
    12 /////////////////////////
    13 // Class Declaration //
    14 /////////////////////////
    15 class InputClass
    16 {
    17 public:
    18     //默认构造、复制、析构函数
    19     InputClass();
    20     ~InputClass();
    21     InputClass(const InputClass&);
    22     //初始化
    23     void Initialize();
    24     //当按键被按下或抬起时调用
    25     void KeyDown(unsigned int);
    26     void KeyUp(unsigned int);
    27     //检测某键是否被按下
    28     bool IsKeyDown(unsigned int);
    29 private:
    30     //储存哪些键被按下
    31     //true表示正被按下
    32     bool m_keys[256];
    33 };
    34 
    35 #endif

    Input.cpp

     1 ////////////////////
     2 // InputClass.cpp //
     3 ///////////////////
     4 #include "InputClass.h"
     5 
     6 InputClass::InputClass()
     7 {
     8 }
     9 InputClass::~InputClass()
    10 {
    11 }
    12 InputClass::InputClass(const InputClass &other)
    13 {
    14 }
    15 
    16 //初始化按键表
    17 void InputClass::Initialize()
    18 {
    19     int i;
    20     for (i = 0; i < 256; i++)
    21     {
    22         m_keys[i] = false;
    23     }
    24 }
    25 
    26 void InputClass::KeyDown(unsigned int input)
    27 {
    28     //将该键设为true
    29     m_keys[input] = true;
    30 }
    31 
    32 void InputClass::KeyUp(unsigned int input)
    33 {
    34     //将该键设为false
    35     m_keys[input] = false;
    36 }
    37 
    38 bool InputClass::IsKeyDown(unsigned int key)
    39 {
    40     return m_keys[key];
    41 }

    GraphicsClass

    最后是GraphicsClass,由于目前只做了窗口的显示,其实还并未涉及到任何 DirectX 的代码,所以这个类基本上是空的。

    GraphicsClass.h

     1 /////////////////////////
     2 // GraphicsClass.h //
     3 ///////////////////////
     4 
     5 /***********************
     6 该类处理图像
     7 ********************/
     8 
     9 #ifndef _GRAPHICSCLASS_H_
    10 #define _GRAPHICSCLASS_H_
    11 
    12 //////////////
    13 // include //
    14 //////////////
    15 #include<Windows.h>
    16 
    17 /////////////
    18 // Global //
    19 /////////////
    20 
    21 //是否全屏显示
    22 const bool FULL_SCREEN = false;
    23 //是否垂直同步
    24 const bool VSYNC_ENABLED = true;
    25 //场景相关数据
    26 const float SCREEN_DEPTH = 1000.0;
    27 const float SCREEN_NEAR = 0.1f;
    28 
    29 /////////////////////////
    30 // Class Declaration //
    31 ////////////////////////
    32 class GraphicsClass
    33 {
    34 public:
    35     GraphicsClass();
    36     GraphicsClass(const GraphicsClass&);
    37     ~GraphicsClass();
    38 
    39     bool Initialize(int, int, HWND);
    40     void Shutdown();
    41     bool Frame();
    42 private:
    43     bool Render();
    44 };
    45 
    46 #endif

    GraphicsClass.cpp

     1 ///////////////////////////
     2 // GraphicsClass.cpp //
     3 //////////////////////////
     4 #include "GraphicsClass.h"
     5 
     6 
     7 
     8 GraphicsClass::GraphicsClass()
     9 {
    10 }
    11 
    12 GraphicsClass::GraphicsClass(const GraphicsClass &other)
    13 {
    14 }
    15 
    16 
    17 GraphicsClass::~GraphicsClass()
    18 {
    19 }
    20 
    21 bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hWnd)
    22 {
    23     return true;
    24 }
    25 
    26 void GraphicsClass::Shutdown()
    27 {
    28 }
    29 
    30 bool GraphicsClass::Frame()
    31 {
    32     return true;
    33 }
    34 
    35 bool GraphicsClass::Render()
    36 {
    37     return true;
    38 }

     最后程序正确运行后,会在屏幕中间产生一个黑色的矩形,没有边框,也没有鼠标指针。按ESC可退出。

    我知道。。。光贴代码屁用没有。。。。。日后补上注释

  • 相关阅读:
    c语言,strcat(),字符串拼接
    c语言,strcpy
    [置顶] linux第二天,g++,gcc,ps,cat,sort,grep,kill,less,ls -l ,
    Yuchuan_Linux_C 编程之四动态库(共享库)制作
    Yuchuan_Linux_C 编程之三 静态库的制作和使用
    Yuchuan_Linux_C编程之二 GCC编译
    Yuchuan_Linux_C编程之一 Vim编辑器的使用
    testng学习笔记-- beforesuit和aftersuit
    testng学习笔记-- beforeclass和afterclass
    pom.xml
  • 原文地址:https://www.cnblogs.com/makejeffer/p/4774006.html
Copyright © 2011-2022 走看看