webGL 在一个页面上,同时显示DDA算法和Bresenham算法画直线

直线的光栅化绘制

算法思想

DDA

设直线两端点为:起点A(x0,y0);终点为B(x1,y1)。
则直线的斜率和方程为:
在这里插入图片描述

下面分为两种情况考虑:当斜率小于等于1的时候,x每次增加1,y最多增加1。
在这里插入图片描述

而当斜率大于1的时候,让y每次递增1,x每次递增最多1

Bresenham

  • 求出初始决策参数值
    p0=2△y-△x

  • 计算后继决策参数值
    2△y
    2△y-2△x

效果图

在这里插入图片描述

源码

HelloLineDDA.html

<!DOCTYPE HTML>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>DDA & Bresenham</title>
</head>

<body onload="startup()">
    <canvas id="webgl" width="640" height="480">
        </canvas>
</body>
<script src="HellolineDDA.js">
</script>

</html>

HelloLineDDA.js

var gl;

function createGLContext(canvas) {
    var names = ["webgl", "experimental-webgl"];
    var context = null;
    for (var i = 0; i < names.length; i++) {
        try {
            context = canvas.getContext(names[i]); //获取webgl context绘图上下文
        } catch (e) {}
        if (context) {
            break;
        }
    }
    if (context) {
        context.viewportWidth = canvas.width;
        context.viewportHeight = canvas.height;
    } else {
        alert("Failed to create WebGL context!");
    }
    return context;
}

function loadShader(type, shaderSource) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert("Error compiling shader" + gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
    }
    return shader;
}

function setupShaders() {
    //顶点着色器程序
    var vertexShaderSource =
        'attribute vec4 a_Position;\n' +
        'void main() {\n' +
        '  gl_Position = a_Position;\n' +
        '  gl_PointSize = 5.0;\n' +
        '}\n';

    //片元着色器程序
    var fragmentShaderSource =
        'void main(){ \n' +
        '    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n' + //gl_FragColor指定像素的颜色
        '} \n';

    var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
    var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);

    var shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Failed to setup shaders");
    }

    gl.useProgram(shaderProgram);
    gl.program = shaderProgram;

    var a_PosLocation = gl.getAttribLocation(gl.program, 'a_Position');
    gl.vertexAttribPointer(a_PosLocation, 2, gl.FLOAT, false, 0, 0);
}

function DDA_Bresenham(x0, y0, xEnd, yEnd, x1, y1, x1End, y1End) {
    //DDA
    var arr = new Array();
    var dx = xEnd - x0,
        dy = yEnd - y0,
        steps, k;
    var xIncrement, yIncrement, x = x0,
        y = y0;
    if (Math.abs(dx) > Math.abs(dy)) {
        steps = Math.abs(dx);
    } else {
        steps = Math.abs(dy);
    }
    xIncrement = dx / steps;
    yIncrement = dy / steps;
    arr[0] = x;
    arr[1] = y;
    for (var i = 0; i < steps; i++) {
        x += xIncrement;
        y += yIncrement;
        k = 2 * i + 2;
        arr[k] = x / 100;
        arr[k + 1] = y / 100;
    }

    //Bresenham
    var dx1 = Math.abs(x1End - x1),
        dy1 = Math.abs(y1End - y1);
    var p = 2 * dy1 - dx1;
    var twoDy = 2 * dy1,
        twoDyMinusDx = 2 * (dy1 - dx1);
    if (x1 > x1End) {
        x = x1End;
        y = y1End;
        x1End = x1;
    } else {
        x = x1;
        y = y1;
    }
    k += 2;
    arr[k++] = x;
    arr[k++] = y;
    while (x < x1End) {
        x++;
        if (p < 0) {
            p += twoDy;
        } else {
            y++;
            p += twoDyMinusDx;
        }
        arr[k++] = x / 100;
        arr[k++] = y / 100;
    }
    console.log(arr);
    return arr;
}

