I test this program but can understand why only max 4 points can render?
This's vertex shader program:
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 20.0;
}
And Fragment program:
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
And then, i use dynamic_draw to pass data to this program using buffer, and update using bufferSubData
:
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint8Array([
0, 0,
128, 191,
0, 0,
128, 191,
0, 0,
128, 63,
0, 0,
128, 191,
0, 0,
128, 191,
0, 0,
128, 63,
0, 0,
128, 63,
0, 0,
128, 63
]));
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.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
gl.vertexAttribPointer(
positionLocation, size, type, normalize, stride, offset);
Then, i using
gl.drawArrays(gl.POINTS, 0, 4);
max 4 points can render ? WHY ?
Link to this program: https://codepen.io/nguyendinhlam88/pen/abajaJZ
// WebGL - 2D Image
// from https://webglfundamentals.org/webgl/webgl-2d-image.html
"use strict";
function main() {
var image = new Image();
requestCORSIfNotSameOrigin(image, "https://webglfundamentals.org/webgl/resources/leaves.jpg")
image.src = "https://webglfundamentals.org/webgl/resources/leaves.jpg";
image.onload = function() {
render(image);
};
}
function render(image) {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, ["vertex-shader-2d", "fragment-shader-2d"]);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "position");
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, 32, gl.DYNAMIC_DRAW);
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
// console.log(gl.canvas.width, gl.canvas.height);
gl.viewport(0, 0, 240, 180);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint8Array([
0, 0,
128, 191,
0, 0,
128, 191,
0, 0,
128, 63,
0, 0,
128, 191,
0, 0,
128, 191,
0, 0,
128, 63,
0, 0,
128, 63,
0, 0,
128, 63
]));
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.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
gl.vertexAttribPointer(
positionLocation, size, type, normalize, stride, offset);
// Draw the rectangle.
var primitiveType = gl.POINTS;
var offset = 0
var count = 4;
gl.drawArrays(primitiveType, offset, count);
}
main();
// This is needed if the images are not on the same domain
// NOTE: The server providing the images must give CORS permissions
// in order to be able to use the image with WebGL. Most sites
// do NOT give permission.
// See: https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html
function requestCORSIfNotSameOrigin(img, url) {
if ((new URL(url, window.location.href)).origin !== window.location.origin) {
img.crossOrigin = "";
}
}
@import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
body {
margin: 0;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
<canvas id="canvas"></canvas>
<!-- vertex shader -->
<script id="vertex-shader-2d" type="x-shader/x-vertex">
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 20.0;
}
</script>
<!-- fragment shader -->
<script id="fragment-shader-2d" type="x-shader/x-fragment">
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
Since there are only 4 coordinates in the buffer, only a maximum of 4 points can be drawn.
The buffer consists only of 4 coordinates coded in bytes. Every 4 bytes form a floating point value:
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Uint8Array([
0, 0, 128, 191, // x0
0, 0, 128, 191, // y0
0, 0, 128, 63, // x1
0, 0, 128, 191, // y1
0, 0, 128, 191, // x2
0, 0, 128, 63, // y2
0, 0, 128, 63, // x3
0, 0, 128, 63 // y3
]));
This can be seen in the vertexAttribPointer
specification. The size is 2
and the type is gl.FLOAT
. Therefore 1 attribute consists of 2 components of type float. The buffer is always just a series of bytes. How the bytes are to be interpreted is defined in the attribute specification.