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

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);
}
});

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.

gl.getBufferSubData not working with ArrayBuffer

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.

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");

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

WebGL solid colors

https://www.dropbox.com/s/4zkhtdv4yaqhpxy/Screenshot%20from%202015-01-28%2010%3A42%3A02%201.png?dl=0
Can someone explain to me, what am I doing wrong? I want every face of the cube to have one solid colour. The code, which creates the cube, is in RunCube.coffee file and the vertices and colour are defined in Cube.coffee file. I think the problem is that I do not know, how to use indexes for colours.
Here is the repository on github https://github.com/trimpirim/shiny-soice
UPDATED:
I have Cube with all it's data.
#vertices: [
[ 6.89954888016507530, 0.39691390817415106, -4.02972512706645780],
[-0.78006682662096161, -3.78853119791598660, -7.00275139558893490],
[-5.79336942493284560, 3.47790796230961650, -4.28264251507835430],
[ 1.88624628185319150, 7.66335306839975420, -1.30961624655587690],
[ 0.78006682662096205, 3.78853119791598920, 7.00275139558893490],
[ 5.79336942493284290, -3.47790796230961740, 4.28264251507835780],
[-1.88624628185319150, -7.66335306839975150, 1.30961624655588270],
[-6.89954888016507440, -0.39691390817415328, 4.02972512706646220]
];
#faces: [
[0, 1, 2], [0, 2, 3],
[0, 3, 4], [0, 4, 5],
[0, 5, 6], [0, 6, 1]
[2, 1, 6], [2, 6, 7],
[2, 7, 4], [2, 4, 3],
[4, 7, 6], [4, 6, 5]
];
#colors: [
[1.0, 0.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[1.0, 0.5, 0.5, 1.0],
[1.0, 0.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
]
Can someone tell me, how should correct colours data look like?
EDIT:
There are not separated indices for colors. Indices are same for both, vertex positions and colors (or any other property you could think of).
To achive cube with 6 solid colors, you will have to repeat some parts of your arrays.
This is kind of prototype, how vertices look like:
vertices: [
{
position: [x,y,z],
color: [r, g, b, a]
},
{
position: [x,y,z],
color: [r, g, b, a]
},
...
];
Vertex with position: [0,0,0], color [1,0,0,1] is not same as vertex with position: [0,0,0], color [0,1,0,1]. You want one corner of cube be part of 3 faces with different color. So there must be 3 vertices in one corner with same position, but different color. Unfortunately in this case, position cannot be shared.
So your definition should look like this:
var vertex_positions = [
// see that front face and back face has 8 unique positions
// front face
[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
// back face
[0, 0, 1],
[1, 0, 1],
[1, 1, 1],
[0, 1, 1],
// see that bottom face and top face has 8 unique positions too,
// but they repeated with different order from front and back
// bottom face
[0, 0, 0],
[1, 0, 0],
[1, 0, 1],
[0, 0, 1],
// top face
[0, 1, 0],
[1, 1, 0],
[1, 1, 1],
[0, 1, 1],
// left and right face have 8 unique positions too, but again
// repeated from front, back / bottom, top
// left face
[0, 0, 0],
[0, 1, 0],
[0, 1, 1],
[0, 0, 1],
// right face
[1, 0, 0],
[1, 1, 0],
[1, 1, 1],
[1, 0, 1]
];
Colors, same amount of elements as for positions:
var vertex_colors = [
// front face
[1.0, 0.0, 0.0, 1.0],
[1.0, 0.0, 0.0, 1.0],
[1.0, 0.0, 0.0, 1.0],
[1.0, 0.0, 0.0, 1.0],
// back face
[1.0, 1.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 1.0],
[1.0, 1.0, 0.0, 1.0],
// bottom face
[0.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
// top face
[1.0, 0.5, 0.5, 1.0],
[1.0, 0.5, 0.5, 1.0],
[1.0, 0.5, 0.5, 1.0],
[1.0, 0.5, 0.5, 1.0],
// left face
[1.0, 0.0, 1.0, 1.0],
[1.0, 0.0, 1.0, 1.0],
[1.0, 0.0, 1.0, 1.0],
[1.0, 0.0, 1.0, 1.0],
// right face
[0.0, 0.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
];
Now indices:
var triangles = [
// front face
[0, 1, 2],
[0, 2, 3],
// back face
[4, 5, 6],
[4, 6, 7],
// bottom face
[8, 9, 10],
[8, 10, 11],
// top face
[12, 13, 14],
[12, 14, 15],
// left face
[16, 17, 18],
[16, 18, 19],
// right face
[20, 21, 22],
[20, 22, 23]
];
Cube is made of 12 triangles. With solid color faces, we need 4 unique vertices for 2 triangles, so we need 24 different vertex definitions.
This is the most traditional way as gman said. There are also other ways to achieve same effect, but theirs usecases are rare.
PS: sorry my indices might not be correct

Categories

Resources