Pages

samedi 21 août 2010

A list of recommended programming-related books

http://www.ogre3d.org/tikiwiki/Recommended+reading

Ogre的场景编辑器Ogitor and Deled3D

Ogitor:  http://www.ogitor.org/tiki-index.php
DeleD3D: http://www.delgine.com/

************
Since creating scene in Ogre is possible and powerful, but a outer scene editor is better.
Just like the demo code of the integration of Ogre and Bullet,  from Q-Avril.

The scene is created out of Ogre, and Export as a kind of format (e.g. mesh format) into Ogre for later applications.

In the demos of Q-Avril, I exported .mesh model from DeleD3D to be used in OgreBullet collision detection applications.
***************


DeleD3D:  with some importers and exporters
                 http://www.delgine.com/plugins/viewPluginCategories.php

  • Exports:
    • DirectX
    • OBJ
    • Torque (plugin sold seperately)
    • B3D
    • Ogre Mesh
    • DBO
    • RAW
    • Collada
  • Imports:
    • DirectX
    • OBJ
    • B3D
    • 3DS
    • CSM
    • MAP

Ogre中文论坛

http://wiki.ogrecn.com/wiki/

网页虚拟现实 Web-based Virtual Reality and 3D

There are some interesting applications for Virtual Reality (VR) on the Web, and a number of hopeful future directions. Yet VR on the Web is not mainstream or widespread. Why has this exciting technology made slow progress? For one thing, users may encounter technical hurdles when they attempt to view VR. This is true on a stand-alone desktop machine, but even more so on the Web. More importantly, there is no VR content on the Web that everybody is dying to see.
June 21, 2000
VR can be broadly defined as interactive three-dimensional content. At its simplest, it is a 3D image of a single object that the user can rotate to see from various angles. At a middle level, it can be an entire scene or virtual world that the user enters and interacts with. High-end VR requires the user to wear special goggles and gloves that make the illusion of reality more complete.
Screen-based VR, including single-object visualization and virtual worlds, predominates on the Web. More sophisticated gloves-and-goggles VR is the province of games or specialized applications like military training, which are not typically Web-based.
The interactive nature of VR allows users to get exactly the information they want in an intuitive fashion, without having to search through databases or FAQs. The three-dimensional nature of VR can enhance the presentation of the information, whether for abstract representations (presenting data in a 3D interactive format) or for depicting actual objects, people or places.
VR applications on the Web include merchandising, entertainment, education, medicine, marketing and training. (See http://web3d.about.com/compute/web3d/msubvrapps.htm.) There are also plenty of sites with tips, tutorials, articles, discussions and other helpful materials for programmers. (As a starting point, check out http://web3d.about.com.)

Virtual Merchandising

Many applications are only in the prototype or demo stage. One that is definitely in real use is merchandising, where interactive 3D can give Web users something like the experience of trying out products without having to go into a bricks-and-mortar store. If nothing else, VR is a novelty that adds pizazz to an e-commerce site. It may inspire "window shoppers" to look more closely at products, spend more time on the site, or tell friends about the cool product demos.
Take the Sharper Image site (http://www.sharperimage.com), which sells high-tech luxury products like reclining chairs that give Shiatsu massage. Here, Internet shoppers have been reported to spend 50% more time in the part of the site that offers interactive 3D images. Page views are also reported to have tripled in a short time after the introduction of VR product demos. Overall sales continue to rise.
Yet it's not clear whether customers are actually buying more products because of VR. And creating such VR product demos is costly, mostly because the expertise to create them is still rare. In addition, content creators typically make a substantial investment in software tools, machines to run them, and perhaps special hardware such as digital cameras that take pictures of objects from multiple angles.

We Are Experiencing Technical Difficulties

More websites would use VR if it weren't for technical impediments. VR is most convincing and pleasing when it uses realistic textures, lighting and sounds. Using those elements makes files large, and large files mean slow performance -- which could account for Web surfers spending more time in 3D areas on e-commerce sites. The upscale Web surfers who go to The Sharper Image site are likely to have fast computers with graphics acceleration that display demanding textures and lightning at a reasonable speed. For much of the rest of the world, realistic VR on the Web may just be too slow to be fun. In particular, graphics processing may be insufficient to present smooth motion with realistic shading and textures.
On the other hand, the limitations of computers and the demands of VR should not be exaggerated. VR files are not necessarily huge. They can be small if they consist mostly of vector graphics. A bit of code that says "draw box, size 10x10x10, color red" takes up a lot less space than even a compressed bitmap of the same box.
"It's been a misconception in the media since day one that VR files are huge," says Dan Ancona, founder of Vizbang.com, which is developing "Spark", a VR-based presentation tool. "File size is increasingly irrelevant, especially with the mushrooming availability of higher than 56K bandwidth."
In addition, many computers shipping today come with built-in 3D graphics acceleration.
But there are areas where limitations remain. Even the best standard monitors aren't big enough and don't have the resolution to give complete, detailed, life-size images of many objects, not to mention whole scenes. Color reproduction is usually inconsistent and audio is seldom hi-fidelity. These problems apply to all 2D and 3D graphics on standard desktop machines, not just the Web. And they apply no matter what the underlying VR technology.
Add to that the bandwidth limitations and possibly unreliable connections of the Web, and you have the potential for a deeply dissatisfying experience.

Inherent Limitations of VR

Problems of speed and resolution will be alleviated over time as standard-issue desktop computers gain speed and are optimized for 3D graphics. Higher-bandwidth and more reliable connections to the Internet will also become more common.
Even so, consumers will often need to get hands-on experience with a product before they are willing to purchase it. Barring cumbersome and expensive gloves and goggles, VR is still strictly an audiovisual experience. Even gloves have serious limitations, they can't provide a tactile experience of the texture of clothing. Nor can VR present the fragrance of a perfume or the taste of food.
The need for hands-on experience is one reason why car sales on the Web have been much sluggish(迟钝的): Most buyers want to test drive before they buy. It would take very sophisticated VR to duplicate the test-drive experience.

Another problem is that VR content can't be viewed with just a standard browser. You need a special viewer - either a special-purpose browser or a plug-in. That wouldn't be so bad if one viewer could handle all VR content, but that's far from the case. Instead, there are many viewers, each of which has to be downloaded and installed. Whichever viewer you've already downloaded, you'll probably need another one at the next VR site you go to.

VRML: The Standard That Wasn't

For content creation, each viewer typically has its own authoring tool. There is no single tool that a programmer can learn with any expectation of addressing more than a fraction of Web users.
A standard is needed to make it possible to create content compatible with multiple viewers. Virtual Reality Modeling Language (VRML) was supposed to be that standard. VRML has been blessed by the ISO. It has been used in education and entertainment, and for visualization in medicine, engineering, and other scientific applications - chemists use VR to visualize complex interactions.
VRML has wide support in programming tools. For instance, professional animators create content using the popular high-end 3D animation program, 3D Studio MAX from Kinetix, and then use the built-in VRML export function to create the VRML file. Some cleanup of the VRML file may be needed afterwards. 3D Studio MAX has been used on a number of TV shows, and even in movies, so in the right hands, the result can be truly professional-level VR.
On the down side, VRML browsers and plug-ins tend to be large. That translates into long downloads on common PCs. For instance, Cosmo Player, a popular VRML-compatible plug-in developed by SGI and now distributed by CAI (http://www.cai.com/cosmo/), requires a download of over 3.2MB for the Windows 95/NT version.
The large size of browsers and plug-ins stems from the fact that VRML has an extensive set of required features. That also makes innovation more difficult, because each new feature has to be integrated into and tested with a complex existing feature set.
VRML applications have also had serious problems with performance and reliability. That was the case with MyTicketmaster, an application that allowed buyers to check out the view from a stadium seat before buying it. It ran very slowly and was extremely unreliable. Ticketmaster pulled it from their site.
Problems of speed and reliability have been exacerbated by the fact that VRML was perceived as not being freely extensible in a way that maintained interoperability among extensions.
"That perception was incorrect," says Ancona. "VRML was designed to be extensible via externprotos. I was able to make this work for a customer: Intervista had a special high-quality text option that looked awesome in our browser and okay in Cosmo Player. The reason companies didn't work with VRML was, quite simply, because they didn't get it. They thought that proprietary [enhancement] would help them in the long run, although really it's gotten nobody any farther than VRML itself."

XML to the Rescue?

XML (Extensible Markup Language) is emerging as the most likely alternative to or fix for VRML. XML is flexible and extensible: It basically just describes rules that enable user communities to define the HTML-style tags they require to represent structured data.
Increasingly, market-oriented companies are simply ignoring VRML in favor of XML. Vizbang.com's upcoming "Spark" presentation tool is based entirely on XML and doesn't use VRML. The file format it uses is based on its own Information Architecture Markup Language (IAML) scene description language. The IAML spec will be published and freely available to anyone who wants to use it. (A rough draft is currently available.)
Vizbang founder Ancona says that he believes people will eventually want Spark to support VR standards. At this point in the standards development process, however, most customers don't care about VR standards.

X3D

The VR community has recognized the growing success of XML, compared to the very limited success of VRML. In response, the Web3D Consortium (http://www.web3d.org), in concert with the W3C (World Wide Web Consortium), has defined an XML-compliant 3D standard for the web: X3D ("Extensible 3D"). X3D extends the capabilities of VRML and provides a means of expressing the geometry and behavior capabilities of VRML using XML. It also allows programmers to bypass much of VRML 97, if they so desire.
With X3D, VR display can take place under various "profiles". There is a "Core Profile" or API that implements minimum VR functionality. (Seehttp://www2.blaxxun.com/products/blaxxun3d/spec/html/api.html for one description of the Core Profile.) Programmers are free to create any number of other profiles that can plug into the Core Profile.
The Core Profile is much lighter weight than the full VRML spec. Other optional profiles are implemented as software components to be downloaded as necessary. Thus, X3D defines a modular architecture with no huge, monolithic VRML plug-in to complicate use, programming and innovation. With X3D, the user only uses the profiles needed to view the current content. Similarly, when content creators test their content, they only need to test with the profiles needed for that specific content, not with a massive VRML browser that may have many features they don't need. Finally, when an innovator comes up with a new profile, they can achieve minimal compatibility with the spec by testing only with the Core Profile. The price of freer innovation is a potential for incompatibility among profiles that have not been tested together. Of course, there is nothing to stop the creator of a new profile from testing with other popular profiles.
As of early May, the VRML 97 profile was the only optional profile that seemed guaranteed to see the light of day in the near future. Nevertheless, if the vision of X3D is realized, the VRML 97 profile will be just one optional profile among many -- not the indispensable standard it was designed to be.
As of early May, the XML tagset for X3D was done, and the Script Authoring Interface (SAI) was almost done. Component and interface code were ready to be tested. (Seehttp://www.web3d.org/TaskGroups/x3d/meetings/2000May4-5/X3dReport5May2000_files/v3_document.htm )
Although the specification of the Core Profile was complete, early implementations by companies like Shout3D (http://www.shout3d.com) and Blaxxun3D (http://www.blaxxun.com) were still inconsistent. The Web3D Consortium was hoping to ship an implemented X3D spec by July, 2000, but there were serious questions about whether they would be able to do so.

Content is Key

Standards and technical issues aside, the lack of compelling(令人信服的) VR applications and content remains a key problem. Before users will make the necessary effort and investment, they need to know "What's in it for me?" Compelling VR applications and content could inspire users to leap the technical hurdles to VR. Then money could presumably be made in providing VR viewing technology or in licensing VR content, and the whole VR industry would take off. So far, no one has created the compelling content.
Several applications do hold promise for VR. One hopeful direction is for creating interactive 3D visualizations of Web sites. Technical support is another area that seems rich in possibilities. Instead of telling a customer how something works, a support technician could demonstrate and then let the customer experiment in VR before attempting the real thing. Other promising areas are desktop and data interfaces, to help people organize their work, data, thoughts and presentations. That's where Vizbang.com is focusing its attention.
Two other areas that could get the ball rolling are medicine and education/training. If VR could help a doctor make a preliminary diagnosis remotely, a patient with a rare disease could be transferred more quickly to the correct medical facility.

"MP3 files are large and require a special viewer, and they're growing like wildfire," observes Ancona. "File sizes or slowness or extra software required, or whatever -- if there's a compelling reason for people to use something, they'll go to the trouble to get it."
Mike Hurwicz has written articles on computer technology for more than 15 years.

vendredi 20 août 2010

OpenGL中使用GLUI

参考Bullet的demos, which are based on OpenGL and GLUI.

C++ Class和Struct 以及如何设计 Class


struct 定义的结构默认情况下是public型的,而class 的默认情况是private 型的.其他都可以同用.
例如:
struct A{
int a;
char b;
};//此时a b 都是公有成员变量.
class B{
int a;
char b;

} //a b 分别属于私有成员变量.



A class is a data structure that contains related data and functions  
and is a unit of object-oriented programming.
Objects are an instantiation of a class  
and share the same properties although their contents may differ. 
Classes may inherit properties from other classes 
and support the encapsulation of data structures through access specifiers. 
The following steps explain how to create a C++ class.

  1. 1
    Define the class using the class keyword. This will provide the class a name, an optional list of access specifiers and an optional list of object names.

  2. 2
    Declare members as either access specifiers, data or functions within the body of the class statement.
3Provide the access specifiers to indicate one of the 3 levels of access in C++. 
  • Private members are only accessible by members of that class and their associates. 
  • Members who are protected are accessible by members in that class, any derived classes and any associates of those classes.
  • When the object is visible public members are accessible. 
  • The default is private.

  1. 4
    Learn the syntax of the class statement: class class_name  { access_specifier_1:member1; access_specifier_2:member2; ... access_specifier_n:membern; } object_names;

  2. 5
    Look at the following example of the class statement: class CTest { int i, j; public: void set_values (int,int); int total (void); } test; Note that the integers i and j do not have an access specifier and are therefore private. The function set_values and the integer total are public.

Creating and applying patch

对于开源软件代码,使用Tortoise SVN进行补丁。

See http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-patch.html for details!

jeudi 19 août 2010

Lib 文件和Dll文件的差别和联系

摘自 痞子龙3D编程



什么是lib文件,lib和dll的关系如何?

(1)lib是编译时需要的,dll是运行时需要的。
如果要完成源代码的编译,有lib就够了。
如果也使动态连接的程序运行起来,有dll就够了。
在开发和调试阶段,当然最好都有。

(2)一般的动态库程序有lib文件和dll文件。
lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。

(3)在动态库的情况下,有两个文件,一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。


一、开发和使用dll需注意三种文件   

  1、   dll头文件   
  它是指dll中说明输出的类或符号原型或数据结构的.h文件。当其它应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
 
  2、   dll的引入库文件   
  它是dll在编译、链接成功后生成的文件。主要作用是当其它应用程序调用dll时,需要将该文件引入应用程序。否则,dll无法引入。
  
  3、   dll文件(.dll)   
  它是应用程序调用dll运行时,真正的可执行文件。dll应用在编译、链接成功后,.dll文件即存在。开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,不必有.lib文件和dll头文件。  
动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。

动态链接与静态链接的不同之处在于:动态链接允许可执行模块(.dll 文件或 .exe 文件)仅包含在运行时定位 DLL 函数的可执行代码所需的信息。在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。

使用动态链接代替静态链接有若干优点。DLL 节省内存,减少交换操作,节省磁盘空间,更易于升级,提供售后支持,提供扩展 MFC 库类的机制,支持多语言程序,并使国际版本的创建轻松完成。

lib与dll文件最大区别在调用方面
dll可以静态陷入
lib与DLL
从这一章起,我讲述的内容将特定于windows平台。其实这篇文章也可看作是我在windows下的开发经验总结,因为以后我决定转unix了。
前面有一章说编译与链接的,说得很简略,其实应该放到这一章一块儿来说的。许多单讲C++的书其实都过于学院派,对于真实的工作环境,上百个源文件怎么结合起来,几乎没有提及。我引导读者一步步看看lib与DLL是怎么回事。
一个最简单的C++程序,只需要一个源文件,这个源文件包含了如下语句
int main(){return 0;}
自然,这个程序什么也不做。
当需程序需要做事情时,我们会把越来越多的语句添加到源文件中,例如,我们会开始在main函数中添加代码:
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
由于人的智力水平的限制,当一个函数中包含了太多的语句时,便不太容易被理解,这时候开始需要子函数:
#include <stdio.h>
void ShowHello()

printf("Hello World!\n");
}
int main()
{
ShowHello();
return 0;
}
同样的道理,一个源文件中包含了太多的函数,同样不好理解,人们开始分多个源文件了
// main.cpp
void ShowHello();//[1]
int main()
{
ShowHello();
return 0;
}
// hello.cpp
#include <stdio.h>
void ShowHello()
{
printf("Hello World!\n");
}
将这两个文件加入到一个VC工程中,它们会被分别编译,最后链接在一起。在VC编译器的输出窗口,你可以看到如下信息
--------------------Configuration: hello - Win32 Debug--------------------
Compiling...
main.cpp
hello.cpp
Linking...
hello.exe - 0 error(s), 0 warning(s)
这展示了它们的编译链接过程。

接下来,大家就算不知道也该猜到,当一个工程中有太多的源文件时,它也不好理解,于是,人们想到了一种手段:将一部分源文件预先编译成库文件,也即lib文件,当要使用其中的函数时,只需要链接lib文件就可以了,而不用再理会最初的源文件

在VC中新建一个static library类型的工程,加入hello.cpp文件,然后编译,就生成了lib文件,假设文件名为hello.lib。
别的工程要使用这个lib有两种方式
1 在工程选项-〉link-〉Object/Library Module中加入hello.lib
2 可以在源代码中加入一行指令
#pragma comment(lib, "hello.lib")
注意这个不是C++语言的一部分,而是编译器的预处理指令,用于通知编译器需要链接hello.lib。

根据个人爱好任意使用一种方式既可。
这种lib文件的格式可以简单的介绍一下,它实际上是任意个obj文件的集合。obj文件则是cpp文件编译生成的,在本例中,lib文件只包含了一个obj文件,如果有多个cpp文件则会编译生成多个obj文件,从而生成的lib文件中也包含了多个obj。
注意,这里仅仅是集合而已,不涉及到link,所以,在编译这种静态库工程时,你根本不会遇到链接错误。即使有错,错误也只会在使用这个lib的EXE或者DLL工程中暴露出来。


关于静态lib,就只有这么多内容了,真的很简单,现在我们介绍另外一种类型的lib,它不是obj文件的集合,即里面不含有实际的实现,它只是提供动态链接到DLL所需要的信息。这种lib可以在编译一个DLL工程时由编译器生成。涉及到DLL,问题开始复杂起来,我不指望在本文中能把DLL的原理说清楚,这不是本文的目标,我介绍操作层面的东西。

简单的说,一个DLL工程和一个EXE工程的差别有两点
1 EXE的入口函数是main或者WinMain,而DLL的入口函数是DllMain
2 EXE的入口函数标志着一段处理流程的开始,函数退出后,流程处理就结束了,而DLL的入口函数对系统来说,只是路过,加载DLL的时候路过一次,卸载DLL的时候又路过一次[2],你可以在DLL入口函数中做流程处理,但这通常不是DLL的目的,DLL的目的是要导出函数供其它DLL或EXE使用。你可以把DLL和EXE的关系理解成前面的main.cpp和hello.cpp的关系,有类似,实现手段不同罢了。
先看如何写一个DLL以及如何导出函数,读者应该先尝试用VC创建一个新的动态链接库工程,创建时选项不选空工程就可以了,这样你能得到一个示例,以便开始在这个例子基础上工作。
看看你创建的例子中的头文件有类似这样的语句:
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
这就是函数的导出与使用导出函数的全部奥妙了。你的DLL工程已经在工程设置中定义了一个宏DLL_EXPORTS,因此你的函数声明只要前面加DLL_API就表示把它导出,而DLL的使用者由于没有定义这个宏,所以它包含这个头文件时把你的函数看作导入的。通过模仿这个例子,你就可以写一系列的标记为导出的函数了。
导出函数还有另一种方法,是使用DEF文件,DEF文件的作用,在现在来说只是起到限定导出函数名字的作用,这里,我们要引出第二种[4]使用DLL的方法:称为显示加载,通过Windows API的LoadLibrary和GetProcAddress这两个函数来实现[5],这里GetProcAddress的参数需要一个字符串形式的函数名称,如果DLL工程中没有使用DEF文件,那么很可能你要使用非常奇怪的函数名称(形如:?fnDll@@YAHXZ)才能正确调用,这是因为C++中的函数重载机制把函数名字重新编码了,如果使用DEF文件,你可以显式指定没编码前的函数名。
有了这些知识,你可以开始写一些简单的DLL的应用,但是我可以百分之百的肯定,你会遇到崩溃,而之前的非DLL的版本则没有问题。假如你通过显式加载来使用DLL,有可能会是调用约定不一致而引起崩溃,所谓调用约定就是函数声明前面加上__stdcall __cdecl等等限定词,注意一些宏如WINAPI会定义成这些限定词之一,不理解他们没关系,但是记住一定要保持一致,即声明和定义时一致,这在用隐式加载时不成问题,但是显示加载由于没有利用头文件,就有可能产生不一致。
调用约定并不是我真正要说的,虽然它是一种可能。我要说的是内存分配与释放的问题。请看下面代码:
void foo(string& str)
{
str = "hello";
}
int main()
{
string str;
foo(str);
printf("%s\n", str.c_str());
return 0;
}
当函数foo和main在同一个工程中,或者foo在静态库中时,不会有问题,但是如果foo是一个DLL的导出函数时,请不要这么写,它有可能会导致崩溃[6]。崩溃的原因在于“一个模块中分配的内存在另一个模块中释放”,DLL与EXE分属两个模块,例子中foo里面赋值操作导致了内存分配,而main中return语句之后,string对象析构引起内存释放。
我不想穷举全部的这类情况,只请大家在设计DLL接口时考虑清楚内存的分配释放问题,请遵循谁分配,谁释放的原则来进行。
如果不知道该怎么设计,请抄袭我们常见的DLL接口--微软的API的做法,如:
CreateDC
ReleaseDC
的成对调用,一个函数分配了内存,另外一个函数用来释放内存。
回到我们有可能崩溃的例子中来,怎么修改才能避免呢?
这可以做为一个练习让读者来做,这个练习用的时间也许会比较长,如果你做好了,那么你差不多就出师了。一时想不到也不用急,我至少见过两个有五年以上经验的程序员依然犯这样的错误。

Errors when compile OgreBullet_demos

http://www.ogre3d.org/addonforums/viewtopic.php?f=12&t=4155&p=61874&hilit=link+error#p61874

关于OgreBullet_SDK的编译和使用Ogre VC8 AppWizard to set up application

 Firstly, using Toitoise SVN software (http://tortoisesvn.net/downloads) to download latest version source code from Ogre Addon svn (https://ogreaddons.svn.sourceforge.net/svnroot/ogreaddons/trunk/).


Secondly, because there is no "makefileList" in the folder, so It is not possible to create VC8 project by using CMake. An alternative way is to create a emplty project in VC8 and add the projects (OgreBulletCollisions and OgreBulletDynamics).


Comple them, and libs are obtained! 
             (Notes: link errors appear when compile "Dynamics_Demos", I tried patches for OgreBullet from
              http://sourceforge.net/tracker/?group_id=225283&atid=1064241)


 Next step is to use Ogre VC8 AppWizard to set up Ogre wrapper application.
 see http://www.ogre3d.org/tikiwiki/OgreBullet+Tutorial+1&structure=Libraries

 (continuing......)  

 Here we go..................



Preparation

- unpack Bullet and fetch OgreBullet to a place in the hard drive
- set an environment variable:
BULLET_HOME C:\OgreSDK\AddOns\bullet-2.76 (if this is were you unpacked Bullet)
You can find the place in Windows XP following this path: open Control Panel (classic view) / System / Advanced / Environment Variables. Set it in the User Variables box.
- build Bullet in your IDE (I done it in VS2008 Express)__
''The project file for VS 2008 is here: ....\bullet-2.76\msvc\2008\BULLET_PHYSICS.sln
Build it in debug and release mode. It should compile without any problem.''
- build OgreBullet also: ....\OgreBullet\OgreBullet_SDK.sln
VS2008 converted the project without any errors for me.
When you build the debug version of the demos you may have some errors about missing .lib files.
Put these files to ....\OgreBullet\lib\Debug\:
BulletCollision.lib, can be found here: ....\bullet-2.76\msvc\2008\src\BulletCollision\Debug\
BulletDynamics.lib, can be found here: ....\bullet-2.76\msvc\2008\src\BulletDynamics\Debug\
ConvexDecomposition.lib, can be found here: ....\bullet-2.76\msvc\2008\Extras\ConvexDecomposition\Debug\
GIMPACTUtils.lib, can be found here: ....\bullet-2.76\msvc\2008\Extras\GIMPACTUtils\Debug\
LinearMath.lib, can be found here: ....\bullet-2.76\msvc\2008\src\LinearMath\Debug\
There are some files what we don't need now but you may need later. For example BulletSoftBody.lib. If something is missing when you use more components from Bullet, don't forget to copy it to the right place.
NOTE: If you want to Compile/Run the OgreBullet demos supplied with OgreBullet and it can't find resources.cfg don't wonder. This tutorial is not about these demos but I think you can solve it yourself. There are some problems with paths :-)
If you want to build the release version of the demos (or any OgreBullet project!) you have to put the Bullet .lib files to the ....\OgreBullet\lib\Release folder.
But beware! You have to put the RELEASE version of Bullet .lib files to this dir, not the same files what were listed before.
Now we have the required files, let's close this project and start a new!

Create an empty project with Bullet support

If you have Ogre Appwizard installed, create a new Ogre project:
New project -->“ Ogre SDK Application -->“ OgreBullet_Collision_test -->“ Finish
I refer to the classes with the names what are generated from the project name. If you want to use another name, be careful with the different names.

(If you don't have Appwizard just create a basic Ogre application what is able to create a window, 
fire up a FrameListener and care for keyboard/mouse input handle.)

From now on I refer to Appwizard basic project.
Before we start coding (in the next tutorial) we need to do some configuration:
    - Open Project\Properties (Alt+F7)
    - Go to Configuration Properties\C/C++\General
    - Find Additional Include Directories, open with '...' button
    - Put $(BULLET_HOME)\src to the end of the list.
    - Change the Configuration (in the top-left corner of the window) to Release and do the same.
    - Now go to Configuration Properties\Linker\Input
    - Find Additional Dependencies
    - Add required elements. In the end it should contain these:
  • OgreMain_d.lib 
  • OIS_d.lib 
  • OgreBulletCollisions_d.lib 
  • OgreBulletDynamics_d.lib 
  • bulletcollision.lib 
  • bulletdynamics.lib 
  • LinearMath.lib 
  • GIMPACTutils.lib 
  • ConvexDecomposition.lib

  - Change the Configuration (in the top-left corner of the window) to Release and insert these to the same place as before:
  • OgreMain.lib OIS.lib 
  • OgreBulletCollisions.lib 
  • OgreBulletDynamics.lib 
  • bulletcollision.lib 
  • bulletdynamics.lib 
  • LinearMath.lib 
  • GIMPACTutils.lib 
  • ConvexDecomposition.lib

- Now close this window and go to Tools\Options\Projects and Solutions\VC++ Directories\
- Set Show directories for: Include files
- Put these into the list (your path to OgreBullet needed):
....\OgreBullet\Collisions\include
....\OgreBullet\Dynamics\include
- Change to Library files and put these to the list:
....\OgreBullet\lib\Debug
....\OgreBullet\lib\Release
Build the project. It should be working. Now you can start the next tutorial what is based on this project :-)
NOTE: source code can be found at the end of the second tutorial.

mercredi 18 août 2010

Call-back函数

摘自 痞子龙3D编程
简介  对于很多初学者来说,往往觉得回调函数很神秘,很想知道回调函数的工作原理。本文将要解释什么是回调函数、它们有什么好处、为什么要使用它们等等问题,在开始之前,假设你已经熟知了函数指针。
什么是回调函数?
简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
为什么要使用回调函数?
因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。

如果想知道回调函数在实际中有什么作用,先假设有这样一种情况,我们要编写一个库,它提供了某些排序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为使库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。

回调可用于通知机制,例如,有时要在程序中设置一个计时器,每到一定时间,程序会得到相应的通知,但通知机制的实现者对我们的程序一无所知。而此时,就需有一个特定原型的函数指针,用这个指针来进行回调,来通知我们的程序事件已经发生。实际上,SetTimer() API使用了一个回调函数来通知计时器,而且,万一没有提供回调函数,它还会把一个消息发往程序的消息队列。

另一个使用回调机制的API函数是EnumWindow(),它枚举屏幕上所有的顶层窗口,为每个窗口调用一个程序提供的函数,并传递窗口的处理程序。如果被调用者返回一个值,就继续进行迭代,否则,退出。EnumWindow()并不关心被调用者在何处,也不关心被调用者用它传递的处理程序做了什么,它只关心返回值,因为基于返回值,它将继续执行或退出。

不管怎么说,回调函数是继续自C语言的,因而,在C++中,应只在与C代码建立接口,或与已有的回调接口打交道时,才使用回调函数。除了上述情况,在C++中应使用虚拟方法或函数符(functor),而不是回调函数。
一个简单的回调函数实现
下面创建了一个sort.dll的动态链接库,它导出了一个名为CompareFunction的类型--typedef int (__stdcall *CompareFunction)(const byte*, const byte*),它就是回调函数的类型。另外,它也导出了两个方法:Bubblesort()和Quicksort(),这两个方法原型相同,但实现了不同的排序算法。
void DLLDIR __stdcall Bubblesort(byte* array,int size,int elem_size,CompareFunction cmpFunc);

void DLLDIR __stdcall Quicksort(byte* array,int size,int elem_size,CompareFunction cmpFunc);

  这两个函数接受以下参数:

  ·byte * array:指向元素数组的指针(任意类型)。

  ·int size:数组中元素的个数。

  ·int elem_size:数组中一个元素的大小,以字节为单位。

  ·CompareFunction cmpFunc:带有上述原型的指向回调函数的指针。

  这两个函数的会对数组进行某种排序,但每次都需决定两个元素哪个排在前面,而函数中有一个回调函数,其地址是作为一个参数传递进来的。对编写者来说,不必介意函数在何处实现,或它怎样被实现的,所需在意的只是两个用于比较的元素的地址,并返回以下的某个值(库的编写者和使用者都必须遵守这个约定):

  ·-1:如果第一个元素较小,那它在已排序好的数组中,应该排在第二个元素前面。

  ·0:如果两个元素相等,那么它们的相对位置并不重要,在已排序好的数组中,谁在前面都无所谓。 

  ·1:如果第一个元素较大,那在已排序好的数组中,它应该排第二个元素后面。

  基于以上约定,函数Bubblesort()的实现如下,Quicksort()就稍微复杂一点:


void DLLDIR __stdcall Bubblesort(byte* array,int size,int elem_size,CompareFunction cmpFunc)
{
for(int i=0; i < size; i++)
{
for(int j=0; j < size-1; j++)
{
//回调比较函数
if(1 == (*cmpFunc)(array+j*elem_size,array+(j+1)*elem_size))
{
//两个相比较的元素相交换
byte* temp = new byte[elem_size];
memcpy(temp, array+j*elem_size, elem_size);
memcpy(array+j*elem_size,array+(j+1)*elem_size,elem_size);
memcpy(array+(j+1)*elem_size, temp, elem_size);
delete [] temp;
}
}
}
}

  注意:因为实现中使用了memcpy(),所以函数在使用的数据类型方面,会有所局限。

  对使用者来说,必须有一个回调函数,其地址要传递给Bubblesort()函数。下面有二个简单的示例,一个比较两个整数,而另一个比较两个字符串:


int __stdcall CompareInts(const byte* velem1, const byte* velem2)
{
int elem1 = *(int*)velem1;
int elem2 = *(int*)velem2;

if(elem1 < elem2)
return -1;
if(elem1 > elem2)
return 1;

return 0;
}

int __stdcall CompareStrings(const byte* velem1, const byte* velem2)
{
const char* elem1 = (char*)velem1;
const char* elem2 = (char*)velem2;
return strcmp(elem1, elem2);
}

  下面另有一个程序,用于测试以上所有的代码,它传递了一个有5个元素的数组给Bubblesort()和Quicksort(),同时还传递了一个指向回调函数的指针。


int main(int argc, char* argv[])
{
int i;
int array[] = {5432, 4321, 3210, 2109, 1098};

cout << "Before sorting ints with Bubblesort\n";
for(i=0; i < 5; i++)
cout << array[i] << '\n';

Bubblesort((byte*)array, 5, sizeof(array[0]), &CompareInts);

cout << "After the sorting\n";
for(i=0; i < 5; i++)
cout << array[i] << '\n';

const char str[5][10] = {"estella","danielle","crissy","bo","angie"};

cout << "Before sorting strings with Quicksort\n";
for(i=0; i < 5; i++)
cout << str[i] << '\n';

Quicksort((byte*)str, 5, 10, &CompareStrings);

cout << "After the sorting\n";
for(i=0; i < 5; i++)
cout << str[i] << '\n';

return 0;
}

  如果想进行降序排序(大元素在先),就只需修改回调函数的代码,或使用另一个回调函数,这样编程起来灵活性就比较大了。

          调用约定
  上面的代码中,可在函数原型中找到__stdcall,因为它以双下划线打头,所以它是一个特定于编译器的扩展,说到底也就是微软的实现。任何支持开发基于Win32的程序都必须支持这个扩展或其等价物。以__stdcall标识的函数使用了标准调用约定,为什么叫标准约定呢,因为所有的Win32 API(除了个别接受可变参数的除外)都使用它。标准调用约定的函数在它们返回到调用者之前,都会从堆栈中移除掉参数,这也是Pascal的标准约定。但在C/C++中,调用约定是调用者负责清理堆栈,而不是被调用函数;为强制函数使用C/C++调用约定,可使用__cdecl。另外,可变参数函数也使用C/C++调用约定。

  Windows操作系统采用了标准调用约定(Pascal约定),因为其可减小代码的体积。这点对早期的Windows来说非常重要,因为那时它运行在只有640KB内存的电脑上。

  如果你不喜欢__stdcall,还可以使用CALLBACK宏,它定义在windef.h中:


#define CALLBACK __stdcallor

#define CALLBACK PASCAL //而PASCAL在此被#defined成__stdcall

  作为回调函数的C++方法

  因为平时很可能会使用到C++编写代码,也许会想到把回调函数写成类中的一个方法,但先来看看以下的代码:


class CCallbackTester
{
public:
int CALLBACK CompareInts(const byte* velem1, const byte* velem2);
};

Bubblesort((byte*)array, 5, sizeof(array[0]),
&CCallbackTester::CompareInts);

  如果使用微软的编译器,将会得到下面这个编译错误:


error C2664: 'Bubblesort' : cannot convert parameter 4 from 'int (__stdcall CCallbackTester::*)(const unsigned char *,const unsigned char *)' to 'int (__stdcall *)(const unsigned char *,const unsigned char *)' There is no context in which this conversion is possible

  这是因为非静态成员函数有一个额外的参数:this指针,这将迫使你在成员函数前面加上static。当然,还有几种方法可以解决这个问题,但限于篇幅,就不再论述了。

环境变量

摘自 痞子龙3D编程
环境变量相当于给系统或用户应用程序设置的一些参数, 具体起什么作用这当然和具体的环境变量相关. 比如path, 是告诉系统, 当要求系统运行一个程序而没有告诉它程序所在的完整路径时, 系统除了在当前目录下面寻找此程序外, 还应到哪些目录下去寻找; 再如tc或vc++中, set include=path1;path2; 是告诉编译程序到哪里去找.h类型的文件; 当然不仅仅是指定什么路径, 还有其它的作用的, 如set dircmd=/4 设置一个环境变量的作用是在使用dir命令时会把/4作为缺省的参数添加到你的dir命令之后, 就像你的每个命令都加了/4参数, 它实际上是给命令解释程序command设置的一个环境变量, 并且是给dir这个内部命令设置的。
DWORD GetEnvironmentVariable(LPCSTR lpName, LPSTR lpBuffer, DWORD dSize), 参数lpName是你要求查询的环境变量的名, lpBuffer是返回你所指定的环境变量的值的, dSize是告诉这个函数lpBuffer可以存放多少个字节.
分析本地故障时原因很可能就是因为环境变量中的默认路径被删除的结果,默认路径一经设置,当前系统如有程序运行时需要某些DLL或EXE文件,以及Active控件时就会到所有默认路径中去查找,如果在这些目录中查找到相应的程序则自动加载,查找不到则报告缺少某某文件的错误信息。
小知识:什么是环境变量?环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,比如临时文件夹位置和系统文件夹位置等。这点有点类似于DOS时期的默认路径,当你运行某些程序时除了在当前文件夹中寻找外,还会到设置的默认路径中去查找。简单地说这里的“Path”就是一个变量,里面存储了一些常用命令所存放的目录路径。
很多朋友会在自己的计算机上安装双系统,例如C盘安装Windows 98,D盘安装Windows XP。可是某些软件往往只在Windows 98系统中安装,Windows XP系统中是无法正常使用的,比较麻烦却有效的方法是再安装一遍。当我们了解了环境变量中的用途后就可以很好解决双系统的软件共用问题。
小提示:为什么在Windows 98中安装了的软件在Windows XP下无法运行呢(绿色软件除外)?原因是安装软件时往往须要向系统目录中复制某些文件,而使用另外一个系统时会由于缺少这些文件而无法运行。因此,我们可以通过设置环境变量的方法来解决这个问题。


环境变量设置方法

在windows操作系统中可以通过我的电脑-〉属性-〉高级,来设置系统的环境变量,然而在此设置的环境变量是否在注册表中具有对应的项呢?答案是肯定的。而在.net 中提供了一个类来获取系统的环境变量及其值。
环境变量分为两类:用户变量与系统变量,在注册表中都有对应的项。
其中用户变量所在位置:
HKEY_CURRENT_USER\Environment;
系统变量所在位置为:\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001
\Control\Session Manager\Environment。
另外也可以右击我的电脑——高级——环境变量——在系统变量里有path选项——双击打开——在原有变量的基础上添加英文状态下的分号——然后将路径名输入即可。(切记,不要删除原先的系统变量,只要用分号隔开,然后添加)


常见环境变量

%ALLUSERSPROFILE% 局部 返回所有“用户配置文件”的位置。
%APPDATA% 局部 返回默认情况下应用程序存储数据的位置。
%CD% 局部 返回当前目录字符串。
%CMDCMDLINE% 局部 返回用来启动当前的 Cmd.exe 的准确命令行。
%CMDEXTVERSION% 系统 返回当前的“命令处理程序扩展”的版本号。
%COMPUTERNAME% 系统 返回计算机的名称。
%COMSPEC% 系统 返回命令行解释器可执行程序的准确路径。
%DATE% 系统 返回当前日期。使用与 date /t 命令相同的格式。由 Cmd.exe 生成。有关 date 命令的详细信息,请参阅 Date。
%ERRORLEVEL% 系统 返回最近使用过的命令的错误代码。通常用非零值表示错误。
%HOMEDRIVE% 系统 返回连接到用户主目录的本地工作站驱动器号。基于主目录值的设置。用户主目录是在“本地用户和组”中指定的。
%HOMEPATH% 系统 返回用户主目录的完整路径。基于主目录值的设置。用户主目录是在“本地用户和组”中指定的。
%HOMESHARE% 系统 返回用户的共享主目录的网络路径。基于主目录值的设置。用户主目录是在“本地用户和组”中指定的。
%LOGONSEVER% 局部 返回验证当前登录会话的域控制器的名称。
%NUMBER_OF_PROCESSORS% 系统 指定安装在计算机上的处理器的数目。
%OS% 系统 返回操作系统的名称。Windows 2000 将操作系统显示为 Windows_NT。
%PATH% 系统 指定可执行文件的搜索路径。
%PATHEXT% 系统 返回操作系统认为可执行的文件扩展名的列表。
%PROCESSOR_ARCHITECTURE% 系统 返回处理器的芯片体系结构。值: x86,IA64。
%PROCESSOR_IDENTFIER% 系统 返回处理器说明。
%PROCESSOR_LEVEL% 系统 返回计算机上安装的处理器的型号。
%PROCESSOR_LEVEL% 系统 返回处理器的版本号。
%PROMPT% 局部 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。
%RANDOM% 系统 返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。
%SYSTEMDRIVE% 系统 返回包含 Windows XP 根目录(即系统根目录)的驱动器。
%SYSTEMROOT% 系统 返回 Windows XP 根目录的位置。
%TEMP% and %TMP% 系统和用户 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP,而其它应用程序则需要 TMP。
%TIME% 系统 返回当前时间。使用与 time /t 命令相同的格式。由 Cmd.exe 生成。有关 time 命令的详细信息,请参阅 Time。
%USERDOMAIN% 局部 返回包含用户帐户的域的名称。
%USERNAME% 局部 返回当前登录的用户的名称。
%UserPrefix% 局部 返回当前用户的配置文件的位置。
%WINDIR% 系统 返回操作系统目录的位置。

在命令行中对环境变量进行编辑


查看当前可用的所有环境变量(=系统变量+用户变量)
set
查看某个环境变量,如PATH
set PATH
添加环境变量,如xxx=aa
set xxx=aa
将环境变量(如xxx)的值置为空
set xxx=
在某个环境变量(如PATH)后添加新的值(如d:\xxx)
set PATH=%PATH%;d:\xxx
(注:在dos窗口中以命令行方式对环境变量的操作只对当前窗口的应用有效)