试图让webGL(2d)绘图工作。看不到我的三角形

时间:2015-03-05 16:17:02

标签: javascript opengl-es webgl

我正在尝试通过webgl绘制一个简单的四边形。以下是一些数据:

顶点数据:(每个顶点2个浮点数) 0:0
1:0
2:1
3:0
4:1
5:1
6:0
7:1

tex coords :(并不重要) 0:-1
1:1
2:1
3:1
4:1
5:-1
6:-1
7:-1

指数: 0:3
1:0
2:1
3:3
4:1
5:2

着色器:

<script id="shader-fs" type="x-shader/x-fragment">
    varying highp vec2 vTextureCoord;
    uniform highp vec3 uColor;
    uniform sampler2D uSampler;
    uniform int uSamplerCount;

    void main(void) {
    highp vec4 texColor =vec4(uColor, 1.0);
    if(uSamplerCount > 0)
        texColor = texture2D(uSampler, vTextureCoord);

    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); //just white for now
    }
</script>

<!-- Vertex shader program -->
<script id="shader-vs" type="x-shader/x-vertex">
    attribute highp vec2 aVertexPosition;
    attribute highp vec2 aTextureCoord;

    uniform highp vec2 uPosition;
    uniform highp float uZLayer;

    varying highp vec2 vTextureCoord;

    void main(void) {
    gl_Position = vec4(uPosition + aVertexPosition, uZLayer, 1.0);
    vTextureCoord = aTextureCoord;
    }
</script>

对我来说这似乎没问题。现在我在这里绑定缓冲区:

$p.UpdateBuffers = function ConvexSprite_UpdateBuffers() {
    this.gl.bindBuffer(34962 /* WebGLRenderingContext.ARRAY_BUFFER */, this.bVertexPositions);
    this.gl.bufferData(34962 /* WebGLRenderingContext.ARRAY_BUFFER */, this.rotatedPoints, 35044 /* WebGLRenderingContext.STATIC_DRAW */);

    // string s = rotatedPoints.join(",");
    // System.Console.WriteLine("Vertices: " + s);
    this.gl.bindBuffer(34962 /* WebGLRenderingContext.ARRAY_BUFFER */, this.bTextureCoords);
    this.gl.bufferData(34962 /* WebGLRenderingContext.ARRAY_BUFFER */, this.texCoords, 35044 /* WebGLRenderingContext.STATIC_DRAW */);
    //System.Console.WriteLine("Texcoords: " + texCoords.join(","));
    this.gl.bindBuffer(34963 /* WebGLRenderingContext.ELEMENT_ARRAY_BUFFER */, this.bIndices);
    this.gl.bufferData(34963 /* WebGLRenderingContext.ELEMENT_ARRAY_BUFFER */, this.triangles, 35044 /* WebGLRenderingContext.STATIC_DRAW */);
};

这就是我的绘画方式:

private void DrawScene()
    {
        gl.viewport(0, 0, (int)canvas.width, (int)canvas.height);
        gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
        testSprite.Draw(aVertexPosition, aTextureCoord, uColor, uPosition, uZLayer, uSampler, uSamplerCount);
    }

绘制功能:

public void Draw(uint aVertexPosition, uint aTextureCoord,
        WebGLUniformLocation uColor, WebGLUniformLocation uPosition, WebGLUniformLocation uZLayer, WebGLUniformLocation uSampler, WebGLUniformLocation uSamplerCount)
    {

        //position
        gl.uniform2f(uPosition, this.position.x, this.position.y);
        gl.uniform1f(uZLayer, this.position.z);
        gl.uniform3f(uColor, 1f, 0.5f, 0.5f);
        gl.uniform1i(uSamplerCount, 0);

        //vertex data
        gl.bindBuffer(GL.ARRAY_BUFFER, bVertexPositions);
        gl.vertexAttribPointer(aVertexPosition, 2, GL.FLOAT, false, 0, 0);

        gl.bindBuffer(GL.ARRAY_BUFFER, bTextureCoords);
        gl.vertexAttribPointer(aTextureCoord, 2, GL.FLOAT, false, 0, 0);

        gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, bIndices);

        //texture
       // gl.activeTexture(GL.TEXTURE0);
       // gl.bindTexture(GL.TEXTURE_2D, texture);
       // gl.uniform1i(uSampler, 0);

        //draw
        gl.drawElements(GL.TRIANGLES, triangles.length, GL.UNSIGNED_SHORT, 0);
    }

不幸的是,我得到的只是黑屏。三角形是ccw,并且在0-1位置范围内。这不应该吸引到屏幕上吗?我忘记了什么?

1 个答案:

答案 0 :(得分:1)

