存档

‘未分类’ 分类的存档

iOS11带来的技术变化注意事项

2017年9月26日 没有评论

相册权限

iOS11以前:
NSPhotoLibraryUsageDescription:访问相册和存储照片到相册(读写),会出现用户授权。

iOS11之后:
NSPhotoLibraryUsageDescription:无需添加。默认开启访问相册权限(读),无需用户授权。
NSPhotoLibraryAddUsageDescription: 添加内容到相册。(写),会出现用户授权。

分类: 未分类 标签:

Unit3d开发 (二十一) 更改Apk的smali 排查Java层问题

2017年9月20日 没有评论

有时候我们会被系统层诡异的Bug绊翻了车,不得已的情况下,需要更改Android代码。有些类我们能拿到源码,一切好说,但更多情况下,是引擎内或SDK中的jar文件,我们无法获得源码。面对这种情况,我的思路是:

  1. 解开Apk文件
  2. 找到对应到.class文件
  3. 定位更改代码位置
  4. 更改smali文件或代码
  5. 编回Apk
  6. 签名文件

流程中规中矩,具体操作如下:

ApkTool解包

首先在ApkTool的官网上下载安装工具,地址为https://ibotpeaches.github.io/Apktool/。安装完成后运行命令:

apktool d xxx.apk

运行后,会在apk的同级目录创建名称相同的文件夹,里面有解包之后的文件。目录结构如下:

Unit3d开发 (二十一) 更改Apk的smali 排查Java层问题

其中smali为对应的可更改文件,build/apk/classes.dex为所有的代码文件。

dex2jar转换代码

由于smali代码没有可读性,我们需要将dex文件转换成jar文件。在官网https://sourceforge.net/projects/dex2jar/上下载工具,解压后,将上面提到的classes.dex复制到dex2jar的目录下,进入到这个路径下,运行命令行:

d2j-dex2jar.bat classes.dex

会生成名为calsses-dex2jar.jar的文件。

jd-gui分析代码

在jd-gui的官网http://jd.benow.ca/下载这个工具,双击运行后,将刚刚生成的jar文件拖动进去,即可看到java文件。

在分析过代码之后,我们希望更改内容或者输出日志,就需要找到smali文件夹中的对应文件。

更改smali

手动改smali就是硬功夫了,大家可以在网上搜搜smali的语法,然后直接去改文件。如果做过破解相信大家很熟悉这种手改汇编的痛苦。这里就不展开吐槽了。举个小栗子:

Log.e("FSY",obj.toString());

这行代码转到smali代码,就是下面这一坨:

invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; 

move-result-object v1

const-string v2, "FSY"
    
