Webgl / Javascript : canvas 纹理内容复制到另一个上下文纹理对象
Webgl / Javascript : canvas texture content copy to another context texture object
我正在尝试将我的第一个 webgl 上下文的内容(图像显示)复制到另一个 webgl 上下文的纹理。
我正在使用带有 canvas 元素的 texImage2D 函数作为源,没有出现任何错误,但它只呈现黑色。
我不知道我错过了什么,所以非常感谢任何帮助。
我正在查看 webgl1 解决方案,并使用 Chrome.
var canvas1;
var texture1;
var image;
var shaderProgram;
var vertex_buffer;
var texture_buffer;
var aVertLocation;
var aTexLocation;
var vertices = [];
var texCoords = [];
var gl;
var gl2;
var canvas2;
var texture2;
var shaderProgram2;
var vertex_buffer2;
var texture_buffer2;
var index_Buffer2;
var aVertLocation2;
var aTexLocation2;
var vertices2 = [];
var texCoords2 = [];
indices = [0, 1, 2, 0, 2, 3];
vertices = [-1, -1, 1, -1, 1, 1, -1, 1];
texCoords = [0, 0, 1, 0, 1, 1, 0, 1];
function initApp()
{
initWebGL();
image = new Image();
image.onload = function(){
render();
render2();
}
image.crossOrigin = '';
image.src = 'https://i.imgur.com/ZKMnXce.png';
}
function initWebGL()
{
canvas1 = document.getElementById('glCanvas1');
gl = canvas1.getContext('webgl');
/*====================== Shaders =======================*/
// Vertex shader source code
var vertCode =
'attribute vec2 coordinates;' +
'attribute vec2 aTexCoord;' +
'varying highp vec2 vTexCoord;' +
'void main(void) {' +
'gl_Position = vec4(coordinates,1.0,1.0);' +
'vTexCoord = aTexCoord;' +
'}';
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
//fragment shader source code
var fragCode =
'uniform sampler2D texture;' +
'varying highp vec2 vTexCoord;' +
'void main(void) {' +
' gl_FragColor = texture2D(texture, vTexCoord);' +
'}';
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.deleteShader( vertShader );
gl.deleteShader( fragShader );
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
aVertLocation = gl.getAttribLocation(shaderProgram, "coordinates");
aTexLocation = gl.getAttribLocation(shaderProgram, "aTexCoord");
vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.enableVertexAttribArray(aVertLocation);
gl.vertexAttribPointer(aVertLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
texture_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texture_buffer);
gl.enableVertexAttribArray(aTexLocation);
gl.vertexAttribPointer(aTexLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
gl.bindTexture(gl.TEXTURE_2D, null);
//==========================================================//
canvas2 = document.getElementById('glCanvas2');
gl2 = canvas2.getContext('webgl');
var vertShader2 = gl2.createShader(gl2.VERTEX_SHADER);
var fragShader2 = gl2.createShader(gl2.FRAGMENT_SHADER);
gl2.shaderSource(vertShader2, vertCode);
gl2.shaderSource(fragShader2, fragCode);
gl2.compileShader(vertShader2);
gl2.compileShader(fragShader2);
shaderProgram2 = gl2.createProgram();
gl2.attachShader(shaderProgram2, vertShader2);
gl2.attachShader(shaderProgram2, fragShader2);
gl2.deleteShader( vertShader2 );
gl2.deleteShader( fragShader2 );
gl2.linkProgram(shaderProgram2);
gl2.useProgram(shaderProgram2);
aVertLocation2 = gl2.getAttribLocation(shaderProgram2, "coordinates");
aTexLocation2 = gl2.getAttribLocation(shaderProgram2, "aTexCoord");
vertex_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, vertex_buffer2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.BYTE, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(vertices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
texture_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, texture_buffer2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.vertexAttribPointer(aTexLocation, 2, gl2.BYTE, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(texCoords), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
index_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.bufferData(gl2.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, null);
texture2 = gl2.createTexture();
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.uniform1i( gl2.getUniformLocation( shaderProgram2, 'texture' ), 0 );
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function updateTexture()
{
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
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.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function render()
{
if ( !shaderProgram ) return;
updateTexture();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.enableVertexAttribArray(aVertLocation);
gl.enableVertexAttribArray(aTexLocation);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(aVertLocation);
gl.disableVertexAttribArray(aTexLocation);
}
function updateTexture2()
{
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
gl2.generateMipmap(gl2.TEXTURE_2D);
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function render2()
{
if ( !shaderProgram2 ) return;
updateTexture2();
gl2.clearColor(0.0, 0.0, 0.0, 1.0);
gl2.clear( gl2.COLOR_BUFFER_BIT | gl2.DEPTH_BUFFER_BIT );
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.drawElements(gl2.TRIANGLES, 6, gl2.UNSIGNED_SHORT,0);
gl2.disableVertexAttribArray(aVertLocation2);
gl2.disableVertexAttribArray(aTexLocation2);
}
document.addEventListener('DOMContentLoaded', initApp);
<canvas id="glCanvas1" width="128" height="128" ></canvas>
<canvas id="glCanvas2" width="128" height="128" ></canvas>
提前致谢:)
副本工作正常。不起作用的是您的代码
这是我找到错误的方法
首先将代码移至片段,这样我就可以 运行 它了。以后请使用代码片段。
接下来我使用了imgur的图片。因为该图像位于另一个域中,所以我需要设置 crossOrigin
。幸运的是,imgur 支持 CORS,允许 WebGL 使用图像。如果是我,我不会使用图像,因为那部分并不重要。单个彩色像素也可以显示问题,并且不需要图像
现在代码是 运行ning 并且显示的错误首先要做的是更改 updateTexture2
中的这一行
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
只使用同一张图片
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, image);
第二个 canvas 仍然是黑色,表明问题与复制 canvas.
无关
所以,接下来我将片段着色器编辑成这样
gl_FragColor = vec4(1,0,0,1);
第二个canvas还是黑的。这表明该问题与纹理完全无关。第二个 canvas.
代码没有绘制任何可见的东西
因此,查看与顶点着色器相关的内容,错误是这两行
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.BYTE, false, 0, 0);
...
gl2.vertexAttribPointer(aTexLocation, 2, gl2.BYTE, false, 0, 0);
需要 gl.FLOAT
而不是 gl.BYTE
其他一些随机评论。
我为着色器使用了多行模板文字
如果您的过滤设置为不使用 mips
,则没有理由调用 gl.generateMips
这段代码没有意义
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
gl.bindTexture(gl.TEXTURE_2D, null);
没有理由在这里绑定纹理。 gl.uniform1i
只是将整数值设置为统一 shaderProgram
。它不记录任何关于纹理本身的信息,所以只是
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
没有 bindTexture
调用就可以了。最重要的是制服默认为 0,所以你真的不需要 gl.uniform1i
调用。另一方面,也许你让他们稍后将其设置为 0 以外的值。
最后,因为 WebGL 无法在 canvases 之间共享资源(至少截至 2017 年 7 月),然后,根据您正在制作的内容,您可能需要考虑使用单个 canvas . See the last solution in this answer
var canvas1;
var texture1;
var image;
var shaderProgram;
var vertex_buffer;
var texture_buffer;
var aVertLocation;
var aTexLocation;
var vertices = [];
var texCoords = [];
var gl;
var gl2;
var canvas2;
var texture2;
var shaderProgram2;
var vertex_buffer2;
var texture_buffer2;
var index_Buffer2;
var aVertLocation2;
var aTexLocation2;
var vertices2 = [];
var texCoords2 = [];
indices = [0, 1, 2, 0, 2, 3];
vertices = [-1, -1, 1, -1, 1, 1, -1, 1];
texCoords = [0, 0, 1, 0, 1, 1, 0, 1];
function initApp()
{
initWebGL();
image = new Image();
image.onload = function(){
render();
render2();
}
image.crossOrigin = '';
image.src = 'https://i.imgur.com/ZKMnXce.png';
}
function initWebGL()
{
canvas1 = document.getElementById('glCanvas1');
gl = canvas1.getContext('webgl');
/*====================== Shaders =======================*/
// Vertex shader source code
var vertCode = `
attribute vec2 coordinates;
attribute vec2 aTexCoord;
varying highp vec2 vTexCoord;
void main(void) {
gl_Position = vec4(coordinates,1.0,1.0);
vTexCoord = aTexCoord;
}
`;
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
//fragment shader source code
var fragCode = `
precision mediump float;
uniform sampler2D texture;
varying highp vec2 vTexCoord;
void main(void) {
gl_FragColor = texture2D(texture, vTexCoord);
}
`;
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.deleteShader( vertShader );
gl.deleteShader( fragShader );
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
aVertLocation = gl.getAttribLocation(shaderProgram, "coordinates");
aTexLocation = gl.getAttribLocation(shaderProgram, "aTexCoord");
vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.enableVertexAttribArray(aVertLocation);
gl.vertexAttribPointer(aVertLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
texture_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texture_buffer);
gl.enableVertexAttribArray(aTexLocation);
gl.vertexAttribPointer(aTexLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
gl.bindTexture(gl.TEXTURE_2D, null);
//==========================================================//
canvas2 = document.getElementById('glCanvas2');
gl2 = canvas2.getContext('webgl');
var vertShader2 = gl2.createShader(gl2.VERTEX_SHADER);
var fragShader2 = gl2.createShader(gl2.FRAGMENT_SHADER);
gl2.shaderSource(vertShader2, vertCode);
gl2.shaderSource(fragShader2, fragCode);
gl2.compileShader(vertShader2);
gl2.compileShader(fragShader2);
shaderProgram2 = gl2.createProgram();
gl2.attachShader(shaderProgram2, vertShader2);
gl2.attachShader(shaderProgram2, fragShader2);
gl2.deleteShader( vertShader2 );
gl2.deleteShader( fragShader2 );
gl2.linkProgram(shaderProgram2);
gl2.useProgram(shaderProgram2);
aVertLocation2 = gl2.getAttribLocation(shaderProgram2, "coordinates");
aTexLocation2 = gl2.getAttribLocation(shaderProgram2, "aTexCoord");
vertex_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, vertex_buffer2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.FLOAT, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(vertices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
texture_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, texture_buffer2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.vertexAttribPointer(aTexLocation, 2, gl2.FLOAT, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(texCoords), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
index_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.bufferData(gl2.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, null);
texture2 = gl2.createTexture();
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.uniform1i( gl2.getUniformLocation( shaderProgram2, 'texture' ), 0 );
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function updateTexture()
{
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
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.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function render()
{
if ( !shaderProgram ) return;
updateTexture();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.enableVertexAttribArray(aVertLocation);
gl.enableVertexAttribArray(aTexLocation);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(aVertLocation);
gl.disableVertexAttribArray(aTexLocation);
}
function updateTexture2()
{
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
gl2.generateMipmap(gl2.TEXTURE_2D);
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function render2()
{
if ( !shaderProgram2 ) return;
updateTexture2();
gl2.clearColor(0.0, 0.0, 0.0, 1.0);
gl2.clear( gl2.COLOR_BUFFER_BIT | gl2.DEPTH_BUFFER_BIT );
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.drawElements(gl2.TRIANGLES, 6, gl2.UNSIGNED_SHORT,0);
gl2.disableVertexAttribArray(aVertLocation2);
gl2.disableVertexAttribArray(aTexLocation2);
}
document.addEventListener('DOMContentLoaded', initApp);
<canvas id="glCanvas1" width="128" height="128" ></canvas>
<canvas id="glCanvas2" width="128" height="128" ></canvas>
我正在尝试将我的第一个 webgl 上下文的内容(图像显示)复制到另一个 webgl 上下文的纹理。 我正在使用带有 canvas 元素的 texImage2D 函数作为源,没有出现任何错误,但它只呈现黑色。 我不知道我错过了什么,所以非常感谢任何帮助。 我正在查看 webgl1 解决方案,并使用 Chrome.
var canvas1;
var texture1;
var image;
var shaderProgram;
var vertex_buffer;
var texture_buffer;
var aVertLocation;
var aTexLocation;
var vertices = [];
var texCoords = [];
var gl;
var gl2;
var canvas2;
var texture2;
var shaderProgram2;
var vertex_buffer2;
var texture_buffer2;
var index_Buffer2;
var aVertLocation2;
var aTexLocation2;
var vertices2 = [];
var texCoords2 = [];
indices = [0, 1, 2, 0, 2, 3];
vertices = [-1, -1, 1, -1, 1, 1, -1, 1];
texCoords = [0, 0, 1, 0, 1, 1, 0, 1];
function initApp()
{
initWebGL();
image = new Image();
image.onload = function(){
render();
render2();
}
image.crossOrigin = '';
image.src = 'https://i.imgur.com/ZKMnXce.png';
}
function initWebGL()
{
canvas1 = document.getElementById('glCanvas1');
gl = canvas1.getContext('webgl');
/*====================== Shaders =======================*/
// Vertex shader source code
var vertCode =
'attribute vec2 coordinates;' +
'attribute vec2 aTexCoord;' +
'varying highp vec2 vTexCoord;' +
'void main(void) {' +
'gl_Position = vec4(coordinates,1.0,1.0);' +
'vTexCoord = aTexCoord;' +
'}';
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
//fragment shader source code
var fragCode =
'uniform sampler2D texture;' +
'varying highp vec2 vTexCoord;' +
'void main(void) {' +
' gl_FragColor = texture2D(texture, vTexCoord);' +
'}';
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.deleteShader( vertShader );
gl.deleteShader( fragShader );
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
aVertLocation = gl.getAttribLocation(shaderProgram, "coordinates");
aTexLocation = gl.getAttribLocation(shaderProgram, "aTexCoord");
vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.enableVertexAttribArray(aVertLocation);
gl.vertexAttribPointer(aVertLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
texture_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texture_buffer);
gl.enableVertexAttribArray(aTexLocation);
gl.vertexAttribPointer(aTexLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
gl.bindTexture(gl.TEXTURE_2D, null);
//==========================================================//
canvas2 = document.getElementById('glCanvas2');
gl2 = canvas2.getContext('webgl');
var vertShader2 = gl2.createShader(gl2.VERTEX_SHADER);
var fragShader2 = gl2.createShader(gl2.FRAGMENT_SHADER);
gl2.shaderSource(vertShader2, vertCode);
gl2.shaderSource(fragShader2, fragCode);
gl2.compileShader(vertShader2);
gl2.compileShader(fragShader2);
shaderProgram2 = gl2.createProgram();
gl2.attachShader(shaderProgram2, vertShader2);
gl2.attachShader(shaderProgram2, fragShader2);
gl2.deleteShader( vertShader2 );
gl2.deleteShader( fragShader2 );
gl2.linkProgram(shaderProgram2);
gl2.useProgram(shaderProgram2);
aVertLocation2 = gl2.getAttribLocation(shaderProgram2, "coordinates");
aTexLocation2 = gl2.getAttribLocation(shaderProgram2, "aTexCoord");
vertex_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, vertex_buffer2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.BYTE, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(vertices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
texture_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, texture_buffer2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.vertexAttribPointer(aTexLocation, 2, gl2.BYTE, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(texCoords), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
index_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.bufferData(gl2.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, null);
texture2 = gl2.createTexture();
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.uniform1i( gl2.getUniformLocation( shaderProgram2, 'texture' ), 0 );
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function updateTexture()
{
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
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.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function render()
{
if ( !shaderProgram ) return;
updateTexture();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.enableVertexAttribArray(aVertLocation);
gl.enableVertexAttribArray(aTexLocation);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(aVertLocation);
gl.disableVertexAttribArray(aTexLocation);
}
function updateTexture2()
{
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
gl2.generateMipmap(gl2.TEXTURE_2D);
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function render2()
{
if ( !shaderProgram2 ) return;
updateTexture2();
gl2.clearColor(0.0, 0.0, 0.0, 1.0);
gl2.clear( gl2.COLOR_BUFFER_BIT | gl2.DEPTH_BUFFER_BIT );
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.drawElements(gl2.TRIANGLES, 6, gl2.UNSIGNED_SHORT,0);
gl2.disableVertexAttribArray(aVertLocation2);
gl2.disableVertexAttribArray(aTexLocation2);
}
document.addEventListener('DOMContentLoaded', initApp);
<canvas id="glCanvas1" width="128" height="128" ></canvas>
<canvas id="glCanvas2" width="128" height="128" ></canvas>
提前致谢:)
副本工作正常。不起作用的是您的代码
这是我找到错误的方法
首先将代码移至片段,这样我就可以 运行 它了。以后请使用代码片段。
接下来我使用了imgur的图片。因为该图像位于另一个域中,所以我需要设置
crossOrigin
。幸运的是,imgur 支持 CORS,允许 WebGL 使用图像。如果是我,我不会使用图像,因为那部分并不重要。单个彩色像素也可以显示问题,并且不需要图像现在代码是 运行ning 并且显示的错误首先要做的是更改
中的这一行updateTexture2
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
只使用同一张图片
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, image);
第二个 canvas 仍然是黑色,表明问题与复制 canvas.
无关
所以,接下来我将片段着色器编辑成这样
gl_FragColor = vec4(1,0,0,1);
第二个canvas还是黑的。这表明该问题与纹理完全无关。第二个 canvas.
代码没有绘制任何可见的东西
因此,查看与顶点着色器相关的内容,错误是这两行
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.BYTE, false, 0, 0); ... gl2.vertexAttribPointer(aTexLocation, 2, gl2.BYTE, false, 0, 0);
需要
gl.FLOAT
而不是gl.BYTE
其他一些随机评论。
我为着色器使用了多行模板文字
如果您的过滤设置为不使用 mips
,则没有理由调用 这段代码没有意义
gl.bindTexture(gl.TEXTURE_2D, texture1); gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 ); gl.bindTexture(gl.TEXTURE_2D, null);
没有理由在这里绑定纹理。
gl.uniform1i
只是将整数值设置为统一shaderProgram
。它不记录任何关于纹理本身的信息,所以只是gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
没有
bindTexture
调用就可以了。最重要的是制服默认为 0,所以你真的不需要gl.uniform1i
调用。另一方面,也许你让他们稍后将其设置为 0 以外的值。
gl.generateMips
最后,因为 WebGL 无法在 canvases 之间共享资源(至少截至 2017 年 7 月),然后,根据您正在制作的内容,您可能需要考虑使用单个 canvas . See the last solution in this answer
var canvas1;
var texture1;
var image;
var shaderProgram;
var vertex_buffer;
var texture_buffer;
var aVertLocation;
var aTexLocation;
var vertices = [];
var texCoords = [];
var gl;
var gl2;
var canvas2;
var texture2;
var shaderProgram2;
var vertex_buffer2;
var texture_buffer2;
var index_Buffer2;
var aVertLocation2;
var aTexLocation2;
var vertices2 = [];
var texCoords2 = [];
indices = [0, 1, 2, 0, 2, 3];
vertices = [-1, -1, 1, -1, 1, 1, -1, 1];
texCoords = [0, 0, 1, 0, 1, 1, 0, 1];
function initApp()
{
initWebGL();
image = new Image();
image.onload = function(){
render();
render2();
}
image.crossOrigin = '';
image.src = 'https://i.imgur.com/ZKMnXce.png';
}
function initWebGL()
{
canvas1 = document.getElementById('glCanvas1');
gl = canvas1.getContext('webgl');
/*====================== Shaders =======================*/
// Vertex shader source code
var vertCode = `
attribute vec2 coordinates;
attribute vec2 aTexCoord;
varying highp vec2 vTexCoord;
void main(void) {
gl_Position = vec4(coordinates,1.0,1.0);
vTexCoord = aTexCoord;
}
`;
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
//fragment shader source code
var fragCode = `
precision mediump float;
uniform sampler2D texture;
varying highp vec2 vTexCoord;
void main(void) {
gl_FragColor = texture2D(texture, vTexCoord);
}
`;
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.deleteShader( vertShader );
gl.deleteShader( fragShader );
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
aVertLocation = gl.getAttribLocation(shaderProgram, "coordinates");
aTexLocation = gl.getAttribLocation(shaderProgram, "aTexCoord");
vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.enableVertexAttribArray(aVertLocation);
gl.vertexAttribPointer(aVertLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
texture_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texture_buffer);
gl.enableVertexAttribArray(aTexLocation);
gl.vertexAttribPointer(aTexLocation, 2, gl.FLOAT, false, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
index_buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i( gl.getUniformLocation( shaderProgram, 'texture' ), 0 );
gl.bindTexture(gl.TEXTURE_2D, null);
//==========================================================//
canvas2 = document.getElementById('glCanvas2');
gl2 = canvas2.getContext('webgl');
var vertShader2 = gl2.createShader(gl2.VERTEX_SHADER);
var fragShader2 = gl2.createShader(gl2.FRAGMENT_SHADER);
gl2.shaderSource(vertShader2, vertCode);
gl2.shaderSource(fragShader2, fragCode);
gl2.compileShader(vertShader2);
gl2.compileShader(fragShader2);
shaderProgram2 = gl2.createProgram();
gl2.attachShader(shaderProgram2, vertShader2);
gl2.attachShader(shaderProgram2, fragShader2);
gl2.deleteShader( vertShader2 );
gl2.deleteShader( fragShader2 );
gl2.linkProgram(shaderProgram2);
gl2.useProgram(shaderProgram2);
aVertLocation2 = gl2.getAttribLocation(shaderProgram2, "coordinates");
aTexLocation2 = gl2.getAttribLocation(shaderProgram2, "aTexCoord");
vertex_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, vertex_buffer2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.vertexAttribPointer(aVertLocation2, 2, gl2.FLOAT, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(vertices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
texture_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, texture_buffer2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.vertexAttribPointer(aTexLocation, 2, gl2.FLOAT, false, 0, 0);
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(texCoords), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ARRAY_BUFFER, null);
index_buffer2 = gl2.createBuffer();
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.bufferData(gl2.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl2.STATIC_DRAW);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, null);
texture2 = gl2.createTexture();
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.uniform1i( gl2.getUniformLocation( shaderProgram2, 'texture' ), 0 );
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function updateTexture()
{
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
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.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function render()
{
if ( !shaderProgram ) return;
updateTexture();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.enableVertexAttribArray(aVertLocation);
gl.enableVertexAttribArray(aTexLocation);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.disableVertexAttribArray(aVertLocation);
gl.disableVertexAttribArray(aTexLocation);
}
function updateTexture2()
{
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA, gl2.RGBA, gl2.UNSIGNED_BYTE, canvas1);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.LINEAR);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_S, gl2.CLAMP_TO_EDGE);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_WRAP_T, gl2.CLAMP_TO_EDGE);
gl2.generateMipmap(gl2.TEXTURE_2D);
gl2.bindTexture(gl2.TEXTURE_2D, null);
}
function render2()
{
if ( !shaderProgram2 ) return;
updateTexture2();
gl2.clearColor(0.0, 0.0, 0.0, 1.0);
gl2.clear( gl2.COLOR_BUFFER_BIT | gl2.DEPTH_BUFFER_BIT );
gl2.bindTexture(gl2.TEXTURE_2D, texture2);
gl2.enableVertexAttribArray(aVertLocation2);
gl2.enableVertexAttribArray(aTexLocation2);
gl2.bindBuffer(gl2.ELEMENT_ARRAY_BUFFER, index_buffer2);
gl2.drawElements(gl2.TRIANGLES, 6, gl2.UNSIGNED_SHORT,0);
gl2.disableVertexAttribArray(aVertLocation2);
gl2.disableVertexAttribArray(aTexLocation2);
}
document.addEventListener('DOMContentLoaded', initApp);
<canvas id="glCanvas1" width="128" height="128" ></canvas>
<canvas id="glCanvas2" width="128" height="128" ></canvas>