eoe·Android开发者门户

标题: gallery3d源码学习总结(一)——绘制流程drawFocusItems [打印本页]


作者: specialbrian    时间: 2010-10-29 20:15     标题: gallery3d源码学习总结(一)——绘制流程drawFocusItems

本帖最后由 specialbrian 于 2010-11-4 07:59 编辑

显示单张图片相关的输入变量

  1. int selectedSlotIndex = mSelectedSlot;
  2. GridDrawables drawables = mDrawables;
  3. GridCamera camera = mCamera;
  4. DisplayItem[] displayItems = mDisplayItems;
  5. int firstBufferedVisibleSlot = mBufferedVisibleRange.begin;
  6. int lastBufferedVisibleSlot = mBufferedVisibleRange.end;
  7. boolean isCameraZAnimating = mCamera.isZAnimating();

复制代码

删除当前选中槽位前后2步之外的大缩略图

  1. for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
  2. if (selectedSlotIndex != Shared.INVALID && (i >= selectedSlotIndex - 2 && i <= selectedSlotIndex + 2)) {
  3. continue;
  4. }
  5. DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
  6. if (displayItem != null) {
  7. displayItem.clearScreennailImage();
  8. }
  9. }

复制代码

得到当前图片的DispalyItem元素

  1. int centerIndexInDrawnArray = (selectedSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT;
  2. if (centerIndexInDrawnArray < 0 || centerIndexInDrawnArray >= displayItems.length) {
  3. return;
  4. }
  5. DisplayItem centerDisplayItem = displayItems[centerIndexInDrawnArray];
  6. if (centerDisplayItem == null || centerDisplayItem.mItemRef.mId == Shared.INVALID) {
  7. return;
  8. }

复制代码

判断大缩略图是否加载完成

  1. boolean focusItemTextureLoaded = false;
  2. Texture centerTexture = centerDisplayItem.getScreennailImage(view.getContext());
  3. if (centerTexture != null && centerTexture.isLoaded()) {
  4. focusItemTextureLoaded = true;
  5. }

复制代码

是否跳过当前图片前一张图片

  1. float camX = camera.mLookAtX * camera.mScale;
  2. float centerTranslateX = centerDisplayItem.mAnimatedPosition.x;
  3. final boolean skipPrevious = centerTranslateX < camX;

复制代码

开启opengl混合模式并设置混合函数

  1. gl.glEnable(GL11.GL_BLEND);
  2. gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);

复制代码

循环遍历前中后三幅图片分别进行“核心绘制处理”

  1. for (int i = -1; i <= 1; ++i) {
  2. if (slideshowMode && timeElapsedSinceView > 1.0f && i != 0)
  3. continue;
  4. 。。。
  5. }

复制代码

