Dart WebGL窗口渲染不起作用

时间:2013-12-19 19:54:00

标签: opengl-es rendering webgl dart viewport

我正在尝试深入研究dart的Web GL支持,但我无法让它发挥作用。我熟悉java中的“旧版”OpenGL(没有着色器等),我对GL的工作原理非常了解。

但是,我的dart WebGL代码有问题,我似乎无法解决。 这是我的代码:

import 'dart:html';
import 'dart:web_gl' as WebGL;
import 'dart:typed_data';
import 'dart:math';
import 'package:vector_math/vector_math.dart';

WebGL.RenderingContext gl;
CanvasElement canvas;
Quad quad;

void main() {
  canvas = querySelector("#game_canvas");
  gl = canvas.getContext("experimental_webgl");
  if (gl == null) {
    gl = canvas.getContext("webgl");
  }
  if (gl == null) {
    canvas.remove();
    querySelector("#error_log").text = "No WebGL";
    return;
  }

  quad = new Quad(new Shader("""
precision highp float;

attribute vec3 a_pos;

uniform mat4 u_transform;
uniform mat4 u_view;

void main() {
  gl_Position = u_view * u_transform * vec4(a_pos, 1.0);
}
""", """
precision highp float;

uniform vec4 u_color;

void main() {
  gl_FragColor = u_color;
}
"""
));

  gl.enable(WebGL.DEPTH_TEST);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  render();
}

void render() {

  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clear(WebGL.COLOR_BUFFER_BIT | WebGL.DEPTH_BUFFER_BIT);

  Matrix4 view = makePerspectiveMatrix(70.0*PI/180.0, canvas.width / canvas.height,         0.1, 100.0);


 quad.setView(view);

  quad.render(new Vector3(150.0, 150.0, 30.0), 100, 100, new Vector4(1.0, 0.0, 0.0, 1.0));
  //quad.render(new Vector3(450.0, 150.0, 0.0), 100, 100, new Vector4(0.0, 1.0, 1.0, 1.0));
}

class Quad {

  Shader shader;
  int posLocation;
  WebGL.UniformLocation transformLocation, colorLocation, viewLocation;

  Quad(this.shader) {
    posLocation = gl.getAttribLocation(shader.program, "a_pos");
    transformLocation = gl.getUniformLocation(shader.program, "u_transform");
    colorLocation = gl.getUniformLocation(shader.program, "u_color");
    viewLocation = gl.getUniformLocation(shader.program, "u_view");

    Float32List vertexArray = new Float32List(4 * 3);
    vertexArray.setAll(0 * 3, [0.0, 0.0, 0.0]);
    vertexArray.setAll(1 * 3, [1.0, 0.0, 0.0]);
    vertexArray.setAll(2 * 3, [1.0, 1.0, 0.0]);
    vertexArray.setAll(3 * 3, [0.0, 1.0, 0.0]);

    Int16List indexArray = new Int16List(6);
    indexArray.setAll(0, [0, 1, 2, 0, 2, 3]);

    gl.useProgram(shader.program);
    gl.enableVertexAttribArray(posLocation);
    WebGL.Buffer vertexBuffer = gl.createBuffer();
    gl.bindBuffer(WebGL.ARRAY_BUFFER, vertexBuffer);
    gl.bufferDataTyped(WebGL.ARRAY_BUFFER, vertexArray, WebGL.STATIC_DRAW);
    gl.vertexAttribPointer(posLocation, 3, WebGL.FLOAT, false, 0, 0);

    WebGL.Buffer indexBuffer = gl.createBuffer();
    gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferDataTyped(WebGL.ELEMENT_ARRAY_BUFFER, indexArray, WebGL.STATIC_DRAW);
    gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, indexBuffer);
  }

  void setView(Matrix4 view) {
    gl.uniformMatrix4fv(viewLocation, false, view.storage);
  }

  Matrix4 matrix = new Matrix4.identity();

  void render(Vector3 pos, int w, int h, Vector4 color) {

    matrix.setIdentity();
    matrix.translate(pos.x - w / 2.0, pos.y - h / 2.0, pos.z);
    matrix.scale(w * 1.0, h * 1.0, 0.0);
    gl.uniformMatrix4fv(transformLocation, false, matrix.storage);

    gl.uniform4fv(colorLocation, color.storage);
    gl.drawElements(WebGL.TRIANGLES, 6, WebGL.UNSIGNED_SHORT, 0);
  }
}

class Shader {

  String vsSource, fsSource;
  WebGL.Shader vertexShader, fragmentShader;
  WebGL.Program program;

  Shader(this.vsSource, this.fsSource) {
    compile();
  }

  void compile() {
    vertexShader = gl.createShader(WebGL.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vsSource);
    gl.compileShader(vertexShader);
    if (!gl.getShaderParameter(vertexShader, WebGL.COMPILE_STATUS)) {
      throw gl.getShaderInfoLog(vertexShader);
    }

    fragmentShader = gl.createShader(WebGL.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fsSource);
    gl.compileShader(fragmentShader);
    if (!gl.getShaderParameter(fragmentShader, WebGL.COMPILE_STATUS)) {
      throw gl.getShaderInfoLog(fragmentShader);
    }

    program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, WebGL.LINK_STATUS)) {
      throw gl.getProgramInfoLog(program);
    }
  }
}

和我的html文件:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="test.css">
  </head>
  <body>

    <p id="error_log"></p>

    <div>
      <canvas id="game_canvas" width="600" height="300"></canvas>
    </div>

    <script type="application/dart" src="test.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

我得到的只是一个完全黑色(颜色取决于清晰的颜色)窗口。在java中工作时遇到了类似的问题,然后是导致它的视口。

但是,我不确定这是不是问题。

1 个答案:

答案 0 :(得分:1)

替换此行

quad.render(new Vector3(150.0, 150.0, 30.0), 100, 100, new Vector4(1.0, 0.0, 0.0, 1.0));

quad.render(new Vector3(0.0, 0.0, -80.0), 100, 100, new Vector4(1.0, 0.0, 0.0, 1.0));

然后你会看到红色方块。

您创建了以(0.5,0.5,0.0)为中心的1x1广场:

vertexArray.setAll(0 * 3, [0.0, 0.0, 0.0]);
vertexArray.setAll(1 * 3, [1.0, 0.0, 0.0]);
vertexArray.setAll(2 * 3, [1.0, 1.0, 0.0]);
vertexArray.setAll(3 * 3, [0.0, 1.0, 0.0]);

然后你按(100x,100x,0x)缩放它:

// quad.render(new Vector3(0.0, 0.0, -80.0), 100, 100 ...
// w=100 h=100
matrix.scale(w * 1.0, h * 1.0, 0.0);

注意重新调整的方形中心现在是(50,50,0)。

然后你翻译了(-50,-50,-80):

// quad.render(new Vector3(0.0, 0.0, -80.0), 100, 100 ...
// w=100 h=100 pos=0,0,-80
matrix.translate(pos.x - w / 2.0, pos.y - h / 2.0, pos.z);

所以你创建了一个以(0,0,-80)

为中心的100x100广场