遇到如下警告:
texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
紋理沒有渲染成功。因為你使用的圖片的分辨率不屬於2的冪數。
正常的圖片並不全部都是這種格式的,那怎么辦呢?
我們使用webgl設置圖形紋理的時候,在設置水平和垂直如何填充的時候,設置成水平和垂直拉伸,代碼如下:
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);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Title</title>
<style>
body {
margin: 0;
text-align: center;
}
#canvas {
margin: 0;
}
</style>
</head>
<body onload="main()">
<canvas id="canvas" height="800" width="800"></canvas>
</body>
<script src="https://johnson2heng.github.io/webgl-demo/lib/webgl-utils.js"></script>
<script src="https://johnson2heng.github.io/webgl-demo/lib/webgl-debug.js"></script>
<script src="https://johnson2heng.github.io/webgl-demo/lib/cuon-utils.js"></script>
<script src="https://johnson2heng.github.io/webgl-demo/lib/cuon-matrix.js"></script>
<script>
/*第一部分頂點着色器接收頂點的紋理坐標,傳遞給片元着色器*/
var VSHADER_SOURCE = "" +
"attribute vec4 a_Position;\n" +//
"attribute vec2 a_TexCoord;\n" +//
"varying vec2 v_TexCoord;\n" +//
"void main(){\n" +
" gl_Position = a_Position;\n" +
" v_TexCoord = a_TexCoord;\n" +//
"}\n";
var FSHADER_SOURCE = "" +
"precision mediump float;\n" +//
"uniform sampler2D u_Sampler;\n" +//
"varying vec2 v_TexCoord;\n" +//
"void main(){\n" +
" gl_FragColor = texture2D(u_Sampler,v_TexCoord);\n" +//
"}\n";
/*第二部分 main()方法 初始化着色器,設置頂點信息,調用配置紋理方法*/
function main() {
var canvas = document.getElementById("canvas");
var gl = getWebGLContext(canvas);
if(!gl){
console.log("你的電腦不支持WebGL!");
return;
}
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("初始化着色器失敗!");
return;
}
//設置頂點的相關信息
var n = initVertexBuffers(gl);
if(n < 0){
console.log("無法獲取到點的數據");
return;
}
//配置紋理
if(!initTextures(gl,n)){
console.log("無法配置紋理");
return;
}
}
/*第三部分 initVertexBuffers() 設置頂點坐標和紋理坐標 調用initTextures()進行下一步處理*/
function initVertexBuffers(gl) {
var verticesSizes = 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
]);
var n = 4;
var vertexSizeBuffer = gl.createBuffer();
if(!vertexSizeBuffer){
console.log("無法創建緩沖區");
return -1;
}
gl.bindBuffer(gl.ARRAY_BUFFER,vertexSizeBuffer);
gl.bufferData(gl.ARRAY_BUFFER,verticesSizes,gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program,"a_Position");
if(a_Position < 0){
console.log("無法獲取到存儲位置");
return;
}
//獲取數組一個值所占的字節數
var fsize = verticesSizes.BYTES_PER_ELEMENT;
//將頂點坐標的位置賦值
gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,fsize*4,0);
gl.enableVertexAttribArray(a_Position);
//將頂點的紋理坐標分配給a_TexCoord並開啟它
var a_TexCoord = gl.getAttribLocation(gl.program,"a_TexCoord");
if(a_TexCoord < 0){
console.log("無法獲取到存儲位置");
return;
}
//將紋理坐標賦值
gl.vertexAttribPointer(a_TexCoord,2,gl.FLOAT,false,fsize*4,fsize*2);
gl.enableVertexAttribArray(a_TexCoord);
return n;
}
/*第四部分 initTextures() 創建紋理對象 並調用紋理繪制方法*/
function initTextures(gl,n) {
var texture = gl.createTexture();//創建紋理對象
if(!texture){
console.log("無法創建紋理對象");
return;
}
//獲取u_Sampler的存儲位置
var u_Sampler = gl.getUniformLocation(gl.program,"u_Sampler");
if(u_Sampler < 0){
console.log("無法獲取變量的存儲位置");
return;
}
//創建Image對象,並綁定加載完成事件
var image = new Image();
image.onload = function () {
loadTexture(gl,n,texture,u_Sampler,image);
};
image.src = "../image/door/001.png";
return true;
}
/*第五部分 設置紋理相關信息供WebGL使用,並進行繪制*/
function loadTexture(gl,n,texture,u_Sampler,image) {
//對紋理圖像進行y軸反轉
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);
//開啟0號紋理單元
gl.activeTexture(gl.TEXTURE0);
//向target綁定紋理對象
gl.bindTexture(gl.TEXTURE_2D,texture);
//配置紋理參數
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
//將0號紋理傳遞給着色器
gl.uniform1i(u_Sampler,0);
//繪制
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP,0,n);
}
</script>
</html>