核心绘制处理——输入变量准备

  1. if (slideshowMode && timeElapsedSinceView > 1.0f && i != 0)
  2. continue;
  3. float viewAspect = camera.mAspectRatio;
  4. int selectedSlotToUse = selectedSlotIndex + i;
  5. if (selectedSlotToUse >= 0 && selectedSlotToUse <= lastBufferedVisibleSlot) {
  6. int indexInDrawnArray = (selectedSlotToUse - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT;
  7. if (indexInDrawnArray < 0 || indexInDrawnArray >= displayItems.length) {
  8. return;
  9. }
  10. DisplayItem displayItem = displayItems[indexInDrawnArray];
  11. MediaItem item = displayItem.mItemRef;
  12. final Texture thumbnailTexture = displayItem.getThumbnailImage(view.getContext(), sThumbnailConfig);
  13. Texture texture = displayItem.getScreennailImage(view.getContext());

复制代码

在幻灯模式下且超过1秒的切换时间无须显示前后两张图片;
得到视角和当前displayItem、对应媒体对象、小缩略图材质、大缩略图材质。
加载高质量的材质资源

  1. if (isCameraZAnimating && (texture == null || !texture.isLoaded())) {
  2. texture = thumbnailTexture;
  3. mSelectedMixRatio.setValue(0f);
  4. mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime());
  5. }
  6. Texture hiRes = (zoomValue != 1.0f && i == 0 && item.getMediaType() != MediaItem.MEDIA_TYPE_VIDEO) ? displayItem
  7. .getHiResImage(view.getContext())
  8. : null;
  9. if (Gallery.PIXEL_DENSITY > 1.0f) {
  10. hiRes = texture;
  11. }
  12. if (i != 0) {
  13. displayItem.clearHiResImage();
  14. }
  15. if (hiRes != null) {
  16. if (!hiRes.isLoaded()) {
  17. view.bind(hiRes);
  18. view.prime(hiRes, true);
  19. } else {
  20. texture = hiRes;
  21. }
  22. }

复制代码

如果Camera正在拉远或拉近,且大缩略图材质为空或未加载完成,则选择小缩略图作为材质,将当前图片的“大缩略图混合比例”变量进行初始化(目标值为1秒,渐变时间为0.75秒,渐变开始时间为当前帧时间)。
如果处于放大状态,则加载原图hiRes,加载成功后赋值给材质变量texture;并清除前后图片的原图。
加载材质

  1. final Texture fsTexture = texture;
  2. if (texture == null || !texture.isLoaded()) {
  3. if (Math.abs(centerTranslateX - camX) < 0.1f) {
  4. if (focusItemTextureLoaded && i != 0) {
  5. view.bind(texture);
  6. }
  7. if (i == 0) {
  8. view.bind(texture);
  9. view.prime(texture, true);
  10. }
  11. }
  12. texture = thumbnailTexture;
  13. if (i == 0) {
  14. mSelectedMixRatio.setValue(0f);
  15. mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime());
  16. }
  17. }

复制代码

保留当前的最佳材质,
如果此材质加载未完成,则继续按优先级加载,并把小缩略图(基本上都已经加载成功了)设置为当前材质;
最佳材质未加载完成之前,替换渐变不会开始。
无须绘制

  1. if (mCamera.isAnimating() || slideshowMode) {
  2. if (!slideshowMode && skipPrevious && i == -1) {
  3. continue;
  4. }
  5. if (!skipPrevious && i == 1) {
  6. continue;
  7. }
  8. }
  9. int theta = (int) displayItem.getImageTheta();

复制代码

如果相机缩放过程中,非幻灯片模式下且镜头中不需要展示前一张的情况下,无须处理前一张;
如果相机缩放或幻灯片绘制过程中,需要展示前一张的情况下,无须处理后一张。
处理前后渐变绘制

  1. // If it is in slideshow mode, we draw the previous item in
  2. // the next item's position.
  3. if (slideshowMode && timeElapsedSinceView < 1.0f && timeElapsedSinceView != 0) {
  4. if (i == -1) {
  5. int nextSlotToUse = selectedSlotToUse + 1;
  6. if (nextSlotToUse >= 0 && nextSlotToUse <= lastBufferedVisibleSlot) {
  7. int nextIndexInDrawnArray = (nextSlotToUse - firstBufferedVisibleSlot)
  8. * GridLayer.MAX_ITEMS_PER_SLOT;
  9. if (nextIndexInDrawnArray >= 0 && nextIndexInDrawnArray < displayItems.length) {
  10. float currentImageTheta = displayItem.mAnimatedImageTheta;
  11. displayItem = displayItems[nextIndexInDrawnArray];
  12. backupImageTheta = displayItem.mAnimatedImageTheta;
  13. displayItem.mAnimatedImageTheta = currentImageTheta;
  14. view.setAlpha(1.0f - timeElapsedSinceView);
  15. }
  16. }
  17. } else if (i == 0) {
  18. displayItem.mAnimatedImageTheta = backupImageTheta;
  19. view.setAlpha(timeElapsedSinceView);
  20. }
  21. }

复制代码

