在 openGL 中绘制二维多边形
Drawing 2D polygons in openGL
我正在使用 DuoCode 尝试在 webGL 中绘制二维多边形。我为此编写了特定的着色器,它采用 2D 顶点和 z 位置以及一些其他数据:
<!-- Fragment shader program -->
<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);
}
</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>
在这种情况下,我禁用了纹理并尝试绘制一个白色多边形。着色器编译没有错误。
我这样创建我的顶点缓冲区:
public void UpdateBuffers()
{
System.Console.WriteLine("Updating buffers");
System.Console.Write("Vertices: ");
for (int i = 0; i < rotatedPoints.length; i++)
System.Console.Write(rotatedPoints[i] + ", ");
System.Console.WriteLine(" ");
System.Console.Write("texCoords: ");
for (int i = 0; i < texCoords.length; i++)
System.Console.Write(texCoords[i] + ", ");
System.Console.WriteLine(" ");
System.Console.Write("Triangles: ");
for (int i = 0; i < triangles.length; i++)
System.Console.Write(triangles[i] + ", ");
System.Console.WriteLine(" ");
gl.bindBuffer(GL.ARRAY_BUFFER, bVertexPositions);
gl.bufferData(GL.ARRAY_BUFFER, rotatedPoints.As<ArrayBufferView>(), GL.STATIC_DRAW);
gl.bindBuffer(GL.ARRAY_BUFFER, bTextureCoords);
gl.bufferData(GL.ARRAY_BUFFER, texCoords.As<ArrayBufferView>(), GL.STATIC_DRAW);
gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, bIndices);
gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, triangles.As<ArrayBufferView>(), GL.STATIC_DRAW);
}
再次没有错误,并给出以下输出:
Updating buffers
Vertices: 0, 0, 10, 0, 10, 10, 0, 10,
texCoords: 0, 1, 1, 1, 1, 0, 0, 0,
Triangles: 3, 0, 1, 3, 1, 2,
(顶点是 2 分量的)
我正在尝试像这样绘制一个多边形:
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);
这里a表示属性,u表示制服位置
绘图本身是这样的:
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);
}
JS 控制台再次没有错误。
不幸的是,屏幕只是保持黑色。我认为错误可能与顶点数组有 2 个组件这一事实有关,但我无法弄清楚。我以为我已经了解了 openGL 的基础知识,但显然我错了,因为这真的不应该是一个很难的问题。然而我什么也画不出来。如果你需要它,我可以 post 剩下的代码,比如缓冲区的创建,但我认为我的错误一定是在这段代码的某个地方。我希望这不会太过分 "find the bug somewhere in my code" post,但我真的不知道从这里该何去何从,我只是想不出我的错误。
编辑:发现我的错误,我将 int 传递给元素索引列表,但我将它们标记为 ushort
错误在这里:
gl.drawElements(GL.TRIANGLES, triangles.length, GL.UNSIGNED_SHORT, 0);
triangles 实际上是 int 类型,而不是 ushort
我正在使用 DuoCode 尝试在 webGL 中绘制二维多边形。我为此编写了特定的着色器,它采用 2D 顶点和 z 位置以及一些其他数据:
<!-- Fragment shader program -->
<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);
}
</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>
在这种情况下,我禁用了纹理并尝试绘制一个白色多边形。着色器编译没有错误。
我这样创建我的顶点缓冲区:
public void UpdateBuffers()
{
System.Console.WriteLine("Updating buffers");
System.Console.Write("Vertices: ");
for (int i = 0; i < rotatedPoints.length; i++)
System.Console.Write(rotatedPoints[i] + ", ");
System.Console.WriteLine(" ");
System.Console.Write("texCoords: ");
for (int i = 0; i < texCoords.length; i++)
System.Console.Write(texCoords[i] + ", ");
System.Console.WriteLine(" ");
System.Console.Write("Triangles: ");
for (int i = 0; i < triangles.length; i++)
System.Console.Write(triangles[i] + ", ");
System.Console.WriteLine(" ");
gl.bindBuffer(GL.ARRAY_BUFFER, bVertexPositions);
gl.bufferData(GL.ARRAY_BUFFER, rotatedPoints.As<ArrayBufferView>(), GL.STATIC_DRAW);
gl.bindBuffer(GL.ARRAY_BUFFER, bTextureCoords);
gl.bufferData(GL.ARRAY_BUFFER, texCoords.As<ArrayBufferView>(), GL.STATIC_DRAW);
gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, bIndices);
gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, triangles.As<ArrayBufferView>(), GL.STATIC_DRAW);
}
再次没有错误,并给出以下输出:
Updating buffers Vertices: 0, 0, 10, 0, 10, 10, 0, 10,
texCoords: 0, 1, 1, 1, 1, 0, 0, 0,
Triangles: 3, 0, 1, 3, 1, 2,
(顶点是 2 分量的)
我正在尝试像这样绘制一个多边形:
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);
这里a表示属性,u表示制服位置
绘图本身是这样的:
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);
}
JS 控制台再次没有错误。 不幸的是,屏幕只是保持黑色。我认为错误可能与顶点数组有 2 个组件这一事实有关,但我无法弄清楚。我以为我已经了解了 openGL 的基础知识,但显然我错了,因为这真的不应该是一个很难的问题。然而我什么也画不出来。如果你需要它,我可以 post 剩下的代码,比如缓冲区的创建,但我认为我的错误一定是在这段代码的某个地方。我希望这不会太过分 "find the bug somewhere in my code" post,但我真的不知道从这里该何去何从,我只是想不出我的错误。
编辑:发现我的错误,我将 int 传递给元素索引列表,但我将它们标记为 ushort
错误在这里:
gl.drawElements(GL.TRIANGLES, triangles.length, GL.UNSIGNED_SHORT, 0);
triangles 实际上是 int 类型,而不是 ushort