#include <Python.h>
int
main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args]n");
return 1;
}
Py_Initialize();
pName = PyString_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyInt_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argumentn");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ldn", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failedn");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"n", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}
这段代码从argv[1]中载入Python脚本,并且调用argv[2]中的函数,整数型的参数则是从argv数组后面得来的。如果编译和链接这个程序,执行如下脚本:
def multiply(a,b):
print "Will compute",a,"times",b
c=0
for i in range(0,a)
c=c+b
return c
结果将是:
$ call multiply multiply 3 2 Will compute 3 times 2 Result of call: 6
虽然这个程序的代码挺多的,但是大部分其实都是做数据转换和错误报告。主要关于嵌入Python的开始于:
Py_Initialize(); pName=PyString_FromString(argv[1]); /* Error checking of pName left out */ pModule=PyImport_Import(pName);
初始化解释器之后,使用 PyImport_Import() 导入模块。这个函数需要字符串作为参数,使用 PyString_FromString() 来构造:
pFunc=PyObject_GetAttrString(pModule,argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
...
}
Py_XDECREF(pFunc);
载入了模块以后,就可以通过 PyObject_GetAttrString() 来获取对象。如果名字存在并且可以执行则可以安全的调用它。程序随后构造参数元组,然后执行调用:
pValue=PyObject_CallObject(pFunc,pArgs);
函数调用之后,pValue要么是NULL,要么是返回值的对象引用。注意在检查完返回值之后要释放引用。
另一个:
1. 安装 Python 到 d:\python23
2. 新建一个VC项目, 在 Project Setting 中,把 d:\python\include 加入“其他头文件”哪一项,把 d:\python\libs 加入 link 的附加目录里。
3. 在主文件里这样写:
#include <python.h> // PYthon 头文件
#include <stdio.h>
void main(void)
{
Py_Initialize(); //python 解释器的初始化
if(!Py_IsInitialized())
{
printf( "can 't init python ");
return;
}
PyRun_SimpleString( "import sys ");
PyRun_SimpleString( "sys.path.append( './ ') ");
PyObject *pName,*pModule,*pDict,*pFunc,*pArgs,*pRes;
pName = PyString_FromString( "pytest "); // 这个就是你要嵌入的python 文件名
pModule = PyImport_Import(pName);
if(!pModule)
{
printf( "can 't find pytest.py ");
getchar();
return ;
}
pDict = PyModule_GetDict(pModule); // 得到python模块中的函数表
if(!pDict)
return;
pFunc = PyDict_GetItemString(pDict, "add ");
if(!pFunc || !PyCallable_Check(pFunc))
{
printf( "can 't find function [add] ");
getchar();
return;
}
*pArgs;
// 添参数
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs,0,Py_BuildValue( "l ",343));
PyTuple_SetItem(pArgs,1,Py_BuildValue( "l ",42356));
PyObject_CallObject(pFunc , pArgs); // 调用 python 程序
pFunc = PyDict_GetItemString(pDict, "str_find ");
if(!pFunc || !PyCallable_Check(pFunc))
{
printf( "can 't find function [add] ");
getchar();
return;
}
// 另外一个函数例子,演示了如何向 python 传递参数,和如何传回 C++
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs,0,Py_BuildValue( "s ", "abcdef "));
PyTuple_SetItem(pArgs,1,Py_BuildValue( "s ", "de "));
long ret_val = PyInt_AsLong(PyObject_CallObject(pFunc , pArgs));
printf( "%d\n ",ret_val);
Py_DECREF(pModule);
Py_Finalize(); // 清除
getchar();
}
// -----------------------------------------
python 文件 pytest.py
def add(a,b):
print "in python function add "
print a+b
return
def str_find(str1,str2):
print "str1: ",str1
print "str2: ",str2
return str1.rfind(str2)
C语言程序可以看成由一系列外部对象构成,这些外部对象可能是变量或函数。而内部变量是指定义在函数内部的函数参数及变量。外部变量定义在函数之外,因此可以在许多函数中使用。由于C语言不允许在一个函数中定义其它函数,因此函数本身只能是“外部的”。
由于C语言代码是以文件为单位来组织的,在一个源程序所有源文件中,一个外部变量或函数只能在某个文件中定义一次,而其它文件可以通过extern声明来访问它(定义外部变量或函数的源文件中也可以包含对该外部变量的extern声明)。
而static则可以限定变量或函数为静态存储。如果用static限定外部变量与函数,则可以将该对象的作用域限定为被编译源文件的剩余部分。通过
static限定外部对象,可以达到隐藏外部对象的目的。因而,static限定的变量或函数不会和同一程序中其它文件中同名的相冲突。如果用
static限定内部变量,则该变量从程序一开始就拥有内存,不会随其所在函数的调用和退出而分配和消失。
C语言中使用静态函数的好处:
- 静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多。
- 关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限 于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
c语言中static的语义
1.static变量:
1).局部
a.静态局部变量在函数内定义,生存期为整个源程序,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
b.对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
2).全局
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
2.static函数(也叫内部函数)
只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数(外部函数)
static在c里面可以用来修饰变量,也可以用来修饰函数。
先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不包含对,不要弄混。
int a ;
main()
{
int b ;
int c* = (int *)malloc(sizeof(int));
}
a是全局变量,b是栈变量,c是堆变量。
static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。
static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就 结束了。但加入static修饰之后,变量已经不在存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数 时,它又可继续使用, 而且保存了前次被调用后留下的值。
static对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
问题:Static的理解
关于static变量,请选择下面所有说法正确的内容:
A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D、静态全局变量过大,可那会导致堆栈溢出。
答案与分析:
对于A,B:根据本篇概述部分的说明b),我们知道,A,B都是正确的。
对于C:根据本篇概述部分的说明a),我们知道,C是正确的(所谓的函数重入问题,下面会详细阐述)。
对于D:静态变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出,D是错误的。
因此,答案是A、B、C。
问题:不可重入函数
曾经设计过如下一个函数,在代码检视的时候被提醒有bug,因为这个函数是不可重入的,为什么?
unsigned int sum_int( unsigned int base )
{
unsigned int index;
static unsigned int sum = 0; // 注意,是static类型的。
for (index = 1; index <= base; index++)
{
sum += index;
}
return sum;
}
答案与分析:
所谓的函数是可重入的(也可以说是可预测的),即:只要输入数据相同就应产生相同的输出。
这个函数之所以是不可预测的,就是因为函数中使用了static变量,因为static变量的特征,这样的函数被称为:带“内部存储器”功能的的函
数。因此如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量,这种函数中的static变量,使用原则是,能不用尽量不用。
将上面的函数修改为可重入的函数很简单,只要将声明sum变量中的static关键字去掉,变量sum即变为一个auto 类型的变量,函数即变为一个可重入的函数。
当然,有些时候,在函数中是必须要使用static变量的,比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
**************************************************************************
* 体系篇
************************
+-----------+-----------------+------------+
| GUI(L4) | Network/DB(L5) | 2D/3D (L6)
|
+-----------+-----------------+------------+
| 系统API(L2)
|
compiler/tool(L3) |
+------------------------------------------+
|
硬件/操作系统(L1)
|
+------------------------------------------+
=========================================================
======
L1 - Layer 1
(硬件/操作系统)
======
=========================================================
此 Layer 主要是介绍操作系统的实现。
《Intel 64 and IA-32 Architectures Software Developer's
Manuals》
http://www.intel.com/products/processor/manuals/
x64/x86 体系结构权威手册,可以下载到 pdf 版本。
《深入理解计算机系统》
http://www.douban.com/subject/1230413/
计算机软硬件体系结构深入浅出的介绍。
《LINUX内核源代码情景分析》
http://www.douban.com/subject/1240321/
《Windows内核情景分析》
http://www.douban.com/subject/3715700/
两本情景分析,是以代码为实例,解说了两大操作系统的具体实现。实践性比较强。
《深入解析Windows操作系统》
http://www.douban.com/subject/2031396/
Windows官方著作,理论多,实践少。
《自己动手写操作系统》
http://www.douban.com/subject/1422377/
《Orange S:一个操作系统的实现》
http://www.douban.com/subject/3735649/
一个作者同一系列的两本书,看一本即可。操作系统的入门材料。
=========================================================
======
L2 - Layer 2
(系统API)
======
=========================================================
系统级对象、API的使用,比如 Process, Thread, Mutex, Socket 等等。
《Windows核心编程》
http://www.douban.com/subject/3235659/
《UNIX环境高级编程》
http://www.douban.com/subject/1692629/
=========================================================
======
L3 - Layer 3
(libc/compiler)
======
=========================================================
使用高级语言,用好编译器、调试工具是必不可少的基础。至于是否需要研究编译器原理,则只是个人爱好了。
《Compilers: Principles, Techniques, and Tools》
http://www.douban.com/subject/1866231/
《Advanced Compiler Design and Implementation》
http://www.douban.com/subject/1821532/
《Modern Compiler Implementation in C》
http://www.douban.com/subject/1886911/
三本讲解编译器实现的大部头,喜爱编译器原理的同学可以参考下。
《Linkers and Loaders》,
http://www.douban.com/subject/1436811/
链接和装载方面的权威理论著作。
中文版下载,http://www.oldlinux.org/oldlinux/viewthread.php?tid=10713
《链接、装载与库》
http://www.douban.com/subject/3652388/
可以看作是《Linkers and Loaders》的升级中文版。
《软件调试》
http://www.douban.com/subject/3088353/
《Windows高级调试》
http://www.douban.com/subject/3781532/
Windows 下的两本 debugging 宝典。
《Makefile/GCC/GDB 学习》
网上很多资料,可以任意 google。当然,gcc/gdb manual 是最详细的,虽然有点枯燥。
http://sourceware.org/binutils/docs/gprof/index.html
http://valgrind.org/
http://dmalloc.com/
linux 下几个性能、内存检查的常用工具。
=========================================================
======
L4
- Layer 4
(GUI)
======
=========================================================
GUI app 算是 desktop
app,虽然是做游戏,但也免不了写点小工具,比如:地图编辑器、资源打包工具等等。
所以 GUI 知识也是需要的。这里介绍的都是 C/C++ 的 GUI 库,一般我们的做法是把 C/C++
库封装到脚本(lua/python),
直接通过脚本写具体的逻辑。MFC 是 windows 官方的古老东西,廉颇老矣,可以不用学习了。
当然,其实用 C# 做界面也是很方便的。Java 也行,就是有点慢。
《Programming Windows Fifth Edition》
http://www.douban.com/subject/1456779/
理解 C/C++ 版的 win app 是如何运作的,第五版是最经典的一个版本。
《深入浅出MFC》
http://www.douban.com/subject/1482240/
这本书其实并不会告诉你MFC怎么用,而让你了解到一个 C++ GUI framework
应该具备哪些最基本的元素。如:消息传递、RTTI等等。
《MFC Windows程序设计》
http://www.douban.com/subject/1128016/
MFC 每个控件的详细介绍,不过不熟悉 MFC 的同学可以不用学了。
wxWidgets
http://www.wxwidgets.org/
Qt
http://www.qtsoftware.com/
GTK+
http://www.gtk.org/
三者是跨平台的UI库,wx与MFC比较像。学一即可满足日常需求,实际工作中,我们用 wx 比较多。
=========================================================
======
L5 - Layer 5
(Network/DB)
======
=========================================================
Network,如果只从 socket api
来说,只属于“系统API”,但网络游戏中,服务端程序还是非常重要的,所以我把其
单独分为一个 Layer,且同时涵盖了网络、数据存储两者。
《TCP/IP 详解》 Vol 1/2/3
http://www.douban.com/subject/1099252/
http://www.douban.com/subject/1231729/
http://www.douban.com/subject/1095214/
IPv4 原理的权威书籍
《UNIX Network Programming》 Vol 1/2
http://www.douban.com/subject/1174626/
http://www.douban.com/subject/1231788/
UNIX 网络编程的权威著作
libevent
http://www.monkey.org/~provos/libevent/
RakNet
http://www.jenkinssoftware.com/
ACE
http://www.cse.wustl.edu/~schmidt/ACE.html
Ice
http://www.zeroc.com/
四个跨平台的网络封装库,其中 libevent 是最轻量级的,而 RakNet 是专为游戏设计。
ACE/Ice 都是比较重量级的,可以阅读其代码,学习一些网络框架的设计思想。
MaNGOS
http://getmangos.com/
WOW 的模拟服务端,C++ 代码还是很清晰的。
Mud OS
http://www.mudos.org/
LDMud
http://www.bearnip.com/lars/proj/ldmud.html
古老的 mud 游戏的服务端,虽然代码老了点,结构乱了点,但也是很多网络游戏的服务端雏形。
《深入浅出MySQL》
http://www.douban.com/subject/3012338/
公司同事的作品,MySQL非常好的入门书籍。:-)
《High Performance MySQL》
http://www.douban.com/subject/3101726/
SQLite
http://www.sqlite.org/
MySQL
http://www.mysql.com/
SQLite 是基于文件的DB,配合 GUI 程序用来做存储,还是很不错的。
=========================================================
======
L6 - Layer 6
(2D/3D)
======
=========================================================
《游戏编程大师技巧》 Vol 1/2
http://www.douban.com/subject/1230286/
http://www.douban.com/subject/1321769/
两本书本别介绍了 2D/3D 的基础。非常非常好的入门资料,特别是 3D 那本,介绍了写3D程序所需要的数学/3D知识。
《3D Engine Design》
http://www.china-pub.com/192098&ref=ps
介绍了主流的3D游戏引擎应如何设计。作者同时实现了 WildMagic,一款开源的3D引擎。
WindSoul
http://blog.codingnow.com
http://www.codingnow.com/2000/index.html
云风GG的力作,2D游戏引擎。
HGE
http://hge.relishgames.com/
2D 引擎的另一个发展方向,用 3D 渲染 2D。(利用硬件加速)
Box2D
http://www.box2d.org/
2D 物理引擎
IrrLicht
http://irrlicht.sourceforge.net/
代码清晰,结构简单,适合入门阅读。
ogre
http://www.ogre3d.org/
结构清晰,但重量级的开源3D引擎
Bullet
http://www.bulletphysics.com/wordpress/
ODE
http://www.ode.org/
两款开源的3D物理引擎
**************************************************************************
* 语言篇
************************
语言是工具,语言没有好坏,只有是否适用,以及你对其有多少的熟练度。
越熟悉,才能写出结构更好、效率更高的代码。
我只列出游戏部常用的开发语言,C#/Java/Lisp 不在此列。:-)
=========================================================
======
C/C++
======
=========================================================
C++ 是门不算古老但足够复杂的语言。实践中,高级的 template 特性的滥用,回导致代码不好维护。
所以在考虑深入 C++ 的高级特性前,可以先读读此 blog。Just thinking, 项目中需要这么多高级特性么?
http://blog.csdn.net/pongba/archive/2007/05/16/1611593.aspx
下面我就不列出我认为有点“偏”的 C++ 图书了。虽然只想列几本重点的,也发现列了不少。- -#
《The C Programming Language》《C++ Primer》《The C++
Programming Language》
http://www.douban.com/subject/1236999/
http://www.douban.com/subject/2696025/
http://www.douban.com/subject/1767741/
三本基础书,C++ 的读其中一本即可。
《C陷阱与缺陷》
http://www.douban.com/subject/1102097/
《C专家编程》
http://www.douban.com/subject/2377310/
《C/C++ 深层探索》
http://www.douban.com/subject/1232030/
C/C++ 的提高篇
《Effective C++》《More Effective C++》《Effective STL》
http://www.douban.com/subject/1453373/
http://www.douban.com/subject/1457891/
http://www.douban.com/subject/1792179/
Effective 三套件
《C++ 编程规范》
http://www.douban.com/subject/1480481/
编码规范的书很多,看一本就好,其他的东西,实践中慢慢体会。
《C++标准程序库自修教程与参考手册》
http://www.douban.com/subject/1110941/
《STL 源码剖析》
http://www.douban.com/subject/1110934/
STL 最好的两本参考手册。
《Imperfect C++》
http://www.douban.com/subject/1470838/
《深度探索C++对象模型》
http://www.douban.com/subject/1091086/
提升 C++ 内力的两本书。
《道法自然:面向对象实践指南》
http://www.douban.com/subject/1231194/
《C++实践之路》
http://www.douban.com/subject/1102104/
上面的书,如果都还偏理论的话,这两本书就是用实践说话了。
=========================================================
======
Lua
======
=========================================================
《Programming Lua, 2nd》
http://www.douban.com/subject/3076942/
《Lua Reference》
http://www.lua.org/manual/5.1/
我最喜欢这种简单的语言 :-) 书籍少,好学,但又很实用。
=========================================================
======
Python
======
=========================================================
Python 的书也很多,看完下面两本,剩下的再参考官方 manual 也就差不多了。
《Learning Python》
http://www.douban.com/subject/3243372/
基础篇
《Python Cookbook》
http://www.douban.com/subject/1418172/
提高篇
**************************************************************************
* 算法/数据结构篇
************************
算法涉及的范畴也很广泛,这里偏重介绍数据结构的基础书籍。
《算法导论》
http://www.douban.com/subject/1152912/
理论基础篇
《Art of Computer Programming》
http://www.douban.com/subject/1418402/
没啥可介绍的,算法著作中的《葵花宝典》。
**************************************************************************
* 软件设计篇
************************
设计模式就是些名词,方便大家交流时,更准确地了解对方用了怎样的程序结构。
《设计模式》
http://www.douban.com/subject/1099305/
《Head First Design Pattern》
http://www.douban.com/subject/1400656/
《大话设计模式》
http://www.douban.com/subject/2334288/
第一本是经典著作,但有点理论化,稍显晦涩。后两本则是通俗易懂型的,老外的例子和我们生活上有点差异,
好像第三本更适合我们,呵呵。
《重构》
http://www.douban.com/subject/1229923/
《UNIX编程艺术》
http://www.douban.com/subject/1467587/
软件设计的 KISS 原则 (Keep It Simple, Stupid)
《Pattern-Oriented Software Architecture》 Vol
1/2/3/4/5
http://www.douban.com/subject/1232017/
http://www.douban.com/subject/1137259/
http://www.douban.com/subject/1444890/
一共五卷,不过中文版似乎还只有三卷。其中卷二对网络框架的设计有比较大的参考意义。
**************************************************************************
* 开发方法篇
************************
不同的开发方法论,适用于不同规模的开发团队。传统的软件工程,比较适合需求固定的庞大的系统。而游戏
开发与之相反,团队规模小而需求变化快,所以 Agile Development (敏捷方法) 比较适合我们。
各种敏捷方法中,我个人比较喜欢 scrum,公司好几个工作室也在实施。下面是个人的一点总结,仅供参考:
http://kasicass.blog.163.com/blog/static/39561920081289380384/
最后一句话:方法是死的,灵活运用,找到属于自己团队最佳的实践。
《代码大全》
http://www.douban.com/subject/1477390/
http://blog.codingnow.com/cloud/CodeComplete
EKP上有链接电子版:http://nie.netease.com/main/department/tech/ziyuanzhongxin/dianzishuji/jishushuji/代码大全2中文版(完整清晰版).pdf/view
《人月神话》
http://www.douban.com/subject/2230248/
说起项目管理,这本书总还是要去读读的。
《I. M. Wright's Hard Code》
http://www.douban.com/subject/3259433/
来自 M$ 的项目管理经验书
《敏捷迭代开发管理者指南》
http://www.douban.com/subject/1801394/
《Agile Software Development with Scrum》
http://www.douban.com/subject/1153186/
Scrum 发起者的著作,用于理解 scrum 的各种概念
《超越传统的软件开发》
http://www.douban.com/subject/1220623/
上面的都是国外和尚念的经,这里强烈推荐一本国人的作品,写得很实在。可惜网上已经买不到了,公司图书馆里还有得借。
这是我接触3D图形编程的第一本书,接触3d图形编程前,我看的是《Windows 游戏编程大师技巧》,只看了前几章,当时我急着想去学3D的酷玩意儿,立刻就没耐心看GDI,DirectDraw。转投Direct3D门下,入门书当 然是这本龙书了。对我来说龙书最棒的地方在于,它除了开始的数学基础章节外,每一章都能详细地引导读者去实现一个简单的3D特性,从画三角形到摄像机,到 简单的粒子系统,地形,甚至到shader。Luna无疑是睿智而狡猾的,他知道初学者往往耐心不够,所以他总是适时地丢出个胡萝卜,让读者保持着继续的 动力。这一点是我在《Windows 游戏编程大师技巧》没看到的。(见鬼,谁爱去学画线那点破玩意...这里完全是个人情感,我没看完后者,所以没资格评价)
但是Luna忽视了一点,就是学完了龙书该做什么?他或许没想到有很多投身于游戏编程的孩子都是像我这样,眼高手低而且懒于探索,爱看现成内容的。起初的 他们编程基础不扎实(1年编程经验),完全不了解图形学(就龙书那点,而且多半只是照葫芦画了个瓢,还是不懂原理)。于是这些孩子后来的日子就苦了。
由于他缺乏埋头苦干的品质,于是他们只能上网寻找高人指点如何走下面的路,接着他苦苦寻找该如何理解和实现更高深的内容,去看DirectX Sampler里晦涩的代码,虽然很多知识对当时缺乏实际代码经验的他实在有点难,在这样茫茫然然浪费了许多时光之后,他找到一本还可以的英文书,里面虽 然内容不深,但是一步一步教着去实现了简单的Demo,里面包含了蹩脚的封装,难堪的场景管理,但对他来说还是可以够到的,于是他终于东拼西凑地写出了第 一个属于自己的Demo。他看到了自己的不足,但还不知道如何改进,他觉得这个学习之旅越来越难,懒惰催促着他该放弃了。但他的内心不愿放弃这个童年的梦 想,于是他甚至逼迫自己翻译了另一本英文书籍,他又能看懂更多了。或许是冥冥中的必然,他看到了Ogre,在经历的那么多晦涩的代码后,学习Ogre已经 不再是那么难了,他在同学的帮助下熟悉了部分Ogre,写了更多的代码,看了更多的代码。终于,他发现曾经如同天书的RTR,现在闪烁着金色的光芒,而他 发现自己图形的基础实在太差了,而且对图形引擎的细节还是一知半解(游戏引擎更别说了)。于是他便开始阅读ogre的源码,并纳为己用......
我不知道还有没有像我这样的笨蛋,但现在回头想想,自己当初如果能有个人来指点一二,并且沉下心,多写代码,今天我能走的更远。下面就是推荐学习的路线:
0.耐下性子,认真学习数据结构与算法,至少要学到图。这是我当年没有好好做而如今最后悔的步骤,推荐书无所谓,严蔚敏的也行,allen weiss的最好,但最重要的是不是光去理解,而是自己去实现,你会发现后者比前者难的多。
1.DirectX的龙书,我推荐看清华大学翻译的这个,首先段菲翻译的的确很不错,有些地方译者还加了自己的话和推荐的书外阅读,虽然有些 链接失效了,但这是原版没有的(准确的说是翁云兵先生翻译的版本里没有的,原文我没看过)。其次,处于尊重版权,我也推荐去买这本书,而不是下电子版,相 信我,对于初学者来说,这本书在你学习3d编程的一两年内,你还是能在从中学到知识的。
2.实现龙书,我不是说把他的例子抄一遍。这时候你需要做的是,把龙书的代码推掉,利用龙书的所有内容,重新自己写一个小的demo,可以就 是一个小场景漫游,但是希望你开动想象力,多写点逻辑,多写点独特的非图形的东西,不要觉得这很难,其实随便想一个简单的东西都有够你写的,推荐看这篇文 章,你会发现灵感有时候没那么难出现:http://www.gamelook.
3.这个时候,如果上述步骤你都完成了,恭喜你,你已经不再是初级菜鸟了,首先,你需要去买RTR(Real-Time Rendering英文版 ,淘宝上影印80),然后,程序设计上我推荐买一本大话设计模式,把其中简单的模式看一下,看不懂的就别看(那说明你还没到那水平,或者说还没遇到过这个 模式能解决的问题)。接着,推荐你阅读clayman大人很有名的一篇博客:http://www.cnblogs.c
然后去选择一个方向去阅读文中推荐的书籍,我推荐是地形和动画,因为这两个方向的书我看过。。。《Real Time 3D Terrain Engines Using C++ And DX9》网上有我翻译的中文版,虽然代码的确需要花一定的时间去理解(作为demo,代码写的不错,可以算一个小的图形引擎了),不过场景管理还是图形里 相当核心的一块,所以读还是有好处的,不过我的建议也是读完4到9章和附录就可以实际编码了。而后者《Character Animation With Direct3D》代码浅显易懂,而且人物动画绝对是当今次世代的一个大头,我虽然没有全看完,但还是相信这本书绝对很值得一读。读完后最后重构你之前写 的demo吧,并且加入这两本书的特性。
4 你将从菜鸟学院毕业了,现在的你对图形已经不再一窍不通,对程序结构也不再那么陌生。下面我终于要向你推荐Ogre了,你将很愉悦的略读一下《Pro OGRE 3D Programming》,(打工仔一帮人翻译了中文版),到此你当初写demo时的许多难题在这里或许能引擎共鸣,然后你将很轻松地阅读ogre的官网 的初中级教程,如今的你手握一个文档详细,社区活跃的图形引擎,接着拿着他重新去写一个小游戏吧,要求还是一样,尽可能多地利用所学知识。
是的,我还想写第5条,但我忍住了,因为曾经有个笨蛋经过或跳过了上述几个阶段后,学到了甚至更多的东西,最重要的是如今他不再需要有人来指点,便可以确定自己该走哪一条路,虽然他不一定看不到旅途的终点,但已然能够嘹望到前方的光明。所以我相信,你也能:)
ps:希望大家有经济能力的还是购买正版书籍,亚马逊没那么麻烦,而且淘宝上其实有很多代购的。
学习ogre的话,只有sdk是不够的,只能看例子,ogre本身的代码都堆叠在那里,没有一个ide来查看是比较悲剧的,下面讲一下我从源代码创建ogre的过程吧。
首先系统要安装vs2005+sp1,注意此sp1有两个哦,另一个不常见的是INTL,解决atl安全的补丁;
还要有directx SDK包,对于ogre1.72,推荐用feb2010版本,我用的jun2010就有一些问题;
如果要支持ogre的paging组件,还需要安装boost,对于我,可以使用boostpro installer来安装,这个一搜就搜到了,注意选择Multithreaded 和Multithreaded Debug支持,注意如果安装了这个,需要设置环境变量
BOOST_ROOT (C:\Program Files\boost\boost_1_44)
BOOST_INCLUDEDIR (C:\Program Files\boost\boost_1_44\boost)
BOOST_LIBRARYDIR (C:\Program Files\boost\boost_1_44\lib)
;
下载ogre的msvc依赖文件,然后切到src目录下打开解决方案,分别将debug和release都编一遍,然后加个系统变量指向这个目录,比如:
OGRE_DEPENDENCIES_DIR(C:\Program Files\ogre\ogredependence)
做完这些就可以用cmake来配置ogre了,安装windows的cmake,打开gui,在source里输入ogre源代码路径,where to build里输入你想要放置工程文件的地方,这个可以是任意路径,然后点击configure,这里你可以定制自己想要的一些配置选项,确定了以后选择generate,然后就一切ok啦,相关的vs工程文件生成了,至此,你就可以用vs打开工程进行编译了,哈哈。
这样,查看,修改,编译各种方便了。
以前弄过,结果这次用到又给忘了,先是在11.04上用,结果发现增强包不支持那么高的内核,所以降到10.04,安装好后升级了下补丁,重启发现又不行了,原来是内核也给升级了,没办法,重新安装增强包,安装完后关机,设置数据共享,比如设定共享名为Share,重启后再控制台探测一下vboxsf模块是否加载成功,modprobe vboxsf,如果成功,就可以手动建立挂在文件夹并挂载了:
mkdir /mnt/share
mount -t vboxsf share /mnt/share
注意,我发现windows下建立的共享名在linux下只认小写,所以Share==share,呵呵。
另外说明一点,vbox里边的数据共享有个auto mount选项,我发现是不管用的,如果想自动挂载,需要在/etc/fstab中添加
share /mnt/share vboxsf rw,gid=100,uid=100,auto 0 0.
大致就这个样子吧。
最近下了ogre的SDK来学习,发现编译好sample之后无法运行的问题,提示应用程序初始化失败,上网搜了很多解决方案,发现其实有一条是很容易忘的,就是安装完sdk后要手动将ogre的环境变量设置好,这个在ogre官网上有说明,但是说明里边是在cmd下设置的,必须永久的添加到系统环境变量中才可以哦,其他的比如安装sp1啥的我就不废话了。
另外在生成sample的时候如果提示预连接错误,则需要将SampleBrowser工程的预链接事件中的命令行对应的cmake安装路径设置对。
就这么多吧。