Posts

一分钟搞定boost库编译

假定已经从www.boost.org下载了最新的boost安装包,以boost1.39.0为例: 把压缩包解压到某目录,比如E:\sdk下,这时候,将得到目录:E:\sdk\boost_1_39_0在此目录下,将有一个子目录boost,里面就是所有的boost内容。 进入 E:\sdk\boost_1_39_0\tools\jam\src 目录,点击 build.bat 文件,将执行 bjam.exe 文件的构建,构建完毕后,将生成E:\sdk\boost_1_39_0\tools\jam\src\bin.ntx86目录。 bjam.exe 就在此目录下。 将 bjam.exe 拷贝到E:\sdk\boost_1_39_0下,在在系统菜单中,点出“运行”对话框,执行cmd命令,调出控制台窗口,然后把当前目录定位到E:\sdk\boost_1_39_0。 输入如下命令: bjam stage --toolset=msvc-8.0 link=shared runtime-link=shared threading=multi debug release 注意上面的命令行中,等号两端的变量不能留有空格,比如-toolset = msvc-8.0会报错。这样子,就将使用VC2005,以生成多线程版本的,同时生成调试版和发行版的动态链接库文件的形式构建所有需要构建的boost库,如果想生成所有版本的:包括单多线程,静态动态链接的,调试版发行版的全部都有的库,则可以用下面一句命令搞定: bjam --toolset=msvc-8.0 --build-type=complete

从计算着色器到四边形【翻译】

原文地址 // input texture Texture2D<float3> _sourceTexture; // a compute buffer that we can append to for output AppendStructuredBuffer<int2> _brightPoints; 在上面的代码段中,_sourceTexture是从外部传给GPU的纹理。和在fragment shader中访问纹理不一样的是,在片元着色器中通过采样器(sampler)获取纹理,纹理坐标是浮点数,而在compute shader中,“纹理”可以视为一个二维数组,可以通过整数索引值,直接访问这“二维数组”中的元素——纹素。 AppendStructedBuffer AppendStructuredBuffer 可视为是原始缓冲区的“升级版”,即结构化缓冲区。原始缓冲区(raw buffer)只是一个字节数组,而结构化缓冲区意味着可以为缓冲区中的每个元素定义一个结构。可以用来AppendStructuredBuffer.Append()方法将元素从缓冲区的末尾加入。重AppendStructuredBuffer.Append()是一个线程安全的操作。即使有数千个线程同时尝试向缓冲区添加某些内容,也不会产生冲突。 // tell Unity that the function "FindBrights" is a compute kernel #pragma kernel FindBrights // define thread groups for the FindBrights kernel [numthreads(32, 32, 1)] pragma kernel 指令 #pragma kernel FindBrights是Unity专用的代码。用来通知Unity函数FindBrights是计算内核(compute kernel),这意味着它可以用作计算着色器,而不仅仅是一个普通函数。 numthreads指令 numthreads指令的三个输入参数分别表示该着色器在工作组(Work Group)内的线程布局。具体来说,numthreads(x, y, z)指令中xyz三个参数分别定义了在X、Y和Z三个维度上每个工作组中线程的数量。这三个参数决定了工作组内线程的总数量,例如numthreads(8, 8, 1) 就定义了一个工作组包含 8 x 8 x 1 = 64 个线程。工作组的总线程数直接影响计算的并行性,在实际调用时,通过Dispatch()函数定义工作组的分布。如下代码:

