• 一个有问题的cube采样


    package test
    {
    import com.adobe.utils.AGALMiniAssembler;
    import com.adobe.utils.PerspectiveMatrix3D;

    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    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.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.PressAndTapGestureEvent;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Vector3D;
    import flash.ui.Keyboard;

    public class TestPointLight extends Sprite
    {
    [Embed(source="/assets/cloth.jpg")]
    private var cloth:Class;

    [Embed(source="/assets/skyBox.png")]
    private var skyBox:Class;

    [Embed(source="/assets/flower.jpg")]
    private var flower:Class;

    [Embed(source="/assets/trinket_diffuse.jpg")]
    private var trinketDiff:Class;

    [Embed(source="/assets/trinket_normal.jpg")]
    private var trinketNor:Class;

    [Embed(source="/assets/trinket_specular.jpg")]
    private var trinketSpe:Class;

    protected var context3D:Context3D;
    protected var program:Program3D;
    protected var vertexbuffer:VertexBuffer3D;
    protected var indexbuffer:IndexBuffer3D;

    private var texture:Texture;
    private var texture1:Texture;
    private var xR:Boolean = false;
    private var yR:Boolean = false;
    private var zR:Boolean = false;
    private var projectionTransform:PerspectiveMatrix3D;

    private var lightPos:Vector3D = new Vector3D(0,0,-10);

    private var lightStr:Number = 1;
    private var lightStrAdd:Number = -0.01;

    private var cameraMatrix:Matrix3D;
    private var objMatrix:Matrix3D = new Matrix3D();
    private var endMatrix:Matrix3D = new Matrix3D();

    private var aspect:Number;
    public function TestPointLight(context3D:Context3D,stage:Stage)
    {
    this.context3D = context3D;
    stage.addEventListener(Event.ENTER_FRAME, onRender);
    stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown)
    stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
    aspect = stage.width/stage.height;
    initProjection();

    var size:Number = 0.3;
    initCube(size,size,size, new Vector3D(0,0,0));
    }
    protected function initProjection():void
    {
    aspect = 4/3;
    var zNear:Number = 0.1;
    var zFar:Number = 1000;
    var fov:Number = 45*Math.PI/180;


    cameraMatrix = new Matrix3D();
    cameraMatrix.appendTranslation(0,0,-5);
    // cameraMatrix.invert();

    projectionTransform = new PerspectiveMatrix3D();
    projectionTransform.perspectiveFieldOfViewLH(fov, aspect, zNear, zFar);
    // projectionTransform.perspectiveFieldOfViewRH(45, aspect, zNear, zFar);
    // projectionTransform.prepend(cameraMatrix);
    }

    private function initCube(l:Number,w:Number,h:Number,position:Vector3D):void
    {
    var size:uint = 1;
    var unitWidth:Number = w / size;
    var unitHeight:Number = h / size;
    var unitLength:Number = l / size;
    var gap:Number = 0//w/size*1.1;

    // var hl:Number = l*0.5;
    // var hw:Number = w*0.5;
    // var hh:Number = h*0.5;

    var hl:Number = unitWidth;
    var hw:Number = unitHeight;
    var hh:Number = unitLength;

    var points:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
    points.push(Vector.<Number>([-hl,-hh,hw]));//左下后
    points.push(Vector.<Number>([-hl,-hh,-hw]));//左下前
    points.push(Vector.<Number>([hl,-hh,-hw]));//右下前
    points.push(Vector.<Number>([hl,-hh,hw]));//右下后
    points.push(Vector.<Number>([-hl,hh,hw]));//左上后
    points.push(Vector.<Number>([-hl,hh,-hw]));//左上前
    points.push(Vector.<Number>([hl,hh,-hw]));//右上前
    points.push(Vector.<Number>([hl,hh,hw]));//右上后

    var normals:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
    normals.push(Vector.<Number>([0,-1,0]));
    normals.push(Vector.<Number>([0,1,0]));
    normals.push(Vector.<Number>([0,0,-1]));
    normals.push(Vector.<Number>([0,0,1]));
    normals.push(Vector.<Number>([-1,0,0]));
    normals.push(Vector.<Number>([1,0,0]));


    var index:Array = [
    0,1,2,3,//下面
    4,5,6,7,//上面
    1,2,5,6,//前面
    0,3,7,4,//后面
    0,1,5,4,//左面
    3,2,6,7//右面
    ];
    var indices:Vector.<uint> = Vector.<uint>([
    0,1,2,0,2,3,
    4,7,5,5,7,6,
    8,10,9,9,10,11,//
    12,13,14,12,14,15,
    18,16,19,18,17,16,
    21,22,23,20,21,23
    ]);
    var uvs:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
    uvs.push(Vector.<Number>([0,0]));//左上
    uvs.push(Vector.<Number>([0,1]));//左下
    uvs.push(Vector.<Number>([1,1]));//右下
    uvs.push(Vector.<Number>([1,0]));//右上

    var allVertices:Vector.<Number> = new Vector.<Number>();
    var allIndices:Vector.<uint> = new Vector.<uint>();


    var cubeIndex:uint = 0;
    for (var i:int = 0; i < size; i++)
    {
    for (var j:int = 0; j < size; j++)
    {
    for (var k:int = 0; k < size; k++)
    {
    var matrix:Matrix3D = new Matrix3D();
    matrix.appendTranslation(i*(unitLength+gap),j*(unitWidth+gap),k*(unitHeight+gap));
    matrix.appendTranslation(-l*0.5-gap,-w*0.5-gap,0);
    //一个批次的定点
    var cubeVectexes:Vector.<Number> = new Vector.<Number>();
    var cubeUVs:Vector.<Number> = new Vector.<Number>();
    for (var n:int = 0; n < index.length; n+=4)
    {
    cubeVectexes = cubeVectexes.concat(points[index[n]],points[index[n+1]],points[index[n+2]],points[index[n+3]]);
    }
    matrix.transformVectors(cubeVectexes,cubeVectexes);
    // trace(cubeVectexes);
    var normalIndex:uint = 0;
    var uvIndex:uint = 0;
    for (n = 0; n < cubeVectexes.length; n+=3)
    {
    if(n%12 == 0) normalIndex = (normalIndex+1) % 6;
    if(n % 3 == 0) uvIndex = (uvIndex + 1) % 4;
    allVertices = allVertices.concat(Vector.<Number>([cubeVectexes[n],cubeVectexes[n+1],cubeVectexes[n+2]]).concat(uvs[uvIndex]).concat(normals[normalIndex]));
    trace(n,uvIndex,uvs[uvIndex])
    }


    var cubeIndices:Vector.<uint> = new Vector.<uint>(indices.length);
    for (n = 0; n < indices.length; n++)
    {
    cubeIndices[n] = indices[n] + index.length * cubeIndex;
    }
    allIndices = allIndices.concat(cubeIndices);
    cubeIndex++;
    }
    }
    }
    trace(allVertices);

    var offset:int = 8;
    vertexbuffer = context3D.createVertexBuffer(allVertices.length/offset, offset);
    vertexbuffer.uploadFromVector(allVertices, 0, allVertices.length/offset);

    indexbuffer = context3D.createIndexBuffer(allIndices.length);
    indexbuffer.uploadFromVector (allIndices, 0, allIndices.length);

    var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();
    vertexShaderAssembler.assemble( Context3DProgramType.VERTEX,
    "m44 op va0 vc0 "+ //顶点
    "mov v1 va1 "+ //UV
    "mov v2 va2"//法线
    );
    var fragmentShaderAssembler : AGALMiniAssembler= new AGALMiniAssembler();
    fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT,
    //fc0 光源位置
    //fc1 环境光颜色 以及w光强
    //fc2 半向量
    //fc3 模型矩阵
    "tex ft0,v1,fs0<2d,linear,repeat> " +
    "mov ft1 fc0 " +
    "mov ft2 v2 " +
    "m44 ft2 ft2 fc3 " +
    //
    // "sub ft5 fc0 ft2" +
    // "mul ft5 ft5 ft5" +
    //
    "dp3 ft3.w ft1 ft2 " + //ft3 = cos涩塔
    "abs ft3.w ft3.w " +
    "mul ft4 ft0 ft3.wwww "+
    "mul ft4 ft4 fc1.wwww "+
    //
    "dp3 ft6.w fc2 ft2 " +
    "abs ft6.w ft6.w " +
    "mul ft7 fc4 ft6.wwww " +
    //
    "add ft0 ft0 ft4 " + // 原始颜色 += 漫反射光照加成颜色
    "add ft0 ft0 ft7 " + // 原始颜色 += 高光加成颜色
    // "add ft0 ft0 fc1 " + // 叠加一个环境光颜色

    "mov oc,ft0"
    );

    var bitmap:Bitmap = new trinketDiff();
    texture = context3D.createTexture(bitmap.width,bitmap.height,Context3DTextureFormat.BGRA,false);
    texture.uploadFromBitmapData(bitmap.bitmapData);

    var bitmap1:Bitmap = new trinketNor();
    texture1 = context3D.createTexture(bitmap1.width,bitmap1.height,Context3DTextureFormat.BGRA,false);
    texture1.uploadFromBitmapData(bitmap1.bitmapData);

    program = context3D.createProgram();
    program.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
    }

    private function culculateNormal(vecVb:Vector.<Number>,vertexNum:int):void
    {
    var data32PerVertex:int = vecVb.length/vertexNum;
    var vertexArr:Array = [];
    for (var i:int=0;i<vertexNum;i++){
    var x:Number = vecVb[data32PerVertex*i];
    var y:Number = vecVb[data32PerVertex*i+1];
    var z:Number = vecVb[data32PerVertex*i+2];
    vertexArr.push(new Vector3D(x,y,z));
    }

    var calcNormal:Function = function(p1:Vector3D,p2:Vector3D,p3:Vector3D):Vector3D{
    var source2:Vector3D = new Vector3D(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z);
    var source1:Vector3D = new Vector3D(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z);
    var norV:Vector3D = new Vector3D();
    norV.x = source1.y * source2.z - source1.z * source2.y;
    norV.y = source1.z * source2.x - source1.x * source2.z;
    norV.z = source1.x * source2.y - source1.y * source2.x;
    norV.normalize();
    return norV;
    }

    var calcNormalAvg:Function = function(arr:Array,offsetNormal:int):void{
    var sideLen:int = arr.length/3;
    var sideAvg:Vector3D = new Vector3D();
    for (var i:int=0;i<sideLen;i++){
    var side:Vector3D = calcNormal(vertexArr[arr[i*3]],vertexArr[arr[i*3+1]],vertexArr[arr[i*3+2]]);
    sideAvg=sideAvg.add(side);
    }
    sideAvg.x = sideAvg.x/sideLen;
    sideAvg.y = sideAvg.y/sideLen;
    sideAvg.z = sideAvg.z/sideLen;
    sideAvg.normalize();
    vecVb[offsetNormal] = -sideAvg.x;
    vecVb[offsetNormal+1] = -sideAvg.y;
    vecVb[offsetNormal+2] = -sideAvg.z;
    }
    // calcNormalAvg([0,1,3,1,2,3],vertexNum*data32PerVertex)
    }

    protected function onRender(e:Event):void
    {
    if ( !context3D ) return;

    if(xR) objMatrix.appendRotation(1,Vector3D.X_AXIS);
    if(yR) objMatrix.appendRotation(1,Vector3D.Y_AXIS);
    if(zR) objMatrix.appendRotation(1,Vector3D.Z_AXIS);

    endMatrix.identity();
    endMatrix.append(objMatrix);
    var viewMatrix:Matrix3D = cameraMatrix.clone();
    viewMatrix.invert();
    viewMatrix.append(projectionTransform);
    endMatrix.append(viewMatrix);

    // endMatrix.copyFrom(objMatrix);
    // endMatrix.append(projectionTransform);

    context3D.setVertexBufferAt (0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);//顶点 Va0
    context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_2);// uv Va1
    context3D.setVertexBufferAt(2,vertexbuffer,5,Context3DVertexBufferFormat.FLOAT_3); // 法线 Va2
    var light:Vector3D=lightPos.clone(); // 不含平移元素的变换
    light.normalize();
    context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,0,Vector.<Number>([light.x,light.y,light.z,0]));

    // -- 设置状态机当前的fc1 静态常量:xyz用于 环境光颜色叠加 W用于漫反射光照强度 这里叠加一个红色环境光
    var ambientR:Number = 1//lightStr*0.2;
    var ambientG:Number = 0//(1-lightStr)*0.2;
    var ambientB:Number = 0//(lightStr/2)*0.2;
    context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,1,Vector.<Number>([ambientR,ambientG,ambientB,lightStr]));//lightStr

    var halfEyeLightPos:Vector3D = cameraMatrix.position.clone();
    halfEyeLightPos=halfEyeLightPos.add(lightPos);

    halfEyeLightPos.x/=2;
    halfEyeLightPos.y/=2;
    halfEyeLightPos.z/=2;
    halfEyeLightPos.normalize();
    context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,2,Vector.<Number>([halfEyeLightPos.x,halfEyeLightPos.y,halfEyeLightPos.z,0]));
    // -- 设置状态机当前的fc3 静态常量:用于将模型矩阵变换传入
    context3D.setProgramConstantsFromMatrix(Context3DProgramType.FRAGMENT,3,objMatrix);
    // -- 设置状态机当前的fc4 静态常量:高光颜色
    var specularR:Number = 0//lightStr*0.3;
    var specularG:Number = 1//lightStr*0.3;
    var specularB:Number = 0//lightStr*0.3;
    context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT,4,Vector.<Number>([specularR,specularG,specularB,0]));

    context3D.setTextureAt(0,texture);
    // context3D.setTextureAt(1,texture1);
    context3D.setProgram(program);

    context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, endMatrix, true);

    context3D.clear();
    context3D.drawTriangles(indexbuffer);
    context3D.present();
    }
    /**
    * 当鼠标移动的时候记录的鼠标点
    */
    private var onMouseDownPt:Point = new Point();
    /**
    * 鼠标移动旋转物体
    * 原理无非就是根据每次移动时的像素差距来计算让物体矩阵M在当前的状态下再围绕X和Y旋转(至于围绕Z轴旋转可以自己添加试试)
    * @param e
    *
    */
    private function onMouseDown(e:MouseEvent):void{
    onMouseDownPt.x = e.stageX;
    onMouseDownPt.y = e.stageY;
    stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
    stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
    }
    private function onMouseMove(e:MouseEvent):void{
    var dx:Number = e.stageX - onMouseDownPt.x;
    var dy:Number = e.stageY - onMouseDownPt.y;
    var degreesY:Number = -dx/2;
    var degreesX:Number = -dy/2;
    onMouseDownPt.x = e.stageX;
    onMouseDownPt.y = e.stageY;
    objMatrix.appendRotation(degreesY,Vector3D.Y_AXIS);
    objMatrix.appendRotation(degreesX,Vector3D.X_AXIS);
    }
    private function onMouseUp(e:MouseEvent):void{
    stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
    stage.removeEventListener(MouseEvent.MOUSE_UP,onMouseUp);
    }

    private var moveDis:Number = 0.1;
    protected function onKeyDown(event:KeyboardEvent):void
    {
    switch(event.keyCode)
    {
    case Keyboard.NUMPAD_ADD:
    lightStr += 0.1;
    break;
    case Keyboard.NUMPAD_SUBTRACT:
    lightStr -= 0.1;
    break;
    case Keyboard.X:
    xR = !xR;
    break;
    case Keyboard.C:
    yR = !yR;
    break;
    case Keyboard.Z:
    zR = !zR;
    break;
    case Keyboard.R:
    objMatrix.identity();
    xR = false;
    yR = false;
    zR = false;
    break;
    case Keyboard.LEFT:
    lightPos.x -= moveDis;
    break;
    case Keyboard.RIGHT:
    lightPos.x += moveDis;
    break;
    case Keyboard.UP:
    lightPos.y += moveDis;
    break;
    case Keyboard.DOWN:
    lightPos.y -= moveDis;
    break;
    case Keyboard.A:
    cameraMatrix.appendTranslation(moveDis,0,0);
    break;
    case Keyboard.D:
    cameraMatrix.appendTranslation(-moveDis,0,0);
    break;
    case Keyboard.W:
    cameraMatrix.appendTranslation(0,-moveDis,0);
    break;
    case Keyboard.S:
    cameraMatrix.appendTranslation(0,moveDis,0);
    break;
    }
    trace("lightPos:"+lightPos);
    trace("cameraPos"+cameraMatrix.decompose())
    trace("lightStr"+lightStr);
    }
    /**
    * 判断设备丢失
    *
    */
    private function get isContextDispose():Boolean{
    return context3D==null||context3D.driverInfo=="Disposed"||context3D.driverInfo=="";
    }
    }
    }

  • 相关阅读:
    [HDU] 1269 迷宫城堡最简单的强连通分支题
    [HDU] 1301 Jungle Roads赤裸裸的最小生成树
    [HDU] 2647 Reward带有贪心算法的拓扑排序
    [HDU] 1181 变形课简单建模后广搜
    【慢慢学Android】:5.短信拦截
    【慢慢学Android】:8.获取所有短信
    ubuntu下设置Android手机驱动
    Win7笔记本变为热点供手机上WiFi
    VS快捷键和小功能
    【慢慢学Android】:11.对话框大全
  • 原文地址:https://www.cnblogs.com/Star9527/p/6720795.html
Copyright © 2020-2023  润新知