WEBGL基础概念及代码

由于给定内容仅为“结果:”,信息过少,无法提炼出关键信息形成摘要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    /* 移除边界 */
    body {
        border: 0;
        background-color: white;
    }
    /* 设置欢度大小为视域大小 */
    canvas {
        width: 100vw;
        height: 100vh;
        display: block;
    }
</style>
<body>
<canvas id="c"></canvas>

<script id="2d-vertex-shader2" type="notjs">
    attribute vec4 a_position;
    void main(){
        gl_Position = a_position;
    }
</script>
<script id="2d-vertex-shader" type="notjs">
    attribute vec2 a_position;
    uniform vec2 u_resolution;
    void main(){
        //从像素坐标转换到0.0到1.0
        vec2 zeroToOne = a_position / u_resolution;
        //在吧0->1转换0->2
        vec2 zeroToTwo = zeroToOne * 2.0;
        //把0->2转换到-1->+1剪裁空间
        vec2 clipSpace = zeroToTwo - 1.0;

        gl_Position = vec4(clipSpace* vec2(1,-1),0,1);
    }
</script>
<script>
    function resize(canvas) {
    // 获取浏览器中画布的显示尺寸
    var displayWidth  = canvas.clientWidth;
    var displayHeight = canvas.clientHeight;

    // 检尺寸是否相同
    if (canvas.width  != displayWidth ||
    canvas.height != displayHeight) {

    // 设置为相同的尺寸
    canvas.width  = displayWidth;
    canvas.height = displayHeight;
    }
    }
</script>
<script id="2d-fragment-shader" type="notjs">
    precision mediump float;
    uniform vec4 u_color;
    void main(){
    gl_FragColor = u_color;
    }
</script>
<script src="js/webgl-utils.js"></script>
<script src="js/helloworld.js"></script>

</body>
</html>
"use strict";

function createShader(gl,type,source){
    var shader = gl.createShader(type);//创建着色器对象

    gl.shaderSource(shader,source);//提供数据按
    gl.compileShader(shader);//编译-》生成着色器
    var success = gl.getShaderParameter(shader,gl.COMPILE_STATUS);
    if(success){
        return shader;
    }
    console.log(gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
}
function createProgram(gl, vertexShader, fragmentShader) {
    var program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    var success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (success) {
        return program;
    }

    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
}

function main(){
    var canvas = document.getElementById("c");
    var gl=canvas.getContext("webgl");

    if(!gl){
        return ;
    }
    /**
     * 初始化代码*/
//以下函数为创建着色器方法,输入参数,渲染上下文,着色器类型,数据源


//利用以上方法创建着色器
    var vertexShaderSource=document.getElementById("2d-vertex-shader").text;
    var fragmentShaderSource=document.getElementById("2d-fragment-shader").text;

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

//将两个着色器link到一个program着色程序上

//调用上面的函数
    var program = createProgram(gl, vertexShader, fragmentShader);
    var program=createProgram(gl,vertexShader,fragmentShader);

//后面要给着色程序提供数据,先找到属性值的位置
    var positionAttributeLocation = gl.getAttribLocation(program,"a_position");//此步骤应该在初始化时完成
    var resolutionUniformLocation = gl.getUniformLocation(program,"u_resolution");
    var colorUniformLocation = gl.getUniformLocation(program, "u_color");
//属性值从缓冲获取数据,所以我们创建一个缓冲
    var positionBuffer = gl.createBuffer();

//绑定点操控全局范围的数据,可以想象成全局变量,下面操作是绑定点指向数据源。
    gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
//通过绑定点向缓冲中存放数据,这其实就是opengl中的VBO
    var positions = [
        10,20,
        80,20,
        10,30,
        10,30,
        80,20,
        80,30,
    ];
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);
//这里WEBGL需要强类型数据,所以nwe Float32Array,通过讲数据绑定到绑定点,最终被传递到positionBuffer,后面的参数是数据使用方式

    /**
     * 渲染代码*/
//画布:两个属性:1,实际像素个数。 2,画布的显示大小 //应该尽可能使用css设置画布大小
//初始化代码只执行一次,渲染代码在每次需要渲染的时候执行
    webglUtils.resizeCanvasToDisplaySize(gl.canvas);

//通过gl.viewport将把gl_Position剪裁空间坐标对应到画布像素坐标
    gl.viewport(0,0,gl.canvas.width,gl.canvas.height);

//清空画布
    gl.clearColor(0,0,0,0);
    gl.clear(gl.COLOR_BUFFER_BIT);
//告诉webgl运行那个着色程序
    gl.useProgram(program);//设置当前使用的周色程序
//接下来告诉webgl从之前准备的缓冲中获取数据给着色器中的属性
    gl.enableVertexAttribArray(positionAttributeLocation);
//指定从缓冲中读取数据的方式
//讲绑定点绑定到缓冲数据
    gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
//告诉属性怎么从positionBuffer中读取数据,因为已经绑定就是从ARRAY_BUFFER中
    var size=2;//每次迭代运行提取两个数据单元
    var type=gl.FLOAT; // 每个单位的数据类型是32位浮点型
    var normalize=false; //不需要归一化数据
    var stride = 0;//0=移动单位*每个单位的占用内存(sizeof(type))
    //每次迭代运动多少内存到下一个数据开始点
    var offset=0;   //从缓冲起始位置开始读取
    gl.vertexAttribPointer(
        positionAttributeLocation,size,type,normalize,stride,offset
    );
//gl.vertexAtrribPointer是将属性绑定到当前ARRAY_BUFFER,所以就绑定到了positionBuffer上

    //设置全局变量 分辨率
    gl.uniform2f(resolutionUniformLocation,gl.canvas.width,gl.canvas.height);
//运行GLSL着色程序
    var primitiveType = gl.TRIANGLES;
    var offset=0;
    var count=6;
    gl.uniform4f(colorUniformLocation,0,0,0,1);//设置黑色
    gl.drawArrays(primitiveType,offset,count);

    drawRandomRect50();
    function drawRandomRect50(){
        for(var ii=0;ii<50;++ii){
            //创建一个随机矩阵
            //并将写入位置缓冲 因为此时位置缓冲是我们绑定在ARRAY_BUFFER绑定点上的最后一个缓冲
            setRectangle(gl,randomInt(300),randomInt(300),randomInt(300),randomInt(300));
            //设置一个随机颜色
            gl.uniform4f(colorUniformLocation,Math.random(),Math.random(),Math.random(),1);

            //绘制矩形
            gl.drawArrays(gl.TRIANGLES,0,6);
        }
        function randomInt(range){
            return Math.floor(Math.random()*range);
        }
        function setRectangle(gl,x,y,width,height){
            var x1=x;
            var x2=x+width;
            var y1=y;
            var y2=y+height;
            //注意gl.bufferData(gl.ARRAY_BUFFER)将会影响到当前绑定的缓冲
            //目前只有一个缓冲,如果我们有多个缓冲
            //我们需要先将所需缓冲绑定到ARRAY_BUFFER
            gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([
                x1,y1,
                x2,y1,
                x1,y2,
                x1,y2,
                x2,y1,
                x2,y2
            ]),gl.STATIC_DRAW);
        }
    }

}

//一下例子绘制50个随机颜色矩形

main();


结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值