如果处于幻灯片模式中 渐变过程中,处理上一幅相片时找到它的下一个DispalyItem,处理本张相片则直接使用当前DispalyItem,为的是同样找到当前DisplayItem,并绑定上一张相片和本张相片,两张相片透明度互补达到渐变的效果。
绘制小大缩略图渐变过程-小缩略图

  1. int vboIndex = i + 1;
  2. float alpha = view.getAlpha();
  3. float selectedMixRatio = mSelectedMixRatio.getValue(view.getFrameTime());
  4. if (selectedMixRatio != 1f) {
  5. texture = thumbnailTexture;
  6. view.setAlpha(alpha * (1.0f - selectedMixRatio));
  7. }
  8. GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex];
  9. float u = texture.getNormalizedWidth();
  10. float v = texture.getNormalizedHeight();
  11. float imageWidth = texture.getWidth();
  12. float imageHeight = texture.getHeight();
  13. boolean portrait = ((theta / 90) % 2 == 1);
  14. if (portrait) {
  15. viewAspect = 1.0f / viewAspect;
  16. }
  17. quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);
  18. quad.bindArrays(gl);
  19. drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT, null, 0.0f);
  20. quad.unbindArrays(gl);

复制代码

绘制小缩略图,请注意:selectedMixRatio表示大缩略图的绘制透明度,小缩略图的自然就是1.0f - selectedMixRatio。
绘制小大缩略图渐变过程-大缩略图

  1. if (selectedMixRatio != 0.0f && selectedMixRatio != 1.0f) {
  2. texture = fsTexture;
  3. if (texture != null) {
  4. float drawAlpha = selectedMixRatio;
  5. view.setAlpha(alpha * drawAlpha);
  6. u = texture.getNormalizedWidth();
  7. v = texture.getNormalizedHeight();
  8. imageWidth = texture.getWidth();
  9. imageHeight = texture.getHeight();
  10. quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);
  11. quad.bindArrays(gl);
  12. drawDisplayItem(view, gl, displayItem, fsTexture, PASS_FOCUS_CONTENT, null, 1.0f);
  13. quad.unbindArrays(gl);
  14. }
  15. }

复制代码

更新当前图片长宽数据

  1. if (i == 0 || slideshowMode) {
  2. mCurrentFocusItemWidth = quad.getWidth();
  3. mCurrentFocusItemHeight = quad.getHeight();
  4. if (portrait) {
  5. // Swap these values.
  6. float itemWidth = mCurrentFocusItemWidth;
  7. mCurrentFocusItemWidth = mCurrentFocusItemHeight;
  8. mCurrentFocusItemHeight = itemWidth;
  9. }
  10. }

复制代码

绘制视频元素

  1. view.setAlpha(alpha);
  2. if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
  3. // The play graphic overlay.
  4. GridDrawables.sVideoGrid.bindArrays(gl);
  5. drawDisplayItem(view, gl, displayItem, drawables.mTextureVideo, PASS_VIDEO_LABEL, null, 0);
  6. GridDrawables.sVideoGrid.unbindArrays(gl);
  7. }

复制代码

【此部分讲解已结束】,如您对其他部分感兴趣请回帖说明


作者: lily0314    时间: 2010-11-1 10:53

本帖最后由 lily0314 于 2010-11-19 15:55 编辑

写的挺好啊,谢谢啦!


作者: lily0314    时间: 2010-11-1 11:15

GridLayer和HudLayer分别是负责什么的?


作者: specialbrian    时间: 2010-11-1 11:26

回复 3# lily0314

HudLayer是交互控件图层,GridLayer是动画元素层。


作者: lily0314    时间: 2010-11-1 14:30

谢谢啦,能否详细讲讲drawBlendedComponents和drawThumbnails方法?


作者: lily0314    时间: 2010-11-1 15:04

STATE_TIMELINE(GridLayer中的)是什么状态?能否截图?


作者: lily0314    时间: 2010-11-1 17:19

你好,我还想请问一下从打开软件,到呈现出文件夹界面,经过了哪些过程?图片的坐标是固定的吗?随着重力感应和手指滑动,位置会有细微的小位移,用什么方法呢?是改变视点还是怎样?具体的代码是怎样呢?


作者: specialbrian    时间: 2010-11-2 09:51

本帖最后由 specialbrian 于 2010-11-2 09:53 编辑

回复 6# lily0314

2010-11-2 09:53 上传

下载附件 (359.51 KB)

[attach]12020[/attach]