this.position.xthis.position.y的值是多少?假设您拥有最佳的0,1 quad,那么您将能够使用此着色器,并且这些顶点坐标在画布的1/4处绘制四边形。您需要输出的值必须在剪辑空间中(-1&lt; - &gt; +1)。

从像素转换为剪辑空间

clipX = pixelX / gl.canvas.width  * 2 - 1
clipY = pixelY / gl.canvas.height * 2 - 1

表示像素空间中的宽度和高度

clipWidth  = pixelWidth  / gl.canvas.width  * 2
clipHeight = pixelHeight / gl.canvas.height * 2

在调试未绘制的WebGL程序时,我做的第一件事就是将片段着色器更改为最简单的东西

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

如果我看到我想到的红色,我知道问题出在了碎片中。如果我不知道问题出在其他地方。

接下来,我可以使用WebGL Inspector来查看我在制服中传递的值。例如,如果this.position.xthis.position.y大于1或小于-2,则不会出现任何内容,因为您的四边形为0到1,因此0 + 1 = 1这意味着您的四边形将是在画布的右侧或顶部。 1 + -2 = -1在这种情况下,四边形将离开画布的左侧或底侧。

其他一些事情。您将其设置为白色gl_FragColor = vec4(1,1,1,1);,但默认网页颜色为白色,默认的清晰颜色为0,0,0,0(透明黑色),这意味着除非(a)制作没有alpha的画布(b)将显示的颜色设置为不显示的地方或(c)将页面或画布的CSS设置为您不会看到任何颜色的其他颜色。

这里有一些在像素位置绘制四边形的代码

&#13;
&#13;
"use strict";

window.onload = function() {
  // Get A WebGL context
  var canvas = document.getElementById("c");
  var gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  // setup GLSL program
  var program = webglUtils.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
  gl.useProgram(program);

  // look up where the vertex data needs to go.
  var positionLocation = gl.getAttribLocation(program, "a_position"); 
  
  // look up uniform locations
  var u_matrixLoc = gl.getUniformLocation(program, "u_matrix");
  var u_colorLoc = gl.getUniformLocation(program, "u_color");

  // provide texture coordinates for the rectangle.
  var positionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
      0.0,  0.0,
      1.0,  0.0,
      0.0,  1.0,
      0.0,  1.0,
      1.0,  0.0,
      1.0,  1.0]), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
  
  function rand(min, max) {
    return min + Math.random() * (max - min) | 0;
  }

  for (var ii = 0; ii < 300; ++ii) {
    var dstX = rand(0, gl.canvas.width - 20);
    var dstY = rand(0, gl.canvas.height - 20);
    var dstWidth = rand(10, 30);
    var dstHeight = rand(10, 30);

    // convert dst pixel coords to clipspace coords      
    var clipX = dstX / gl.canvas.width  *  2 - 1;
    var clipY = dstY / gl.canvas.height * -2 + 1;
    var clipWidth = dstWidth  / gl.canvas.width  *  2;
    var clipHeight = dstHeight / gl.canvas.height * -2;

    // build a matrix that will stretch our
    // unit quad to our desired size and location
    gl.uniformMatrix3fv(u_matrixLoc, false, [
        clipWidth, 0, 0,
        0, clipHeight, 0,
        clipX, clipY, 1,
      ]);
      
    gl.uniform4f(u_colorLoc, Math.random(), Math.random(), Math.random(), 1);

    // Draw the rectangle.
    gl.drawArrays(gl.TRIANGLES, 0, 6);
  }
}
&#13;
canvas { 
  border: 1px solid black;
}
&#13;
<script src="//webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<canvas id="c"></canvas>  
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;

uniform mat3 u_matrix;

void main() {

   gl_Position = vec4(u_matrix * vec3(a_position, 1), 1);
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;

// our texture
uniform vec4 u_color;

void main() {
   gl_FragColor = u_color;
}
</script>
&#13;
&#13;
&#13;

如果你没有得到矩阵数学here's an article that explains it

另一个建议,而不是uSamplerCount的条件,你可能只考虑

gl_FragColor = uColor * texture2D(uSampler, vTextureCoord);

然后制作1像素的白色纹理

whiteTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, whiteTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, gl.RGBA, gl.UNSIGNED_BYTE,
              new Float32Array([255,255,255,255]));

现在每当你想用纯色绘制时,

gl.bindTexture(gl.TEXTURE_2D, whiteTex);
gl.uniform4f(uColorLocation, r, g, b, a);

每当你想用纹理绘制时

gl.bindTexture(gl.TEXTURE_2D, someTexture);
gl.uniform4f(uColorLocation, 1, 1, 1, 1);
相关问题