webgl-画任意多边形

Posted 不穿铠甲的穿山甲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webgl-画任意多边形相关的知识,希望对你有一定的参考价值。

注意:

let canvas = document.getElementById('webgl')

canvas.width = window.innerWidth

canvas.height = window.innerHeight

let radio = window.innerWidth/window.innerHeight;

let ctx = canvas.getContext('webgl')

 

由于屏幕长宽像素不一样,导致了长宽像素比不是1,进而导致每个像素四边形不是正方形,画出来的图形有误差 

需要let radio = window.innerWidth/window.innerHeight;计算

关键代码

for (let index = 0; index < n; index++)

        let angle = Math.PI*2/n * index;

        let x = 0.5 * Math.cos(angle)/radio //解决像素比不是1的问题,导致画出的图形与预期不一致,如画圆可能画出来的时椭圆

        let y = 0.5 * Math.sin(angle)

        vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)

   

控制多边形

     let n = 3;

html

<!DOCTYPE html>

<head>

    <style>

        *

            margin: 0px;

            padding: 0px;

       

    </style>

</head>

<body>

    <canvas id = 'webgl'>

        您的浏览器不支持HTML5,请更换浏览器

    </canvas>

    <script src="./main.js"></script>

</body>

main.js

 

let canvas = document.getElementById('webgl')

canvas.width = window.innerWidth

canvas.height = window.innerHeight

let radio = window.innerWidth/window.innerHeight;

let ctx = canvas.getContext('webgl')

//创建顶点资源和像素资源(颜色)

let vertexSource = `

attribute vec2 a_Position;

attribute vec3 a_Position_color;

varying vec3 a_color;

void main()

  a_color = a_Position_color;

  gl_Position = vec4(a_Position, 0.0, 1.0);

  gl_PointSize = 10.0;

`

let fragmentSource = `

precision mediump float;

uniform vec3 u_color;

varying vec3 a_color;

void main ()

  gl_FragColor = vec4(a_color, 1.0);

`

if (initShader(ctx, vertexSource, fragmentSource))

    //设置颜色

    let color = ctx.getUniformLocation(ctx.program, "u_color2")

    ctx.uniform3f(color, 1.0, 0.0, 0.0)

    //画三角形

    let vertexs = []

    let n = 3;

    for (let index = 0; index < n; index++)

        let angle = Math.PI*2/n * index;

        let x = 0.5 * Math.cos(angle)/radio

        let y = 0.5 * Math.sin(angle)

        vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)

   

    // //画三角形

    // let vertexs = [

    //     //   x     y    R    G    B

    //     -0.5, 0.5, 1.0, 0.0, 0.0, //第一个点的信息

    //     -0.5, -0.5, 0.0, 1.0, 0.0, //第二个点的信息

    //     0.5, -0.5, 0.0, 0.0, 1.0,//第三个点的信息

    //     0.5, 0.5, 1.0, 1.0, 1.0 //第三个点的信息

    // ]

    let float32Array = new Float32Array(vertexs)

    //创建buffer

    let buffer = ctx.createBuffer()

    //绑定buffer

    ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)

    //往buffer中填充值,并指定数据用途

    ctx.bufferData(ctx.ARRAY_BUFFER, float32Array, ctx.STATIC_DRAW)

    //获取vertexShader指定变量内存

    let a_Position = ctx.getAttribLocation(ctx.program, "a_Position")

    //指定每两个数组元素为一个点

    /*

     * 当数组元素不需进行分割拆分的时候最后两位可以指定为0,0

     *

     *

     */

    ctx.vertexAttribPointer(

        a_Position, //location: vertex Shader里面的attributes变量的location

        2, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3

        false, //normalized: 正交化 true或false  , [1, 2] => [1/根号5, 2/根号5]

        5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES

        0 //offset: 每个点的信息,从第几个BYTES开始数

    )

    ctx.enableVertexAttribArray(a_Position);

    //获取vertexShader指定变量内存

    let a_Position_color = ctx.getAttribLocation(ctx.program, "a_Position_color")

    ctx.vertexAttribPointer(

        a_Position_color, //location: vertex Shader里面的attributes变量的location

        3, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3

        false, //normalized: 正交化 true或false  , [1, 2] => [1/根号5, 2/根号5]

        5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES

        2 * float32Array.BYTES_PER_ELEMENT //offset: 每个点的信息,从第几个BYTES开始数

    )

    //确认吧带有数据的buffer赋值给a_Position

    ctx.enableVertexAttribArray(a_Position_color);

    ctx.drawArrays(ctx.TRIANGLE_FAN, 0, n)


 