图片附件: device.png (2010-11-2 09:53, 359.51 KB) / 下载次数 1
http://www.eoeandroid.com/forum.php?mod=attachment&aid=MTIwMjR8MWI5NzVmYWN8MTMwMTYyMzkxNnw0ODEyMzA%3D


作者: lily0314    时间: 2010-11-2 10:17

回复 8# specialbrian

噢,同一个文件夹内,按时间分类的界面啊,为什么我看不到这种界面?是需要怎样触发呢?
  那么STATE_MEDIA_SETS是刚打开时候的主界面(有文件夹的),STATE_GRID_VIEW是缩略图矩阵浏览的界面,对吗?


作者: specialbrian    时间: 2010-11-2 14:24

回复 9# lily0314
    你的理解没错,不过我习惯管STATE_MEDIA_SETS叫做相册表格页,STATE_GRID_VIEW是相片表格页,时间分类页在相片表格页的右上角控件控制,详见我图中的红色标记


作者: lily0314    时间: 2010-11-2 14:54

回复 10# specialbrian

非常感谢!不知我之前的问题有没有可解?


作者: eoe-android-com    时间: 2010-11-2 15:29

想了解一下 缓存管理那一块的
CacheService类 ,以及怎么进行异步加载的呢 以及缓存文件的的写入读取的过程
特别是DCIM\.thumbnails\.thumbdata3--1967290299 缩略图文件是如何创建的
可否 详细的讲解一下呢 谢谢
如果方便的话可否加QQ:907288406交流一下


作者: specialbrian    时间: 2010-11-2 15:43

回复 11# lily0314
正在汇总整理当中,估计今明两天给出响应帖子


作者: lily0314    时间: 2010-11-2 16:05

回复 13# specialbrian

呵呵谢谢啦,我就是看到哪,想到一些问题,就问你了,很期待你的讲解!


作者: lily0314    时间: 2010-11-2 16:55

本帖最后由 lily0314 于 2010-11-2 16:57 编辑

HudLayer.java文件中的MODE_NORMAL和MODE_SELECT是指哪些模式呢?是不是普通的模式和标记选中模式?我偶然能到标记选中模式下,但是不知道是怎么触发的,想请教下,可否有截图?


作者: specialbrian    时间: 2010-11-2 21:28

回复 5# lily0314

已经写了另一篇帖子,写了下drawThumbnails
    http://www.eoeandroid.com/viewthread.php?tid=41731&extra=


作者: specialbrian    时间: 2010-11-2 21:31

回复 15# lily0314

是的,你的理解完全正确。出发多选的方式是长按一个相册或相片。


作者: specialbrian    时间: 2010-11-3 17:10

回复 12# eoe-android-com

第三篇文章
http://www.eoeandroid.com/viewthread.php?tid=41920&extra=
    写了大体流程,如有疑问请提到这个帖子中吧


作者: eoe-android-com    时间: 2010-11-8 15:43

回复 18# specialbrian

非常感谢


作者: xiaomeigu330    时间: 2010-12-7 13:31

非常好,学习中。。。


作者: kuanbaobei    时间: 2010-12-8 11:45

楼主,你太帅了!能否把你对gallery3d的学习笔记,提供打包下载呢?真是讲的太好了!


作者: specialbrian    时间: 2010-12-30 14:38

目前只有这三篇:gallery3d源码学习总结(一)(二)(三),留下我的QQ:634589207


作者: contentroot    时间: 2011-1-24 11:46

问个问题。
大缩略图是做什么用的?
我跟代码没看到运行过呀?


作者: MEYEGG    时间: 2011-2-22 19:06

:):):)


作者: lzl26689    时间: 2011-3-7 17:39

谢谢啦


作者: qiuxueming    时间: 2011-3-7 18:38

不错,做个记号


