Opengl 如何使用WebGL渲染二维精灵?

Opengl 如何使用WebGL渲染二维精灵?,opengl,opengl-es,html5-canvas,dart,webgl,Opengl,Opengl Es,Html5 Canvas,Dart,Webgl,我正在努力使用Dart和WebGL将2D精灵渲染到画布上。我可以在网上找到很少的例子;大多数都是3D的,或者包含大量的意大利面代码,但没有真正解释它们在做什么。我正在尝试做最简单的事情来渲染精灵 到目前为止,我已经成功地在画布上渲染了一个绿色正方形(两个三角形)。我正在努力解决的问题是,如何将这一点从一个绿色正方形改为使用我的纹理(我相信纹理已正确加载和绑定)。我认为这需要对着色器进行更改(以获取纹理坐标,而不是颜色),并传递与缓冲区中顶点相关的纹理坐标 这个代码 注意:这只是一个一次性样品;大

我正在努力使用Dart和WebGL将2D精灵渲染到画布上。我可以在网上找到很少的例子;大多数都是3D的,或者包含大量的意大利面代码,但没有真正解释它们在做什么。我正在尝试做最简单的事情来渲染精灵

到目前为止,我已经成功地在画布上渲染了一个绿色正方形(两个三角形)。我正在努力解决的问题是,如何将这一点从一个绿色正方形改为使用我的纹理(我相信纹理已正确加载和绑定)。我认为这需要对着色器进行更改(以获取纹理坐标,而不是颜色),并传递与缓冲区中顶点相关的纹理坐标

这个代码

注意:这只是一个一次性样品;大多数代码都存在于构造函数中;我现在对代码的整洁程度不太感兴趣;当我看到屏幕上有精灵的时候,我就可以整理了

注意:我对使用第三方库不感兴趣;我这样做是为了学习WebGL

<!DOCTYPE html>
<html>
  <head>
    <title>MySecondGame</title>
  </head>
  <body>
    <canvas width="1024" height="768"></canvas>

    <div style="display: none;">
      <img id="img-player" src="assets/player.png" />
    </div>

    <script id="vertex" type="x-shader">
      attribute vec2 aVertexPosition;

      void main() {
        gl_Position = vec4(aVertexPosition, 0.0, 1.0);
      }
    </script>
    <script id="fragment" type="x-shader">
      #ifdef GL_ES
      precision highp float;
      #endif

      uniform vec4 uColor;

      void main() {
        gl_FragColor = uColor;
      }
    </script>

    <script type="application/dart">
      import 'dart:async';
      import 'dart:html';
      import 'dart:math';
      import 'dart:typed_data';
      import 'dart:web_gl';

      Game game;

      main() {
        game = new Game(document.querySelector('canvas'));
      }

      class Game {
        RenderingContext _gl;
        Buffer vbuffer;
        int numItems;
        Texture playerTexture;
        double elapsedTime;
        double fadeAmount;

        Game(CanvasElement canvas) {
          _gl = canvas.getContext3d();
          playerTexture = _gl.createTexture();
          _gl.bindTexture(TEXTURE_2D, playerTexture);
          _gl.texImage2DUntyped(TEXTURE_2D, 0, RGBA, RGBA, UNSIGNED_BYTE, document.querySelector('#img-player'));
          _gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
          _gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR_MIPMAP_NEAREST);
          _gl.generateMipmap(TEXTURE_2D);
          _gl.bindTexture(TEXTURE_2D, null);

          var vsScript = document.querySelector('#vertex');
          var vs = _gl.createShader(VERTEX_SHADER);
          _gl.shaderSource(vs, vsScript.text);
          _gl.compileShader(vs);

          var fsScript = document.querySelector('#fragment');
          var fs = _gl.createShader(FRAGMENT_SHADER);
          _gl.shaderSource(fs, fsScript.text);
          _gl.compileShader(fs);

          var program = _gl.createProgram();
          _gl.attachShader(program, vs);
          _gl.attachShader(program, fs);
          _gl.linkProgram(program);

          if (!_gl.getShaderParameter(vs, COMPILE_STATUS))
            print(_gl.getShaderInfoLog(vs));

          if (!_gl.getShaderParameter(fs, COMPILE_STATUS))
            print(_gl.getShaderInfoLog(fs));

          if (!_gl.getProgramParameter(program, LINK_STATUS))
            print(_gl.getProgramInfoLog(program));

          var aspect = canvas.width / canvas.height;
          var vertices = new Float32List.fromList([
            -0.5, 0.5 * aspect, 0.5, 0.5 * aspect,  0.5, -0.5 * aspect,  // Triangle 1
            -0.5, 0.5 * aspect, 0.5,-0.5 * aspect, -0.5, -0.5 * aspect   // Triangle 2
          ]);

          vbuffer = _gl.createBuffer();
          _gl.bindBuffer(ARRAY_BUFFER, vbuffer);                                       
          _gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW);
          numItems = vertices.length ~/ 2;

          _gl.useProgram(program);

          var uColor = _gl.getUniformLocation(program, "uColor");
          _gl.uniform4fv(uColor, new Float32List.fromList([0.0, 0.3, 0.0, 1.0]));

          var aVertexPosition = _gl.getAttribLocation(program, "aVertexPosition");
          _gl.enableVertexAttribArray(aVertexPosition);
          _gl.vertexAttribPointer(aVertexPosition, 2, FLOAT, false, 0, 0);

          window.animationFrame.then(_gameLoop);
        }

        _gameLoop(num time) {
          elapsedTime = time;
          _update();
          _render();
          window.animationFrame.then(_gameLoop);
        }

        _update() {
          // Use sine curve for fading. Sine is -1-1, so tweak to be 0 - 1.
          fadeAmount = (sin(elapsedTime/1000) / 2) + 0.5;
        }

        _render() {
          // Set colour for clearing to.
          _gl.clearColor(fadeAmount, 1 - fadeAmount, 0.0, 1.0);
          // Clear.
          _gl.clear(RenderingContext.COLOR_BUFFER_BIT);

          _gl.bindTexture(TEXTURE_2D, playerTexture);
          _gl.drawArrays(TRIANGLES, 0, numItems);
          _gl.bindTexture(TEXTURE_2D, null);
        }
      }
    </script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