invoke-static {v2, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

具体语法可以参考这篇文章http://blog.csdn.net/wdaming1986/article/details/8299996以及它后面的引用链接。

如果你实在想直接改Java代码,可以创建一个Java工程,把jar包扔进去,改了代码之后,再把对应的smali文件检出来。理论上是可行,不过我不建议尝试,因为通常都会缺少依赖项编译失败。

编译回Apk

改过smali文件之后,运行apktool的命令可以把包打回去

apktool b path/to/unzip/file -o songyangApp.apk

运行之后,就可以生成新包了。

签名

最后如果希望包可以运行还需要重新签名。运行命令

jarsigner -verbose -keystore yourKey.keystore -storepass yourPassword path/to/apk /path/to/keystore/file

即可完成签名。

总结

如果看了上面的这套复杂的流程,你还是要坚持这样查问题,那你可能和我一样走投无路,希望上面的文字对你有帮助,祝你好运。

Unit3d开发 (二十一) 更改Apk的smali 排查Java层问题

关注我的微信公众号,获取更多优质内容

分类: 未分类 标签:

解决UITableView xib添加到Storyboard出现IB Designables错误

2017年8月3日 没有评论

之前提过 Swift下自定义xib添加到Storyboard 的方法。最近有人问说按照文中方法会出现IBDesignables错误,导致在xcode Storyboard中无法显示。

这个应该是我漏讲了。如果你的自定义xib中有UITableView,而且UITableViewCell也是xib,一般这个错误肯定是加载的时候找不到对应的Bundle文件了。

错误如下:
解决UITableView xib添加到Storyboard出现IB Designables错误

IB Designables: Failed to render and update auto layout status for ViewController (BYZ-38-t0r): The agent threw an exception.
IB Designables: Failed to update auto layout status: The agent raised a
"NSInternalInconsistencyException" exception: Could not load NIB in bundle:
'NSBundle </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays> (loaded)' with name 'MyTableViewCell'

为什么会出现这个错误?

这个就要说到ios xib(Storyborad)加载机制了,但apple把这个Bundle加载机制隐藏的很深,之后我会单独写一篇文章介绍xib(Storyborad)加载机制。这里我简单说下上面的错误是怎么导致的。

上面错误主要因为我们使用的了自定义的MyTableViewCell(Xib),在Storyboard渲染Build的时候,会去读取加载这个MyTableViewCell(Xib)。这个时候我们代码一般是这么写的:

tableView.register(UINib(nibName: "MyTableViewCell", bundle: nil),
forCellReuseIdentifier: "MyTableViewCell")

注意这一句:UINib(nibName: "MyTableViewCell", bundle: nil),这个在App运行起来没有问题,因为bundle = nil 则默认使用mainBundle,但是xcode中预览Storyboard的时候,我们App没有运行,所以根据上下文无法找到对应的Bundle,所以导致该Nib无法加载。
所以出现了上面的错误exception: Could not load NIB in bundle


那么如何修改呢?

很简单,既然根据上下文无法找到对应的Bundle,我们告诉它不就行了。改成:

tableView.register(UINib(nibName: "MyTableViewCell",
        bundle: Bundle(for: self.classForCoder)),
        forCellReuseIdentifier: "MyTableViewCell")

你也可以加载TARGET_INTERFACE_BUILDER来区分下。当然不区分也没关系。

#if TARGET_INTERFACE_BUILDER
    tableView.register(UINib(nibName: "MyTableViewCell",
        bundle: Bundle(for: self.classForCoder)),
        forCellReuseIdentifier: "MyTableViewCell")
#else
    tableView.register(UINib(nibName: "MyTableViewCell",
        bundle: nil), 
        forCellReuseIdentifier: "MyTableViewCell")
#endif

我非常欢迎大家给我提问题(让人民群众监督我学习哈哈哈~~~~, 这不我就得重新理下Nib加载机制)

分类: 未分类 标签:

[置顶] 房卡麻将分析之“缺人玩法”

2017年6月21日 没有评论

         一般玩麻将都是四个人,遇到 “三缺一”怎么办?大多数情况下,玩家只好等待或叫人,这无疑增加了玩家的等待时间,同时也减缓了房卡的消耗速度。其实四个人并不是玩麻将的硬性条件,如果能在游戏中不受四人限制随时开局,就会大大提升房卡麻将的实用性和可玩性,同时有效的加快房卡销售速度。


         所谓”缺人玩法“,即在原有基础上提供二人,三人的玩法,如果玩家有两个人在房间里开局,那就形成南北对立局势进行游戏。

[置顶]        房卡麻将分析之“缺人玩法”


         如果玩家有三个人在房间里开局,那就形成去掉对门,左右代表上家和下家,形成三国鼎力之势。

[置顶]        房卡麻将分析之“缺人玩法”

         在开发过程中,本身的技术难度并不大,主要是要注意表现层的细节,总体来说有以下几个方面:

   

         (1)。玩家坐下后所在方向的处理:二人麻将比较好处理,房间两个玩家,自身处下方位无须处理,对方玩家需要放置在对门。要注意东南西北方面显示和切换的细节。可以根据服务器分配的座位号进行重新的整理。三人麻将的话,要注意一个地方,就是如果三个玩家的手机上显示的都是自已居下位,左边为上家,右边为下家,座位与方位的不统一,这是很奇怪的一个现象,但又的确存在。即如果玩家A是南,玩家B是东,玩家C是西,这时就会出现B玩家,C玩家本应显示为对门但确不是的情况,哈哈,但为了美观,这里可以不太讲究。毕竟不影响胜负和打牌顺序。

[置顶]        房卡麻将分析之“缺人玩法”

                                          《大赢家》麻将的三人开局


[置顶]        房卡麻将分析之“缺人玩法”


         (2)。玩家出牌的排列处理:因为二人,三人玩的情况下,每个人摸到的牌的数量会多出来一些,在桌面上显示时就会遇到出牌牌墙过长的问题,这里要做一下对齐或增加行数的问题。


[置顶]        房卡麻将分析之“缺人玩法”

                                   二人麻将,要增长出牌的牌墙


[置顶]        房卡麻将分析之“缺人玩法”

                              三人麻将,三人出牌的牌墙不要交叉。


         (3)。玩家结算显示处理:这个就比较简单了,玩家结算时能够同态的根据人数进行界面结算框显示,保证美观。


[置顶]        房卡麻将分析之“缺人玩法”

           服务器方面,要改进的地方并不是很多,在房间第一次开局时记录下人数,并以这个人数来进行后续开局判断,起牌顺序处理和结算就行了,整体改动比较简单。

        地方棋牌,VR,AR技术,请关注公众号:"红孩儿的游戏开发之路“

               红孩儿微信:honghaier_game


          [置顶]        房卡麻将分析之“缺人玩法”

分类: 未分类 标签:

OpenGL(十三) 天空盒 的 shader 实现

2017年6月19日 没有评论

天空盒 的使用可以使用户感觉所处一个封闭的世界环境,使得游戏更加真实。本文主要介绍如何通过OpenGL和GLSL来实现天空盒。

核心原理

天空盒 的核心原理其实并不复杂,它相当于在视线外套上一个盒子。盒子有6个面,分别使用6张可以拼接在一起的图片。从原理上讲,通过比较视线的xyz,可以找到方向,可以计算出应该渲染的与盒子面的交点,进而选出应绘制的面进行渲染。从实现的角度理解,首先将天空盒与摄像机放在同一位置,然后将盒子绘制出来即可。

实现

C++代码方面,通过SOIL可以创建一个cubemap,然后将其传入shader,其接方法如下:

//Create
GLuint mainTexture = SOIL_load_OGL_cubemap(
        "res/image/right.bmp",
        "res/image/left.bmp", 
        "res/image/top.bmp", 
        "res/image/bottom.bmp", 
        "res/image/back.bmp", 
        "res/image/front.bmp",
        0, 0, SOIL_FLAG_POWER_OF_TWO);

//Draw
glBindTexture(GL_TEXTURE_CUBE_MAP, mainTexture);
glUniform1i(originalProgram.GetLocation("U_MainTexture"),0);
cube.Bind(originalProgram.GetLocation("pos"), originalProgram.GetLocation("texcoord"), originalProgram.GetLocation("normal"));
cube.Draw();

着色器方面,接收传入的值后,将3D采样纹理绘制出即可。实现shader为:

//vs
attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;

uniform mat4 M;
uniform mat4 P;
uniform mat4 V;

varying vec3 V_Texcoord;
void main()
{
    V_Texcoord=pos;
    gl_Position=P*V*M*vec4(pos,1.0);
}

//fs
varying vec3 V_Texcoord;

uniform samplerCube U_MainTexture;

void main()
{
    gl_FragColor=textureCube(U_MainTexture,V_Texcoord);
}

总结

通过上面的代码即可在OpenGL中实现 天空盒 的效果。

OpenGL(十三) 天空盒 的 shader 实现

OpenGL(十三) 天空盒 的 shader 实现

关注我的微信公众号,获取更多优质内容

分类: 未分类 标签:

OpenGL(十二) 光源类型 平行光 、 点光源 、 聚光灯 的实现

2017年5月17日 没有评论

常规的 光源类型 有三种。最简单的自然是平行光。稍复杂些的为点光源,最复杂的为聚光灯。总体说来,在可编程管线中原理是一样的。在OpenGL代码中传入必要的参数,在shader中进行相关的计算绘制出效果。本文分别介绍三种效果的shader实现。

平行光

平行光我们已经写的轻车熟路了。它只需要一个光源方向就够了。通常我们会定义一个光源点,它与坐标轴原点的连线就是光线方向。

//GL Code
float lightPos[] = { 0.0f,1.5f,0.0f,0.0f };
float diffuseLightColor[] = { 1.0f,1.0f,1.0f,1.0f };

glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1,GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, identity);
glUniformMatrix4fv(gpuProgram.GetLocation("P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix));
glUniform4fv(gpuProgram.GetLocation("U_LightPos"), 1, lightPos);
glUniform4fv(gpuProgram.GetLocation("U_DiffuseLightColor"), 1, diffuseLightColor);

//fs
void main(){
    //...
    vec3 n = normalize(V_Normal);
    vec3 L = U_LightPos.xyz;
    float diffuseIntensity=max(0.0,dot(L,n));
    vec4 diffuseColor=U_DiffuseLightColor*diffuseIntensity;
    //...
    gl_FragColor=ambientColor+diffuseColor;
}

获取的光线方向直接与法线点乘,即为光照强度。

点光源

在平行光的基础上,根据模型与光源之间的距离进行衰减。衰减为与距离相关的二次函数。因此需要加入三个因数,分别为expFactorlinearFactorconstantFactor

//GL Code
float constantFactor = 1.0;
float linearFactor = 0.2;
float expFactor=0.0;

glUniform1f(gpuProgram.GetLocation("U_ConstantFactorn"), 1, constantFactor);
glUniform1f(gpuProgram.GetLocation("U_LinearFactor"), 1, linearFactor);
glUniform1f(gpuProgram.GetLocation("U_ExpFactor"), 1, expFactor);


//fs
float attenuation =  1.0;

void main(){
    //...
    vec3 n = normalize(V_Normal);
    vec3 L = U_LightPos.xyz - V_WorldPos;
    float distance = length(L);
    attenuation = 1.0/(U_ExpFactor*distance*distance + U_LinearFactor*distance + U_ConstantFactor);
    float diffuseIntensity = max(0.0,dot(L,n));
    vec4 diffuseColor = U_DiffuseLightColor*attenuation*diffuseIntensity;
    //...
    gl_FragColor=ambientColor+diffuseColor;
}

聚光灯

在点光源的基础上,添加一个带角度的锥形区域的检测。只有在区域内的部分才有照亮处理。因此需要传入shader两个参数,分别为光照方向和范围角度。

//GL Code
//...
float spotLightDirection[] = { 0.0f,-1.0f,0.0f,128.0f };
float spotLightCutoff = 15.0f;

glUniform1f(gpuProgram.GetLocation("U_Cutoff"), spotLightCutoff);
glUniform4fv(gpuProgram.GetLocation("U_LightDirection"), 1, spotLightDirection);

//...

//fs
float attenuation =  1.0;

void main(){
    //...

    float radianCutoff = U_Cutoff*3.14/180;
    float cosThta = cos(radianCutoff);
    vec3 spotLightDirection = normalize(U_LightDirection.xyz);

    vec3 n = normalize(V_Normal);
    vec3 L = U_LightPos.xyz - V_WorldPos;
    float distance = length(L);
    attenuation = 1.0/(U_ExpFactor*distance*distance + U_LinearFactor*distance + U_ConstantFactor);
    
    float currentCosThta=max(0.0,dot(-L,spotLightDirection));
    float diffuseIntensity = 0.0;
    if(currentCosThta > cosThta)
    {
        if(dot(L,n) >0.0)
        {
            diffuseIntensity = pow(currentCosThta,U_LightDirection.w); 
        }
    }
    vec4 diffuseColor = U_DiffuseLightColor*attenuation*diffuseIntensity;

    //...
    gl_FragColor=ambientColor+diffuseColor;
}

总结

以上为三种光源的OpenGL实现,可以看出,计算量最大的为聚光灯效果,而且为了让边缘柔和,需要pow的大量计算。移动端跑实时运算估计要优化算法了。

OpenGL(十二) 光源类型 平行光 、 点光源 、 聚光灯 的实现

关注我的微信公众号,获取更多优质内容

分类: 未分类 标签:

Mac搭建本地局域网SVN服务(Cornerstone)

2017年5月10日 没有评论

下周需要和团队一起去外地工作几天,发现提交代码合并比较麻烦,考虑到团队还有美术同学,想想还是本地开启个svn,先临时用用吧。

mac系统是已经安装了svn服务的,所以这里我们只需要开启就行了。

1. 验证本地已安装svn服务。

$ svnserve --version

2. 创建代码库文件夹LocalSVNServer

$ sudo mkdir -p ~/Documents/LocalSVNServer

3. 初始化svn代码库

$ sudo svnadmin create ~/Documents/LocalSVNServer

打开LocalSVNServer文件夹,你会发现已经生成了svn服务。
Mac搭建本地局域网SVN服务(Cornerstone)

4. 配置svn用户权限,打开conf/svnserve.conf

Mac搭建本地局域网SVN服务(Cornerstone)

修改以上位置,其中anon-access = read代表匿名访问的时候是只读的,若改为anon-access = none代表禁止匿名访问,需要帐号密码才能访问

5. 配置账号passwd文件,打开conf/passwd

Mac搭建本地局域网SVN服务(Cornerstone)
[users]标签下面的是用户账号,把需要的 用户名=密码 添加在这里

6. 配置权限authz文件,打开conf/authz

Mac搭建本地局域网SVN服务(Cornerstone)
在[groups]下添加dev = liuyanghui标示创建了一个用户组dev,此用户组包含有liuyanghui用户,多个的话逗号连接:dev = liuyanghui,liuyanghui2

[/]
@dev = rw 这两句标示给dev用户组相应的权限

[/]表示授权的目录路径,这里是根目录,假如根目录下有一个目录叫做test,那么我们如果要编辑此目录的权限那么就要写成[test:/]

@dev表示给用户组授权,如果要给某一个用户授权则不用写前面的@,r表示可读,w表示可写

7. 启动svn(启动成功后活动监视器中可以搜索svnserve,会发现存在)

$ svnserve -d -r ~/Documents/LocalSVNServer

  • 关闭SVN
  • 命令终端直接输入下面命令,第一个数字为进程号。
  • $ ps aux | grep svn
  • Mac搭建本地局域网SVN服务(Cornerstone)
  • 然后$ sudo kill -xxx (xxx代表进程号),上面图片就是18328
  • 可以在活动监视器里进行搜索:svnserve,停止该服务

8. Cornerstone添加svn仓库,局域网其他机器svn地址写ip。本机的话localhost

Mac搭建本地局域网SVN服务(Cornerstone)

9. 如果发现提交svn出现文件夹无权限的话(一般是txn-current-lock无读写权限),增加svn仓库文件夹权限

$ sudo chmod -R a+w ~/Documents/LocalSVNServer/

分类: 未分类 标签:

OpenGL(十一) 可编程管线 基础光照 的实现

2017年5月2日 没有评论

在OpenGL中创建 基础光照 ,主要的工作将模型中的法线信息和法线空间运算矩阵传入到shader中。另一方面,LightDir,ViewDir通常是在shader中从引擎参数获取的,为了简化光照模型的实现,这里我们可以在shader中写死。至于经典的 ambient+diffuse+specular 光照原理,不是本文的重点,就在shader中一笔带过了。

原理

通过函数

glm::mat4 normalMatrix = glm::inverseTranspose(s_shaderData.model);

可以获取当前模型的法线矩阵。用来将法线信息从模型坐标转换为世界坐标。这个矩阵是随着模型的Transform改变而改变的,因此需要在Render时动态计算。

实现

在 基础光照 中,数据传递没什么特殊的,将Normal信息作为attribute传递到shader,将NormalMatrix作为uniform传递到shader。

//normalmatrix
glm::mat4 normalMatrix = glm::inverseTranspose(s_shaderData.model)
glUniformMatrix4fv(s_shaderData.NMLocation,1,GL_FALSE,glm::value_ptr(normalMatrix))

// normal
glEnableVertexAttribArray(s_shaderData.normalLocation);
glVertexAttribPointer(s_shaderData.normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float)*5)); 