欢迎光临 eoe·Android开发者门户 (http://www.eoeandroid.com/) Powered by Discuz! X1.5

gallery3d源码学习总结(一)——绘制流程drawFocusItems相关推荐

  1. ASP.NET Core MVC 源码学习:MVC 启动流程详解

    前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...

  2. mybatis源码学习篇之——执行流程分析

    前言 在正式学习mybatis框架源码之前,需要先弄懂几个问题?myabtis框架是什么?为什么需要mybatis框架?使用mybatis框架带来的好处是什么? 回答这几个问题之前,我们先来看一下,之 ...

  3. android自定义view流程,Android 自定义View--从源码理解View的绘制流程

    前言 在Android的世界里,View扮演着很重要的角色,它是Android世界在视觉上的具体呈现.Android系统本身也提供了很多种原生控件供我们使用,然而在日常的开发中我们很多时候需要去实现一 ...

  4. sofa源码学习----启动获取ServerConfig流程

    蚂蚁金服sofa rpc框架.公司想使用它作为架构的一部分,所以记录学习笔记. 1.从github下载源代码,版本为 5.6.0-SNAPSHOT,整个项目结构如下: 2.为了尽可能地只关注sofa ...

  5. patch请求_SpringMVC源码学习(三) 请求处理的流程

    在最近的一篇文章中我们大概了解了SpringMVC的九大组件,以及初始化的问题.根本初始化的发起是Spring的事件机制.而这九大组件是什么?我们先回顾一下,他们分别是文件处理器.语言处理器.主题处理 ...

  6. spring源码学习:spring初始化流程

    首先借个图,说明一下spring的bean的整个生命流程. 销毁什么的这个看图就知道怎么回事,使用的话一般都是纯业务,而且我们更关心spring是怎么初始化的,初始化成我们定义的那个样子.我们就是以这 ...

  7. ThinkPHP5.0源码学习之框架启动流程

    ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...

  8. Prometheus源码学习(8) scrape总体流程

    1. main 函数中初始化 scrapeManager 实例 // 初始化 scrapeManager,fanout Storage 是一个读写多个底层存储的代理 scrapeManager = s ...

  9. 【Android 源码学习】系统架构和启动流程

    Android 源码学习 系统架构和启动流程 望舒课堂 学习记录整理.以及以下参考文章的整理汇总.便于我个人的学习记录. 感谢IngresGe,Gityuan的精彩文章.为我们这些初探android系 ...

最新文章

  1. sqlserver ADO.net 查询数据库加锁,事务提交
  2. 一、目前在ASP.NET中页面传值共有这么几种方式:
  3. Linux单独编译设备树,迅为IMX6Q开发板-非设备树内核-单独编译内核驱动
  4. 鸿蒙轻内核的得力助手:带你掌握4种内存调试方法
  5. 为什么我坚持用Go语言做Web应用开发框架?
  6. Hp Dell服务器硬件监控
  7. kitti数据集格式
  8. stata15中文乱码_如何解决 Stata 14 的中文乱码问题?Chinese support in Stata 14
  9. 李国庆PK刘强东:最失败是品类战略
  10. html4角星,运用ai绘画出5角星4角星三角形形状的设置步骤
  11. CalBioreagents 绵羊抗α-2-HS糖蛋白 亲和纯化说明
  12. 微信公众号/订阅号留言板使用介绍
  13. 机器学习 损失函数 Loss function
  14. 截止失真放大电路_一起学模电:6、放大电路静态与动态分析方法
  15. Still,yet和already的用法
  16. Android 私有权限白名单
  17. Ubuntu查看当前IP地址
  18. 视频教程-Photoshop(PS)软件基础入门-Photoshop
  19. HBO Max for Mac(HBO Max客户端)
  20. 最新阿里云服务器和GPU服务器长期优惠活动价格表

热门文章

  1. 3D建模角色男人头雕刻 | 不要再花钱买教程啦
  2. 主分区、扩展分区、逻辑分区
  3. char* char[] char** char*[] char[][]详解
  4. 菜鸟落泪:debian 9 安装 python 库记录
  5. js获取内网/局域网ip地址,操作系统,浏览器版本等信息
  6. 基于Huggingface的预训练语言模型分类体系及实战
  7. @Column(columnDefinition)的使用
  8. 01.【入门必备】认识python-->Linux中python环境搭建-->Linux交互模式ipython
  9. 判断HTTP代理的高匿程度
  10. vue下拉el-select二级联动