You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebGL使用gl.TRIANGLES绘制正方形失败,求提示(附代码)

WebGL 同一缓冲区存储顶点位置与颜色,使用gl.TRIANGLES绘制正方形仅显示三角形的问题

我尝试在WebGL中将顶点位置与颜色数据存入同一缓冲区,用gl.TRIANGLES绘制正方形,但最终只显示出三角形。不清楚代码哪里出错,同时对drawArrays中的count参数作用有疑问,希望得到相关提示而非直接答案。

相关代码片段:

缓冲区数据配置

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
   // position
    -0.9, 0.9, 
    0.9, 0.9,
    -0.9, -0.9,
    0.9, 0.9,
   // color
   1, 0, 0, 1,
   0, 1, 0, 1,
   1, 0, 1, 1,
   1, 0, 0, 1
   ]), gl.STATIC_DRAW);

顶点属性指针配置

gl.enableVertexAttribArray(positionLocation);
gl.enableVertexAttribArray(colorLocation);

var size = 2;
var type = gl.FLOAT;
var normalize = false;
var stride = 0;
var offset = 0;
gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

var size = 4;
var type = gl.FLOAT;
var normalize = false;
var stride = 0;
var offset = Float32Array.BYTES_PER_ELEMENT * 8; 
gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset);

绘制代码

// Draw the geometry.
var offset = 0;
var count = 3;
gl.drawArrays(gl.TRIANGLES, offset, count);

完整代码

<!DOCTYPE html>
<html>
<head>
  <title>CS299 - Assignment 1.1</title>
  <link type="text/css" href="https://webgl2fundamentals.org/webgl/resources/webgl-tutorials.css" rel="stylesheet" />
  <!-- css override -->
  <style type="text/css">
  body { background-color: #CCCCCC; }
  #group {background-color: #E8F49F;}
  canvas { background-color: #4DC72F; width: 300px; height: 300px; border: 0px; }
  .gman-widget-slider {min-width: 200px;}
</style>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>

<!-- util functions -->
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script>

<!-- main WebGL2 code -->
<script>
  "use strict";

  var vs = `#version 300 es
  
  // an attribute is an input (in) to a vertex shader.
  // It will receive data from a buffer
  in vec2 a_position;
  in vec4 a_color;
  
  // color output from vertex shader to fragment shader
  out vec4 v_color;

  // all shaders have a main function.
  void main() {
    
    // default position output variable
    // convert vec2 to vec4
    gl_Position = vec4(a_position, 0, 1);
    
    // color passthrough
    v_color = a_color;
  }
  `;

  var fs = `#version 300 es

  precision highp float;

  // color passthrough
  in vec4 v_color;
  
  // outout color 
  out vec4 outColor;

  void main() {
    outColor = v_color;
  }
  `;

  function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  var canvas = document.querySelector("#canvas");
  var gl = canvas.getContext("webgl2");
  if (!gl) {
    return;
  }

  // setup GLSL program
  var program = webglUtils.createProgramFromSources(gl, [vs, fs]);

  // look up where the vertex data needs to go.
  var positionLocation = gl.getAttribLocation(program, "a_position");
  var colorLocation = gl.getAttribLocation(program, "a_color");
  

  // Create set of attributes
  var vao = gl.createVertexArray();
  gl.bindVertexArray(vao);

  // Create a buffer (formerly called "vertex buffer object", now just "buffer").
  var vbo = gl.createBuffer();
  
  // Set Geometry.
  gl.bindBuffer(gl.ARRAY_BUFFER, vbo);

  // [40%] Modify the code to draw a square instead of a triangle. 
  // Assign C,M,Y, and K colors to the 4 vertices of the square. 
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
   // position
    -0.9, 0.9, 
    0.9, 0.9,
    -0.9, -0.9,
    0.9, 0.9,
   // color
   1, 0, 0, 1,
   0, 1, 0, 1,
   1, 0, 1, 1,
   1, 0, 0, 1
   ]), gl.STATIC_DRAW);

   // tell the position attribute how to pull data out of the current ARRAY_BUFFER
  gl.enableVertexAttribArray(positionLocation);
  gl.enableVertexAttribArray(colorLocation);

  var size = 2;
  var type = gl.FLOAT;
  var normalize = false;
  var stride = 0;
  var offset = 0;
  gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

  var size = 4;
  var type = gl.FLOAT;
  var normalize = false;
  var stride = 0;
  var offset = Float32Array.BYTES_PER_ELEMENT * 8; // must be in bytes
  gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset);

  // Draw the scene.
  function drawScene() {
    webglUtils.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    // Clear the canvas
    gl.clearColor(0.15, 0.15, 0.15, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    // Tell it to use our program (pair of shaders)
    gl.useProgram(program);

    // Bind the attribute/buffer set we want.
    gl.bindVertexArray(vao);

    // Draw the geometry.
    var offset = 0;
    var count = 3;

    // [1.5 points] Use gl.TRIANGLE_STRIP instead of gl.TRIANGLES
    gl.drawArrays(gl.TRIANGLES, offset, count);
  }

  drawScene();
}

main();
</script>

<p id="group">Group: 4DC72F</p>
</html>

提示方向

  • 回忆gl.TRIANGLES的绘制逻辑:每3个连续顶点构成一个独立三角形,绘制正方形需要多少个顶点才能组成两个三角形?
  • 确认drawArrays的count参数含义:它指定的是参与绘制的顶点总个数,而非三角形的数量。
  • 检查缓冲区的数据布局:当前你把所有位置数据放在前面,所有颜色数据放在后面,这种布局下,vertexAttribPointer的stride参数设置是否匹配?当stride=0时,WebGL会认为每个顶点的所有属性是连续存放的。
  • 检查顶点完整性:你准备的位置顶点是否包含正方形的四个顶点?当前的位置数组里有没有重复或缺失的顶点?

内容的提问来源于stack exchange,提问作者Powzer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:36:29