vs中首先将法线转置到世界坐标,然后将其传递给fs。

//vs
attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;

uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 NM;

varying vec3 V_Normal;
varying vec3 V_WorldPos;

void main()
{
    V_Normal = mat3(NM)*normal;
    V_WorldPos = M * vec4(pos,1.0);
    gl_Position=P*V*M*vec4(pos,1.0);
}

在fs中使用经典的pong公式做个最简单的效果。

varying vec3 V_Normal;
varying vec3 V_WorldPos;

void main()
{
    vec3 lightPos = vec3(10.0,10.0,0.0);
    vec3 L = lightPos;

    L = normalize(L);
    vec3 n = normalize(V_Normal);

    //ambient
    vec4 AmbientLightColor = vec4(0.2,0.2,0.2,1.0);
    vec4 AmbientMaterial = vec4(0.2,0.2,0.2,1.0);
    vec4 ambientColor = AmbientLightColor * AmbientMaterial;
    
    //diffuse
    vec4 DiffuseLightColor = vec4(1.0,1.0,1.0,1.0);
    vec4 DiffuseMaterial = vec4(0.8,0.8,0.8,1.0);
    vec4 diffuseColor = DiffuseLightColor * DiffuseMaterial * max(0.0,dot(L,n));

    //specular
    vec3 reflectDir = normalize(reflect(-L,n));
    vec3 viewDir = normalize(vec3(0.0)-V_WorldPos.xyz);
    vec4 SpecularLightColor = vec4(1.0,1.0,1.0,1.0);
    vec4 SpecularMaterial = vec4(1.0,1.0,1.0,1.0);
    vec4 specularColor = SpecularLightColor*SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),128);

    gl_FragColor= ambientColor+diffuseColor+specularColor;
}

