【问题标题】:Webgl / Javascript : canvas texture content copy to another context texture objectWebgl / Javascript:画布纹理内容复制到另一个上下文纹理对象
【发布时间】:2017-12-09 04:29:36
【问题描述】:

我正在尝试将我的第一个 webgl 上下文的内容(图像的显示)复制到另一个 webgl 上下文的纹理中。 我将 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>

提前致谢:)

【问题讨论】:

  • 我不确定你的意思是什么。我发布的代码是从 canvas1 复制到 canvas2 中使用的纹理。使用image 只是一个调试测试。它表明您真正的错误与复制画布无关。真正的错误在其他地方。现在真正的错误已经修复,它可以正常工作。
  • 我明白了!谢谢gman,它工作正常。

标签: javascript html5-canvas copy textures webgl


【解决方案1】:

副本运行良好。什么不工作是你的代码?

这是我为找到错误所做的工作

  • 首先将代码移至 sn-p,以便我可以实际运行它。以后请使用sn-ps。

  • 接下来我使用了来自 imgur 的图像。因为该图像位于另一个域中,所以我需要设置crossOrigin。幸运的是 imgur 支持 CORS 允许 WebGL 使用图像。如果是我,我不会使用图像,因为那部分并不重要。单个彩色像素也可以显示问题并消除对图像的需求

  • 现在代码正在运行并且显示的错误首先要做的是更改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);
    

    第二个画布仍然是黑色的,表明问题与复制画布无关。

  • 所以,接下来我将片段着色器编辑到这个

      gl_FragColor = vec4(1,0,0,1);
    

    第二张画布仍然是黑色的。这表明该问题与纹理完全无关。代码没有在第二个画布上绘制任何可见的东西。

  • 所以,看看与顶点着色器相关的东西,错误是这两行

    gl2.vertexAttribPointer(aVertLocation2, 2, gl2.BYTE, false, 0, 0);
    
    ...
    
    gl2.vertexAttribPointer(aTexLocation, 2, gl2.BYTE, false, 0, 0);
    

    需要gl.FLOAT 而不是gl.BYTE

其他一些随机的 cmets。

  • 我为着色器使用了多行模板文字

  • 如果您的过滤设置为不使用 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 无法跨画布共享资源(至少截至 2017 年 7 月),因此,根据您制作的内容,您可能需要考虑使用单个画布。 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>

【讨论】:

    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 2020-11-17
    • 2016-09-13
    • 2016-08-28
    • 2016-10-02
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    相关资源
    最近更新 更多