function initVertexBuffers(gl) {
    var arr = DDA_Bresenham(-25.0, -100.0, 100.0, 100.0, -50.0, -50.0, 50.0, 50.0);
    var vertices = new Float32Array(arr);
    var n = arr.length / 2; // The number of vertices

    // Create a buffer object
    var vertexBuffer = gl.createBuffer();
    if (!vertexBuffer) {
        console.log('Failed to create the buffer object');
        return -1;
    }

    // Bind the buffer object to target
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    // Write date into the buffer object
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    var a_PosLocation = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_PosLocation < 0) {
        console.log('Failed to get the storage location of a_Position');
        return -1;
    }
    // Assign the buffer object to a_Position variable
    gl.vertexAttribPointer(a_PosLocation, 2, gl.FLOAT, false, 0, 0);

    // Enable the assignment to a_Position variable
    gl.enableVertexAttribArray(a_PosLocation);

    return n;
}

function startup() {
    var canvas = document.getElementById('webgl'); //获取<canvas>元素
    gl = createGLContext(canvas);
    setupShaders();
    var n = initVertexBuffers(gl);
    if (n < 0) {
        console.log('Failed to set the positions of the vertices');
        return;
    }
    gl.clearColor(0.0, 0.0, 0.0, 1.0); //指定清空<canvas>的颜色    
    gl.clear(gl.COLOR_BUFFER_BIT); //清空<canvas>
    gl.drawArrays(gl.POINTS, 0, n); //从第0个元素开始,在指定位置(gl_Position)画1个点
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在h5页面中使用js导入fbx、cfg、tga和MP4文件,需要使用以下步骤: 1. 导入Three.js库,这是一个流行的WebGL库,用于创建3D场景和动。 2. 使用Three.js中的FBXLoader、MTLLoader和TGALoader等加载器,分别加载fbx、cfg和tga文件。例如: ```javascript // 加载fbx文件 var loader = new THREE.FBXLoader(); loader.load( 'model.fbx', function ( object ) { scene.add( object ); } ); // 加载cfg文件 var mtlLoader = new THREE.MTLLoader(); mtlLoader.load( 'model.mtl', function ( materials ) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials( materials ); objLoader.load( 'model.obj', function ( object ) { scene.add( object ); } ); } ); // 加载tga文件 var loader = new THREE.TGALoader(); loader.load( 'texture.tga', function ( texture ) { // 使用纹理创建材质 var material = new THREE.MeshBasicMaterial( { map: texture } ); // 创建一个立方体网格 var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); } ); ``` 3. 加载MP4文件并将其添加到HTML页面中。例如: ```javascript // 创建视频元素 var video = document.createElement('video'); video.src = 'video.mp4'; video.loop = true; video.autoplay = true; // 将视频元素添加到HTML页面中 var videoContainer = document.getElementById('video-container'); videoContainer.appendChild(video); ``` 4. 使用Three.js中的CSS3DRenderer创建一个CSS3D对象,并将它添加到场景中。 5. 在CSS3D对象中创建一个DOM元素,并将视频元素添加到该元素中。例如: ```javascript // 创建CSS3D对象和DOM元素 var css3DObject = new THREE.CSS3DObject( document.createElement('div') ); var videoElement = document.createElement('video'); videoElement.src = 'video.mp4'; videoElement.loop = true; videoElement.autoplay = true; css3DObject.element.appendChild( videoElement ); // 将CSS3D对象添加到场景中 var css3DRenderer = new THREE.CSS3DRenderer(); css3DRenderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( css3DRenderer.domElement ); scene.add( css3DObject ); ``` 6. 使用Three.js中的AnimationMixer和Action对象创建动,并启动它。例如: ```javascript // 加载fbx文件 var loader = new THREE.FBXLoader(); loader.load( 'model.fbx', function ( object ) { // 创建动混合器 var mixer = new THREE.AnimationMixer( object ); // 获取动作序列 var action = mixer.clipAction( object.animations[ 0 ] ); // 启动动 action.play(); // 将模型添加到场景中 scene.add( object ); // 更新动 function update() { requestAnimationFrame( update ); mixer.update( clock.getDelta() ); } update(); } ); ``` 通过以上步骤,就可以在h5页面中使用js导入fbx、cfg、tga和MP4文件,组成一个ar动
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值