另外需要注意的是,有光照的模型通常需要打开深度测试,也需要记得将深度缓存清空。

//Open test
glEnable(GL_DEPTH_TEST);

//when render
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

总结

通过上面的代码,搭建基本框架。可以实现 基础光照 模型。如果需要添加其他参数效果,则需要增加Uniform传递的参数了。

OpenGL(十一) 可编程管线 基础光照 的实现

关注我的微信公众号,获取更多优质内容

分类: 未分类 标签:

OpenGL(十) 手机不可用特性 ComputeShader GeometryShader …

2017年4月25日 没有评论

由于当前市场上还存在大量低端Android机器,它们只支持到OpenGL ES2.0,因此 手机不可用特性 有很多。对于一些3.0 甚至4.0的特性,只能看看热闹了。当然基本了解还是需要的,万一哪天都升级到3.0了呢。由于我现在也使用Unity3d开发,文中也有Unity3d的相关指标一起参考。

Subroutine

这个技术在之前的文章:OpenGL(八)使用 subroutine 切换可编程管线中介绍过,它是在OpenGL 4.0中加入的特性。目前我似乎未在Unity中找到对应的封装技术,唯一有些类似的是shader中的LOD技术,不过其实并不一样。

Instancing

这个技术之前也介绍过:OpenGL(七) GeometryInstancing 几何体实例化,它是OpenGL ES3.0引入的,同时又支持IOS,因此还是可以勉强用用的。对于Unity3d中的封装可以看官方文档

