WebGL加载纹理例子

show_texture.html

<!DOCTYPE html>
<html>
<head>
<title>hello web gl</title>
<script type="text/javascript" src="js/hi.js"></script>
</head>
<body>
<div>
<canvas id="canvas" width="200px" height="200px"></canvas>
</div>
</body>
</html>

hi_server.go

package main
import(
	"net/http"
)

func main(){
	http.Handle("/", http.FileServer(http.Dir("./")))
	http.ListenAndServe(":8123", nil)
}

hi.js

/**
 * Created by houbingshuai on 2016/12/3.
 */

window.onload = function () {

    //顶点着色器程序
    let VSHADER_SOURCE =
        "attribute vec4 a_Position;" +
        "attribute vec2 a_TextCoord;" + // 接受纹理坐标
        "varying vec2 v_TexCoord;" +    // 传递纹理坐标
        "void main() {" +
        //设置坐标
        "gl_Position =  a_Position; " +
        "v_TexCoord = a_TextCoord; " +  // 设置纹理坐标
        "} ";

    //片元着色器
    let FSHADER_SOURCE =
        "precision mediump float;" +  //需要声明浮点数精度,否则报错No precision specified for (float)
        "uniform sampler2D u_Sampler;" + // 取样器
        "varying vec2 v_TexCoord;" +  // 接受纹理坐标
        "void main() {" +
        //设置颜色
        "gl_FragColor = texture2D(u_Sampler, v_TexCoord);" +  // 设置颜色
        "}";
    //获取canvas元素
    let canvas = document.getElementById('canvas');
    //获取绘制二维上下文
    let gl = canvas.getContext('webgl');
    if (!gl) {
        console.log("Failed");
        return;
    }
    //编译着色器
    let vertShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertShader, VSHADER_SOURCE);
    gl.compileShader(vertShader);

    let fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragShader, FSHADER_SOURCE);
    gl.compileShader(fragShader);
    //合并程序
    let shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertShader);
    gl.attachShader(shaderProgram, fragShader);
    gl.linkProgram(shaderProgram);
    //不加"precision mediump float;" ,则useProgram函数调用会出错。
    gl.useProgram(shaderProgram);



    //获取坐标点
    let a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');

    if (a_Position < 0) {
        console.log('Failed to get the storage location of a_Position');
        return;
    }

    //绘制一个点
    initBuffers(gl, shaderProgram, 4);

    // 清除指定<画布>的颜色
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    // 清空 <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);

    initTexture(gl, shaderProgram);

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

// Fill the buffer with the values that define multi pt.
function initBuffers(gl, shaderProgram) {

    //顶点坐标和纹理坐标
    var vertices = new Float32Array([
        -0.5, 0.5, 0.0, 1.0,
        -0.5, -0.5, 0.0, 0.0,
        0.5, 0.5, 1.0, 1.0,
        0.5, -0.5, 1.0, 0.0
    ]);

    //获取单个字节
    let FSIZE = vertices.BYTES_PER_ELEMENT;

    //创建缓冲区对象
    let vertexBuffer = gl.createBuffer();
    if (!vertexBuffer) {
        console.log("Failed to create the butter object");
        return -1;
    }

    //将缓冲区对象绑定到目标
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

    //向缓冲区写入数据
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    //获取坐标点
    let a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
    //将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
    //连接a_Position变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(a_Position);

    //获取纹理坐标点
    let a_TextCoord = gl.getAttribLocation(shaderProgram, 'a_TextCoord');
    //
    gl.vertexAttribPointer(a_TextCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
    //连接a_TextCoord变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(a_TextCoord);
}


function initTexture(gl, shaderProgram, n) {
    const texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);

    // Because images have to be download over the internet
    // they might take a moment until they are ready.
    // Until then put a single pixel in the texture so we can
    // use it immediately. When the image has finished downloading
    // we'll update the texture with the contents of the image.
    const level = 0;
    const internalFormat = gl.RGBA;
    const width = 1;
    const height = 1;
    const border = 0;
    const srcFormat = gl.RGBA;
    const srcType = gl.UNSIGNED_BYTE;
    const pixel = new Uint8Array([0, 0, 255, 255]);  // opaque blue
    gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
        width, height, border, srcFormat, srcType,
        pixel);


   //创建image对象
    var image = new Image();

    //加载纹理
    image.onload = function(){ loadTexture(gl, texture, image, shaderProgram); };
    // 浏览器开始加载图片 注意:一定是2^mx2^n尺寸的图片
    image.src = "./TexturedQuad/shan.png";

}

function loadTexture(gl, texture, image, shaderProgram) {
    const level = 0;
    const internalFormat = gl.RGBA;
    const srcFormat = gl.RGBA;
    const srcType = gl.UNSIGNED_BYTE;

    //gl.activeTexture(gl.TEXTURE0);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
        srcFormat, srcType, image);

    /*
    //must write the following code, otherwize report the following warning.
    [.Offscreen-For-WebGL-08413F30]RENDER WARNING: texture bound to texture unit 0 is not renderable.
     It maybe non-power-of-2 and have incompatible texture filtering.
    */
    // WebGL1 has different requirements for power of 2 images
    // vs non power of 2 images so check if the image is a
    // power of 2 in both dimensions.
    if (isPowerOf2(image.width) && isPowerOf2(image.height)) {
        // Yes, it's a power of 2. Generate mips.
        gl.generateMipmap(gl.TEXTURE_2D);
    } else {
        // No, it's not a power of 2. Turn of mips and set
        // wrapping to clamp to edge
        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);
    }
    

    var u_Sampler = gl.getUniformLocation(shaderProgram, 'u_Sampler');
    //6.将0号纹理图像传递给着色器
    gl.uniform1i(u_Sampler, 0);
    // 清空 <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);

    //must write the following code, because this function is called when image is loaded successful.
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

}

function isPowerOf2(value) {
    return (value & (value - 1)) == 0;
}

源码下载地址

参考资料

http://www.cnblogs.com/bsman/p/6196871.html
https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/generateMipmap

转载于:https://my.oschina.net/u/2247783/blog/1546769

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebGL是一种在浏览器中实现3D图形渲染的技术,它允许开发者使用JavaScriptWebGL API创建和显示3D场景。加载ktx纹理是使用WebGL加载3D纹理的一种方式。 KTX纹理是一种特殊的3D纹理格式,它被广泛用于游戏开发和3D渲染。这种格式的纹理文件通常使用.ktx后缀,并且可以在大多数现代图形处理器(GPU)上以高效的方式渲染。 要使用WebGL加载ktx纹理,你需要执行以下步骤: 1. 确保你已经安装了适当的WebGL和OpenGL库,例如Three.js或GLGE。这些库提供了用于加载和渲染3D纹理的API。 2. 在你的代码中,使用库提供的API加载ktx纹理文件。通常,你需要使用库提供的函数来读取文件并将其转换为可在WebGL中使用的数据格式。 3. 将加载纹理数据传递给WebGL上下文的纹理对象。这可以通过调用库中的相关函数来完成,该函数将纹理数据分配给纹理对象,并将其绑定到WebGL纹理单元中。 4. 在渲染循环中,将已绑定的纹理对象传递给着色器程序,以便在3D场景中使用。 需要注意的是,加载ktx纹理可能需要特定的库和环境支持。不同的库可能会有不同的API和语法,因此你需要查阅相关文档以了解如何正确加载和使用ktx纹理。 总的来说,使用WebGL加载ktx纹理是一个相对复杂的过程,需要一定的3D编程和图形处理知识。如果你不熟悉这些概念,建议查阅相关文档和教程以获取更详细的指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值