Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Webgl 我可以将多重纹理与DrawArrayStanceDangle一起使用吗?_Webgl_Webgl Extensions - Fatal编程技术网

Webgl 我可以将多重纹理与DrawArrayStanceDangle一起使用吗?

Webgl 我可以将多重纹理与DrawArrayStanceDangle一起使用吗?,webgl,webgl-extensions,Webgl,Webgl Extensions,我尝试在屏幕上绘制多个图标,并使用DrawArrayInstanceDangle方法。 我尝试使用多个纹理像这样,但一些图标绘制不同的几何体,我找不到什么画像那样 我使用一个大图标贴图纹理并使用以下函数填充图标顶点坐标数组: FillIconTextCoordBuffer(data, mapW, mapH, i) { const ULiconW = data.x / mapW const ULiconH = data.y / mapH const LRiconW =

我尝试在屏幕上绘制多个图标,并使用DrawArrayInstanceDangle方法。 我尝试使用多个纹理像这样,但一些图标绘制不同的几何体,我找不到什么画像那样

我使用一个大图标贴图纹理并使用以下函数填充图标顶点坐标数组:

  FillIconTextCoordBuffer(data, mapW, mapH, i) {
    const ULiconW = data.x / mapW
    const ULiconH = data.y / mapH
    const LRiconW = (data.x + data.width) / mapW
    const LRiconH = (data.y + data.height) / mapH
    const { gl } = this.FGlobe

    this.IconMapTexCoordArr[i] = gl.createBuffer()
    gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapTexCoordArr[i])
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
      ULiconW, ULiconH,
      LRiconW, LRiconH,
      LRiconW, ULiconH,
      LRiconW, LRiconH,
      ULiconW, ULiconH,
      ULiconW, LRiconH]), gl.STATIC_DRAW)
  }

然后我的绘图函数如下所示:

  gl.uniform1f(P2DRotationForLayer, icon.rotDeg)
  gl.uniform2fv(P2DScaleLocForLayer, icon.__size)
  gl.uniform4fv(P2DOpacityLocForLayer, __iconColor)

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 1) // This makes it instanced!

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapVertCoordArr)
  gl.enableVertexAttribArray(P2DvertexPosForLayer)
  gl.vertexAttribPointer(P2DvertexPosForLayer, 3, gl.FLOAT, false, 0, 0)

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconCoordBuff)
  gl.enableVertexAttribArray(P2DoffsetForLayer)
  gl.vertexAttribPointer(P2DoffsetForLayer, 2, gl.FLOAT, false, 0, 0)

  gl.bindTexture(gl.TEXTURE_2D, IconMap[icon.mapIndex].texture)
  gl.disable(gl.BLEND)
  for (var j = this.StartCountArr.length; j--;) {
     this.DrawInstances(this.StartCountArr[j].start, this.StartCountArr[j].count, j)
  }

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 0)

DrawInstances(start, count, j) {
    const {
      gl, ext,
      P2DtextCoordLocForLayer,
    } = this.FGlobe

    gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapTexCoordArr[j])
    gl.enableVertexAttribArray(P2DtextCoordLocForLayer)
    gl.vertexAttribPointer(P2DtextCoordLocForLayer, 2, gl.FLOAT, false, 0, 0)
    gl.bindBuffer(gl.ARRAY_BUFFER, null)
    ext.drawArraysInstancedANGLE(gl.TRIANGLES, start, 6, count)
  }
|\
| \
|  \
|  /
| /
|/

我的画是这样的:

  gl.uniform1f(P2DRotationForLayer, icon.rotDeg)
  gl.uniform2fv(P2DScaleLocForLayer, icon.__size)
  gl.uniform4fv(P2DOpacityLocForLayer, __iconColor)

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 1) // This makes it instanced!

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapVertCoordArr)
  gl.enableVertexAttribArray(P2DvertexPosForLayer)
  gl.vertexAttribPointer(P2DvertexPosForLayer, 3, gl.FLOAT, false, 0, 0)

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconCoordBuff)
  gl.enableVertexAttribArray(P2DoffsetForLayer)
  gl.vertexAttribPointer(P2DoffsetForLayer, 2, gl.FLOAT, false, 0, 0)

  gl.bindTexture(gl.TEXTURE_2D, IconMap[icon.mapIndex].texture)
  gl.disable(gl.BLEND)
  for (var j = this.StartCountArr.length; j--;) {
     this.DrawInstances(this.StartCountArr[j].start, this.StartCountArr[j].count, j)
  }

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 0)