Compute Shader

这是在OpenGL 4.3中引入的特性。对应的ES版本为OpenGL ES3.1。在Unity3d的官方文档 中说明了它的使用范围:Modern OpenGL platforms (OpenGL 4.3 on Linux or Windows; OpenGL ES 3.1 on Android). Note that Mac OS X does not support OpenGL 4.3, so no compute shaders there yet。所以等到Android3.1成为主流且IOS支持,才能利用起强大的GPU运算啊。

Geometry Shader

它是在OpenGL 3.2中引入的特性。能用来凭空产生顶点。这就能有很多想象空间了,比如我绘制一个GL_POINT,但我在这里加进来6个顶点,就能绘制一个六星芒阵。可惜 官方表示 它需要 #pragma target 4.0 也就是要OpenGL ES3.2 或 OpenGL ES3.1+AEP。所以估计短期之内应该没戏。

Transform Feedback

OpenGL ES3.0加入的特性,用于将图元的属性在GPU上读取与更改。可以极大的减少CPU与GPU之间由于属性读写引起的通信。至于ParticleSystem底层应该没使用这种技术,我并未找到相应的资料,然而我估计为了兼容ES2.0,应该是没使用。在shader中我也没有对应的接口,希望有人知道可以告诉我。

Tessellation Shaders

