gpt4 book ai didi

webgl - 在 WebGL 中绘制许多形状

转载 作者:行者123 更新时间:2023-12-04 22:22:36 27 4
gpt4 key购买 nike

我正在阅读 here 的教程。

<script class = "WebGL">
var gl;
function initGL() {
// Get A WebGL context
var canvas = document.getElementById("canvas");
gl = getWebGLContext(canvas);
if (!gl) {
return;
}
}
var positionLocation;
var resolutionLocation;
var colorLocation;
var translationLocation;
var rotationLocation;
var translation = [50,50];
var rotation = [0, 1];
var angle = 0;
function initShaders() {
// setup GLSL program
vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");
program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);

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

// lookup uniforms
resolutionLocation = gl.getUniformLocation(program, "u_resolution");
colorLocation = gl.getUniformLocation(program, "u_color");
translationLocation = gl.getUniformLocation(program, "u_translation");
rotationLocation = gl.getUniformLocation(program, "u_rotation");

// set the resolution
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
}
function initBuffers() {
// Create a buffer.
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

// Set Geometry.
setGeometry(gl);
}

function setColor(red, green, blue) {
gl.uniform4f(colorLocation, red, green, blue, 1);
}
// Draw the scene.
function drawScene() {
// Clear the canvas.
gl.clear(gl.COLOR_BUFFER_BIT);

// Set the translation.
gl.uniform2fv(translationLocation, translation);
// Set the rotation.
gl.uniform2fv(rotationLocation, rotation);

// Draw the geometry.
gl.drawArrays(gl.TRIANGLES, 0, 6);
}


// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl) {
/*Assume size1 is declared*/
var vertices = [
-size1/2, -size1/2,
-size1/2, size1/2,
size1/2, size1/2,
size1/2, size1/2,
size1/2, -size1/2,
-size1/2, -size1/2 ];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(vertices),
gl.STATIC_DRAW);
}
function animate() {
translation[0] += 0.01;
translation[1] += 0.01;
angle += 0.01;
rotation[0] = Math.cos(angle);
rotation[1] = Math.sin(angle);
}
function tick() {
requestAnimFrame(tick);
drawScene();
animate();
}
function start() {

initGL();
initShaders();
initBuffers();
setColor(0.2, 0.5, 0.5);
tick();
}

</script>

<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;

uniform vec2 u_resolution;
uniform vec2 u_translation;
uniform vec2 u_rotation;
void main() {
vec2 rotatedPosition = vec2(
a_position.x * u_rotation.y + a_position.y * u_rotation.x,
a_position.y * u_rotation.y - a_position.x * u_rotation.x);

// Add in the translation.
vec2 position = rotatedPosition + u_translation;

// convert the position from pixels to 0.0 to 1.0
vec2 zeroToOne = position / u_resolution;

// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;

// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;

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

uniform vec4 u_color;

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

我的 1 个形状的 WebGL 程序的工作方式如下:
  • 从 Canvas 元素获取上下文 (gl)。
  • 用我的对象
  • 的形状初始化缓冲区
  • drawScene() : 调用 gl.drawArrays()
  • 如果有动画,一个更新函数,它更新我的形状的角度、位置、
    然后 drawScene() 都在 tick() 中,这样它就会被重复调用。

  • 现在,当我需要 1 个以上的形状时,是否应该一次用许多对象填充单个缓冲区,然后使用它稍后调用 drawScene() 一次绘制所有对象
    [或]
    我应该从 initBuffer 重复调用 drawScene()requestAnimFrame() 吗?

    最佳答案

    在伪代码中

    在初始化时

  • 从 Canvas 元素获取上下文 (gl)。
  • 每个着色器的

  • 创建着色器
  • 查找属性和统一位置
  • 每个形状的

  • 用形状
  • 初始化缓冲区
    每个纹理的

  • 创建纹理和/或用数据填充它们。

  • 抽奖时

    每个形状的

  • 如果最后使用的着色器与此形状所需的着色器不同,则调用 gl.useProgram
  • 着色器需要的每个属性
  • 使用当前着色器的属性位置为形状所需的每个属性调用 gl.enableVertexAttribArraygl.bindBuffergl.vertexAttribPointer
  • 对于着色器需要的每个制服
  • 使用当前着色器
  • 的位置调用具有所需值的 gl.uniformXXX
  • 调用 gl.drawArrays 或者如果数据被索引调用 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferOfIndicesForCurrentShape) 后跟 gl.drawElements

  • 常见优化

    1) 通常你不需要设置每一个制服。例如,如果您使用 着色器绘制 10 个形状,并且该着色器采用 viewMatrix 或 cameraMatrix,则可能每个形状的 viewMatrix 统一或相机矩阵统一都相同,因此只需设置一次即可。

    2) 你可以经常把对 gl.enableVertexAttribArray 的调用移到初始化时间。

    关于webgl - 在 WebGL 中绘制许多形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13009328/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com