HarmonyOS鸿蒙Next中WebGL如何初始化纹理对象并绘制图片

HarmonyOS鸿蒙Next中WebGL如何初始化纹理对象并绘制图片

WebGL如何初始化纹理对象并绘制图片

在WebGL中,纹理图像是用来给3D模型或2D图形添加颜色、纹理、图案等视觉效果的。纹理图像可以是任何类型的图像文件,如JPEG、PNG、GIF等。在WebGL中,纹理图像被映射到3D模型或2D图形的表面上,从而使其看起来更加真实、生动。

初始化纹理对象步骤

1、创建一个纹理对象

使用WebGL的createTexture()方法创建一个纹理对象。

const texture = gl.createTexture();

2、绑定纹理对象

使用WebGL的bindTexture()方法将纹理对象绑定到纹理目标上。

gl.bindTexture(gl.TEXTURE_2D, texture);

3、设置纹理参数

使用WebGL的texParameteri()方法设置纹理参数,例如纹理过滤器和纹理包裹模式。

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

4、加载纹理图像

使用WebGL的texImage2D()方法加载纹理图像。可以从图片、视频或者canvas中获取纹理图像。

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

5、绘制图片

使用WebGL的drawArrays()方法绘制图片。

gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

总结

相关WebGL API详情见:https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API

以下便是完整的WebGL初始化纹理对象并绘制图片的方案:

Let _startDraw = false

const initTextures = (gl, n) => {
    const texture = gl.createTexture();

    if (!texture) {
        console.log('Failed to create the texture object');
        return false;
    }

    const u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');

    if (!u_Sampler) {
        console.log('Failed to get the storage location of u_Sampler');
        return false;
    }

    let image = new Image();
    if (!image) {
        console.log('Failed to create the image object');
        return false;
    }

    image.onload = function () {
        loadTexture(gl, n, texture, u_Sampler, image);
    };

    image.src = '...';
    return true;
}

const loadTexture = (gl, n, texture, u_Sampler, image) => {
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.uniform1i(u_Sampler, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    _startDraw = true
}

function draw() {
    if (!_startDraw) {
        return;
    }

    gl.useProgram(program);
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
    gl.enableVertexAttribArray(a_Position);
    gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
    gl.enableVertexAttribArray(a_TexCoord);

    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.uniform1i(u_Sampler, 0);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

// 可以再开章节介绍,也可以放到此章节末尾

注意:

  1. 我们需要把之前的所有方案都放到SplashScreen对象中,并在SplashScreen对象中新增init方法中完成统一调度。
  2. 新增doDraw方法,使用requestAnimationFrame来调用绘图方法
init() {
    const VSHADER_SOURCE = `
        attribute vec4 a_Position;
        attribute vec2 a_TexCoord;
        varying vec2 v_TexCoord;

        void main() {
            gl_Position = a_Position;
            v_TexCoord = a_TexCoord;
        }
    `;

    const FSHADER_SOURCE = `
        #ifdef GL_ES
        precision mediump float;
        #endif
        uniform sampler2D u_Sampler;
        varying vec2 v_TexCoord;

        void main() {
            gl_FragColor= texture2D(u_Sampler, v_TexCoord);
        }
    `;

    if (!SplashScreen.initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed to intialize shaders.');
        return;
    }

    const n = SplashScreen.initVertexBuffers(gl);

    if (n < 0) {
        console.log('Failed to set the vertex information');
        return;
    }

    if (!SplashScreen.initTextures(gl, n)) {
        console.log('Failed to intialize the texture.');
        return;
    }

}

function doDraw() {
    window.requestAnimationFrame(doDraw);
    window.SplashScreen.draw();
}

// 游戏初始化
SplashScreen.init();
// 开始每帧绘图
window.requestAnimationFrame(doDraw);

更多关于HarmonyOS鸿蒙Next中WebGL如何初始化纹理对象并绘制图片的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中WebGL如何初始化纹理对象并绘制图片的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用WebGL初始化纹理对象并绘制图片的步骤如下:

  1. 创建纹理对象:使用gl.createTexture()创建纹理对象。
  2. 绑定纹理:通过gl.bindTexture(gl.TEXTURE_2D, texture)绑定纹理。
  3. 设置纹理参数:使用gl.texParameteri()设置纹理参数,如gl.TEXTURE_MIN_FILTERgl.TEXTURE_MAG_FILTER
  4. 加载图片:通过Image对象加载图片,并在onload回调中处理。
  5. 上传纹理数据:使用gl.texImage2D()将图片数据上传到纹理。
  6. 绘制:在渲染循环中,使用gl.drawArrays()gl.drawElements()绘制纹理。

示例代码:

const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const image = new Image();
image.onload = () => {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    // 绘制逻辑
};
image.src = 'path/to/image.png';
回到顶部