OpenGL4.0加入的特性(似乎还没加入到ES中?)它可以自定义tcs之后出来的曲面细分规则。不用说,跟Geometry Shader一样,短期没戏。

总结

对于Unity3d来说,手机不可用的特性 与OpenGL是基本相同的。如果想仔细分辨,你可以查阅 官方的ShderModeTarget Levels 来确认相关的技术是否支持。总的说来对于移动平台:

  • 当前可用技术是Instancing(Unity5.5加入)
  • 遥遥无期的是Compute Shader,Geometry Shader,Tessellation Shader
  • 未具体说明的是Subrotine,Transform Feedback.

另外,关于OpenGL教程,极客学院翻译了一个tutorial 在这里 也蛮不错的。

OpenGL(十) 手机不可用特性 ComputeShader  GeometryShader ...

关注我的微信公众号,获取更多优质内容

分类: 未分类 标签:

iOS 10.3 改进后的App Review机制

2017年4月24日 没有评论

今天没事查看了下iOS 10.3 的变更功能。发现Apple修改了Review机制,提供App内直接Review弹窗。

SKStoreReviewController.requestReview()

iOS 10.3 改进后的App Review机制

如果没有网络则无任何反应。
据说有调用次数限制,不过API中没有提到,我测试也没有触发这个现象。

看了API说明的话,有人可能注意到了,这句话:

available to the App Store by appending the query params "action=write-review" to a product URL.

我测试了下,如果在itms-apps url中添加action=write-review则可以打开AppStore中App评论详情,同时自动打开评论编辑窗口

func reviewApp(for appId: String) {
        if let url = URL(string: "itms-apps://itunes.apple.com/app/id/(appId)?action=write-review") {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
    }

iOS 10.3 改进后的App Review机制

分类: 未分类 标签: