var gl;
var canvas;
var shaderProgram;
var triangleVertexBuffer;
var triangleVertexColorBuffer;
var stripElementBuffer;
var stripVertexBuffer;
//Declare new variables here
function createGLContext(canvas) {
var names = ["webgl", "experimental-webgl"];
var context = null;
for (var i=0; i < names.length; i++) {
try {
context = canvas.getContext(names[i]);
} catch(e) {}
if (context) {
break;
}
}
if (context) {
context.viewportWidth = canvas.width;
context.viewportHeight = canvas.height;
} else {
alert("Failed to create WebGL context!");
}
return context;
}
function loadShaderFromDOM(id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var shaderSource = "";
var currentChild = shaderScript.firstChild;
while (currentChild) {
if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
shaderSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
function setupShaders() {
vertexShader = loadShaderFromDOM("shader-vs");
fragmentShader = loadShaderFromDOM("shader-fs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Failed to setup shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
// For the triangle we want to use per-vertex color so
// the vertexColorAttribute, aVertexColor, in the vertex shader
// is enabled.
// You must enable this attribute here or in draw method before the
//triangle is drawn
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
}
function setupBuffers() {
triangleVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBuffer);
var triangleVertices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
triangleVertexBuffer.itemSize = 3;
triangleVertexBuffer.numberOfItems = 3;
// Triangle vertex colours
triangleVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
var colors = [
1.0, 0.0, 0.0, 1.0, //v0
0.0, 1.0, 0.0, 1.0, //v1
0.0, 0.0, 1.0, 1.0 //v2
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
triangleVertexColorBuffer.itemSize = 4;
triangleVertexColorBuffer.numberOfItems = 3;
// Add new items: the followings are newly added items
//hexagon vertices
hexagonVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, hexagonVertexBuffer);
var hexagonVertices = [
-0.3, 0.6, 0.0, //v0
-0.4, 0.8, 0.0, //v1
-0.6, 0.8, 0.0, //v2
-0.7, 0.6, 0.0, //v3
-0.6, 0.4, 0.0, //v4
-0.4, 0.4, 0.0, //v5
-0.3, 0.6, 0.0, //v6
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(hexagonVertices), gl.STATIC_DRAW);
hexagonVertexBuffer.itemSize = 3;
hexagonVertexBuffer.numberOfItems = 7;
//Triangle strip vertices.
stripVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, stripVertexBuffer);
var stripVertices = [
-0.5, 0.2, 0.0, //v0
-0.4, 0.0, 0.0, //v1
-0.3, 0.2, 0.0, //v2
-0.2, 0.0, 0.0, //v3
-0.1, 0.2, 0.0, //v4
0.0, 0.0, 0.0, //v5
0.1, 0.2, 0.0, //v6
0.2, 0.0, 0.0, //v7
0.3, 0.2, 0.0, //v8
0.4, 0.0, 0.0, //v9
0.5, 0.2, 0.0, //v10
// Second strip
-0.5, -0.3, 0.0, //v11
-0.4, -0.5, 0.0, //v12
-0.3, -0.3, 0.0, //v13
-0.2, -0.5, 0.0, //v14
-0.1, -0.3, 0.0, //v15
0.0, -0.5, 0.0, //v16
0.1, -0.3, 0.0, //v17
0.2, -0.5, 0.0, //v18
0.3, -0.3, 0.0, //v19
0.4, -0.5, 0.0, //v20
0.5, -0.3, 0.0 //v21
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(stripVertices), gl.STATIC_DRAW);
stripVertexBuffer.itemSize = 3;
stripVertexBuffer.numberOfItems = 22;
// Strip vertex indices
stripElementBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, stripElementBuffer);
var indices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
// put correct indices here. Use degenerated triangles to link the
// strips together
];
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
stripElementBuffer.numberOfItems = 25;
}
function draw() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw triangle. No change is made to the last week's code here
// For the triangle we want to use per-vertex color so
// the vertexColorAttribute, aVertexColor, in the vertex shader
// is enabled
// gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
// Make vertex buffer "triangleVertexBuffer" the current buffer
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBuffer);
// Link the current buffer to the attribute "aVertexPosition" in
// the vertex shader
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// Make color buffer "triangleVertexColorBuffer" the current buffer
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
// Link the current buffer to the attribute "aVertexColor" in
// the vertex shader
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexBuffer.numberOfItems);
gl.drawElements(gl.TRIANGLE_STRIP, 0, stripVertexBuffer.numberOfItems, 25);
// Draw the newly added items
}
function startup() {
canvas = document.getElementById("myGLCanvas");
gl = createGLContext(canvas);
setupShaders();
setupBuffers();
gl.clearColor(1.0, 1.0, 1.0, 1.0);
draw();
}
startup();
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
varying vec4 vColor;
void main() {
vColor = aVertexColor;
gl_Position = vec4(aVertexPosition, 1.0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
</script>
<canvas id="myGLCanvas" width="250" height="250"></canvas>
嘿伙计们。 WEBGL的新手,尝试绘制三角形条带但不知道如何处理这个问题。
我所知道的:
gl.TRIANGLE_STRIP
模式绘制时,缓冲区中顶点坐标或索引的顺序非常重要。答案 0 :(得分:1)
代码中的这两行没有任何意义
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexBuffer.numberOfItems);
gl.drawElements(gl.TRIANGLE_STRIP, 0, stripVertexBuffer.numberOfItems, 25);
通常无需在两者之间进行任何更改就调用绘图是没有意义的,因为绘制2件事需要设置不同的数据。
此外,第二行是完全错误的
gl.drawElements(gl.TRIANGLE_STRIP, 0, stripVertexBuffer.numberOfItems, 25);
如果您打开了JavaScript控制台,则会看到类似
的错误有几个问题
代码将错误值传递给type
gl.drawElements
参数
gl.drawElements
的类型参数是当前ELEMENT_ARRAY_BUFFER
中的数据类型。
第二个参数是计数。
它传递了顶点数(stripVertexBuffer.numberOfItems
)而不是索引数(stripElementBuffer.numberOfItems
)
它应该是这样的
{
const primitive = gl.TRIANGLE_STRIP;
const count = stripElementBuffer.numberOfItems;
const offset = 0;
const indexType = gl.UNSIGNED_SHORT;
gl.drawElements(primitive, count, indexType, offset);
}
修复它虽然不够,因为代码实际上并没有将索引放在索引缓冲区中。那段代码
// Strip vertex indices
stripElementBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, stripElementBuffer);
var indices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
// put correct indices here. Use degenerated triangles to link the
// strips together
];
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
stripElementBuffer.numberOfItems = 25;
也毫无意义。索引是从0到N的无符号整数值,其中N小于绑定到属性的顶点数。此外,只输入了9个值,但代码集stripElementBuffer.numberOfItems
为25 ..?
然后,除此之外,代码没有设置使用条带顶点的属性。
在WebGL中绘制多个内容就像这样
for each thing you want to draw
gl.useProgram(theProgramYouWantToDrawWith);
// setup attributes
for each attribute
gl.bindBuffer(gl.ARRAY_BUFFER, bufferWithDataForAttribute);
gl.enableVertexAttribArray(attribLocation);
gl.vertexAttribPointer(attribLocation, ... how to get data out of buffer ...)
// if using indices setup the ELEMENT_ARRAY_BUFFER
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferWithIndices);
// setup textures
for each texture you're going to draw with
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_??, someTexture);
// setup uniforms
for each uniform
gl.uniformXXX(...)
// draw
gl.drawXXX (either gl.drawArrays or gl.drawElements)
在您尝试退化三角形条之前,您需要修复代码以遵循该模式。另外here's some other tutorials you might find helpful