3D 游戏编程大师(一) 环境搭建篇

来源:互联网 发布:广电网络10兆宽带快吗 编辑:程序博客网 时间:2024/05/17 04:04

前言

适合的读者:
不怕折腾 喜欢从难开始学习.

先说下为何要做软件渲染器吧?
主要有以下几方面原因:
1. 对图形底层有深厚的兴趣
2. 掌握底层可以方便的切换框架
3. 编程更加灵活

做为一个新手,还是要从书籍中的模仿开始了.
我选择的是一本老书3D游戏编程大师. 主线应该会遵从书上的顺序,但是实现细节等很多可能会不一样,走一步看一步吧.

这本书上主要是用老版的dx和老版的编译器. 搭建真的很麻烦而且总会出很多问题. 我突发奇想是否能用mingw来搭建. 耗时一天,现在分享给大家.

准备环境

首先准备一个DX9的SDK(下载地址). 密码 4c2a
然后下载一个mingw(下载地址). 密码 68d7
默认安装即可.

了解GCC与Make

Ex1 最简GCC

首先如图建立一个c文件.
这里写图片描述

#include<stdio.h>int main(int argc, char const *argv[]){    char *s="hello world";    printf("%s\n", s);    return 0;}

打开命令行,运行以下代码:
这里写图片描述
目录会如下所示:
这里写图片描述
命令行运行exe文件:
这里写图片描述

我们已经迈出脱离VS的第一步了.

Ex2 GCC之迈入Windows

和上一步类似,不过我们把代码替换成如下:

#include <windows.h>const char g_szClassName[] = "myWindowClass";// Step 4: the Window ProcedureLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch(msg)    {        case WM_CLOSE:            DestroyWindow(hwnd);        break;        case WM_DESTROY:            PostQuitMessage(0);        break;        default:            return DefWindowProc(hwnd, msg, wParam, lParam);    }    return 0;}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,    LPSTR lpCmdLine, int nCmdShow){    WNDCLASSEX wc;    HWND hwnd;    MSG Msg;    //Step 1: Registering the Window Class    wc.cbSize        = sizeof(WNDCLASSEX);    wc.style         = 0;    wc.lpfnWndProc   = WndProc;    wc.cbClsExtra    = 0;    wc.cbWndExtra    = 0;    wc.hInstance     = hInstance;    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);    wc.lpszMenuName  = NULL;    wc.lpszClassName = g_szClassName;    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);    if(!RegisterClassEx(&wc))    {        MessageBox(NULL, "Window Registration Failed!", "Error!",            MB_ICONEXCLAMATION | MB_OK);        return 0;    }    // Step 2: Creating the Window    hwnd = CreateWindowEx(        WS_EX_CLIENTEDGE,        g_szClassName,        "The title of my window",        WS_OVERLAPPEDWINDOW,        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,        NULL, NULL, hInstance, NULL);    if(hwnd == NULL)    {        MessageBox(NULL, "Window Creation Failed!", "Error!",            MB_ICONEXCLAMATION | MB_OK);        return 0;    }    ShowWindow(hwnd, nCmdShow);    UpdateWindow(hwnd);    // Step 3: The Message Loop    while(GetMessage(&Msg, NULL, 0, 0) > 0)    {        TranslateMessage(&Msg);        DispatchMessage(&Msg);    }    return Msg.wParam;}

希望大家不要被大片代码吓到,因为这次我们的任务可以完全忽略以上代码.只要知道它是可以编写一个windows窗口的代码即可.
好了,现在我们运行以下代码:
这里写图片描述
这次我们可以直接点击exe程序了,因为它已经不是一个console的程序了.
这里写图片描述
我们这里简单解释一下我们新加的参数:

-mwindows Create GUI application

Ex3 开始makefile

先看下文件列表:
这里写图片描述
以下是每个文件的内容
hello.cpp

#include<stdio.h>void hello(){    printf("hello\n");}

hello.h

void hello();

main.cpp

#include<stdio.h>#include<hello.h>int main(int argc, char const *argv[]){    hello();    return 0;}

Makefile

makemain.exe: main.cpp hello.cpp    gcc -o makemain main.cpp hello.cpp -I .

运行方式如下:
这里写图片描述
细心的同学可能会发现这比我们上面敲得gcc命令就多了一行:

makemain.exe: main.cpp hello.cpp

这行的意思是只要更改了main.cpp和hello.cpp就重新生成makemain.exe. 而生成过程就是我们第二行输入的GCC命令.
所以当我第二次敲入make指令时,会发现up to date的显示.

Ex4 简化makefile

代码和上面一致,这次我们仅略微修改下makefile.

CFLAGS=-I .makemain.exe: main.cpp hello.cpp    gcc -o $@ $? $(CFLAGS)clean:    del *.exe

这里一行一行解释下代码的含义:
CFLAGS其实就是普通意义的宏. 后面的$(CFLAGS)其实就是解宏. 可以理解成变量的含义. 但是多数宏有默认的推导含义. 比如我们常用变量i来代表循环变量.

这里CFLAGS默认的推导含义为:

Extra flags to give to the C compiler.

接下来我们介绍两个比较特殊的变量. 如果懂shell编程的同学可能会看着很眼熟.
$@ $? :
$@用来标明我们想生成文件的目标,这里即makemain.exe.
@?用来标明变动的依赖文件.

接下来就是clean的含义. 我们可以把cleanmakemain.exe即要生成的”文件”当成一种类型. 为了要生成clean, 我们先看有没有依赖变化. 如果是空,则直接执行下面的生成规则.

这里即del *.exe.

Ex5 DirectX

由于DX代码比较多,而我们更关心的是环境问题,这里只给出makefile. 大家想尝试的话在文后看共享链接.

CFLAGS=-I . \    -I "C:\Program Files (x86)\Microsoft DirectX SDK (October 2006)\Include"\    -L "C:\Program Files (x86)\Microsoft DirectX SDK (October 2006)\Lib\x86"\    -mwindowsLIBS = -ld3d9 -ld3dx9 -lwinmm\       -lstdc++demo.exe: d3dInit.cpp d3dUtility.cpp     gcc -o $@ $? $(CFLAGS) $(LIBS)clean:    del *.exe

相比较上面的例子. 这个例子其实多了三个点.
1. -I 这个含义是指定头文件的搜索目录
2. -L 这个含义是指定库文件的搜索目录
3. -ld3d9 这个含义是让链接器去链接 d3d9.lib这个库.

本系列程序代码都在GameMaster.

0 0
原创粉丝点击