webgl-native texture map

Step on the pit:

1. The picture is not displayed: the picture resolution is not a power of 2, and the picture cannot be rendered.
The graph becomes the Nth power of black square 2: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096
... 2. Geometry configuration mapping method, vertex coordinates and texture coordinates need to pay attention, the construction order is related to the parity of the newly added vertices.
If the number of new vertices is odd, the order of the vertices is: T = [n-1 n-2 n];
if the number of new vertices is even, the order of the vertices is: T = [n-2 n-1 n];

 

Picture material:

Link: https://pan.baidu.com/s/1CQ2fZ36Ke8QfGFDytFkyQw

Extraction code: 3dh4

key code:

function initTexture(ctx) {

    let texture = ctx.createTexture()

    let u_sampler = ctx.getUniformLocation(ctx.program, "u_sampler")

    let image = new Image()

    image.crossOrigin = "anonymous"

    image.src = "http://localhost:8080/upload/dog.webp"

    //Asynchronous loading, execute the tasks in this function after the picture is loaded

    image.onload = () => {

        //Reverse the y-axis of the texture image, whether to flip

        ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, true);

        //By default, 8 pictures can be posted, starting from index 0, activate the first one here

        ctx.activeTexture(ctx.TEXTURE0)

        // Bind textures in TEXTURE_2D mode

        ctx.bindTexture(ctx.TEXTURE_2D, texture)

        //Set the parameters of the texture texParameteri (the type of texture, the name of the parameter, the specific value)

        ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR)

        //Set the texture map filling method (the pixel size of the texture map is smaller than the pixel size of the vertex drawing area)

        ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR)

        console.log(image)

        //The texture is textured with that kind of picture

        ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image)

        //Paste the 0th texture to u_sampler

        ctx.uniform1i(u_sampler, 0)

        draw(ctx)

    }

}

html

<!DOCTYPE html>

<head>

    <style>

        *{

            margin: 0px;

            padding: 0px;

        }

    </style>

</head>

<body>

    <canvas id = 'webgl'>

        Your browser does not support HTML5, please change your browser

    </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')

//Create vertex resource and pixel resource (color)

let vertexSource = `

attribute vec2 a_position;

attribute vec2 a_uv;

varying vec2 v_uv;

void main() {

  v_uv = a_uv;

  gl_Position = vec4(a_position, 0.0, 1.0);

  gl_PointSize = 10.0;

}

`

let fragmentSource = `

precision mediump float;

varying vec2 v_uv;

uniform sampler2D u_sampler;

void main (){

  vec4 color = texture2D(u_sampler, v_uv);

  gl_FragColor = color;

}

`

//gl_FragColor = vec4(v_uv, 0.0, 1.0);

if (initShader(ctx, vertexSource, fragmentSource)) {

    let box = [

        -0.5, -0.5,

        0.5, -0.5,

        0.5, 0.5,

        -0.5, 0.5

    ]

    let boxFloat32Array = new Float32Array(box)

    //Create buffer

    let buffer = ctx.createBuffer()

    //bind buffer

    ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)

    //Fill the value in the buffer and specify the purpose of the data

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

    //Get vertexShader specified variable memory

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

    //Specify every two array elements as a point

    /*

     * When the array elements do not need to be split, the last two digits can be specified as 0, 0

     *

     *

     */

    ctx.vertexAttribPointer(

        a_Position, //location: the location of the attributes variable in the vertex Shader

        2, ctx.FLOAT, //size: the length of the attribute variable vec2 length 2 vec3 length 3

        false, //normalized: Orthogonalization true or false, [1, 2] => [1/root 5, 2/root 5]

        2 * boxFloat32Array.BYTES_PER_ELEMENT, //stride: BYTES occupied by the information of each point

        0 //offset: the information of each point, starting from the number of BYTES

    )

    ctx.enableVertexAttribArray(a_Position);

    let color = [

        0.0, 0.0,

        1.0, 0.0,

        1.0, 1.0,

        0.0, 1.0

    ]

    let colorFloat32Array = new Float32Array(color)

    let colorBuffer = ctx.createBuffer()

    ctx.bindBuffer(ctx.ARRAY_BUFFER, colorBuffer)

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

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

    ctx.vertexAttribPointer(a_uv, 2, ctx.FLOAT, false, 2 * colorFloat32Array.BYTES_PER_ELEMENT, 0)

    ctx.enableVertexAttribArray(a_uv)

    initTexture(ctx)

}


 

function draw(ctx) {

    ctx.clearColor(0.0, 0.0, 0.0, 1.0)

    ctx.clear(ctx.COLOR_BUFFER_BIT)

    ctx.drawArrays(ctx.TRIANGLE_FAN,

        0,//Start from the first point

        4 //Draw a few points)

    )

    // ctx.drawArrays(ctx.TRIANGLE_FAN,

    // 0,//Start from the first few points

    // 4 // draw a few points)

    // )

}

function initTexture(ctx) {

    let texture = ctx.createTexture()

    let u_sampler = ctx.getUniformLocation(ctx.program, "u_sampler")

    let image = new Image()

    image.crossOrigin = "anonymous"

    image.src = "http://localhost:8080/upload/dog.webp"//Resource address needs to be changed

    //Asynchronous loading, execute the tasks in this function after the picture is loaded

    image.onload = () => {

        / / Invert the y-axis of the texture image

        ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, 1);

        //By default, 8 pictures can be posted, starting from index 0, activate the first one here

        ctx.activeTexture(ctx.TEXTURE0)

        // Bind textures in TEXTURE_2D mode

        ctx.bindTexture(ctx.TEXTURE_2D, texture)

        //Set the parameters of the texture texParameteri (the type of texture, the name of the parameter, the specific value)

        ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR)

        //Set the texture map filling method (the pixel size of the texture map is smaller than the pixel size of the vertex drawing area)

        ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR)

        console.log(image)

        //The texture is textured with that kind of picture

        ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image)

        //Paste the 0th texture to u_sampler

        ctx.uniform1i(u_sampler, 0)

        draw(ctx)

    }

}


 

//Create vertex shadows and pixel shadows

function createShader(ctx, type, source) {

    //Create shader

    let shader = ctx.createShader(type)

    //bind

    ctx.shaderSource(shader, source)

    //compile the shader

    ctx.compileShader(shader)

    //Get the compilation result

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

    if (compiler) {

        return shader

    } else {

        let log = ctx.getShaderInfoLog(shader)

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

        //Delete the abnormal shader to prevent memory leaks

        ctx.deleteShader(shader)

        return null

    }

}

function createProgram(ctx, vertexShader, fragmentShader) {

    //Create program

    let program = ctx.createProgram()

    if (!program) {

        return null

    }

    //Merge point resource and pixel resource

    ctx.attachShader(program, vertexShader)

    ctx.attachShader(program, fragmentShader)

    ctx.linkProgram(program)

    //Get the linked result

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

    if (linked) {

        return program

    } else {

        //Get link error message

        let log = ctx.getProgramInfoLog(program)

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

        //delete to prevent memory leak

        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)

        //Mount to ctx

        ctx.program = program

        return true

    } else {

        return false

    }

}

renderings

Guess you like

Origin blog.csdn.net/sunboylife/article/details/130113520