个人认为,既然手机设备支持wp8支持dx11,那么dds的压缩纹理必然是被支持的。不过依然不保证完全如此。希望看此文章的同仁留意。
微软wp系统在内存管理上有一个不同于ios和android的地方,那就是给程序预先分配的内存是有限的。正常情况是150mb,通过设置一些标志可以允许180mb或者300mb。程序分配的内存超过限额就会分配失败抛出异常,即便这个时候手机剩余内存还剩七八百兆。所以买低端手机的劣势就是很多游戏不是没有,而是你看不到,因为那些游戏因为安全起见,申请了300mb的内存,那么只有512mb内存的手机可能就看不到这个应用了,即便它可以在这个手机上跑起来。
反过来,对游戏开发而言,内存控制就变得更加重要了。 不过这里还是要吐槽一下,wp8使用native c++进行开发的话,没有任何途径可以获取内存使用情况进行分析。一没有工具,二没有系统api。 只能靠程序员给力些了。
比如我的卡牌游戏,一开始分配内存可能达到200mb,那么就经常性的崩溃。后面使用dds的压缩纹理后,就没有出现崩溃情况了。理论上说dds跟pvrtc4一样都是4个字节表示一个像素,所以使用dds的游戏在wp8上面的运行内存情况应该跟使用pvrtc4在ios上面运行一样。
首先说转换工具,我找了半天终于找到个靠谱的工具。Nvida Texture Tools,这个有工具有代码。不过默认情况下程序不识别png jpg图片,后面我重新用源代码编译了一份。
之所以要使用这个工具而不是市面上大多数图片转换工具是因为dds图片的压缩纹理格式分很多种,常见的有dxt1 dxt3 dxt5,常用的是dxt3,dxt1色彩不足,而dxt5不是所有设备都支持,比如我的lumia920,使用dx api检测时就不支持dxt5。
较新的cocos2d-x代码里面已经包含了s3tc压缩纹理的支持。dds的压缩纹理格式就是s3tc。读取纹理可以直接使用,而不需要特别写初始化代码了(比如 CreateDDSTextureFromFile就没有必要了)
private String[] mArrData;
private TextView mTV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTV = (TextView) findViewById(R.id.tvShow);
mArrData = new String[1000];
for (int i = 0; i < 1000; i++) {
mArrData[i] = "Google IO Adapter" + i;
}
mAdapter = new TestAdapter(this, mArrData);
((ListView) findViewById(android.R.id.list)).setAdapter(mAdapter);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 开始计时
long startTime = System.nanoTime();
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text,
null);
holder = new ViewHolder();
holder.icon1 = (ImageView) convertView.findViewById(R.id.icon1);
holder.text1 = (TextView) convertView.findViewById(R.id.text1);
holder.icon2 = (ImageView) convertView.findViewById(R.id.icon2);
holder.text2 = (TextView) convertView.findViewById(R.id.text2);
convertView.setTag(holder);
}
else{
holder = (ViewHolder)convertView.getTag();
}
holder.icon1.setImageResource(R.drawable.icon);
holder.text1.setText(mData[position]);
holder.icon2 .setImageResource(R.drawable.icon);
holder.text2.setText(mData[position]);
// 停止计时
long endTime = System.nanoTime();
// 计算耗时
long val = (endTime - startTime) / 1000L;
Log.e("Test", "Position:" + position + ":" + val);
if (count < 100) {
if (val < 1000L) {
sum += val;
count++;
}
} else
mTV.setText(String.valueOf(sum / 100L));// 显示统计结果
return convertView;
}
}
static class ViewHolder {
TextView text1;
ImageView icon1;
TextView text2;
ImageView icon2;
}
NSURL *url = [NSURLURLWithString:@"http://pica.nipic.com/2007-12-12/20071212235955316_2.jpg"];
ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL:url];//创建数据请求对象
[request setRequestMethod:@"GET"];
[request setTimeOutSeconds:60];
// [request setDelegate:self];//设置代理
// 设置缓存--
ASIDownloadCache *cache = [[ASIDownloadCachealloc]init];//创建缓存对象
NSString *cachePath = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]; //设置缓存目录,这里设置沙盒目录下的Documents目录作为缓存目录
NSLog(@"cachepath:%@",cachePath);
[cache setStoragePath:cachePath];
cache.defaultCachePolicy =ASIOnlyLoadIfNotCachedCachePolicy; //设置缓存策略
//每次请求会将上一次的请求缓存文件清除
// request.cacheStoragePolicy = ASICacheForSessionDurationCacheStoragePolicy;
//持久缓存,一直保存在本地(是持久缓存,程序下次启动,缓存仍然还在)
request.cacheStoragePolicy =ASICachePermanentlyCacheStoragePolicy;
request.downloadCache = cache;
[request startAsynchronous];//发送异步请求
//设置网络请求完成后调用的block
[request setCompletionBlock:^{
// NSLog(@"%@",request.responseHeaders);
NSData *data = request.responseData;
self.showImageView.image = [UIImageimageWithData:data];
//---------------判断数据的来源:网络 or缓存------------------
if (request.didUseCachedResponse) {
NSLog(@"数据来自缓存");
} else {
NSLog(@"数据来自网络");
}
}];
//请求失败调用的block
[request setFailedBlock:^{
NSError *error = request.error;
NSLog(@"请求网络出错:%@",error);
}];
在 NSData *data = request.responseData;这一行报警告:::Capturing \'request\'
strongly in this block is likely to lead to a retain cycle..........
先开始我想应该是内存管理的问题,后来想自己使用了arc应该不存在这个问题吧。。后
来朋友说,block里面不能使用自己自定义的属性,因为block是独立的。。网上查了一下
关于block的使用问题,看的懵懵懂懂不太明白,没有理解。。。。没有明白。。这个和
我的程序死掉有什么关系??我写的代码,
照点击打开链接这个网站的写的......
嗯,现在我把设置缓存的代码注释掉了,程序就可以了。。。这个跟缓存有关么?
ViewController.m
@interface ViewController (){
ASIDownloadCache *myCache;
}
// 设置缓存--
ASIDownloadCache *cache = [[ASIDownloadCachealloc]init];//创建缓存对象
myCache = cache;
//路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentDirectory = [pathsobjectAtIndex:0];
NSLog(@"path-%@",documentDirectory);
//设置缓存存放路径
[myCachesetStoragePath:[documentDirectorystringByAppendingPathComponent:@"pic"]];
myCache.defaultCachePolicy =ASIOnlyLoadIfNotCachedCachePolicy; //设置缓存策略
//每次请求会将上一次的请求缓存文件清除
// request.cacheStoragePolicy = ASICacheForSessionDurationCacheStoragePolicy;
//持久缓存,一直保存在本地(是持久缓存,程序下次启动,缓存仍然还在)
request.cacheStoragePolicy =ASICachePermanentlyCacheStoragePolicy;
request.downloadCache = cache;
-----------------
打印了路径,前往文件夹,输入路径,就的到以下图示:
----------------
源代码: