【问题标题】:OpenGL Point Functionality in WebGLWebGL 中的 OpenGL 点功能
【发布时间】:2017-03-17 21:33:46
【问题描述】:

在 OpenGL 中,您可以 draw 像这样定义点:

glBegin(GL_POINTS);
for(float theta=0, radius=60.0; radius>1.0; theta+=0.1, radius-=0.3){
   glColor3f(radius/60.0,0.3,1-(radius/60.0));
   glVertex2i(200+radius*cos(theta),200+radius*sin(theta));
}
glEnd();

您如何在 WebGL 中完成同样的功能?

【问题讨论】:

  • 你试过什么?你最喜欢的 WebGL 教程或书籍有什么建议?

标签: opengl-es webgl


【解决方案1】:

除了定义一些点之外,您编写的代码实际上并没有什么作用。在 WebGL 中这样做可以这样做

var colors = [];
var verts = [];
var theta=0 
for(var radius=60.0; radius>1.0; radius-=0.3) {
  colors.push(radius/60.0, 0.3, 1-(radius/60.0));
  verts.push(200+radius*Math.cos(theta),200+radius*Math.sin(theta));
  theta+=0.1;
}
var numPoints = colors.length / 3;

这将产生 2 个 JavaScript 数组。然后你需要把它们放到 WebGLBuffers

var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

var vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);

之后,您需要编写一个着色器并进行设置。着色器是一个巨大的话题。对于您的特定数据,我猜这些着色器会做

顶点着色器

uniform mat4 u_matrix;
attribute vec4 a_vertex;
attribute vec4 a_color;
varying vec4 v_color;

void main() {
  // Set the size of the point
  gl_PointSize = 3.0;

  // multiply each vertex by a matrix.
  gl_Position = u_matrix * a_vertex;

  // pass the color to the fragment shader
  v_color = a_color;
}

片段着色器

precision mediump float;
varying vec4 v_color;
void main() {
  gl_FragColor = v_color;
}

接下来您需要初始化着色器和参数。我将假设我将着色器放在 ID 为“vshader”和“fshader”以及use this boilerplate code 的脚本标签中以加载它们。

var program = createProgramFromScriptTags(gl, "vshader", "fshader");
gl.useProgram(program);

// look up the locations for the inputs to our shaders.
var u_matLoc = gl.getUniformLocation(program, "u_matrix");
var colorLoc = gl.getAttribLocation(program, "a_color");
var vertLoc = gl.getAttribLocation(program, "a_vertex");

// Set the matrix to some that makes 1 unit 1 pixel.
gl.uniformMatrix4fv(u_matLoc, false, [
  2 / width, 0, 0, 0,
  0, 2 / height, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
]);

// Tell the shader how to get data out of the buffers.
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorLoc);
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertLoc);

最后画点

gl.drawArrays(gl.POINTS, 0, numPoints);

这是一个sn-p

var canvas = document.getElementById("c");
var gl = canvas.getContext("webgl");
if (!gl) {
    alert("no WebGL");
    //return;
}

var colors = [];
var verts = [];
var theta=0 
for(var radius=160.0; radius>1.0; radius-=0.3) {
    colors.push(radius/160.0, 0.3, 1-(radius/160.0));
    verts.push(radius*Math.cos(theta),radius*Math.sin(theta));
    theta+=0.1;
}
var numPoints = colors.length / 3;

var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

var vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);

var program = twgl.createProgramFromScripts(gl, ["vshader", "fshader"]);
gl.useProgram(program);

// look up the locations for the inputs to our shaders.
var u_matLoc = gl.getUniformLocation(program, "u_matrix");
var colorLoc = gl.getAttribLocation(program, "a_color");
var vertLoc = gl.getAttribLocation(program, "a_vertex");

function draw() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.clearColor(1.0, 1.0, 1.0, 1.0);
    
 // Set the matrix to some that makes 1 unit 1 pixel.
gl.uniformMatrix4fv(u_matLoc, false, [
    2 / canvas.width, 0, 0, 0,
    0, -2 / canvas.height, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
]);
    
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorLoc);
    gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vertLoc);
    
    gl.drawArrays(gl.POINTS, 0, numPoints);
    
    requestAnimationFrame(draw, canvas);
}

draw();
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<script id="vshader" type="whatever">
    uniform mat4 u_matrix;
    attribute vec4 a_vertex;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main() {
      // Set the size of the point
      gl_PointSize = length(a_vertex) * 0.1;
    
      // multiply each vertex by a matrix.
      gl_Position = u_matrix * a_vertex;

      // pass the color to the fragment shader
      v_color = a_color;
    }    
</script>
<script id="fshader" type="whatever">
precision mediump float;
varying vec4 v_color;
void main() {
    gl_FragColor = v_color;
}
</script>
<canvas id="c" width="400" height="400"></canvas>

你可能会找到these WebGL tutorials helpful

【讨论】:

  • 感谢您的回答。我不确定如何绘制点,因为我看过的教程只指定了形状。我的问题是我没有为每个定义的顶点指定颜色(和我发现的纹理)。
【解决方案2】:

WebGL 基于 OpenGL ES 2.0(请参阅 here),它放弃了立即模式支持。

本规范描述了 HTML 5 画布元素 [CANVAS] 的附加渲染上下文和支持对象。此上下文允许使用非常符合 OpenGL ES 2.0 API 的 API 进行渲染。

您需要使用顶点缓冲区来存储顶点数据。请参阅here1 以获得关于在保留模式下如何工作的很好的解释。 there 是一个很好的小例子,可以帮助您入门。

1:向在这里发布此内容的人表示敬意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多