从零开始写渲染器(1):创建一个窗口

前言:

不知不觉,我已经开始上大学了,从零开始写个渲染器在我几年前就有这个想法了,无奈由于种种原因一直没有深入的研究下去(懒)。或许是自己认为,要想理解图形学,最好的做法是写个渲染器。由于自己是弄虚幻4的,在虚幻4里,自己搭建个美如画的场景对我来说已经是十分简单了,但是知其然而不知其所以然是无法透彻理解这些精美的画面背后蕴藏的知识的,在查阅相关资料后,决定自己动手做一个渲染器,潜入这些精美漂亮的画面的背后所蕴含的数学和物理知识的海洋,去发现其中的奥秘。

 

正文:

第一步当然得首先有个开发环境了,我这里用的IDE是VS2019,图形api的话是使用DirectX来进行绘制渲染。

在安装vs2019,请将c++桌面开发与c++游戏开发勾上

 

安装完成后我们创建windows桌面程序,如下图

 

 

成功后我们将其所含的代码全部删除,因为我们要自己建一个窗口。

然后我们讲这份代码复制上去,一一讲解。

// include the basic windows header file
#include <windows.h>
#include <windowsx.h>

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// the handle for the window, filled by a function
HWND hWnd;
// this struct holds information for the window class
WNDCLASSEX wc;

// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));

// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;//
wc.hInstance = hInstance;//窗口句柄附加到程序句柄上
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//加载鼠标指针
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;//
wc.lpszClassName = L"WindowClass1";

// register the window class
RegisterClassEx(&wc);

// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"WindowClass1", // name of the window class
L"my windows", // title of the window
WS_OVERLAPPEDWINDOW, // window style
300, // x-position of the window
300, // y-position of the window
500, // width of the window
400, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL); // used with multiple windows, NULL

// display the window on the screen
ShowWindow(hWnd, nCmdShow);

// enter the main loop:

// this struct holds Windows event messages
MSG msg;

// wait for the next message in the queue, store the result in 'msg'
while (GetMessage(&msg, NULL, 0, 0))
{
// translate keystroke messages into the right format
TranslateMessage(&msg);

// send the message to the WindowProc function
DispatchMessage(&msg);
}

// return this part of the WM_QUIT message to Windows
return msg.wParam;
}

// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// sort through and find what code to run for the message given
switch (message)
{
// this message is read when the window is closed
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
} break;
}

// Handle any messages the switch statement didn't
return DefWindowProc(hWnd, message, wParam, lParam);
}

 

首先是头文件

 

 

#include<windows.h>
#include<windowsx.h>

两个头文件包含了大量的宏和常量,在窗口程序里,能让Windows编程更方便。

 

之后是主要部分,Windows应用程序的主入口

WinMain()

 

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)

 

第一个参数是窗口句柄,窗口句柄可以理解为程序的数字名字,系统要想控制操作相应程序,都得先获得相应的程序句柄(数字名字)才行,

举个例子就是班主任(操作系统)可以通过喊名字(获取句柄)分配学生干着干那。

第二个是当前实例的前一个实例的句柄,没用忽略,因为已经过时了,参数总是null

LPSTR IpCmdLine 一个字符串,用来传梯给应用程序的命令行参数,如一个文件是txt,我们双击他,会启动文本程序(txt查看器)然后讲txt的作为命令行参数传给文本程序的winmain函数,程序得到路径后,就会显示相应的内容了。

举个例子:当我们有pdf文件,但没有查看器,就看不了pdf,而有的话(我们的程序)将通过这个参数获取pdf文件的路径,然后打开查看(不知道解释听懂没)

Int nCmdShow 程序开始运行时的状态,是最大还是最小化,(通常不用它

 

接下来我们要弄窗口了。

弄窗口有三个步骤:

注册窗口

HWND hWnd;

WNDCLASSEX wc;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass1";

// register the window class
RegisterClassEx(&wc);

创建窗口

// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"WindowClass1",
L"my windows", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口风格
300, // 窗口位置x坐标
300, // 窗口位置y坐标
500, // 窗口宽度
400, // 窗口高度
NULL,
NULL,
hInstance,
NULL);

和显示窗口

ShowWindow(hWnd, nCmdShow);

 

 

 

 

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像