在Unity3D中使用Visual Studio调试shader【翻译】

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 原文地址 本文主要介绍在U3D中调试shader代码的主要技术:false-color images:通过设置片元颜色中的某个分量,使得该值可视。然后根据resulting image中的颜色分量的亮度(intensity of that color component),你可以得到shader代码中的值的结论,这种技术的确是一种很原始的调试技术,但不幸的是,这在U3D中并不是不常见的。 1 顶点数据来自何方 在RGB cube一节中,你可以看到片元着色器如何通过顶点着色器输出的结构体中,获取到对应的数据。那么问现在的问题是:顶点着色器从何方拿到这些数据?在U3D环境下,答案是从绑定到game object中的Mesh Renderer组件中获取。Mesh Renderer组件将在每一帧中所有的发送网格顶点数据给OpenGL。这一步发送操作通常被称为“draw call”。必须注意的是,每一个的draw call都有一些性能耗费(performance overhead)。因而,一次性地给OpenGL发送一个大的网格数据,比分多次发送,每次发送一些较小的网格数据,要来得更高效些。这些网格数据通常由一系列的三角形组成,而每一个三角形则是以”三个顶点数据和一些其他属性数据“的方式被定义。这些属性数据将会通过”顶点输入参数(vertex input parameter)“的方式在顶点着色器中被启用。每一个顶点输入参数将会指定一系列的语义,如POSITION, NORMAL, TEXCOORD0, TEXCOORD1, TANGENT, COLOR等等。在U3D环境下的Cg语言的特定编程实现中。这些内建的顶点输入参数将会由一个特定的名字。 2 内建的顶点输入参数,以及如何使得它们可视 在U3D中的,内建的顶点输入参数不仅仅有特定的语义表示符号,还有特定的变量名字和类型,此外,他们还被包含在一个单独的结构体中,如下: struct vertexInput { float4 vertex:POSITION; // position (in object coordinates, i.e. local or model coordinates) float4 tangent:TANGENT; // vector orthogonal to the surface normal float3 normal:NORMAL; //surface normal vector (in object coordinates; usually normalized to unit //length float4 texcoord:TEXCOORD0; //0th set of texture coordinates (a.

Leap Motion的坐标系和变换操作(翻译)

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 原文地址 Coordinate Systems A fundamental task when using the Leap Motion controller in an application is mapping the coordinate values received from the controller to the appropriate application-defined coordinate system. 在一个应用里面使用Leap Motion控制器的一个基本的任务是:把从控制器处接收到的基于Leap Motion坐标系下的坐标值,转换到对应的应用内定义的坐标系下。 Leap Motion Coordinates The Leap Motion Controller provides coordinates in units of real world millimeters within the Leap Motion frame of reference. That is, if a finger tip’s position is given as (x, y, z) = [100, 100, -100], those numbers are millimeters – or, x = +10cm, y = 10cm, z = -10cm.

Unity3D PlayerPrefs的存储位置

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 平台 存储位置 macOS 存储在 【~/Library/Preferences】 目录下名字为 【unity.[company name].[product name].plist】 文件中,其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置。而且这个plist文件是为编辑器版本和单独可执行版本的程序共同使用。 Windows 存在注册表中的注册项中,该注册项的路径是 【HKEY_CURRENT_USER\Software[company name][product name]】。其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置。注意编辑器版本和单独可执行版本的注册表路径是不同的,例如 【company name】 是 “TomCompany” ,例如 【product name】 是 “TomGame” 的话,在编辑器中执行程序,其注册项路径为 【计算机\HKEY_CURRENT_USER\Software\Unity\UnityEditor\TomCompany\TomGame】 Linux PlayerPrefs存储在 【~/.config/unity3d/[CompanyName]/[ProductName]】 。其中的 【company name】 和 【product names】 在 【Project Settings】 面板中设置.。 Windows Store Apps PlayerPrefs存储在 【%userprofile%\AppData\Local\Packages[ProductPackageId]\LocalState\playerprefs.dat】 文件中 Windows Phone 8 PlayerPrefs存储在应用的 “local folder” 中,可查阅Directory.

Windows平台上无法启动Android ADB Server的解决方案

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 在Windows系统上使用adb时。经常会出现adb devices命令长时间无响应、adb start-server 失败、eclipse adt初始化时卡在dbms-init上等现象。造成这个问题的大部分原因,是在于adb server所默认使用的5037号端口被占用了。这种情况尤其在Windows系统装了类似于360手机助手等软件时经常出现。比如360助手在启动之后,会启动一个名字为360MobileLink.exe的进程。这个进程一般会占用这个默认端口号。 解决这个问题的最直接野蛮的方法,就是找出占用5037端口的进程,然后关闭它。我们可以使用命令行操作,如下: netstat -aon | findstr 127.0.0.1:5037 执行此命令后,便会打印出占用这个端口的进程的PID,根据这个PID值。我们再输入命令如下: tasklist|findstr "进程PID" 执行此命令后,便会打印出这个进程对应的可执行文件名,启动任务管理器关闭它即可。关闭了这个进程后,执行 adb kill-server adb start-server 便可重新启动adb server。所以在开发时,最好先打开elipse等软件,启动了adb之后,再启动360手机助手等软件,才不会发生这种占用端口的问题。 还有另一种方法就是自己配置adb server使用的端口号,只要在系统环境变量中定义 ANDROID_ADB_SERVER_PORT 的值即可。最好选择一个5位数的端口号(10000 ~ 65535),使用一个生僻的值。不易重复。Windows下只要在环境变量中增加一个ANDROID_ADB_SERVER_PORT值填你自己定义的端口。Linux下只要 export $ANDROID_ADB_SERVER_PORT = 自定义端口,即可。

使用VS2005编译freetype的动态链接库

使用VS2005编译freetype的动态链接库 请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 使用freetype是2.3.8版本,freetype2.3.8包解压缩后,在**.\builds\win32\visualc**目录下有基于vs2005的sln文件,不过这个解决方案文件,只是包含有生成静态链接的工程设置,要编译动态链接库,还需要手动去处理一下。步骤如下: 参考./doc目录下的INSTALL.ANY文档。该文档其实已经把标准编译所要包含的文件及它们的作用说得很清楚了,现在使用VC2005建立一个空的win32DLL工程,然后按照INSTALL.ANY的说明把需要加入的文件加入工程内,INSTALL.ANY文件内有一很明显的提醒:“DO NOT COMPILE ALL C FILES!”,就是不要编译所有的C文件,这点应该注意。 要进行修改的文件是ftoption.h,该文件在**/include/freetype/config**目录下,该目录主要存放一些配置头文件。ftoption.h文件里对每一可定制项目都有很详细的解释,为了可以编译成DLL,要进行的修改是: 首先备份一下ftoption.h,如,另存为ftoption_bak.h文件。 根据ftoption.h在 “DLL export compilation” 项里的描述,FreeType2库在需要导出的函数前都使用了FT_EXPORT(用在函数定义处),FT_EXPORT_DEF(用在函数声明处)两个宏,需要重新定义这两个宏。FreeType2库对于FT_EXPORT和FT_EXPORT_DEF宏的缺省定义在ftconfig.h文件中。所以在ftopion.h的该处重新定义自己的FT_EXPORT和FT_EXPORT_DEF就可以了,重新定义如下所示: #ifdef FT2_DLL //因为在静态库与动态中都使用该文件,所以区别使用该指示字,使用FT2_DLL表示要编译为DLL动态库。 #ifdef FT2_EXPORTS //按照微软的标准做法,定义__declspec(dllexport)与__declspec(dllimport) #define FT_EXPORT( x ) __declspec(dllexport) x #define FT_EXPORT_DEF( x ) x #else //按照微软的说法,其它__declspec(dllimport)也可以不要的,但这样做,更有效率并且如果不这么做的话有时会出现问题 #define FT_EXPORT( x ) __declspec(dllimport) x #define FT_EXPORT_DEF( x ) x #endif #endif

Unity2D的碰撞检测响应处理细节

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com Unity中的2D碰撞/触发回调的触发规则遵循一下的规则 详细的触发规则 首先明确两个核心概念的区别: 碰撞(Collision):需要两个Collider2D都勾选Is Trigger = false,且满足物理交互条件 触发(Trigger):至少一个Collider2D勾选Is Trigger = true 1. 碰撞回调(OnCollisionEnter2D/Stay2D/Exit2D)的触发条件 要接收到碰撞回调,必须满足: 两个Collider2D都未勾选Is Trigger 至少其中一个 GameObject拥有 非静态 的Rigidbody2D组件(注意:Rigidbody2D不能设为Kinematic+Is Kinematic且另一个也无Rigidbody2D,这种情况不会触发) 两个Collider2D的Layer层碰撞矩阵允许交互 2. 触发回调(OnTriggerEnter2D/Stay2D/Exit2D)的触发条件 要接收到触发回调,规则更宽松: 至少一个Collider2D勾选Is Trigger 满足以下任一条件即可: 其中一个GameObject有 非静态 的Rigidbody2D(可以是动态/运动学) 其中一个GameObject是 运动的静态物体(Static GameObject,且通过代码主动改变位置/旋转) 注意:两个纯静态(Static)且无Rigidbody2D的物体碰撞,不会触发任何回调 常见场景示例 为了让你更直观理解,这里列出几个典型场景: 场景 A物体(Collider2D) B物体(Collider2D) 是否触发回调 1 有Rigidbody2D(动态) 无Rigidbody2D ✅(碰撞/触发都可) 2 无Rigidbody2D 有Rigidbody2D(动态) ✅(碰撞/触发都可) 3 无Rigidbody2D(静态) 无Rigidbody2D(静态) ❌(无任何回调) 4 有Rigidbody2D(运动学) 无Rigidbody2D ✅(触发可,碰撞需B也有非运动学Rigidbody2D) 关键补充 回调函数(如OnCollisionEnter2D)必须写在有Collider2D的GameObject所挂载的脚本中,且脚本所在的GameObject需满足上述Rigidbody2D条件,否则接收不到回调。 Rigidbody2D的Body Type影响: Dynamic(动态):受物理力影响,是最常用的能触发回调的类型 Kinematic(运动学):不受物理力影响,但主动移动时能触发触发回调 Static(静态):等同于无Rigidbody2D的静态物体 总结 核心规则:要接收2D碰撞/触发回调,不能两个物体都没有Rigidbody2D且都是静态的,至少一个物体要有非静态的Rigidbody2D(触发回调允许运动学Rigidbody2D)。 简化记忆:日常开发中,给需要检测碰撞/触发的物体(或其中一个)挂载Rigidbody2D(动态类型),就能稳定接收到回调。 触发vs碰撞:触发回调规则更宽松(运动学Rigidbody2D也可),碰撞回调要求更严格(至少一个动态Rigidbody2D)。 3D的Collider和Rigidbody也是遵循一样的规则吗 你问的这个问题很关键,3D的Collider和Rigidbody的碰撞/触发回调规则核心逻辑和2D一致,但在细节上有一些专属的差异,并不是完全一模一样。

Unity3D的碰撞检测响应处理细节

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 对碰撞做出响应所必须的条件 要想两个物体A,B发生碰撞检测,即触发OnCollision相关事件,或者触发OnTrigger相关事件。必须: 物体A,B都挂接上了一个碰撞器组件,即Collider类(2D环境下是Collider2D类)的子类 运动着的物体,要携带一个刚体组件,即RigidBody类(2D环境下是RigidBody2D类),另一方的物体如果是静止的话,可以不用携带刚体组件。 2 碰撞时触发OnCollision相关事件的条件 在满足第1节中所提出的条件下,当两者的刚体组件(如果有的话)的Is Kinematic属性都未勾选,且两者的碰撞器组件的Is Trigger属性,都没勾选时,便会触发OnCollision相关事件。 3 碰撞时触发OnCollision相关事件的条件 在满足第1节中所提出的条件下,当两者的碰撞器组件的Is Trigger属性,其中有一个勾选时,就会触发OnTrigger相关事件。 4 响应事件的分类 响应事件分为Enter、Stay、Exit。以OnTrigger为例,就是OnTriggerEnter、OnTriggerStay、OnTriggerExit(2D环境下就是OnTriggerEnter2D,OnTriggerStay2D,OnTriggerExit2D,OnCollision事件以此类推)。 Enter事件便是两个物体碰撞的那一瞬间,此事件在碰撞过程会执行一次 Stay事件表示两个物体在持续接触时,此事件在碰撞过程会多次执行。 Exit事件便是两个物体在分开的那一瞬间,此事件在碰撞过程会执行一次

解决Unity3D在编译时出现libpng iccp警告的问题

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 项目组使用Unity3D4.6进行渠道商SDK接入,在编译Android版本时,发现部分渠道商提供的SDK包在编译时会出现如下图的问题: 经查证,新版本的Unity3D采用了较高版本的libpng库作为png格式图片的处理模块,产生此问题的原因是新版本的libpng对png的ICCP采用了更严格的约束条件,因此,我们必须使用软件对渠道商提供的这些资源png图片进行处理,以解决这个问题。开源软件 ImageMagick 提供了处理这个问题的方案。 从ImageMagick网站下载了ImageMagick Display软件包,安装后如下图: 我们使用软件包中的convert.exe程序对这些图片进行处理。convert程序是一个命令行程序,该程序有很多开关参数。我们使用-strip参数处理。命令行格式为: convert 待处理的图片的文件名 -strip 处理后输出的图片文件名 如果需要一口气处理同一文件夹下的许多png,我们可以将处理命令写成一个批处理文件,代码如下: set fn=E:\software\ImageMagick-6.9.0-Q16\convert.exe for /f "tokens=*" %%i in ('dir/s/b *.png') do "%fn%" "%%i" -strip "%%i"