上一篇我们在Linux上面通过XCB创建了一个基本的窗口。
既然画布已经准备好,接下来就应该是准备画笔进行作画的阶段了。让我们在Windows和Linux这两个版本的窗口上各自绘制一个矩形。
首先我们来看Windows版本。依然回到我们的PlatformWindows目录。上一次我们是使用我们自己编译的Clang工具链进行编译的。这次我们用Visual Studio自带的cl.exe进行编译:
D:wenliSourceReposGameEngineFromScratchPlatformWindows>cl -l user32.lib helloengine_win.c
用于 x86 的 Microsoft (R) C/C++ 优化编译器 19.11.25506 版
版权所有(C) Microsoft Corporation。保留所有权利。
cl: 命令行 warning D9002 :忽略未知选项“-l”
helloengine_win.c
Microsoft (R) Incremental Linker Version 14.11.25506.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:helloengine_win.exe
user32.lib
helloengine_win.obj
可以看到,编译正常,没有任何问题。这是因为我们的代码是严格按照C/C++标准写的,Clang这方面的检查比Visual C++要严格很多,因此在Clang上面能够编译的代码,在Visual C++上面一般也是没有任何问题可以编译的。(当然,严格来说,Clang可以兼容gcc的一些gnu扩展。这些扩展是Visual C++所不能接受的。因此,并不是说Clang可以通过的代码VC++就一定能通过,这里面还有一个条件就是不要使用任何编译器特定的扩展)
好了,下面给我们的helloengine_win.c添加几行绘图指令(下面是通过git diff显示的文件变化情况。左侧有一个+号的行是本次新加的)
D:wenliSourceReposGameEngineFromScratchPlatformWindows>git diff helloengine_win.c
diff --git a/Platform/Windows/helloengine_win.c b/Platform/Windows/helloengine_win.c
index 041462a..b996344 100644
--- a/Platform/Windows/helloengine_win.c
+++ b/Platform/Windows/helloengine_win.c
@@ -77,6 +77,17 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
// sort through and find what code to run for the message given
switch(message)
{
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hWnd, &ps);
+ RECT rec = { 20, 20, 60, 80 };
+ HBRUSH brush = (HBRUSH) GetStockObject(BLACK_BRUSH);
+
+ FillRect(hdc, &rec, brush);
+
+ EndPaint(hWnd, &ps);
+ } break;
// this message is read when the window is closed
case WM_DESTROY:
{
然后编译这个程序。因为我们使用了GetStockObject这个函数,这个函数属于GDI接口(就是我前面提到过的,因为爆慢而最后导致不得不推出Direct X的接口),我们需要在编译的时候加上gdi32.lib这个库。
D:wenliSourceReposGameEngineFromScratchPlatformWindows>cl user32.lib gdi32.lib helloengine_win.c
运行生成的程序,看到如下画面:
很好,如果我们再在右边画个方块,中间画个圆圈,并且加入一点碰撞计算的代码和键盘操作代码的话,那么一个Ping-pong游戏(乒乓游戏)就完成了。那就到达了二十几岁乔布斯走过的地方:)
不过不要忘了我们目前是在图形支线任务里面。所以让我们暂时不要去管碰撞计算,也不要管键盘操作。让我们Save我们的代码,然后切换到Linux平台。
D:wenliSourceReposGameEngineFromScratchPlatformWindows>git add helloengine_win.c
D:wenliSourceReposGameEngineFromScratchPlatformWindows>git commit -m "in the middle of article_9"
[master 7f05a0e] in the middle of article_9
1 file changed, 11 insertions(+)
首先,让我们如下修改我们的helloengine_xcb.c:
diff --git a/Platform/Linux/helloengine_xcb.c b/Platform/Linux/helloengine_xcb.c
index 62cb467..7e44b48 100644
--- a/Platform/Linux/helloengine_xcb.c
+++ b/Platform/Linux/helloengine_xcb.c
@@ -75,6 +75,11 @@ int main(void) {
while((pEvent = xcb_wait_for_event(pConn)) && !isQuit) {
switch(pEvent->response_type & ~0x80) {
case XCB_EXPOSE:
+ {
+ xcb_rectangle_t rect = { 20, 20, 60, 80 };
+ xcb_poly_fill_rectangle(pConn, window, foreground, 1, &r
+ xcb_flush(pConn);
+ }
break;
case XCB_KEY_PRESS:
isQuit = 1;
@@ -83,6 +88,8 @@ int main(void) {
free(pEvent);
}
+ xcb_disconnect(pConn);
+
return 0;
最后的xcb_disconnect是上次漏掉的,补上。任何事情要善始善终,Connect了就一定要Disconnect。
注意这里有一个小小的Trick。因为我们的文件后缀名为.c,所以Clang会将我们的代码作为C代码来编译。在C代码当中,变量的定义必须出现在每个block的开始,而不能夹杂在语句之间。但是,有些变量我们只有在函数当中某个地方才会使用,放在函数体的头上也怪怪的。比如这个rect。
所以,我们在这里使用了{},将这部分声明为一个语句块,也就是block。这样我们就可以在这里面申明变量了。
当然,还有一个简便的方法。你可以把文件后缀改为.cpp。因为所有合法的.c都是合法的.cpp,而C++允许在语句中间申明变量。
不过我依然不鼓励这么做。就像我前面说的,要脱离Visual Studio。舒服的环境只会使人模棱两可。我们首先应该精确地掌握各种概念,在这个基础之上,选择舒服方便的方法,才是正确的。
好了,编译这个代码:
tim@iZuf6iup3mphicesefdwajZ:~/src/GameEngineFromScratch/Platform/Linux$ clang -lxcb -o helloengine_xcb helloengine_xcb.c
执行它,看到如下画面:
好了,我们在Linux上面也实现了同样的效果。保存我们的代码,准备迈出下一步。
tim@iZuf6iup3mphicesefdwajZ:~/src/GameEngineFromScratch/Platform/Linux$ git status
# On branch article_8
# Your branch is ahead of 'origin/article_8' by 1 commit.
# (use "git push" to publish your local commits)
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: helloengine_xcb.c
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# helloengine_xcb
no changes added to commit (use "git add" and/or "git commit -a")
tim@iZuf6iup3mphicesefdwajZ:~/src/GameEngineFromScratch/Platform/Linux$ git add helloengine_xcb.c
tim@iZuf6iup3mphicesefdwajZ:~/src/GameEngineFromScratch/Platform/Linux$ git commit -m "end of article_9"
[article_8 c502b89] end of article_9
1 file changed, 7 insertions(+)
参考引用: