t_wの輪郭

Feedlyでフォローするボタン

あれ

2022/12/15 15:53:00

やはり大量の手書きの軌跡を描画して滑らかに視点移動しようとすると、泣きながらWebGLを触るしかないのか。
下手にライブラリを使うよりも、生のAPIを薄々で使った方が速いし、素性が良い。ただし地獄。

「WebGL行くぞッ」と思ってもWebGLとWebGL2.0があり、どちらも情報が薄い。獣道がうっすら見えるだけで知の高速道路をウェイできない。

あれ

2022/12/15 16:50:00

WebGL2.0で三角形が描画できたッ!

人様のサイトに従って書いただけでなんとかなった。ありがてぇ……
https://webgl2fundamentals.org/webgl/lessons/ja/webgl-fundamentals.html

見よ!この長大なプログラムを!

gl2 = canvas.getContext('webgl2');
if (!gl2) {
    console.log('webgl2 is unsupported');
    return;
}
console.log("webgl2 is supported");

const vertex_shader = createShader(gl2, gl2.VERTEX_SHADER, `#version 300 es
    // an attribute is an input (in) to a vertex shader.
    // It will receive data from a buffer
    in vec4 a_position;
    
    // all shaders have a main function
    void main() {
    // gl_Position is a special variable a vertex shader
    // is responsible for setting
    gl_Position = a_position;
    }
`);

const fragment_shader = createShader(gl2, gl2.FRAGMENT_SHADER, `#version 300 es
    // fragment shaders don't have a default precision so we need
    // to pick one. highp is a good default. It means "high precision"
    precision highp float;
    
    // we need to declare an output for the fragment shader
    out vec4 outColor;
    
    void main() {
    // Just set the output to a constant reddish-purple
    outColor = vec4(1, 0, 0.5, 1);
    }
`);

const gl2_program = createProgram(gl2, vertex_shader, fragment_shader);
const position_attribute_location = gl2.getAttribLocation(gl2_program, "a_position");
var position_buffer = gl2.createBuffer();
gl2.bindBuffer(gl2.ARRAY_BUFFER, position_buffer);

// three 2d points
var positions = [
    0, 0,
    0, 0.5,
    0.7, 0,
];
gl2.bufferData(gl2.ARRAY_BUFFER, new Float32Array(positions), gl2.STATIC_DRAW);

const vao = gl2.createVertexArray();
gl2.bindVertexArray(vao);
gl2.enableVertexAttribArray(position_attribute_location);

var size = 2;          // 2 components per iteration
var type = gl2.FLOAT;   // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0;        // start at the beginning of the buffer
gl2.vertexAttribPointer(position_attribute_location, size, type, normalize, stride, offset)


console.log({gl2_canvas:gl2.canvas});

// webglUtils.resizeCanvasToDisplaySize(gl2.canvas);    // webglUtilsが見つからないためコメントアウト
// webglUtils.resizeCanvasToDisplaySize(gl2.canvas);    と同等と思われる処理を追加
gl2.canvas.setAttributeNS(null, "height", `${gl2.canvas.clientHeight}`);
gl2.canvas.setAttributeNS(null, "width", `${gl2.canvas.clientWidth}`);

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

// Clear the canvas
gl2.clear(gl2.COLOR_BUFFER_BIT);
gl2.clearColor(1.0, 1.0, 1.0, 1.0);

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

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

var primitiveType = gl2.TRIANGLES;
var offset = 0;
var count = 3;
gl2.drawArrays(primitiveType, offset, count);

function createProgram(gl, vertexShader, fragmentShader) {
    var program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    var success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (success) {
        return program;
    }

    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
}

function createShader(gl2, type, source: string) {
    var shader = gl2.createShader(type);
    gl2.shaderSource(shader, source);
    gl2.compileShader(shader);
    var success = gl2.getShaderParameter(shader, gl2.COMPILE_STATUS);
    if (success) {
        return shader;
    }

    console.log(gl2.getShaderInfoLog(shader));
    gl2.deleteShader(shader);
}

if (canvas && canvas_geometry.canvas_x && canvas_geometry.canvas_y && canvas_geometry.canvas_width && canvas_geometry.canvas_height) {
    const clientRect = canvas.getBoundingClientRect();
    const scale = Math.min(clientRect.width / canvas_geometry.canvas_width, clientRect.height / canvas_geometry.canvas_height)
    const x = (canvas_geometry.canvas_x - (canvas_geometry.canvas_width * scale) / 2) + clientRect.width / 2;
    const y = (canvas_geometry.canvas_y - clientRect.height / 2) + (canvas_geometry.canvas_height * scale) / 2;
    const scale_center_x = clientRect.width / 2 - x;
    const scale_center_y = clientRect.height / 2 - y;
    // canvas_move_to(canvas, x, y, scale, scale_center_x, scale_center_y);
}