红龙书随书源码第一例D3D9 Init在VS2019下编译通过的方法

红龙书DirectX9.0 3D游戏开发编程基础(Introduction to 3D Game Programming with DirectX 9.0)  一书中

随书源码(https://d3dcoder.net/Data/Book1/BookICode.zip) 里 Book Part II code 目录 下面第一章第一个例子 (D:\c++_test\Introduction to 3D Game Programming with DirectX 9.0\Book Part II Code\Chapter 1\D3D9 Init)

在vs2019上编译通过的方法:

 

 先下载安装  Microsoft DirectX SDK (June 2010) 

Version:

Date Published:
9.29.1962
6/7/2010
File name:
File size:
DXSDK_Jun10.exe
571.7 MB

下载地址: http://www.microsoft.com/en-us/download/details.aspx?id=6812

 

安装位置随你喜欢,我就安装在 D:\Program Files (x86)\Microsoft DirectX SDK (June 2010) ,安装中可能会出现问题,其实是和你原先安装的vs2010的什么可重新分发包的版本有关系,如果安装出错,只要进入windows的程序安装删除里面,把两个跟vs2010的可重新分发包删掉即可,然后再重新安装一遍Microsoft DirectX SDK (June 2010)  就ok了,我的安装位置选择在 D:\Program Files (x86)\Microsoft DirectX SDK (June 2010) , 可以看到该目录下的Lib目录里,9-11 版本的库文件都有,d3d9.lib, d3d10.lib,d3d11.lib, d3dx9.lib, d3dx10.lib,d3dx11.lib, 还有XInput.lib

 

打开vs2019,建立test目录 (D:\c++_test\Introduction to 3D Game Programming with DirectX 9.0\Test)

把随书源码中的这四个文件 d3dUtility.h, d3dInit.cpp, d3dUtility.cpp, chap1_0.jpg 拷贝到 Test目录中

在Test目录中建立一个vs2019空项目,在打开的空项目中,把d3dInit.cpp, d3dUtility.cpp 拖入解决方案资源管理器中“”源文件“”图标,将d3dUtility.h 拖入解决方案资源管理器中头文件图标

按F7编译,结果报错!

 

那么开始一个个解决报错问题(如果你不能解决书中第一个例子代码的编译链接问题,那么你去买或读这本书就是一件愚蠢至极的事,相信我,没错的):

首先看一个报错:error LNK2019: 无法解析的外部符号 __imp__timeGetTime@0,该符号在函数 “void __cdecl TimerInit(void)” (?TimerInit@@YAX

网查,说是要将winmm.lib打入“附加依赖项”,这指的是vs2019 中的项目属性页-链接器-输入-附加依赖项,把winmm.lib加入进去,其实这样写就等价于在源代码开头添加一句#pragma comment(lib, "winmm.lib")   ,如在附加依赖项里已经加入了winmm.lib则源代码中就无需加这一句了。这也是为什么其实vs2019编译链接时还链接了其他多个库,比如user32.lib之类的,但却根本不需要在源代码开头写上#pragma comment(lib, "user32.lib") 的缘故,就是因为user32.lib早已被默认加入了附加依赖项  

当然,除了把winmm.lib加入附加依赖项以外,也可以直接就在 d3dInit.cpp 源代码开头添加一句  #pragma comment(lib, "winmm.lib")   我采用该方法,在d3dInit.cpp源代码开头 添加  #pragma comment(lib, "winmm.lib")

 

再按F7, 依然报错!

 

再在 d3dInit.cpp源代码开头添加一句

#pragma comment(lib, "d3d9.lib")

 

 再按F7, 还是报错!

再在 d3dInit.cpp源代码开头添加一句

#pragma comment(lib, "d3dx9.lib")

再按F7 还是报错,报错信息很长,略,其实大概率就是vs2019并没有找到directx的库文件,比如 dxd9.lib,d3dx9.lib, 即便你把wimm.lib已经加入了附加依赖项,依然要告诉vs2019,到硬盘哪个目录下面去找这个.lib库文件

因此,你需要按ALT+F7, 打开VC++目录,把 D:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;  这一句加入包含目录, 而把D:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86; 这一句加入库目录, 注意最后的分号; 不能漏掉

反复试验证明,在本例代码中, #pragma comment(lib, "d3dx9.lib") 这一句无需添加,添加后并不能让报错信息消除(但书中其他例子中肯定会用到d3dx9.lib,因此要么在源代码开头也添加上 #pragma comment(lib, "d3dx9.lib") ,要么就是把d3dx9.lib 也添加进项目属性-配置属性-输入-附加依赖项 里面 )

 

再按F7,还是有一堆报错,但大概意思明白是跟字符串的类型转换有关系,这里需要将vs2019中 项目属性-配置属性-高级-字符集   从使用unicode字符集 改为 使用多字节字符集 。这样,一堆报错就立马消失了。 

 

最后一个报错  MSVCRTD.lib(exe_main.obj) : error LNK2019: 无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)" 的原因是:【main函数没有找到!!!】

目前该程序入口函数是WinMain,也就是说这个程序应该是窗口程序而不是console程序(window下的控制台程序),这一点要搞清楚

因当时在D:\c++_test\Introduction to 3D Game Programming with DirectX 9.0\Test 下创建一个空项目时,也没注意,直接连着点击就生成了空项目(也奇怪为何没有选择的步骤,难道空项目也可以自己选择成为win32项目而不是win下命令行项目?)

由于按缺省方式建立成的是console控制台项目,因此编译时候报错说找不到main,这里分明是WinMain,当然找不到main,因此可以这样,

要么将该项目改为创建Win32项目,要么更省事,就是直接更改项目属性,先打开属性页,配置属性-->链接器-->系统-->子系统-->将子系统由控制台(subsystem:console)改为 窗口(subsystem:windows), 之后点击确定。

这时再按 ctrl+ALT+F7 重新生成解决方案,发现 终于可以编译成功,生成 D3D9Init.exe 


此时再按F5,直接编译并且运行,会看到产生了一个内容全黑的小窗口,没有右上角关闭按钮,按esc键可关闭该窗口

 

这样,红龙书中随书源码第一个例子D3D9 Init 【 Book Part II code 目录 下面第一章第一个例子 (D:\c++_test\Introduction to 3D Game Programming with DirectX 9.0\Book Part II Code\Chapter 1\D3D9 Init)】就编译运行成功了

 

 

 

以下是编译运行成功的D3D9 Init 项目代码 中 d3dinit.cpp的全部内容,

其他随同编译的d3dUtility.cpp和d3dUtility.h 无需任何改动

//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dinit.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Demonstrates how to initialize Direct3D, how to use the book's framework
// functions, and how to clear the screen to black. Note that the Direct3D
// initialization code is in the d3dUtility.h/.cpp files.
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"

#pragma comment(lib, "winmm.lib")   // 添加这一句,不然编译报错
#pragma comment(lib, "d3d9.lib")    // 添加这一句,不然编译报错
//#pragma comment(lib, "d3dx9.lib")

//最后一个报错是 MSVCRTD.lib(exe_main.obj) : error LNK2019: 无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)"
//这说明main函数没有找到,目前该程序入口函数是WinMain,也就是说这个程序应该是窗口程序而不是console程序,因当时创建空项目时建立成了控制台项目,需要改为创建Win32项目,
//也可以更改项目属性,先打开属性页,配置属性-->链接器-->系统-->子系统-->窗口(subsystem:windows),之后点击确定。再ctrl+ALT+F7 重新生成解决方案即可编译通过生成 .exe文件
// 此时按F5直接编译运行产生一个全黑的小窗,没有右上角关闭窗口,按esc键可关闭该窗口


//
// Globals
//

IDirect3DDevice9* Device = 0;

//
// Framework Functions
//

bool Setup()
{
// Nothing to setup in this sample.

return true;
}

void Cleanup()
{
// Nothing to cleanup in this sample.
}

bool Display(float timeDelta)
{
if( Device ) // Only use Device methods if we have a valid device.
{
// Instruct the device to set each pixel on the back buffer black -
// D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on
// the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);

// Swap the back and front buffers.
Device->Present(0, 0, 0, 0);
}
return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage(0);
break;

case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
640, 480, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}

if(!Setup())
{
::MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}

d3d::EnterMsgLoop( Display );

Cleanup();

Device->Release();

return 0;
}

 

 

===============================

另外再举一个编译DX官方sample 中最简单的空窗口例子 时编译出错的解决方法  

看完红龙书之后推荐看 Microsoft DirectX SDK (June 2010) 安装目录下面自带的官方sample例子代码

 

 ==============================================

红龙书 各个版本系列的源码下载

https://d3dcoder.net/ 可以下载以下这些书籍的源码
This is the supplement website for the books:

Introduction to 3D Game Programming with DirectX 9.0
Introduction to 3D Game Programming with DirectX 9.0c: A Shader Approach
Introduction to 3D Game Programming with Direct3D 10.0
Introduction to 3D Game Programming with Direct3D 11.0
Introduction to 3D Game Programming with Direct3D 12.0
Information about these books, such as table of contents, source code, and errata, can be found by clicking the Books menu item. If you need to download the DirectX 9.0/10.0/11.0 SDK, you can find it here at DirectX. In addition, you can find extra articles, sample source code, and programs by clicking the Articles and Code menu item. The message forum is available for readers to communicate with each other, and ask questions.

===============================================

 

游戏开发的学习资料汇总

https://www.cnblogs.com/Thermo/p/15777113.html

==============================================

posted @ 2022-01-08 18:35  Thermo  阅读(553)  评论(0编辑  收藏  举报