Stage3D学习笔记(三):使用GPU绘制一个图片
首先准备我们需要的图片,尺寸必须是2的幂数,我修改了一下Starling的图标拿来用:
还是先看看最终效果:
代码是居于上一节的代码进行修改的:
package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap; import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=800, height=600, frameRate=60)]
public class DrawTexture extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; //3D 场景对象
private var _stage3D:Stage3D;
//3D 上下文渲染对象
private var _context3D:Context3D; //顶点缓冲数据
private var _vertexBuffer:VertexBuffer3D;
//索引缓冲数据
private var _indexBuffer:IndexBuffer3D;
//纹理数据对象
private var _texture:Texture; //着色器对象
private var _program3D:Program3D; public function DrawTexture()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); //3D 场景存在, 一般存在 4 个 3D 场景对象
if(stage.stage3Ds.length > 0)
{
//使用最下层的 3D 场景
_stage3D = stage.stage3Ds[0];
//请求 3D 上下文渲染对象
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
initProgram(); //每帧进行渲染
addEventListener(Event.ENTER_FRAME, render);
} private function initContext3D():void
{
//获取 3D 渲染对象
_context3D = _stage3D.context3D;
//调整 3D 舞台位置
_stage3D.x = 150;
_stage3D.y = 50;
//设置后台缓冲区
_context3D.configureBackBuffer(500, 500, 2);
} private function initBuffer():void
{
//顶点数据
var vertexData:Vector.<Number> = Vector.<Number>(
[
// x, y, z, u, v
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]); //创建顶点缓冲对象, 参数设定存在几组数据和每组数据的个数
_vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
//上传顶点数据到GPU, 参数设定从第几组数据开始上传和上传多少组数据
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); //索引数据
var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); //创建索引缓冲对象, 每个索引对应顶点数据中的相对应的一组数据,
//每3个索引组成一个会被绘制出来的三角形, 参数指定索引的长度
_indexBuffer = _context3D.createIndexBuffer(indexData.length);
//上传索引数据到GPU, 参数设定从第几个数据开始上传和上传多少个数据
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
//创建位图
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
//创建纹理, 注意尺寸必须是 2 的幂数
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
//上传纹理到 GPU, 第二个参数表示该纹理的 mipmap 级别, 级别零是高级全分辨率图像
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} private function initProgram():void
{
//顶点着色器代码, 每个上传的顶点前都会执行一次该代码
var vertexArr:Array =
[
//op 代表位置输出寄存器, 无论对顶点进行多少次的运算最终都要将结果
//赋值给他, 这里我们不进行运行, 直接赋值
"mov op, va0",
//片段着色器需要用的数据要在这里通过 v0 中转一下, 因为片段着色器不
//能直接读取 va0 和 va1 的数据
"mov v0, va1"
]; //片段着色器代码, 每个可以显示的像素都会执行一次该代码
var fragmentArr:Array =
[
//对纹理 fs0 进行取样, 通过 v0 代表的 uv 坐标来获取对应的像素点颜
//色, 将该颜色值存储到 ft0 中
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
//oc 代表颜色输出寄存器, 每个顶点的颜色数据都要赋值给他
"mov oc, ft0"
]; //使用 Adobe 自己提供的编译器编译代码为程序可使用的二进制数据
var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //----- 这段代码是从 render 里搬过来的, 因为不会进行改动就不放在帧循环中了 ----- //指定着色器代码的 va0 代表的数据段, 表示顶点的 x, y, z 坐标
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
//指定着色器代码的 va1 代表的数据段, 表示顶点的 u, v 数据
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//指定上传的纹理由 fs0 表示
_context3D.setTextureAt(0, _texture);
//指定当前使用的着色器对象
_context3D.setProgram(_program3D);
} private function render(event:Event):void
{
//清除已绘制过的 3D 图像
_context3D.clear();
//通过顶点索引数据绘制所有的三角形
_context3D.drawTriangles(_indexBuffer);
//将后台缓冲的图像显示到屏幕
_context3D.present();
}
}
}
Stage3D学习笔记(三):使用GPU绘制一个图片的更多相关文章
- ROS学习笔记三:编写第一个ROS节点程序
在编写第一个ROS节点程序之前需要创建工作空间(workspace)和功能包(package). 1 创建工作空间(workspace) 创建一个catkin_ws: #注意:如果使用sudo一次 ...
- angular学习笔记(三十)-指令(9)-一个简单的指令示例
学了前面这么多关于指令的知识,现在就用指令来写一个小组件:expander 这个组件的功能就是点击开展菜单,再点击收起菜单: ↑↓点击展开收起 下面来看它的代码: html: <!DOCTYPE ...
- angular学习笔记(三十)-指令(10)-require和controller
本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...
- ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...
- Stage3D学习笔记(五):通过矩阵操作纹理
虽然我们上一节已经实现了正交矩阵的显示,但是可以明显的感觉到要调整显示纹理的坐标和尺寸是相当复杂的,需要对每个顶点进行操作,如果还要加上注册点和旋转的话,用上一节的方法来做是会让人发疯的! 所以我们距 ...
- 【Stage3D学习笔记续】真正的3D世界(一):透视矩阵
如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上 ...
- 【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现
批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制. 先想一想我们最开始是怎么向GPU绘制一幅图像的,可 ...
- 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记
回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
随机推荐
- Photoshop:路径填充边缘虚化问题
怎么才能不让它虚化呢? 解决方案一: 1.同样画出路径 2.新建图层 3.回到路径面板,右击路径图层,选择“填充路径” 4.把“羽化”设置为0,取消选择“消除锯齿” 换个背景色看看效果:一点虚化都没 ...
- binary 和 varbinary
固定长度或可变长度的 Binary 数据类型. binary [ ( n ) ] 长度为 n 字节的固定长度二进制数据,其中 n 是从 1 到 8,000 的值.存储大小为 n 字节. varbina ...
- python学习链接
http://www.cnblogs.com/dkblog/archive/2011/06/24/2089026.html 异常处理 http://xiagu1.iteye.com/blog/6195 ...
- 让JAVA代码跑得更快
本文简单介绍一下在写代码过程中用到的一些让JAVA代码更高效的技巧. 1. 将一些系统资源放在池中(如数据库连接, 线程等) 在standalone的应用中, 数据库连接池可以使用一些开源的连接池 ...
- 简单的ftpserver设置
一.安装: yum install vsftpd* 二. 修改配置文档如下: vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO chroot_list_en ...
- 【转】Android Service被关闭后自动重启,解决被异常kill 服务
http://www.kaifajie.cn/android/10182-2.html 每次调用startService(Intent)的时候,都会调用该Service对象的onStartComman ...
- windows下的go语言的环境搭建和初探
闲话不说,直入主题. 1.准备工具 a.windows下的Go语言开发安装包 官方下载地址:https://code.google.com/p/go/downloads/list b.Go语言中文官网 ...
- sublime text2卸载和重新安装
很多同学使用 sublime text2 的时候,出现一些奇怪的bug,且重启无法修复. 于是,就会想到卸载 sublime text2 再重新安装. 然而,你会发现,重新安装后,这个bug任然存在, ...
- 最受 Web 开发者欢迎的 NoSQL 和关系数据库
Web应用离不开数据库,目前市场上有种类繁多数据库可供开发者选择,例如SQL.NoSQL.键值.图谱数据库等等.关于不同数据库在开发者中的受欢迎程度也是仁者见仁智者见智,但是通过统计亚马逊这样的公共云 ...
- eayui 验证扩展
$.extend($.fn.validatebox.defaults.rules, { idcard : {// 验证身份证 validator : function(value) { return ...