//创建顶点阴影和像素阴影

function createShader(ctx, type, source)

    //创建shader

    let shader = ctx.createShader(type)

    //绑定

    ctx.shaderSource(shader, source)

    //编译shader

    ctx.compileShader(shader)

    //获取编译结果

    let compiler = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)

    if (compiler)

        return shader

    else

        let log = ctx.getShaderInfoLog(shader)

        console.log("compile shaders error", log)

        //删除异常的shader,防止内存泄露

        ctx.deleteShader(shader)

        return null

   

function createProgram(ctx, vertexShader, fragmentShader)

    //创建program

    let program = ctx.createProgram()

    if (!program)

        return null

   

    //点资源和像素资源合并

    ctx.attachShader(program, vertexShader)

    ctx.attachShader(program, fragmentShader)

    ctx.linkProgram(program)

    //获取linked的结果

    let linked = ctx.getProgramParameter(program, ctx.LINK_STATUS)

    if (linked)

        return program

    else

        //获取link错误信息

        let log = ctx.getProgramInfoLog(program)

        console.log("link program error", log)

        //删除防止内存泄漏

        ctx.delete(program)

        ctx.deleteShader(vertexShader)

        ctx.deleteShader(fragmentShader)

        return null

   

function initShader(ctx, vertexSource, fragmentSource)

    let vertexShader = createShader(ctx, ctx.VERTEX_SHADER, vertexSource)

    let fragmentShader = createShader(ctx, ctx.FRAGMENT_SHADER, fragmentSource)

    let program = createProgram(ctx, vertexShader, fragmentShader)

    if (program)

        ctx.useProgram(program)

        //挂载到ctx

        ctx.program = program

        return true

    else

        return false

   

 效果

n=3

n=4

n=6

 

n=50

 

WebGL学习系列-WebGL简介

前言

本篇简要介绍一下WebGL的历史以及用途。

WebGL概述

相信大家都知道Web中有个叫canvas的画布,通过其提供的一些API,我们可以很方便的在浏览器的页面上画点、线、多边形、图片等。现在很多的html5小游戏也是由canvas来实现的。canvas技术相当于所见即所得,你画什么就在页面上展示什么,原理比较好懂。但是canvas主要是针对2D的,所以通常我们主要用于实现2D类的游戏。

要说WebGL,得提提OpenGL。OpenGL是一套开放的图形库,用于在pc端上绘制3D图形,它是一套开放的标准API,在不同平台上底层有不同的实现。可以把WebGL看成是Web端的OpenGL。先来看下OpenGL的版本图,如下所示:

可以看到,目前Web端使用的WebGL为WebGL1.0,它是基于OpenGL ES2.0的, 而
OpenGL ES主要服务于一些嵌入式设备。可以说,我们将要学习的WebGL和OpenGL ES2.0是比较像的,至少很多原理都是共通的。所以有时候,当你遇到WebGL一些问题的时候,可以尝试通过OpenGL关键字去查找相关的资料。

OpenGL从2.0开始便支持可编程着色器,着色器通俗的说,就是给界面中的每一个像素上色,这个很快就会了解到了。自然的,WebGL也继承了这个重大的特性。

最后,再来看下WebGL程序的结构,先看下图:

左边为传统的web页面开发,右边为包含了WebGL的网页,GLSL ES是用于编写着色器的语言,开发WebGL程序的时候,除了直接调用WebGL相关的api,我们还要编写着色器。

结束语

借由WebGL,我们可以打开通往3D的一个切入点,因为学习WebGL是需要学习计算机图形学一些基础知识的,当然,这里不会假设你懂的很多。笔者也是在学习过程中一点一点弥补的。笔者水平有限,但仍然会尝试使用最最简单的语言来进行表述,这也是自我提升的一种方式。

参考资料:
<<WebGL编程指南>>

以上是关于webgl-画任意多边形的主要内容,如果未能解决你的问题,请参考以下文章

WebGL -- 多边形

webgl基础:绘制多边形

WebGL-画一个三角形

WebGL小姐姐教我学画画之起手式

WebGL学习系列-多边形绘制原理

TeaPot 用webgl画茶壶