MySecondName
属性向量2;
void main(){
gl_位置=vec4(0.0,1.0);
}
#国际财务报告准则
高精度浮点;
#恩迪夫
均匀的维柯色;
void main(){
gl_FragColor=uColor;
}
导入“dart:async”;
导入“dart:html”;
导入“dart:math”;
导入“dart:键入的_数据”;
导入“dart:web_gl”;
游戏;
main(){
游戏=新游戏(document.querySelector('canvas');
}
班级游戏{
渲染上下文_gl;
缓冲区缓冲区;
int numItems;
纹理织物;
双延时;
双法德蒙特;
游戏(CanvasElement画布){
_gl=canvas.getContext3d();
playerTexture=_gl.createTexture();
_gl.bindTexture(纹理2D,playerTexture);
_gl.texImage2Untyped(纹理2D,0,RGBA,RGBA,无符号字节,document.querySelector('img player'));
_gl.texParameteri(纹理2D,纹理贴图过滤器,最近的);
_gl.texParameteri(纹理2D、纹理最小过滤器、线性MIPMAP最近);
_gl.generateMipmap(纹理_2D);
_gl.bindTexture(纹理为2D,空);
var vsScript=document.querySelector(“#vertex”);
var vs=_gl.createShader(顶点着色器);
_gl.shaderSource(vs,vsScript.text);
_总帐编译主管(vs);
var fsScript=document.querySelector('#fragment');
var fs=_gl.createShader(片段着色器);
_gl.shaderSource(fs,fsScript.text);
_总帐编辑主任(fs);
var program=_gl.createProgram();
_总分类:attachShader(项目,vs);
_总承包商助理(项目,财政司);
_总账链接程序(程序);
if(!\u总账getShaderParameter(vs,编译状态))
打印(_gl.getShaderInfoLog(vs));
if(!\u总账getShaderParameter(fs,编译状态))
打印(_gl.getShaderInfoLog(fs));
if(!\u总账getProgramParameter(程序、链接状态))
打印(_gl.getProgramInfoLog(程序));
var aspect=canvas.width/canvas.height;
var顶点=新Float32List.fromList([
-0.5,0.5*纵横比,0.5,0.5*纵横比,0.5,-0.5*纵横比,//三角形1
-0.5,0.5*纵横比,0.5,-0.5*纵横比,-0.5,-0.5*纵横比//三角形2
]);
vbuffer=_gl.createBuffer();
_gl.bindBuffer(数组_BUFFER,vbuffer);
_gl.bufferData(数组缓冲区、顶点、静态绘制);
numItems=顶点.length~/2;
_gl.useProgram(程序);
变量uColor=_gl.getUniformLocation(程序,“uColor”);
_gl.uniform4fv(uColor,新Float32List.fromList([0.0,0.3,0.0,1.0]);
var aVertexPosition=_gl.GetAttriblLocation(程序,“aVertexPosition”);
_gl.EnableVertexAttributeArray(可编程逻辑阵列);
_gl.VertexAttributePointer(1,2,FLOAT,false,0,0);
然后(_gameLoop);
}
_gameLoop(num时间){
elapsedTime=时间;
_更新();
_render();
然后(_gameLoop);
}
_更新(){
//使用正弦曲线进行衰减。正弦为-1-1,因此调整为0-1。
fadeAmount=(sin(elapsedTime/1000)/2)+0.5;
}
_render(){
//设置清除颜色。
_gl.clearColor(fadeAmount,1-fadeAmount,0.0,1.0);
//清楚。
_gl.clear(RenderingContext.COLOR\u BUFFER\u位);
_gl.bindTexture(纹理2D,playerTexture);
_gl.绘图阵列(三角形,0,numItems);
_gl.bindTexture(纹理为2D,空);
}
}

(也用
opengl
标记它,因为我相信解决方案很可能与WebGL/opengl相同)。

好的,成功地实现了这一点。你可以

我可能错了;但我似乎希望在设置缓冲区时设置缓冲区中的数据;但我找不到任何方法来说明哪些数据是针对哪个缓冲区的。我将代码拆分为一些设置代码:

vbuffer = _gl.createBuffer();
_gl.bindBuffer(ARRAY_BUFFER, vbuffer);
_gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW);
numItems = vertices.length ~/ 2;

tbuffer = _gl.createBuffer();
_gl.bindBuffer(ARRAY_BUFFER, tbuffer);                                       
_gl.bufferData(ARRAY_BUFFER, textureCoords, STATIC_DRAW);

aVertexPosition = _gl.getAttribLocation(program, "aVertexPosition");
_gl.enableVertexAttribArray(aVertexPosition);

aTextureCoord = _gl.getAttribLocation(program, "aTextureCoord");
_gl.enableVertexAttribArray(aTextureCoord);

uSampler = _gl.getUniformLocation(program, "uSampler");
和一些渲染代码:

_gl.bindBuffer(ARRAY_BUFFER, vbuffer);
_gl.vertexAttribPointer(aVertexPosition, 2, FLOAT, false, 0, 0);

_gl.bindBuffer(ARRAY_BUFFER, tbuffer);
_gl.vertexAttribPointer(aTextureCoord, 2, FLOAT, false, 0, 0);

_gl.bindTexture(TEXTURE_2D, playerTexture);
_gl.uniform1i(uSampler, 0);

_gl.drawArrays(TRIANGLES, 0, numItems);
我不完全确定这是否正确(感觉好像每帧都发送相同的顶点和纹理命令),但它工作正常


?@gman谢谢;还没看过这个,就要看穿了!你没有每帧发送任何数据。你告诉WebGL你已经发送了哪些数据要使用。@gman哦,是的!我知道纹理就是这样,但不知怎的把我的顶点缓冲区和实际数组搞混了。这是一个漫长的下午!:)@gman在其他方面看起来是否相同;我在设置和循环中得到了正确的代码吗?是的,看起来很正常。大多数人可能会在这里添加矩阵乘法
gl_Position=vec4(0.0,1.0)