gl.getBufferSubData not working with ArrayBuffer - javascript

I'm trying to read data from a buffer using gl.getBufferSubData, I followed the example from MDN
let position_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, position_buffer);
let positions = [
-1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0,
1.0, 1.0, 0.0,
-1.0, -1.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
let arrBuffer = new ArrayBuffer(positions.length * Float32Array.BYTES_PER_ELEMENT);
gl.getBufferSubData(gl.ARRAY_BUFFER, 0, arrBuffer);
But I'm getting this error (both on Firefox and Chrome):
Uncaught TypeError: WebGL2RenderingContext.getBufferSubData: Argument 3 does not implement interface ArrayBufferView.

Related

My webGL drawn cube has no outer layer and the part being lit up is the inside

The program that I am using draws the cube perfectly when there is no lighting applied to the color of it. When applied it looks like it doesn't have an outer layer and the outer parts are simply non-existent. The part that is being lit up is the inside of the cube and this is very visible in the output of the program.
I tried messing around with the code itself but it doesn't seem like that is the real problem here (I may be wrong), I also tried changing the values in the position, normal and indices vectors, however, this did not yield any results either.
These are the position, normal, and index values that are used:
var positions = new Float32Array([
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
]);
var normals = new Float32Array([
// Front
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
]);
var indices = new Uint16Array([
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // back
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // bottom
16, 17, 18, 16, 18, 19, // right
20, 21, 22, 20, 22, 23, // left
]);
Sorry for the spam of code. I can provide any more that will be necessary. The output of the program.

Javascript split rows from csv file based on value in first column

I am trying to split a csv file into a groups based on a vlue within the first column. Then store the rows in an array for displaying on a web page.
I'm new to javascript and can't figure it out.
I have a csv file with the following structure:
0,-1.0,0.0,0.0,0.0
1,0.0,0.0,0.0,0.0
0,-1.0,0.0,0.0,0.0
1,-1.0,0.0,0.0,0.0
2,0.0,0.0,0.0,0.0
0,-1.0,0.0,0.0,0.0
1,-1.0,0.0,0.0,0.0
2,-1.0,0.0,0.0,0.0
3,0.0,0.0,0.0,0.0
0,-1.0,0.0,0.0,0.0
1,-1.0,0.0,0.0,0.0
2,-1.0,0.0,0.0,0.0
3,-1.0,0.0,0.0,0.0
4,0.0,0.0,0.0,0.0
I am trying to split the data rows into groups based on the values of the first column in the file. I am trying to group from 0 up to the next zero then have each block of split data stored in an array for displaying on a web page.
I am able to access the first row from a for loop and set a condition to check if the value is 0, but i'm am having trouble adding the next rows up until the next 0 is dectected.
Please see below for what i have so far.
// AJAX in the data file
$.ajax({
type: "GET",
url: "static/Dataframe.csv",
dataType: "text",
cache: false,
success: function(data) {
var arr1 = data.split(/\r\n|\n|\r/);
var array2 = [];
for (let i = 0; i < arr1.length; i++) {
arr1[i].split(',');
array2.push(arr1[i]);
if(arr1[i][0]== 0){
array2.pop()
}
}
// for debugging
// document.getElementById("dialog").innerHTML = arr1;
console.log(array2);
}
});
This is the result i am getting so far.
[0: "1,0.0,0.0,0.0,0.0"
1: "1,-1.0,0.0,0.0,0.0"
2: "2,0.0,0.0,0.0,0.0"
3: "1,-1.0,0.0,0.0,0.0"
4: "2,-1.0,0.0,0.0,0.0"
5: "3,0.0,0.0,0.0,0.0"
6: "1,-1.0,0.0,0.0,0.0"
7: "2,-1.0,0.0,0.0,0.0"
8: "3,-1.0,0.0,0.0,0.0"
9: "4,0.0,0.0,0.0,0.0"]
What i need it to be is:
[
[0, -1.0, 0.0, 0.0, 0.0, 1, 0.0, 0.0, 0.0, 0.0],
[0, -1.0, 0.0, 0.0, 0.0, 1, -1.0, 0.0, 0.0, 0.0, 2, 0.0, 0.0, 0.0, 0.0],
[0, -1.0, 0.0, 0.0, 0.0, 1, -1.0, 0.0, 0.0, 0.0, 2, -1.0, 0.0, 0.0, 0.0, 3, 0.0, 0.0, 0.0, 0.0],
[0, -1.0, 0.0, 0.0, 0.0, 1, -1.0, 0.0, 0.0, 0.0, 2, -1.0, 0.0, 0.0, 0.0, 3, -1.0, 0.0, 0.0, 0.0, 4, 0.0, 0.0, 0.0, 0.0]
]
I'm new to javaScript and I'm having trouble figuring this out.
Any advice would be greatly appreciated.
You could check the first value of the inner arrays and add a new array to the result set.
var data = '0,-1.0,0.0,0.0,0.0\n1,0.0,0.0,0.0,0.0\n0,-1.0,0.0,0.0,0.0\n1,-1.0,0.0,0.0,0.0\n2,0.0,0.0,0.0,0.0\n0,-1.0,0.0,0.0,0.0\n1,-1.0,0.0,0.0,0.0\n2,-1.0,0.0,0.0,0.0\n3,0.0,0.0,0.0,0.0\n0,-1.0,0.0,0.0,0.0\n1,-1.0,0.0,0.0,0.0\n2,-1.0,0.0,0.0,0.0\n3, -1.0, 0.0, 0.0, 0.0\n4, 0.0, 0.0, 0.0, 0.0',
result = data.split(/\r\n|\n|\r/).reduce((r, s) => {
var array = s.split(',').map(Number);
if (!array[0]) {
r.push([]);
}
r[r.length - 1].push(...array);
return r;
}, []);
console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
use this
// AJAX in the data file
$.ajax({
type: "GET",
url: "static/Dataframe.csv",
dataType: "text",
cache: false,
success: function(data) {
var arr1 = data.split(/\r\n|\n|\r/);
var array2 = [];
for (let i = 0; i < arr1.length; i++) {
tmp = arr1[i].split(',');
array2.push(tmp);
if(arr1[i][0]== 0){
array2.pop()
}
}
// for debugging
// document.getElementById("dialog").innerHTML = arr1;
console.log(array2);
}
});
// AJAX in the data file
// Just removed the for loop with the length and see the modified code.
$.ajax({
type: "GET",
url: "static/Dataframe.csv",
dataType: "text",
cache: false,
success: function(data) {
var arr1 = data.split(/\r\n|\n|\r/);
var array2 = [];
for (var items of arr1) {
tmp = items.split(',');
array2.push(tmp);
if(items[0]== 0){
array2.pop()
}
}
// for debugging
// document.getElementById("dialog").innerHTML = arr1;
console.log(array2);
}
});

Is it possible to use the Javascript Array.prototype.filter() function with an array of other arrays?

In a Javascript code, I am using an array that contains other arrays. The array is actually four layers deep (There is an array with arrays of arrays of variables) and I need to remove some strings of a specific value from this array. I had seen the Array.prototype.filter() function and thought it would be useful, but I think it did not work because the strings were within other arrays. I cannot specifically address each sub-array though, for several reasons. Any suggestions for how to make it work or any alternatives would be welcome.
This is an example of a possible array created in my code:
[
[
[
[
1.0,
1.0,
1.0
],
[
0.0,
1.0,
1.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
0.0,
1.0
],
[
t
]
],
[
[
0.0,
0.0,
1.0,
0.0,
0.0
],
[
1.0,
0.0,
1.0,
1.0,
0.0
],
[
1.0,
1.0,
0.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0,
1.0,
1.0
],
[
0.0,
1.0,
0.0,
0.0,
0.0
],
[
1.0,
0.0,
1.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0,
1.0,
0.0
],
[
t
]
],
[
[
0.0,
1.0,
1.0,
1.0,
0.0,
0.0,
1.0
],
[
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0
],
[
1.0,
0.0,
0.0,
0.0,
1.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0,
0.0,
0.0,
0.0,
1.0
],
[
1.0,
0.0,
1.0,
1.0,
1.0,
0.0,
0.0
],
[
t
]
],
[
[
0.0,
0.0,
0.0,
1.0,
1.0
],
[
0.0,
1.0,
1.0,
0.0,
1.0
],
[
1.0,
1.0,
1.0,
0.0,
1.0
],
[
t
]
],
[
[
t
]
]
],
[
[
[
1.0,
1.0,
0.0
],
[
0.0,
1.0,
1.0
],
[
1.0,
1.0,
0.0
],
[
0.0,
1.0,
0.0
],
[
1.0,
0.0,
1.0
],
[
t
]
],
[
[
0.0,
0.0,
1.0,
0.0,
0.0
],
[
0.0,
0.0,
0.0,
0.0,
1.0
],
[
1.0,
1.0,
1.0,
1.0,
1.0
],
[
1.0,
0.0,
0.0,
0.0,
1.0
],
[
1.0,
0.0,
0.0,
1.0,
0.0
],
[
0.0,
0.0,
1.0,
0.0,
1.0
],
[
1.0,
0.0,
1.0,
0.0,
0.0
],
[
t
]
],
[
[
0.0,
0.0,
1.0,
1.0,
1.0,
0.0,
1.0
],
[
1.0,
0.0,
0.0,
1.0,
1.0,
0.0,
0.0
],
[
1.0,
0.0,
1.0,
0.0,
0.0,
1.0,
0.0
],
[
0.0,
1.0,
1.0,
0.0,
0.0,
0.0,
1.0
],
[
1.0,
1.0,
1.0,
1.0,
0.0,
1.0,
0.0
],
[
t
]
],
[
[
1.0,
0.0,
0.0,
1.0,
0.0
],
[
0.0,
1.0,
1.0,
0.0,
0.0
],
[
0.0,
1.0,
1.0,
1.0,
0.0
],
[
t
]
],
[
[
t
]
]
],
[
[
[
0.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0
],
[
1.0,
1.0,
0.0
],
[
t
]
],
[
[
1.0,
1.0,
0.0,
0.0,
1.0
],
[
1.0,
0.0,
0.0,
0.0,
1.0
],
[
0.0,
0.0,
0.0,
0.0,
0.0
],
[
0.0,
0.0,
1.0,
1.0,
1.0
],
[
1.0,
1.0,
0.0,
1.0,
0.0
],
[
0.0,
0.0,
1.0,
1.0,
0.0
],
[
0.0,
0.0,
1.0,
1.0,
0.0
],
[
t
]
],
[
[
1.0,
1.0,
1.0,
0.0,
0.0,
0.0,
1.0
],
[
1.0,
0.0,
1.0,
0.0,
1.0,
0.0,
1.0
],
[
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
0.0
],
[
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
1.0
],
[
1.0,
1.0,
1.0,
0.0,
1.0,
1.0,
1.0
],
[
t
]
],
[
[
1.0,
0.0,
1.0,
0.0,
1.0
],
[
1.0,
1.0,
1.0,
0.0,
1.0
],
[
1.0,
0.0,
0.0,
0.0,
0.0
],
[
t
]
],
[
[
t
]
]
],
[
[
[
t
]
]
]
]
I need to remove all of the "t" strings. This array is a bit smaller than it would normally be, and it will be a different size on each execution of the code. If it is unclear what I am asking, or if you thin it would be helpful, I can post the code, but it is a bit big so I don't want to clog up the page.
The array is actually four layers deep
You can use object destructuring to get the value of the fourth nested array
let res = arr.filter(([[[inner]]]) => typeof inner !== "string");

Sort an array by two fields

I'm trying to summarise this unordered 2d array:
[
[3.0, 1.0, 4.0],
[2.0, 1.0, 1.0],
[1.0, 1.0, 6.0],
[1.0, 1.0, 1.0],
[3.0, 2.0, 5.0],
[2.0, 2.0, 1.0],
[3.0, 1.0, 1.0],
[1.0, 1.0, 4.0],
[1.0, 2.0, 3.0],
[3.0, 1.0, 2.0],
[2.0, 1.0, 1.0],
[2.0, 2.0, 2.0]
]
I'm able to order it by the first then second columns like so:
[
[1.0, 1.0, 6.0],
[1.0, 1.0, 1.0],
[1.0, 1.0, 4.0],
[1.0, 2.0, 3.0],
[2.0, 1.0, 1.0],
[2.0, 1.0, 1.0],
[2.0, 2.0, 1.0],
[2.0, 2.0, 2.0],
[3.0, 1.0, 4.0],
[3.0, 1.0, 1.0],
[3.0, 1.0, 2.0],
[3.0, 2.0, 5.0]
]
Using this code:
function sortData(myArr) {
// sort on second column, asc
myArr.sort(function (element_a, element_b) {
return element_a[1] - element_b[1];
});
// sort on first column, asc
myArr.sort(function (element_a, element_b) {
return element_a[0] - element_b[0];
});
return myArr;
}
Ultimately, the result below is what I'm trying to get (sum of third column, grouped by 1st and 2nd in ascending order):
[
[1.0, 1.0, 11.0],
[1.0, 2.0, 3.0],
[2.0, 1.0, 2.0],
[2.0, 2.0, 3.0],
[3.0, 1.0, 7.0],
[3.0, 2.0, 5.0]
]
You can first sort your data and then use forEach() loop to group by first two elements and sum third element.
var data = [[3,1,4],[2,1,1],[1,1,6],[1,1,1],[3,2,5],[2,2,1],[3,1,1],[1,1,4],[1,2,3],[3,1,2],[2,1,1],[2,2,2]]
data.sort(function(a, b) {
return a[0] - b[0] || a[1] - b[1]
})
var result = [];
data.forEach(function(e) {
var key = e[0].toString() + e[1].toString();
if(!this[key]) result.push(this[key] = e.slice())
else this[key][2] += e[2]
}, {})
console.log(JSON.stringify(result))
Go through the sorted array, creating a new array of sums.
Create a new element when the 1st or the 2nd column become different, or add to the current element as long as those columns remain the same.
Using Array#reduce:
let arr = [
[3.0, 1.0, 4.0],
[2.0, 1.0, 1.0],
[1.0, 1.0, 6.0],
[1.0, 1.0, 1.0],
[3.0, 2.0, 5.0],
[2.0, 2.0, 1.0],
[3.0, 1.0, 1.0],
[1.0, 1.0, 4.0],
[1.0, 2.0, 3.0],
[3.0, 1.0, 2.0],
[2.0, 1.0, 1.0],
[2.0, 2.0, 2.0]
]
let res = Object.values(arr.reduce((a, c)=>{
let key = c.slice(0,2).join('|');
if(!a[key]){
a[key] = c
}else{
a[key][2] += c[2]
}
return a
},{})).sort((a, b)=>{
return a[0]-b[0] || a[1] - b[1]
});
console.log(JSON.stringify(res))
Basic theory is to use first 2 values to create an object key. If that key doesn't exist create a new one with current array as value.... if it already exists sum last value of each

First steps with drawing 3D shapes in WebGL

I am learning WebGL from few weeks and I've got a problem with drawing some 3D shapes. Guess I am corectly counting vertices and indices, as well as a color for each triangle, but it does not work. Could someone tell me what am I doing wrong ?
I would like to make pyramide which will looks like :
And here is the code :
var gl = null,
canvas = null,
glProgram = null,
fragmentShader = null,
vertexShader = null;
var coordinateArray = [ ],
triangleVerticeColors = [ ],
verticesArray = [ ],
verticesIndexArray = [ ];
var vertexPositionAttribute = null,
trianglesVerticeBuffer = null,
vertexColorAttribute = null,
trianglesColorBuffer = null,
triangleVerticesIndexBuffer = null;
var P = mat4.create(),
V = mat4.create();
M = mat4.create();
function initWebGL() {
canvas = document.getElementById("my-canvas");
try {
gl = canvas.getContext("webgl") ||
canvas.getContext("experimental-webgl");
} catch (e) {
}
if (gl) {
setupWebGL();
initShaders();
setupBuffers();
getMatrixUniforms();
setMatrixUniforms();
animationLoop();
//drawScene();
} else {
alert("Error: Your browser does not appear to" + "support WebGL.");
}
}
function animationLoop() {
var R = mat4.create();
var angle = 0;
var i = 0;
var loop = function() {
angle = performance.now() / 1000 / 6 * 2 * Math.PI;
i++;
mat4.rotate(M, R, angle, [ 0, 1, 0 ]);
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M);
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
drawScene();
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
}
function setupWebGL() {
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
console.log(P);
console.log(V);
console.log(M);
mat4.lookAt(V, [ 3, -1, -5 ], [ 0, 0, 0 ], [ 0, 1, 0 ]);
mat4.perspective(P, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 1000.0);
}
function initShaders() {
var fs_source = document.getElementById('shader-fs').innerHTML,
vs_source = document.getElementById('shader-vs').innerHTML;
vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER);
glProgram = gl.createProgram();
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram);
if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program.");
}
gl.useProgram(glProgram);
}
function makeShader(src, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("Error compiling shader: " + gl.getShaderInfoLog(shader));
}
return shader;
}
function setupBuffers() {
// n-sides polygon
var n = 6;
var radius = 1;
var angle = (Math.PI * 2) / n;
var xCoordinate = 0;
var yCoordinate = 0;
for (var i = 0; i < n; i++) {
var a = angle * i;
var xNewCoordinate = xCoordinate + radius * Math.cos(a);
var yNewCoordinate = yCoordinate + radius * Math.sin(a);
var zNewCoordinate = 0;
coordinateArray.push(xNewCoordinate);
coordinateArray.push(yNewCoordinate);
coordinateArray.push(zNewCoordinate);
}
verticesArray = [
//Bottom Face
0.0, 0.0, 0.0,
0.0, 0.0, -1.0,
1.0, 0.0, -1.0,
0.0, 0.0, 0.0,
1.0, 0.0, -1.0,
1.0, 0.0, 0.0,
//Front Face
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.5, 1.0, -0.5,
//Right Face
1.0, 0.0, 0.0,
1.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Back Face
1.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Left Face
0.0, 0.0, -1.0,
0.0, 0.0, 0.0,
0.5, 1.0, -0.5,
];
trianglesVerticeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArray), gl.STATIC_DRAW);
verticesIndexArray = [
3, 2, 1,
3, 1, 0,
3, 0, 4,
0, 1, 4,
1, 2, 4,
2, 3, 4,
];
triangleVerticesIndexBuffer = gl.createBuffer();
triangleVerticesIndexBuffer.number_vertext_points = verticesIndexArray.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleVerticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(verticesIndexArray), gl.STATIC_DRAW);
triangleVerticeColors = [
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 5.0, 0.0,
0.0, 5.0, 0.0,
0.0, 5.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
];
trianglesColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW);
}
function getMatrixUniforms() {
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix");
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix");
glProgram.vMatrixUniform = gl.getUniformLocation(glProgram, "uVMatrix");
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M);
gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, P);
gl.uniformMatrix4fv(glProgram.vMatrixUniform, false, V);
}
function drawScene() {
vertexPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
vertexColorAttribute = gl.getAttribLocation(glProgram, "aVertexColor");
gl.enableVertexAttribArray(vertexColorAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 3, gl.FLOAT, false, 0, 0);
gl.drawElements(gl.TRIANGLE_STRIP, triangleVerticesIndexBuffer.number_vertext_points, gl.UNSIGNED_SHORT, 0);
}
initWebGL();
body{ background-color: grey; }
canvas{ background-color: white; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
varying vec4 vColor;
// Model matrix
uniform mat4 uMVMatrix;
// Projection matrix
uniform mat4 uPMatrix;
// View matrix
uniform mat4 uVMatrix;
void main(void) {
vColor = aVertexColor;
gl_Position = uPMatrix * uVMatrix * uMVMatrix * aVertexPosition;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<canvas id="my-canvas" width="400" height="300">
Your browser does not support the HTML5 canvas element.
</canvas>
With output looking like :
Second thing on which I am working atm is couting 'gl_position' in GPU
gl_Position = uPMatrix * uVMatrix * uMVMatrix * aVertexPosition;
How can I count in on CPU ?
Thanks in advance!
The vertex indices are wrong. Try
verticesIndexArray = [
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
];
var gl = null,
canvas = null,
glProgram = null,
fragmentShader = null,
vertexShader = null;
var coordinateArray = [ ],
triangleVerticeColors = [ ],
verticesArray = [ ],
verticesIndexArray = [ ];
var vertexPositionAttribute = null,
trianglesVerticeBuffer = null,
vertexColorAttribute = null,
trianglesColorBuffer = null,
triangleVerticesIndexBuffer = null;
var P = mat4.create(),
V = mat4.create();
M = mat4.create();
function initWebGL() {
canvas = document.getElementById("my-canvas");
try {
gl = canvas.getContext("webgl") ||
canvas.getContext("experimental-webgl");
} catch (e) {
}
if (gl) {
setupWebGL();
initShaders();
setupBuffers();
getMatrixUniforms();
setMatrixUniforms();
animationLoop();
//drawScene();
} else {
alert("Error: Your browser does not appear to" + "support WebGL.");
}
}
function animationLoop() {
var R = mat4.create();
var angle = 0;
var i = 0;
var loop = function() {
angle = performance.now() / 1000 / 6 * 2 * Math.PI;
i++;
mat4.rotate(M, R, angle, [ 0, 1, 0 ]);
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M);
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
drawScene();
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
}
function setupWebGL() {
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.lookAt(V, [ 3, -1, -5 ], [ 0, 0, 0 ], [ 0, 1, 0 ]);
mat4.perspective(P, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 1000.0);
}
function initShaders() {
var fs_source = document.getElementById('shader-fs').innerHTML,
vs_source = document.getElementById('shader-vs').innerHTML;
vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER);
glProgram = gl.createProgram();
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram);
if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program.");
}
gl.useProgram(glProgram);
}
function makeShader(src, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("Error compiling shader: " + gl.getShaderInfoLog(shader));
}
return shader;
}
function setupBuffers() {
// n-sides polygon
var n = 6;
var radius = 1;
var angle = (Math.PI * 2) / n;
var xCoordinate = 0;
var yCoordinate = 0;
for (var i = 0; i < n; i++) {
var a = angle * i;
var xNewCoordinate = xCoordinate + radius * Math.cos(a);
var yNewCoordinate = yCoordinate + radius * Math.sin(a);
var zNewCoordinate = 0;
coordinateArray.push(xNewCoordinate);
coordinateArray.push(yNewCoordinate);
coordinateArray.push(zNewCoordinate);
}
verticesArray = [
//Bottom Face
0.0, 0.0, 0.0,
0.0, 0.0, -1.0,
1.0, 0.0, -1.0,
0.0, 0.0, 0.0,
1.0, 0.0, -1.0,
1.0, 0.0, 0.0,
//Front Face
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.5, 1.0, -0.5,
//Right Face
1.0, 0.0, 0.0,
1.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Back Face
1.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Left Face
0.0, 0.0, -1.0,
0.0, 0.0, 0.0,
0.5, 1.0, -0.5,
];
trianglesVerticeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArray), gl.STATIC_DRAW);
verticesIndexArray = [
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
];
triangleVerticesIndexBuffer = gl.createBuffer();
triangleVerticesIndexBuffer.number_vertext_points = verticesIndexArray.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleVerticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(verticesIndexArray), gl.STATIC_DRAW);
triangleVerticeColors = [
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 5.0, 0.0,
0.0, 5.0, 0.0,
0.0, 5.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
];
trianglesColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW);
}
function getMatrixUniforms() {
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix");
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix");
glProgram.vMatrixUniform = gl.getUniformLocation(glProgram, "uVMatrix");
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M);
gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, P);
gl.uniformMatrix4fv(glProgram.vMatrixUniform, false, V);
}
function drawScene() {
vertexPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
vertexColorAttribute = gl.getAttribLocation(glProgram, "aVertexColor");
gl.enableVertexAttribArray(vertexColorAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 3, gl.FLOAT, false, 0, 0);
gl.drawElements(gl.TRIANGLES, triangleVerticesIndexBuffer.number_vertext_points, gl.UNSIGNED_SHORT, 0);
}
initWebGL();
body{ background-color: grey; }
canvas{ background-color: white; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
varying vec4 vColor;
// Model matrix
uniform mat4 uMVMatrix;
// Projection matrix
uniform mat4 uPMatrix;
// View matrix
uniform mat4 uVMatrix;
void main(void) {
vColor = aVertexColor;
gl_Position = uPMatrix * uVMatrix * uMVMatrix * aVertexPosition;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<canvas id="my-canvas" width="400" height="300">
Your browser does not support the HTML5 canvas element.
</canvas>
These indices will also work
verticesIndexArray = [
0, 1, 2,
0, 2, 5,
5, 0, 8,
0, 1, 8,
1, 2, 8,
2, 5, 8,
];
The difference being if you share vertices they will also share colors. If you want each face to be able to have unique colors then each vertex has to be unique (or you have to use complex texture based vertex indexing).
Looking at your vertice the first 6 vertices from the base
verticesArray = [
//Bottom Face
0.0, 0.0, 0.0, // 0
0.0, 0.0, -1.0, // 1
1.0, 0.0, -1.0, // 2
0.0, 0.0, 0.0, // 3
1.0, 0.0, -1.0, // 4
1.0, 0.0, 0.0, // 5
The square they make puts each vertex at these locations
1----24
| |
| |
03----5
So you can use
0, 1, 2,
3, 4, 5,
Or (for example)
0, 1, 2,
0, 2, 5,
Looking at the rest of the points
//Front Face
0.0, 0.0, 0.0, // 6
1.0, 0.0, 0.0, // 7
0.5, 1.0, -0.5, // 8
//Right Face
1.0, 0.0, 0.0, // 9
1.0, 0.0, -1.0, // 10
0.5, 1.0, -0.5, // 11
//Back Face
1.0, 0.0, -1.0, // 12
0.0, 0.0, -1.0, // 13
0.5, 1.0, -0.5, // 14
//Left Face
0.0, 0.0, -1.0, // 15
0.0, 0.0, 0.0, // 16
0.5, 1.0, -0.5, // 18
Points 8, 11, 14, 18 are all the same point above the base. All the other points are copies of the base points.
As mentioned above you need copies if you want to be able to specify different colors and or normals and or texture coordinates for each vertex's use on a specific face.
There's one more issue. The code is using gl.TRIANGLE_STRIP instead of gl.TRIANGLES
So given that you can see the difference. If you use the individual vertices you get this
If you use the shared vertices you get this

Categories

Resources