2014-10-05 8 views
4

저는 Dart와 WebGL을 사용하여 2D Sprite를 캔버스에 렌더링하는 데 어려움을 겪고 있습니다. 이 온라인 예제는 거의 찾을 수 없습니다. 대부분은 3D이거나 스파게티 코드 톤을 포함하고 있습니다. 스프라이트를 렌더링하는 가장 단순한 작업을 수행하려고합니다.WebGL을 사용하여 2D 스프라이트를 렌더링하는 방법은 무엇입니까?

지금까지 캔버스에 녹색 사각형 (두 개의 삼각형)을 렌더링했습니다. 내가 고민하고있는 비트는 녹색 사각형에서 내 텍스처를 사용하는 방법입니다 (질감이 올바르게로드되고 바운드 됨). 이것은 셰이더 (색 대신 텍스쳐 좌표를 취함)와 버퍼의 정점과 관련된 텍스처 좌표를 전달하기위한 것이 필요하다고 생각합니다.

이 코드 also exists in a Gist.

참고 : 이것은 단지 샘플입니다. 대부분의 코드는 생성자에 있습니다. 나는 그 코드가 얼마나 깔끔한 지에 너무 관심이 없다. 화면에 스프라이트를 볼 수있을 때 정리할 수 있습니다!

참고 : 제 3 자 라이브러리 사용에 관심이 없습니다. 나는 WebGL을 배우기 위해 이렇게하고있다! (필자는 솔루션 가능성이 WebGL을/OpenGL을위한 동일 생각도 있기 때문에 opengl에이 태그)

<!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> 

.

+0

[이 자습서를 시도] (http://webglfundamentals.org)? – gman

+0

@gman 감사합니다; 이 사람들을 보지 못했고, 통해 보일 것입니다! –

답변

1

좋아,이 작업을 관리 할 수 ​​있습니다. 당신은 see the full diff in a gist here 일 수 있습니다.

내가 잘못했을 수 있습니다. 하지만 내가 그들을 설정하는 동안 버퍼에 데이터를 설정할 것으로 예상했다 보인다; 그러나 어떤 데이터가 어떤 버퍼를위한 것인지 말할 수있는 방법을 찾지 못했습니다.

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); 

(이 느낌 textureCoord 모든 프레임),하지만 작동합니다.

I MADE A GAME!!!!111

+0

모든 프레임마다 데이터를 전송하지 않습니다. 이미 보낸 데이터를 WebGL에 사용하도록 지시합니다. – gman

+0

@gman 오, 그래! 나는 이것이 텍스쳐의 경우라는 것을 알았지 만, 내 버텍스 버퍼를 실제 배열과 혼동스럽게 만들었습니다. 긴 오후 였어! :) –

+0

@gman 달리 그렇지 않으면 보이나요? 루프에서 설치 대 올바른 코드를 얻었습니까? –

관련 문제