WebGL编程笔记3:纹理图片texture
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了WebGL编程笔记3:纹理图片texture,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5723字,纯文字阅读大概需要9分钟。
内容图文
![WebGL编程笔记3:纹理图片texture](/upload/InfoBanner/zyjiaocheng/637/4e349763ab9f49cda239d670091c63db.jpg)
HTML部分
<script type="text/javascript" src="gl-matrix.js"></script> <canvas id="myCanvas" width="400" height="400" style="border: 1px solid red"></canvas>
JavaScript部分
以下两点若不注意texture2D有可能取不到值,一片黑色。
- 老的显卡只支持图片尺寸为2的n次幂的纹理图片。
- TEXTURE_MAG_FILTER和TEXTURE_MIN_FILTER参数需要制定。
const vertex = ` attribute vec3 v3Position; uniform mat4 u_matrix; attribute vec2 inUv; varying vec2 outUv; void main() { gl_Position = u_matrix * vec4(v3Position, 1.0); outUv = inUv; } `; // texture2D(u_texture, vec2(outUv.x, outUv.y)); // texture2D(u_texture, outUv; // 从纹理texture中根据outUv坐标取色素rgba const fragment = ` precision mediump float; uniform sampler2D u_texture; varying vec2 outUv; void main() { gl_FragColor = texture2D(u_texture, vec2(outUv.x, outUv.y)); } `; let canvas = document.getElementById('myCanvas'); let webgl = canvas.getContext('webgl'); const data_position = new Float32Array([ // x y z u v 30, 30, 0, 0.0, 0.0, 330, 30, 0, 2.0, 0.0, 330, 330, 0, 2.0, 2.0, 30, 30, 0, 0.0, 0.0, 330, 330, 0, 2.0, 2.0, 30, 330, 0, 0.0, 2.0 ]); const data_mat4 = glMatrix.mat4.ortho([], 0, canvas.clientWidth, canvas.clientHeight, 0, -10, 10); // 第一步:编译程序 let program = createProgram(webgl, vertex, fragment); // 第二步:建立buffer let buffer_position = bindBufferWidthData(webgl, webgl.ARRAY_BUFFER, data_position); // 创建数据缓冲区 // 第三步:变量绑定 let v3Position = bindVertexAttributePointer(webgl, program, "v3Position", 3, 20, 0); // 绑定顶点输入变量v3Position的指针和取数方式 let inUv = bindVertexAttributePointer(webgl, program, "inUv", 2, 20, 12); // 绑定顶点输入变量inUv坐标的指针和取数方式 let matrix = setUniformMatrix(webgl, program, 'u_matrix', data_mat4); // 设置全局变量u_matrix的值 let img = new Image(); img.onload = ImageLoaded; img.src = '/static/imgs/sky.png'; function ImageLoaded() { var texture = webgl.createTexture(); webgl.activeTexture(webgl.TEXTURE1); // webgl有32个问题里图片,激活第二个纹理图片,一般使用第一个webgl.TEXTURE0 webgl.bindTexture(webgl.TEXTURE_2D, texture); // 设置webgl的TEXTURE1为TEXTURE_2D,实例为创建的texture变量 // 设置纹理图片的参数 webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, img); // 图片的真实大小为256*256,实际绘制时的区域有可能大于图片实际尺寸,也有可能小于图片实际尺寸 // 用于定义大于或小于真实尺寸时的图片算法,NEAREST效率高,LINEAR效率低但效果好,图片较小时看不出差别 webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MAG_FILTER,webgl.NEAREST); webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MIN_FILTER,webgl.NEAREST); // 一般UV坐标或ST坐标处于0到1之间,有时也会超过1,超过1时的显示方式 // gl.REPEAT 平铺 // gl.MIRRORED_REPEAT 镜像(倒影)平铺 // gl.CLAMP_TO_EDGE 使用边缘颜色填充 webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT); // 横向 webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.REPEAT); // 纵向 let u_texture = webgl.getUniformLocation(program, "u_texture"); // 获取全局变量u_texture webgl.uniform1i(u_texture, 1); // 将全局变量赋值为webgl的第二个纹理图片 clearCanvas(webgl); webgl.drawArrays(webgl.TRIANGLES, 0, 6); };
函数
/** * 编译shader源码并与webgl绑定,返回program对象 * @param {*} webgl * @param {*} vertex * @param {*} fragment */ function createProgram(webgl, vertex, fragment) { // 创建程序 let shader_vertex = webgl.createShader(webgl.VERTEX_SHADER); let shader_fragment = webgl.createShader(webgl.FRAGMENT_SHADER); webgl.shaderSource(shader_vertex, vertex); webgl.shaderSource(shader_fragment, fragment); // 编译源码 webgl.compileShader(shader_vertex); webgl.compileShader(shader_fragment); if (webgl.getShaderParameter(shader_vertex, webgl.COMPILE_STATUS) === false) { console.error('Compile Shader Error: shader_vertex,' + webgl.getShaderInfoLog(shader_vertex)); } if (webgl.getShaderParameter(shader_fragment, webgl.COMPILE_STATUS) === false) { console.error('Compile Shader Error: shader_fragment,' + webgl.getShaderInfoLog(shader_fragment)); } // 创建执行程序 let program = webgl.createProgram(); webgl.attachShader(program, shader_vertex); webgl.attachShader(program, shader_fragment); // 连接context和program webgl.linkProgram(program); if(webgl.getProgramParameter(program, webgl.LINK_STATUS) === false) { console.error(webgl.getProgramInfoLog(program)); } webgl.useProgram(program); return program; } /** * 向webgl添加buffer并传入data * @param {*} webgl * @param {*} target 数据类型,gl.ARRAY_BUFFER * @param {*} data */ function bindBufferWidthData(webgl, target, data) { let buffer = webgl.createBuffer(); webgl.bindBuffer(target, buffer); webgl.bufferData(target, data, webgl.STATIC_DRAW); // 内存数据传入显存 } /** * 建立JS变量和顶点输入变量的引用,返回JS变量 * @param {*} webgl * @param {*} program * @param {String} varName Shader中的变量名 * @param {Number} varSize 变量维度 * @param {Number} stride 每段数据长度 * @param {Number} offset 每段中的偏移量 */ function bindVertexAttributePointer(webgl, program, varName, varSize, stride, offset) { var pointer = webgl.getAttribLocation(program, varName); webgl.vertexAttribPointer(pointer, varSize, webgl.FLOAT, false, stride, offset); webgl.enableVertexAttribArray(pointer); return pointer; } /** * 向Shader传入mat4类型的全局变量 * @param {*} webgl * @param {*} program * @param {String} varName 变量名称 * @param {mat4} data 变量值 */ function setUniformMatrix(webgl, program, varName, data) { let matrix = webgl.getUniformLocation(program, 'u_matrix'); webgl.uniformMatrix4fv(matrix, false, data); // r g b a return matrix; } function clearCanvas(webgl) { webgl.clearColor(0.7, 0.7, 0.7, 1); webgl.clear(webgl.COLOR_BUFFER_BIT); }
内容总结
以上是互联网集市为您收集整理的WebGL编程笔记3:纹理图片texture全部内容,希望文章能够帮你解决WebGL编程笔记3:纹理图片texture所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。