Javascript WebGL:使用单独的纹理渲染两个对象
我目前正在WebGL中进行一个简单的项目,该项目要求渲染多个2D对象,并在其上设置简单的图像纹理。实际项目生成随机数量的对象,通常在5到9之间,在画布周围为它们设置顶点数据以将它们分开,并且应该进行渲染,但是一次只渲染一个对象(通常是最后一个,但我可以在gl.activeTexture周围更改以显示阵列中的其他对象)。我尝试在着色器中使用一个关于纹理数组的on here,但没有效果,因此我创建了一个非常简单的测试程序,它只尝试加载两个对象和纹理,一个在画布的左侧,另一个在右侧 从这里开始,我尝试将所有操作完全分开,甚至为每个对象提供它们自己的着色器、程序、缓冲区和所有内容,然后在为每个对象调用gl.drawElements之前,为每个对象绑定draw调用中的所有内容。这仍然没有告诉我正确的结果,只有第二个纹理出现,但是它确实让我发现了我认为正在发生的事情。通过注释第二个纹理的绑定和绘制调用,第一个纹理将显示,但它显示在第二个纹理的位置,而不是其顶点应放置的位置。因此,我假设在这个程序(和我的项目代码)中发生的事情是,它实际上正在绘制这两个,但出于某种原因,将最后绘制的顶点应用于所有顶点,从而堆叠它们,并仅显示顶部(或最后绘制的顶点) 我也尝试过对下面的代码进行大量的调整,只使用一个程序,使用相同的索引、纹理坐标,还有一些注释掉的行,它们试图以不同的顺序调用。任何被注释掉的东西并不意味着我一定认为它是错的或是对的,只是从我在这一点上漫无目的地尝试过的各种事情来看 我曾与OpenGL合作过一段时间,用它们自己的纹理绘制多个对象几乎没有问题,我知道WebGL在某些方面与OpenGL的工作方式不同,包括纹理,但我不知道我在哪里创建了这个问题。我相信这是一件非常简单的事情,任何指导都将不胜感激 很抱歉,代码太长了,我觉得只要把我认为需要的东西都直接打出来就行了,不需要走捷径。initShaders调用来自我在教科书中使用的WebGL js文件,不是我写的东西,loadImage调用只是从html代码中加载一个Javascript WebGL:使用单独的纹理渲染两个对象,javascript,webgl,textures,Javascript,Webgl,Textures,我目前正在WebGL中进行一个简单的项目,该项目要求渲染多个2D对象,并在其上设置简单的图像纹理。实际项目生成随机数量的对象,通常在5到9之间,在画布周围为它们设置顶点数据以将它们分开,并且应该进行渲染,但是一次只渲染一个对象(通常是最后一个,但我可以在gl.activeTexture周围更改以显示阵列中的其他对象)。我尝试在着色器中使用一个关于纹理数组的on here,但没有效果,因此我创建了一个非常简单的测试程序,它只尝试加载两个对象和纹理,一个在画布的左侧,另一个在右侧 从这里开始,我尝试
。据我所知,正确加载图像没有问题。我只包括第一个顶点和片段着色器,因为其他两个都是相同的id保存
<script id="vertex-shader1" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 vTexCoord;
varying vec2 fTexCoord;
void main() {
fTexCoord = vTexCoord;
gl_Position = vPosition;
}
</script>
<script id="fragment-shader1" type="x-shader/x-fragment">
precision mediump float;
varying vec2 fTexCoord;
uniform sampler2D texture;
void main() {
gl_FragColor = texture2D(texture, fTexCoord);
}
</script>
首先,你的代码不能工作。它调用函数
loadImages
,然后立即使用图像。图像在浏览器中异步加载,因此您需要在加载图像时进行回调,或者使用异步函数
这是你的代码。首先,我制作了一个loadImage
,返回一个承诺。然后我创建了一个名为loadImages
的异步函数,它使用该函数加载所有图像并等待它们加载。然后我创建了另一个异步函数,名为main
what,首先等待loadImages
,然后调用init
第二个问题是,在WebGL1中,属性是全局状态。这意味着您需要在渲染时而不是在初始化时设置它们,以便调用转到gl.enableVertexAttribArray
和gl.vertexAttribPointer
需要在渲染时使用适当的值来渲染您正在渲染的特定对象gl.vertexattributepointer
将当前ARRAY\u BUFFER
绑定复制到该属性
您可能会发现有帮助,尤其是,这可能会帮助您可视化WebGL内部发生的事情
“严格使用”;
常量vec2=(…args)=>[…args];
常量vec4=(…args)=>[…args];
const flatte=a=>新的Float32Array(a.flat());
常数WebGLUtils={
setupWebGL:(canvas)=>{return canvas.getContext('webgl');},
};
const initShaders=(gl,vs,fs)=>twgl.createProgram(gl[vs,fs]);
const requestAnimFrame=requestAnimationFrame;
var-gl;
var图像=[];
var程序1;
var程序2;
var-texture1;
var-texture2;
var vBuff1;
var vBuff2;
iBuff1变种;
iBuff2变种;
var-tBuff1;
var-tBuff2;
var vPos1;
var vPos2;
变量fTexCoord1;
变量fTexCoord2;
var采样器1;
var采样器2;
变量vertices1=[
vec4(-0.8,0.1,0.0,1.0),
vec4(-0.8,0.3,0.0,1.0),
vec4(-0.6,0.3,0.0,1.0),
vec4(-0.6,0.1,0.0,1.0)
];
变量vertices2=[
vec4(0.1,0.1,0.0,1.0),
vec4(0.1,0.3,0.0,1.0),
vec4(0.3,0.3,0.0,1.0),
vec4(0.3,0.1,0.0,1.0)
];
变量指标1=[
0, 1, 2,
0, 2, 3
];
变量指标2=[
0, 1, 2,
0, 2, 3
];
变量tcs1=[
vec2(0,0),
vec2(0,1),
vec2(1,1),
vec2(1,0)
];
变量tcs2=[
vec2(0,0),
vec2(0,1),
vec2(1,1),
vec2(1,0)
];
函数init(){
var canvas=document.getElementById(“gl画布”);
gl=WebGLUtils.setupWebGL(画布);
如果(!gl){alert(“WebGL不可用”);}
总图视口(0,0,canvas.width,canvas.height);
gl.clearColor(0.0,0.0,0.0,1.0);
program1=初始着色器(gl,“顶点着色器1”、“片段着色器1”);
总账使用计划(计划1);
vBuff1=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vBuff1);
总账缓冲数据(总账数组缓冲、展平(垂直1)、总账静态绘图);
vPos1=gl.GetAttriblLocation(程序1,“vPosition”);
iBuff1=gl.createBuffer();
gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,iBuff1);
总账缓冲数据(总账元素\数组\缓冲区、新UINT8数组(指示1)、总账静态\绘图);
tBuff1=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,tBuff1);
总账缓冲数据(总账数组缓冲、展平(tcs1)、总账静态绘图);
fTexCoord1=gl.GetAttriblLocation(程序1,“vTexCoord”);
采样器1=gl.getUniformLocation(程序1,“纹理”);
纹理
"use-strict"
var gl;
var images = [];
var program1;
var program2;
var texture1;
var texture2;
var vBuff1;
var vBuff2;
var iBuff1;
var iBuff2;
var tBuff1;
var tBuff2;
var vPos1;
var vPos2;
var fTexCoord1;
var fTexCoord2;
var sampler1;
var sampler2;
var vertices1 = [
vec4(-0.8, 0.1, 0.0, 1.0),
vec4(-0.8, 0.3, 0.0, 1.0),
vec4(-0.6, 0.3, 0.0, 1.0),
vec4(-0.6, 0.1, 0.0, 1.0)
];
var vertices2 = [
vec4(0.1, 0.1, 0.0, 1.0),
vec4(0.1, 0.3, 0.0, 1.0),
vec4(0.3, 0.3, 0.0, 1.0),
vec4(0.3, 0.1, 0.0, 1.0)
];
var indices1 = [
0, 1, 2,
0, 2, 3
];
var indices2 = [
0, 1, 2,
0, 2, 3
];
var tcs1 = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var tcs2 = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
window.onload = function init() {
var canvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
if (!gl) { alert("WebGL isn't available"); }
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
loadImages();
program1 = initShaders(gl, "vertex-shader1", "fragment-shader1");
gl.useProgram(program1);
vBuff1 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuff1);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices1), gl.STATIC_DRAW);
vPos1 = gl.getAttribLocation(program1, "vPosition");
gl.vertexAttribPointer(vPos1, 4, gl.FLOAT, false, 0, 0);
//gl.enableVertexAttribArray(vPos1);
iBuff1 = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff1);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices1), gl.STATIC_DRAW);
tBuff1 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, tBuff1);
gl.bufferData(gl.ARRAY_BUFFER, flatten(tcs1), gl.STATIC_DRAW);
fTexCoord1 = gl.getAttribLocation(program1, "vTexCoord");
gl.vertexAttribPointer(fTexCoord1, 2, gl.FLOAT, false, 0, 0);
//gl.enableVertexAttribArray(fTexCoord1);
sampler1 = gl.getUniformLocation(program1, "texture");
texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images[0]);
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.bindTexture(gl.TEXTURE_2D, null);
///////////////////////////////////////////////////////////////////////////////////////
/*
program2 = initShaders(gl, "vertex-shader2", "fragment-shader2");
gl.useProgram(program2);
*/
vBuff2 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuff2);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices2), gl.STATIC_DRAW);
vPos2 = gl.getAttribLocation(program1, "vPosition");
gl.vertexAttribPointer(vPos2, 4, gl.FLOAT, false, 0, 0);
//gl.enableVertexAttribArray(vPos2);
iBuff2 = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff2);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices2), gl.STATIC_DRAW);
tBuff2 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, tBuff2);
gl.bufferData(gl.ARRAY_BUFFER, flatten(tcs2), gl.STATIC_DRAW);
fTexCoord2 = gl.getAttribLocation(program1, "vTexCoord");
gl.vertexAttribPointer(fTexCoord2, 2, gl.FLOAT, false, 0, 0);
//gl.enableVertexAttribArray(fTexCoord2);
sampler2 = gl.getUniformLocation(program1, "texture");
texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, images[1]);
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.bindTexture(gl.TEXTURE_2D, null);
render();
};
function render() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program1);
gl.bindBuffer(gl.ARRAY_BUFFER, vBuff1);
gl.enableVertexAttribArray(vPos1);
gl.enableVertexAttribArray(fTexCoord1);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.uniform1i(sampler1, 0);
// gl.bindBuffer(gl.ARRAY_BUFFER, vBuff1);
// gl.enableVertexAttribArray(vPos1);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff1);
gl.drawElements(gl.TRIANGLES, indices1.length, gl.UNSIGNED_BYTE, 0);
//gl.bindTexture(gl.TEXTURE_2D, null);
// gl.useProgram(program2);
gl.bindBuffer(gl.ARRAY_BUFFER,vBuff2);
gl.enableVertexAttribArray(vPos2);
gl.enableVertexAttribArray(fTexCoord2);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.uniform1i(sampler2, 0);
// gl.bindBuffer(gl.ARRAY_BUFFER, vBuff2);
// gl.enableVertexAttribArray(vPos2);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff2);
gl.drawElements(gl.TRIANGLES, indices2.length, gl.UNSIGNED_BYTE, 0);
requestAnimFrame(render);
}