DrawInstances(start, count, j) {
    const {
      gl, ext,
      P2DtextCoordLocForLayer,
    } = this.FGlobe

    gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapTexCoordArr[j])
    gl.enableVertexAttribArray(P2DtextCoordLocForLayer)
    gl.vertexAttribPointer(P2DtextCoordLocForLayer, 2, gl.FLOAT, false, 0, 0)
    gl.bindBuffer(gl.ARRAY_BUFFER, null)
    ext.drawArraysInstancedANGLE(gl.TRIANGLES, start, 6, count)
  }
|\
| \
|  \
|  /
| /
|/

事实上,有些图标向右拉,我看到两个不同的图标,但还有一种类型,看起来像这样:

  gl.uniform1f(P2DRotationForLayer, icon.rotDeg)
  gl.uniform2fv(P2DScaleLocForLayer, icon.__size)
  gl.uniform4fv(P2DOpacityLocForLayer, __iconColor)

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 1) // This makes it instanced!

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapVertCoordArr)
  gl.enableVertexAttribArray(P2DvertexPosForLayer)
  gl.vertexAttribPointer(P2DvertexPosForLayer, 3, gl.FLOAT, false, 0, 0)

  gl.bindBuffer(gl.ARRAY_BUFFER, this.IconCoordBuff)
  gl.enableVertexAttribArray(P2DoffsetForLayer)
  gl.vertexAttribPointer(P2DoffsetForLayer, 2, gl.FLOAT, false, 0, 0)

  gl.bindTexture(gl.TEXTURE_2D, IconMap[icon.mapIndex].texture)
  gl.disable(gl.BLEND)
  for (var j = this.StartCountArr.length; j--;) {
     this.DrawInstances(this.StartCountArr[j].start, this.StartCountArr[j].count, j)
  }

  ext.vertexAttribDivisorANGLE(P2DoffsetForLayer, 0)

DrawInstances(start, count, j) {
    const {
      gl, ext,
      P2DtextCoordLocForLayer,
    } = this.FGlobe

    gl.bindBuffer(gl.ARRAY_BUFFER, this.IconMapTexCoordArr[j])
    gl.enableVertexAttribArray(P2DtextCoordLocForLayer)
    gl.vertexAttribPointer(P2DtextCoordLocForLayer, 2, gl.FLOAT, false, 0, 0)
    gl.bindBuffer(gl.ARRAY_BUFFER, null)
    ext.drawArraysInstancedANGLE(gl.TRIANGLES, start, 6, count)
  }
|\
| \
|  \
|  /
| /
|/

我的图标只有两个三角形,如下图所示,我不设置任何形状如上图所示

______
|\   |
| \  |
|  \ |
|   \|
------

下面是一个使用实例化图形从精灵图纸绘制多个精灵的示例

注意,如果是我,我会为每个实例使用一个矩阵,但我认为在这里使用偏移量和比例会更简单

