Stage3D_Game_Programming:渲染3D模型
OBJ是文件,先来解释下OBJ文件。随便找一个OBJ文件,用文本查看:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # Max2Obj Version 4.0Mar 10th, 2001## object (null) to come ...#v -0.2570.1910.423v -0.1150.29-0.068v -0.2370-0.074v -0.2370.0710.646...# 82verticesvt 0.6230.2270vt 0.6150.530vt 0.8950.5550vt 0.8250.2460vt 0.6470.8470...# 39texture verticesf 1/12/23/3f 3/34/41/1f 2/25/56/6f 6/63/32/2...# 142faces | 
v:是模型的顶点信息 vt:是贴图的UV坐标 f:是定义面的顶点索引和顶点对应的UV坐标索引 清楚了OBJ文件里各种数据所代表的信息,接下来就是如何把数据传递给显卡渲染。 那么我们需要一个解析OBJ文件的类(代码比较简单,注释就省了)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | packagecom.parser{    importflash.utils.ByteArray;      publicclassOBJParser    {        privatevar_lines:Array;        privateconstLINE_FEED:String= String.fromCharCode(10);        privateconstSPACE:String= String.fromCharCode(32);        privatevar_scale:Number;        publicfunctionOBJParser(objfile:ByteArray,scale:Number= 1)        {            _scale = scale;            if(objfile)            {                varlineStr:String= parserToStr(objfile);                _lines = lineStr.split(LINE_FEED);                varloop:uint= _lines.length;                for(vari:uint= 0; i < loop; i++)                {                    parseLine(_lines[i]);                }            }           }        privateconstVERTEX:String= 'v';        privateconstUV:String= 'vt';        privateconstINDEX_DATA:String= 'f';        privatefunctionparseLine(lineStr:String):void        {            vardata:Array= lineStr.split(SPACE);            if(!data.length)return;            varkey:String= data[0];            varparseData:Array= data.slice(1);            switch(key)            {                caseVERTEX:                    parseVertex(parseData);                    break;                caseUV:                    parseUV(parseData);                    break;                caseINDEX_DATA:                    parseIndexData(parseData);                    break;            }        }        privatevar_vertices:Vector.<Number> = newVector.<Number>();        privatefunctionparseVertex(data:Array):void        {            if(data[0] == ''|| data[0] == " ")            {                data = data.slice(1);            }            varloop:uint= data.length;            for(vari:uint= 0; i < loop; i++)            {                varvalue:Number= Number(data[i]);                _vertices.push(value*_scale);            }        }        privatevar_uvs:Vector.<Number> = newVector.<Number>();        privatefunctionparseUV(data:Array):void        {            if(data[0] == ''|| data[0] == " ")            {                data = data.slice(1);            }            varloop:uint= 2;            for(vari:uint= 0; i < loop; i++)            {                varvalue:Number= Number(data[i]);                _uvs.push(value*_scale);            }        }        privateconstSLASH:String= "/";        privatevar_indexData:Vector.<uint> = newVector.<uint>();        privatevar_vertexsData:Vector.<Number> = newVector.<Number>();        privatevar_uvData:Vector.<Number> = newVector.<Number>();        privatevar_faceIndex:uint;        privatefunctionparseIndexData(data:Array):void        {            varindex:uint= 0;            while((data[index] == '') || (data[index] == ' '))index++;            varloop:uint= index+3;            varvertexIndex:int;            varuvIndex:int;            varnormalIndex:int;            for(vari:uint= index; i < loop; i++)            {                vartriplet:String= data[i];                varsubdata:Array= triplet.split(SLASH);                vertexIndex = int(subdata[0]) - 1;                uvIndex     = int(subdata[1]) - 1;                if(vertexIndex < 0) vertexIndex = 0;                if(uvIndex < 0) uvIndex = 0;                index = 3*vertexIndex;                _vertexsData.push(_vertices[index + 0],                 _vertices[index + 1], _vertices[index + 2]);                index = 2*uvIndex;                _uvData.push(1-_uvs[index+0],1-_uvs[index+1]);            }            _indexData.push(_faceIndex+0,_faceIndex+1,_faceIndex+2);            _faceIndex += 3;        }        privatefunctionparserToStr(objFileByteArray:ByteArray):String        {            returnobjFileByteArray.readUTFBytes(objFileByteArray.bytesAvailable);        }        /**         * 顶点数据          * @return          *          */        publicfunctiongetvertexsData():Vector.<Number>        {            return_vertexsData;        }        /**         * UV数据          * @return          *          */        publicfunctiongetuvData():Vector.<Number>        {            return_uvData;        }        /**         * 索引数据          * @return          *          */        publicfunctiongetindexData():Vector.<uint>        {            return_indexData;        }    }} | 
| 1 |  | 
有了顶点信息,uv信息和面的索引信息接下来就可以把这货渲染出来了。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | package{    importcom.adobe.utils.AGALMiniAssembler;    importcom.adobe.utils.PerspectiveMatrix3D;    importcom.parser.OBJParser;    importflash.display.Bitmap;    importflash.display.BitmapData;    importflash.display.Sprite;    importflash.display.Stage3D;    importflash.display.StageAlign;    importflash.display.StageScaleMode;    importflash.display3D.Context3D;    importflash.display3D.Context3DProgramType;    importflash.display3D.Context3DTextureFormat;    importflash.display3D.Context3DVertexBufferFormat;    importflash.display3D.IndexBuffer3D;    importflash.display3D.Program3D;    importflash.display3D.VertexBuffer3D;    importflash.display3D.textures.Texture;    importflash.events.Event;    importflash.geom.Matrix;    importflash.geom.Matrix3D;    importflash.geom.Vector3D;    importflash.utils.ByteArray;    [SWF(width='800',height='600',backgroundColor='0x333333',frameRate="60")]       publicclassGameTest extendsSprite    {        [Embed (source = "art/spaceship.obj",         mimeType = "application/octet-stream")]         privatevarobjData:Class;        [Embed (source = "art/spaceship_texture.jpg")]         privatevarTextureBitmap:Class;        privatevartextureData:Bitmap = newTextureBitmap();        privatevar_stage3D:Stage3D;        privatevar_context3D:Context3D;        privateconstsw:uint= 700;        privateconstsh:uint= 500;        privatevar_objParser:OBJParser;        //顶点缓冲 存储顶点信息        privatevar_vertexBuffer:VertexBuffer3D;        //顶点缓冲 存储UV信息        privatevar_uvBuffer:VertexBuffer3D;        //顶点索引        privatevar_indexBuffer:IndexBuffer3D;        privatevar_texture:Texture;        privatevar_textureSize:uint= 512;        privatevar_projectionmatrix:PerspectiveMatrix3D;        privatevar_viewmatrix:Matrix3D;        privatevar_modelmatrix:Matrix3D = newMatrix3D();        privatevar_modelViewProjection:Matrix3D = newMatrix3D();        privatevar_vertexShaderAssembler:AGALMiniAssembler;        privatevar_fragmentAssembler:AGALMiniAssembler;        privatevar_program:Program3D;        publicfunctionGameTest()        {            if(this.stage)            {                init();            }else            {                addEventListener(Event.ADDED_TO_STAGE,init);            }        }        privatefunctioninit(e:Event = null):void        {            if(hasEventListener(Event.ADDED_TO_STAGE))removeEventListener(Event.ADDED_TO_STAGE,init);            this.stage.scaleMode = StageScaleMode.NO_SCALE;            this.stage.align = StageAlign.TOP_LEFT;            initStage3D();        }        privatefunctioninitStage3D():void        {            _stage3D = this.stage.stage3Ds[0];            if(_stage3D)            {                _stage3D.addEventListener(Event.CONTEXT3D_CREATE,onContext3DCreate);                _stage3D.requestContext3D();            }        }        privatefunctiononContext3DCreate(e:Event):void        {            _context3D = _stage3D.context3D;            if(_context3D == null)            {                thrownewError("无法创建Context3D");                return;            }            _stage3D.x = (this.stage.stageWidth - sw)/2;            _stage3D.y = (this.stage.stageHeight - sh)/2;            _context3D.configureBackBuffer(sw,sh,1);            _context3D.clear(205,205,205);            _context3D.enableErrorChecking = true;            initData();            initShader();            this.stage.addEventListener(Event.ENTER_FRAME,onEnterFrame);        }        privatefunctioninitData():void        {            varobjdata:ByteArray = newobjData() asByteArray;            _objParser = newOBJParser(objdata);            varvertexCont:uint= _objParser.vertexsData.length/3;            _vertexBuffer = _context3D.createVertexBuffer(vertexCont,3);            _vertexBuffer.uploadFromVector(_objParser.vertexsData,0,vertexCont);            varuvCont:uint= _objParser.uvData.length/2;            _uvBuffer = _context3D.createVertexBuffer(uvCont,2);            _uvBuffer.uploadFromVector(_objParser.uvData,0,uvCont);            _context3D.setVertexBufferAt(0,_vertexBuffer,0,Context3DVertexBufferFormat.FLOAT_3);            _context3D.setVertexBufferAt(1,_uvBuffer,0,Context3DVertexBufferFormat.FLOAT_2);            varindexData:Vector.<uint> = _objParser.indexData;            _indexBuffer = _context3D.createIndexBuffer(indexData.length);            _indexBuffer.uploadFromVector(indexData,0,indexData.length);            _texture = _context3D.createTexture(_textureSize,_textureSize,Context3DTextureFormat.BGRA,false);            uploadTextureWithMipmaps(_texture,textureData.bitmapData);            _projectionmatrix = newPerspectiveMatrix3D();            _projectionmatrix.identity();            // 45 degrees FOV, 640/480 aspect ratio, 0.1=near, 100=far            _projectionmatrix.perspectiveFieldOfViewRH(                45.0, sw / sh, 0.01, 100.0);            _viewmatrix = newMatrix3D();            // camera Matrix3D            _viewmatrix.identity();            // 移动镜头到(0,0,0)            _viewmatrix.appendTranslation(0,0,0);        }        privatefunctioninitShader():void        {            _vertexShaderAssembler = newAGALMiniAssembler();            _vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,                "m44 op, va0, vc0\n"+                "mov v0, va0\n"+                "mov v1, va1\n");            _fragmentAssembler= newAGALMiniAssembler();            _fragmentAssembler..assemble                (                     Context3DProgramType.FRAGMENT,                      "tex ft0, v1, fs0 <2d,linear,repeat,miplinear>\n"+                    "mov oc, ft0\n"                );            _program = _context3D.createProgram();            _program.upload(_vertexShaderAssembler.agalcode,_fragmentAssembler.agalcode);            _context3D.setTextureAt(0,_texture);                        _context3D.setProgram(_program);        }        privatevar_t:Number= 0;        privatefunctiononEnterFrame(e:Event):void        {            _context3D.clear(0,0,0,.7);             _t += 2.0;            _modelmatrix.identity();            //旋转模型            _modelmatrix.appendRotation(_t*1.0, Vector3D.Y_AXIS);            _modelmatrix.appendRotation(_t*-0.2, Vector3D.X_AXIS);            _modelmatrix.appendRotation(_t*0.3, Vector3D.Y_AXIS);            _modelmatrix.appendTranslation(-0.4, 0, -5);            _modelViewProjection.identity();            _modelViewProjection.append(_modelmatrix);            _modelViewProjection.append(_viewmatrix);            _modelViewProjection.append(_projectionmatrix);            _context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, _modelViewProjection, true);            //绘制模型            _context3D.drawTriangles(_indexBuffer, 0, _objParser.indexData.length/3);            //呈现至屏幕            _context3D.present();        }        /**         * Mipmap          * @param dest         * @param src         *          */        privatefunctionuploadTextureWithMipmaps(dest:Texture, src:BitmapData):void        {            varws:int= src.width;            varhs:int= src.height;            varlevel:int= 0;            vartmp:BitmapData;            vartransform:Matrix = newMatrix();            tmp = newBitmapData(src.width, src.height, true, 0);            while( ws >= 1&& hs >= 1)            {                 tmp.draw(src, transform, null, null, null, true);                 dest.uploadFromBitmapData(tmp, level);                transform.scale(0.5, 0.5);                level++;                ws >>= 1;                hs >>= 1;                if(hs && ws)                 {                    tmp.dispose();                    tmp = newBitmapData(ws, hs, true, 0x00000000);                }            }            tmp.dispose();        }    }} | 
Stage3D_Game_Programming:渲染3D模型的更多相关文章
- WPF 3D模型 3D场景
		1.首先得说明的是这并不是真正的3D,模型被导出为一系列的单个图片,例如一个3D户型图,以某个视角旋转360°,渲染出一系列连续的单个图片文件. 2.在Image.MouseMove事件中添加相应代码 ... 
- unity3d设置3D模型显示在2D背景之前(多个相机分层显示)(转)
		解决步骤: 1.添加一个摄像机,命名为BackgroundCamera,然后在Layer添加一个background层.并且将plane拖放到改相机节点下. 然后将BackgroundCamera和P ... 
- Flash Stage3D  在2D UI 界面上显示3D模型问题完美解决
		一直以来很多Stage3D开发者都在为3D模型在2DUI上显示的问题头疼.Stage3D一直是在 Stage2D下面.为了做到3D模型在2DUI上显示通常大家有几种实现方式,下面来说说这几种实现方式吧 ... 
- three.js实现3D模型展示
		由于项目需要展示3d模型,所以对three做了点研究,分享出来 希望能帮到大家 先看看效果: three.js整体来说 不是很难 只要你静下心来研究研究 很快就会上手的 首先我们在页面上需要创建一个能 ... 
- 3D模型展示以及体积、表面积计算
		本文原创 如转载请注明出处!!! 本博客地址http://www.cnblogs.com/we-jack 本文原创,如果有同样需求的小伙伴请第一时间联系我 或者在留言区留言 上次为大家提供了3D模型的 ... 
- Unity在UI界面上显示3D模型/物体,控制模型旋转
		Unity3D物体在UI界面的显示 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ... 
- 使用Chrome控制台进行3D模型编辑的尝试
		前言:3D模型编辑的核心是对顶点位置和纹理颜色的编辑,这个研究的目的在于寻找一种通过编程方式直接对模型进行编辑的方法,这种编辑方法和时下流行的通过鼠标点选.拖拽进行编辑的方法之间的关系,和前端编程中“ ... 
- XNA 中3D模型的显示
		XNA 中3D模型的显示: ModelMeshPart[] meshParts; Model start_model; Matrix[] dq_model_transforms; Matrix vie ... 
- 分享一个WebGL开发的网站-用JavaScript + WebGL开发3D模型
		这张图每位程序员应该都深有感触. 人民心目中的程序员是这样的:坐在电脑面前噼里啪啦敲着键盘,运键如飞. 现实中程序员是这样的:编码5分钟,调试两小时. 今天我要给大家分享一个用WebGL开发的网站,感 ... 
随机推荐
- corejava_chap02
			//单行注释 --不能用在一行代码的中间/**/多行注释 --任何地方/** */文档注释 文档注释用在:package.class.member variables.member method. ... 
- Oauth认证简介
			Oauth是什么: 1.Oauth是一种安全认证的协议: 2.Oauth为用户资源的授权提供了一个安全的.开放而又简易的标准: 3.Oauth的授权不会使第三方触及到用户的账号信息(用户名和密码). ... 
- photoshop中rgb与索引模式的区别
			RGB: 是色域最宽广的颜色模式它是一种光色模式不难理解 你的显示器 就是根据这个模式来显示图像的同样 我们在自然界中 看到的所有五颜六色的东西都是吸收了不同颜色的光 而得到的所以这一颜色模式 与我 ... 
- phpcms(4) V9 栏目管理
			phpcms V9框架系统后台管理之栏目管理,请参见下文的源码分析(添加栏目和修改栏目): 参照添加栏目的界面图示,便于对源代码的理解: <?php // 文件路径:phpcms/modul ... 
- JS作用域概念-预解析规则
			// 作用域: // 域:空间.范围.区域…… // 作用:读.写 script 全局变量.全局函数 自上而下 函数 由里到外 {} 浏览器: “JS解析器” 1)“找一些东西” :var funct ... 
- 深入解析.NET框架
			一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种 ... 
- Hash索引和BTree索引区别
			(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询. 由于 Hash 索引比较的是进行 Hash ... 
- wdcp-apache配置错误导致进程淤积进而内存吃紧
			内存总是越来越少,虚拟内存使用越来越多 首先确定到底是什么占用了大量的内存 可以看到,大部分内存被闲置的httpd进程占用 且当我重启mysql服务后,内存没有出现明显变化,但是当我重启apache时 ... 
- linux常用命令(4)rm命令
			rm是一个危险的命令,使用的时候要特别当心,尤其对于新手,否则整个系统就会毁在这个命令(比如在/(根目录)下执行rm * -rf).所以,我们在执行rm之前最好先确认一下在哪个目录,到底要删除什么东西 ... 
- oracle 的一点累积
			1. oracle用户相关 sqlplus sys/oracle as sysdba -- sys登录 create user xxx identified by password; -- ... 