const gl=document.querySelector('canvas').getContext('webgl');
const ext=gl.getExtension('ANGLE_instanced_array');
如果(!ext)警报('需要角度\实例\数组');
常数vs=`
属性向量2位置;
属性向量2 uv;
属性vec2偏移量;//实例
属性向量2比例;//实例
属性vec2 uvOffset;//实例
属性vec2 uvScale;//实例
一致mat4矩阵;
可变vec2 v_uv;
void main(){
gl_位置=矩阵*vec4(位置*刻度+偏移,0,1);
v_uv=uv*uv比例+uv偏移;
}
`;
常数fs=`
高精度浮点;
可变vec2 v_uv;
均匀采样器;
void main(){
gl_FragColor=纹理2d(spriteAtlas,v_uv);
}
`;
const program=twgl.createProgram(gl[vs,fs]);
const positionLoc=gl.getAttriblLocation(程序“位置”);
const uvLoc=gl.getAttriblLocation(程序“uv”);
const offsetLoc=gl.getAttribLocation(程序“offset”);
常量scaleLoc=gl.getAttribLocation(程序“scale”);
const uvOffsetLoc=gl.getAttriblLocation(程序“uvOffset”);
const uvScaleLoc=gl.getAttribLocation(程序“uvScale”);
常量matrixLoc=gl.getUniformLocation(程序“矩阵”);
//设置四元位置和uv
const positionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,positionBuffer);
gl.bufferData(gl.ARRAY\u BUFFER,新Float32Array([
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
])、总图、静态图);
const uvBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,uvBuffer);
gl.bufferData(gl.ARRAY\u BUFFER,新Float32Array([
0, 0,
1, 0,
0, 1,
0, 1,
1, 0,
1, 1,
])、总图、静态图);
//为实例数据创建类型化数组
常量maxSprites=1000;
常量偏移=新的Float32Array(maxSprites*2);
const scales=新的Float32Array(maxSprites*2);
const uvOffsets=新的Float32Array(maxSprites*2);
const uvScales=新的Float32Array(maxSprites*2);
//为实例数据创建缓冲区
const offsetBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER,Offset.ByTeleLength,gl.DYNAMIC_DRAW);
常量scaleBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,scaleBuffer);
gl.bufferData(gl.ARRAY_BUFFER,Scale.ByTeleLength,gl.DYNAMIC_DRAW);
const uvOffsetBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,uvOffsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER,uvOffsets.ByTeleLength,gl.DYNAMIC_DRAW);
const uvScaleBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,uvScaleBuffer);
gl.bufferData(gl.ARRAY_BUFFER,uvScales.ByTeleLength,gl.DYNAMIC_DRAW);
设spriteNdx=0;
函数addSprite(
雪碧灯,雪碧灯,
srcX,srcY,srcWidth,srcHeight,
dstX、dstY、dstWidth、dstHeight){
常数off0=spriteNdx*2;
常数off1=off0+1;
偏移量[off0]=dstX;
偏移量[off1]=dstY;
刻度[off0]=宽度;
刻度尺[off1]=高度;
uvOffsets[off0]=srcX/spriteAtlasWidth;
uvOffsets[off1]=srcY/spriteAtlasHeight;
uvScales[off0]=srcWidth/spriteAtlasWidth;
uvScales[off1]=SRCEIGHT/spriteAtlasHeight;
++spriteNdx;
}
常量精灵=[
{msg:'A',x:0,y:0,w:64,h:32,bg:'red',fg:'yellow'},
{msg:'B',x:64,y:0,w:64,h:32,bg:'blue',fg:'white'},
{msg:'C',x:0,y:32,w:40,h:32,bg:'green',fg:'pink'},
{msg:'D',x:40,y:32,w:48,h:32,bg:'purple',fg:'cyan'},
{msg:'F',x:88,y:32,w:40,h:32,bg:'black',fg:'red'},
];
//在地图册中制作5个精灵
常数spriteAtlasWidth=128;
常数spriteAtlasHeight=64;
const ctx=document.createElement('canvas').getContext('2d');
ctx.canvas.width=spriteAtlasWidth;
ctx.canvas.height=spriteAtlasHeight;
用于(精灵的常数spr){
ctx.fillStyle=spr.bg;
ctx.fillRect(spr.x、spr.y、spr.w、spr.h);
ctx.strokeStyle=spr.fg;
ctx.strokeRect(spr.x+.5,spr.y+.5,spr.w-1,spr.h-1);
ctx.fillStyle=spr.fg;
ctx.font='bold 26px sans serif';
ctx.textAlign='中心';
ctx.textb基线='中间';
ctx.fillText(spr.msg、spr.x+spr.w/2、spr.y+spr.h/2);
}
//展示地图册
document.body.appendChild(ctx.canvas);
//将地图集复制到纹理
常量tex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_字节,ctx.canvas);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MAG\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D、gl.TEXTURE_WRAP_S、gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE\u 2D、gl.TEXTURE\u WRAP\u T、gl.CLAMP\u至边缘);
函数渲染(时间){
时间*=0.001;//转换为秒
spriteNdx=0;
常数numSprites=10;
for(设i=0;i