I have geometries created on my server which have vertices and normals interleaved in one array. I tried colors also since it is easier to debug. The ONLY example I can find is webgl_buffergeometry_instancing_interleaved_dynamic.html.
Here is what I tried based on the example. That example is a bit different since it also uses InstancedBufferGeometry but this is based on my understanding of that example:
function exp_crate() {
var geometry = new THREE.BufferGeometry();
// per mesh data x,y,z,r,g,b for 6-element stride
var vertexBuffer = new THREE.InterleavedBuffer(new Float32Array([
// Front
-1000, 1000, 1000, 0, 0, 1,
1000, 1000, 1000, 0, 1, 0,
-1000, -1000, 1000, 1, 0, 1,
1000, -1000, 1000, 0, 1, 1,
// Back
1000, 1000, -1000, 0, 0, 1,
-1000, 1000, -1000, 0, 0, 1,
1000, -1000, -1000, 0, 0, 1,
-1000, -1000, -1000, 0, 0, 1,
// Left
-1000, 1000, -1000, 0, 0, 1,
-1000, 1000, 1000, 0, 0, 1,
-1000, -1000, -1000, 0, 0, 1,
-1000, -1000, 1000, 0, 0, 1,
// Right
1000, 1000, 1000, 0, 0, 1,
1000, 1000, -1000, 0, 0, 1,
1000, -1000, 1000, 0, 0, 1,
1000, -1000, -1000, 0, 0, 1,
// Top
-1000, 1000, 1000, 0, 0, 1,
1000, 1000, 1000, 0, 0, 1,
-1000, 1000, -1000, 0, 0, 1,
1000, 1000, -1000, 0, 0, 1,
// Bottom
1000, -1000, 1000, 0, 0, 1,
-1000, -1000, 1000, 0, 0, 1,
1000, -1000, -1000, 0, 0, 1,
-1000, -1000, -1000, 0, 0, 1,
]), 6);
// Use vertexBuffer, starting at offset 0, 3 items in position attribute
var positions = new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0);
geometry.addAttribute('inVertex', positions);
// Use vertexBuffer, starting at offset 4, 3 items in color attribute
var colors = new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 4);
geometry.addAttribute('inColor', colors);
var indices = new Uint16Array([
0, 1, 2,
2, 1, 3,
4, 5, 6,
6, 5, 7,
8, 9, 10,
10, 9, 11,
12, 13, 14,
14, 13, 15,
16, 17, 18,
18, 17, 19,
20, 21, 22,
22, 21, 23
]);
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
docvShader = document.getElementById('cratevertexShader').textContent;
docfShader = document.getElementById('cratefragmentShader').textContent;
var material = new THREE.ShaderMaterial({
uniforms: [],
vertexShader: docvShader,
fragmentShader: docfShader
});
material.side= THREE.DoubleSide;
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
Here are the shaders:
<script id="cratevertexShader" type="x-shader/x-vertex">
attribute highp vec3 inVertex;
attribute highp vec3 inColor;
varying mediump vec4 Color;
void main()
{
float df;
float opac;
gl_Position = projectionMatrix * modelViewMatrix * vec4(inVertex, 1.0);
Color = vec4(inColor, 1.0);
}
</script>
<script id="cratefragmentShader" type="x-shader/x-fragment">
varying mediump vec4 Color;
void main()
{
gl_FragColor = Color;
gl_FragColor.w = Color.w;
}
</script>
If I comment out this line:
geometry.addAttribute('inColor', colors);
I see a black cube. If I leave that line in I get the following GL error:
GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1
And nothing is displayed at all. Can anyone offer a suggestion?
Your offset for the 2nd attribute is not correct.
// Use vertexBuffer, starting at offset 0, 3 items in position attribute
var positions = new THREE.InterleavedBufferAttribute( vertexBuffer, 3, 0 );
geometry.addAttribute( 'inVertex', positions );
// Use vertexBuffer, starting at offset 3, 3 items in color attribute
var colors = new THREE.InterleavedBufferAttribute( vertexBuffer, 3, 3 );
geometry.addAttribute( 'inColor', colors );
three.js r.85
Related
I have been making a simple platformer using phaser 3. The level is designed with a tile map from an array and the only sprite is the player itself. When the player presses the right arrow key the x velocity of the player increases. What I would like to do is have friction between the ground and the player so that our player stops once they let go of the key. I know that you can do this with other sprites but can you do it with tilemaps?
With arcade physics it is abit difficult to do this (or more or less impossible). I personally would fake the friction by setting a callback with the method map.setTileLocationCallback, this callback sets the drag of the player (or if you have multiple layers, you could even define a layer for this case).
With matter physics engine it should be possible, checkout this demo and/or the documentation.
Here is a short Demo for arcade physics:
In this small demo, the player is moved with the cursor-keys.
(the player should slide less on the left side = more friction)
document.body.style = 'margin:0;';
let player;
let cursors;
let playerStateText;
let config = {
type: Phaser.AUTO,
width: 12 * 16,
height: 6 * 16,
zoom: 2,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 100 },
debug: true
}
},
scene: { create, preload, update },
banner: false
};
function preload () {
this.load.image('mario-tiles', 'https://labs.phaser.io/assets/tilemaps/tiles/super-mario.png');
}
function create () {
playerStateText = this.add.text(10, 10, 'Playerstate: ???', {color: '#ffffff', fontSize: 10})
.setDepth(10);
// Load a map from a 2D array of tile indices
let level = [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 39, 39, 39, 39, 39, 39, 14, 14, 14, 14, 14, 14 ]
];
// When loading from an array, make sure to specify the tileWidth and tileHeight
let map = this.make.tilemap({ data: level, tileWidth: 16, tileHeight: 16 });
let tiles = map.addTilesetImage('mario-tiles');
let layer = map.createLayer(0, tiles, 0, 0);
map.setCollision([ 39, 14], true, true, layer);
player = this.add.rectangle(10, 10, 8, 8, 0xffffff);
this.physics.add.existing(player);
player.body.setCollideWorldBounds(true);
// Just to be sure that the player doesn't get too fast
player.body.setMaxSpeed(160);
// Tweak this value to define how far/long the player should slide
player.body.setDrag(120, 0);
this.physics.add.collider(player, layer);
map.setTileLocationCallback(0, 4, 6, 1, _ => player.body.setDrag(1000, 0) )
map.setTileLocationCallback(6, 4, 6, 1, _ => player.body.setDrag(100, 0) )
cursors = this.input.keyboard.createCursorKeys();
}
function update(){
let currentState = 'Playerstate: running';
if (cursors.left.isDown){
player.body.setAccelerationX(-160);
} else if (cursors.right.isDown) {
player.body.setAccelerationX(160);
}
else {
player.body.setAccelerationX(0);
if(Math.abs(player.body.velocity.x) > 3) {
currentState = 'Playerstate: sliding';
} else if(Math.abs(player.body.velocity.y) > 3) {
currentState = 'Playerstate: falling';
} else {
currentState = 'Playerstate: stopped';
}
}
if(player.x > 400){
player.x = -20;
}
if(player.x < -20){
player.x = 400;
}
playerStateText.setText(currentState);
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
I have a "crosshair code" from CS:GO game: CSGO-O4Jsi-V36wY-rTMGK-9w7qF-jQ8WB
I can decode some values by using this function:
import BigNumber from 'bignumber.js';
// Intentionally no 0 and 1 number in DICTIONARY
const DICTIONARY = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijkmnopqrstuvwxyz23456789';
const DICTIONARY_LENGTH = DICTIONARY.length;
const SHARECODE_PATTERN = /CSGO(-?[\w]{5}){5}$/;
function bigNumberToByteArray(big) {
const str = big.toString(16).padStart(36, '0');
const bytes = [];
for (let i = 0; i < str.length; i += 2) {
bytes.push(parseInt(str.slice(i, i + 2), 16));
}
return bytes;
}
function bytesToInt32(bytes) {
let number = 0;
for (let i = 0; i < bytes.length; i++) {
number += bytes[i];
if (i < bytes.length - 1) {
number = number << 8;
}
}
return number;
}
const decode = shareCode => {
if (!shareCode.match(SHARECODE_PATTERN)) {
throw new Error('Invalid share code');
}
shareCode = shareCode.replace(/CSGO|-/g, '');
const chars = Array.from(shareCode).reverse();
let big = new BigNumber(0);
for (let i = 0; i < chars.length; i++) {
big = big.multipliedBy(DICTIONARY_LENGTH).plus(DICTIONARY.indexOf(chars[i]));
}
const bytes = bigNumberToByteArray(big);
return {
cl_crosshaircolor_r: bytesToInt32(bytes.slice(4, 5).reverse()),
cl_crosshaircolor_g: bytesToInt32(bytes.slice(5, 6).reverse()),
cl_crosshaircolor_b: bytesToInt32(bytes.slice(6, 7).reverse())
};
};
console.log(decode('CSGO-O4Jsi-V36wY-rTMGK-9w7qF-jQ8WB'))
// { cl_crosshaircolor_r: 50, cl_crosshaircolor_g: 250, cl_crosshaircolor_b: 84
I can't figure out how to get the rest of the values, because it does not show correct numbers.
I should get these values from it:
{
cl_crosshair_drawoutline: 0,
cl_crosshair_dynamic_maxdist_splitratio: 0.3,
cl_crosshair_dynamic_splitalpha_innermod: 0.6,
cl_crosshair_dynamic_splitalpha_outermod: 0.8,
cl_crosshair_dynamic_splitdist: 127,
cl_crosshair_outlinethickness: 1.5,
cl_crosshair_t: 1,
cl_crosshairalpha: 200,
cl_crosshaircolor: 5,
cl_crosshaircolor_b: 84,
cl_crosshaircolor_g: 250,
cl_crosshaircolor_r: 50,
cl_crosshairdot: 1,
cl_crosshairgap: 1,
cl_crosshairgap_useweaponvalue: 0,
cl_crosshairsize: 33,
cl_crosshairstyle: 2,
cl_crosshairthickness: 4.1,
cl_crosshairusealpha: 0,
cl_fixedcrosshairgap: -10
}
Additional examples:
CSGO-tEAHu-36Ro8-Oyms7-NVvnV-F6XDJ
{
cl_crosshair_drawoutline: 0,
cl_crosshair_dynamic_maxdist_splitratio: 0.1,
cl_crosshair_dynamic_splitalpha_innermod: 0.8,
cl_crosshair_dynamic_splitalpha_outermod: 0.6,
cl_crosshair_dynamic_splitdist: 13,
cl_crosshair_outlinethickness: 2,
cl_crosshair_t: 0,
cl_crosshairalpha: 250,
cl_crosshaircolor: 5,
cl_crosshaircolor_b: 90,
cl_crosshaircolor_g: 255,
cl_crosshaircolor_r: 55,
cl_crosshairdot: 1,
cl_crosshairgap: -2,
cl_crosshairgap_useweaponvalue: 0,
cl_crosshairsize: 10,
cl_crosshairstyle: 2,
cl_crosshairthickness: 4.5,
cl_crosshairusealpha: 1,
cl_fixedcrosshairgap: 12
}
CSGO-rGhtd-eWuUm-EWVO7-72rvk-zqAUM
{
cl_crosshair_drawoutline: 1,
cl_crosshair_dynamic_maxdist_splitratio: 0.9,
cl_crosshair_dynamic_splitalpha_innermod: 0.5,
cl_crosshair_dynamic_splitalpha_outermod: 0.6,
cl_crosshair_dynamic_splitdist: 12,
cl_crosshair_outlinethickness: 0.5,
cl_crosshair_t: 0,
cl_crosshairalpha: 189,
cl_crosshaircolor: 2,
cl_crosshaircolor_b: 123,
cl_crosshaircolor_g: 229,
cl_crosshaircolor_r: 67,
cl_crosshairdot: 1,
cl_crosshairgap: 3,
cl_crosshairgap_useweaponvalue: 0,
cl_crosshairsize: 7,
cl_crosshairstyle: 4,
cl_crosshairthickness: 1.2,
cl_crosshairusealpha: 0,
cl_fixedcrosshairgap: -5
}
CSGO-wQ3FD-JiRVa-kKcFt-6XfbF-uMD7K
{
cl_crosshair_drawoutline: 1,
cl_crosshair_dynamic_maxdist_splitratio: 0.9,
cl_crosshair_dynamic_splitalpha_innermod: 0.5,
cl_crosshair_dynamic_splitalpha_outermod: 0.6,
cl_crosshair_dynamic_splitdist: 12,
cl_crosshair_outlinethickness: 1.5,
cl_crosshair_t: 1,
cl_crosshairalpha: 158,
cl_crosshaircolor: 5,
cl_crosshaircolor_b: 198,
cl_crosshaircolor_g: 182,
cl_crosshaircolor_r: 91,
cl_crosshairdot: 1,
cl_crosshairgap: 1.4,
cl_crosshairgap_useweaponvalue: 1,
cl_crosshairsize: 6.4,
cl_crosshairstyle: 4,
cl_crosshairthickness: 1.8,
cl_crosshairusealpha: 1,
cl_fixedcrosshairgap: -5
}
Range of properties:
{
// acts like boolean
cl_crosshair_drawoutline: {
min: 0,
max: 1
},
cl_crosshair_dynamic_maxdist_splitratio: {
min: 0,
step: 0.1, // e.g: 0, 0.1, 0.2, 0.3 etc.
max: 1
},
cl_crosshair_dynamic_splitalpha_innermod: {
min: 0,
step: 0.1, // e.g: 0, 0.1, 0.2, 0.3 etc.
max: 1
},
cl_crosshair_dynamic_splitalpha_outermod: {
min: 0.3,
step: 0.1, // 0.3, 0.4, 0.5 etc.
max: 1
},
cl_crosshair_dynamic_splitdist: {
min: 0,
step: 1, // e.g: 0, 1, 2, 3, ..., 127
max: 127
},
cl_crosshair_outlinethickness: {
min: 0,
step: 0.5, // e.g: 0, 0.5, 1, ..., 3
max: 3
},
// acts like boolean
cl_crosshair_t: {
min: 0,
max: 1
},
cl_crosshairalpha: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 255
max: 255
},
cl_crosshaircolor: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 7
max: 7
},
cl_crosshaircolor_b: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 255
max: 255
},
cl_crosshaircolor_g: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 255
max: 255
},
cl_crosshaircolor_r: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 255
max: 255
},
// acts like boolean
cl_crosshairdot: {
min: 0,
max: 1
},
cl_crosshairgap: {
min: -12.8,
step: 0.1, // e.g: 10, 10.1 etc.
max: 12.7
},
// acts like boolean
cl_crosshairgap_useweaponvalue: {
min: 0,
max: 1
},
cl_crosshairsize: {
min: 0,
step: 0.1, // e.g: 0, 0.1, 0.2, 14.4 etc.
max: 819.100037 // can't say why such an unusual output
},
cl_crosshairstyle: {
min: 0,
step: 1, // e.g: 1, 2, 3, ..., 7
max: 7
}
cl_crosshairthickness: {
min: 0,
step: 0.1, // e.g: 0, 0.1, 0.2, ..., 6.3
max: 6.3
}
// acts like boolean
cl_crosshairusealpha: {
min: 0,
max: 1
},
cl_fixedcrosshairgap: {
min: -12.8,
step: 0.1, // e.g: 10, 10.1 etc.
max: 12.7
}
}
Values changed one at a time:
Default: CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
{
cl_crosshair_drawoutline: 1,
cl_crosshair_dynamic_maxdist_splitratio: 0.3,
cl_crosshair_dynamic_splitalpha_innermod: 1,
cl_crosshair_dynamic_splitalpha_outermod: 0.5,
cl_crosshair_dynamic_splitdist: 7,
cl_crosshair_outlinethickness: 1,
cl_crosshair_t: 0,
cl_crosshairalpha: 200,
cl_crosshaircolor: 1,
cl_crosshaircolor_b: 50,
cl_crosshaircolor_g: 250,
cl_crosshaircolor_r: 50,
cl_crosshairdot: 1,
cl_crosshairgap: 1,
cl_crosshairgap_useweaponvalue: 0,
cl_crosshairsize: 5,
cl_crosshairstyle: 2,
cl_crosshairthickness: 0.5,
cl_crosshairusealpha: 1,
cl_fixedcrosshairgap: 3
}
The only value changed is described beside, rest stays the same as default
above.
cl_crosshair_drawoutline
1 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
0 = CSGO-of9RX-KD5Fp-4kb7Q-EoVSz-cb7nM
cl_crosshair_dynamic_maxdist_splitratio
0 = CSGO-Vtkiw-zkx82-6AYMS-9OXdk-6yXHK
0.5 = CSGO-Trqu8-WUQCn-5MfrP-KDUGF-CFeKP
1 = CSGO-QMSEL-6KJoK-vvajh-WpPKZ-Bh2ED
cl_crosshair_dynamic_splitalpha_innermod
0 = CSGO-Tabp9-L98iF-Btmcu-64Das-MdaEC
0.5 = CSGO-HRKjJ-R5sqr-Q6t9r-GsADN-SthGH
1 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
cl_crosshair_dynamic_splitalpha_outermod
0.3 = CSGO-RBqva-DumOx-WPvGy-cDxic-5zcBN
0.7 = CSGO-jNCMK-q6UXz-pA93e-FAGu4-2GzQN
1 = CSGO-DWSPa-oEJum-4Tn8R-SrTXs-jxkbN
cl_crosshair_dynamic_splitdist
0 = CSGO-Dxzuf-AUuea-G7enM-c3Zza-sBhrM
50 = CSGO-LcTca-Laf43-7pmXZ-jnJGu-oS9zP
127 = CSGO-xa4d4-MN8pW-aETR7-jhzeQ-6DjjD
cl_crosshair_outlinethickness
0 = CSGO-aQUWL-7ysnT-Ve8rS-PHXDY-5zcBN
1.5 = CSGO-LhmCW-jzV4T-m6T4z-SOtbU-nhPNN
3 = CSGO-5x4rh-N29JU-3VqEY-WUF3Q-VPBYN
cl_crosshair_t
0 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
1 = CSGO-iyOcd-YLrjN-8xQqU-xZa3G-zjRFE
cl_crosshairalpha
0 = CSGO-sQOF4-9RKDe-sLeFU-wqGMn-uonpQ
200 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
255 = CSGO-BqGwL-hirNt-AX6Dy-YbCoB-fFDmQ
cl_crosshaircolor
0 = CSGO-4KA8L-stYs2-aqTxt-3R3GF-KZEFN
4 = CSGO-C8ZDo-TJrEr-uafja-dOLSe-GqZUN
7 = CSGO-JxAn9-Qa5UE-AvLpN-r6X6T-yWMfN
cl_crosshaircolor_b
0 = CSGO-8fuTL-n9Uqy-iF6pY-6tOYX-brNAK
200 = CSGO-xWpEr-keTtj-QmeUw-XpE3a-FCPcF
255 = CSGO-W58Ja-mo8Q6-e7Phv-3mK2v-NJn6J
cl_crosshaircolor_g
0 = CSGO-BvDs8-JUwK4-54sLY-c745T-yWMfN
200 = CSGO-h7whC-Uiy99-WKxr3-HLJYX-brNAK
255 = CSGO-Wnbcy-QvJ47-65Eqz-MQUXs-jxkbN
cl_crosshaircolor_r
0 = CSGO-uznHJ-WZpew-rQpJS-p2F8W-brNAK
200 = CSGO-aaBpx-XNVPr-zES6H-MTdMc-FCPcF
255 = CSGO-nOKuX-kEo8c-hBOZh-WaOpx-NJn6J
cl_crosshairdot
0 = CSGO-c8tdf-txA5L-UFDY3-zuu69-i6OJM
1 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
cl_crosshairgap
-12.8 = CSGO-N5fyF-u3u8M-4jU9j-O9vLu-aSYbD
0 = CSGO-qis8G-DpZxE-Z9QeN-upthN-OSveM
12.7 = CSGO-XuT3W-BvVvv-cvEFo-cM8iA-CtxXD
cl_crosshairgap_useweaponvalue
0 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
1 = CSGO-zYEbz-m4Zmk-5MfrP-KDUGF-CFeKP
cl_crosshairsize
0 = CSGO-hzFpv-XtPmX-wHSxa-LvOYX-brNAK
100 = CSGO-Cn2cE-Mau97-N4rOC-typ7o-ayzpH
819 = CSGO-GC68x-Jh9L4-73R6P-zjXN8-WGSyL
819.100037 = CSGO-MjLui-qkX6J-CUzmL-Pybui-mp33L
cl_crosshairstyle
0 = CSGO-TjyO2-rj2yR-OWps8-pjocQ-asS4M
4 = CSGO-ho3st-BGGwV-y3ERW-4bPzG-VPBYN
7 = CSGO-875F5-AdfP5-QfXa5-S3qGu-vnhvN
cl_crosshairthickness
0 = CSGO-r6TO2-WsYFC-K6GCD-RVj6o-MKsyM
3.1 = CSGO-ToYxk-5EQKD-ciNhr-tn3ya-kq8vO
6.3 = CSGO-LAYaa-DEf8T-2n2tR-mKQRz-OwxwQ
cl_crosshairusealpha
0 = CSGO-GfZhN-2sjMv-t8iFe-hcMv4-Gw8GJ
1 = CSGO-6G2cS-WzcxT-fH3dp-Rf7oq-X9oJN
cl_fixedcrosshairgap
-12.80 = CSGO-OPDHV-Ab3cf-pmoFG-8ecMS-eNqRP
0 = CSGO-NJ6Z7-bRb8Y-qSBRv-cZ8Ys-7xSOG
12.70 = CSGO-SSCsS-u4nYT-rKGYL-iRYoq-QoFOP
Here you go. Add this parseBytes function, modify decode as shown, and keep the rest of your code as it.
function parseBytes(bytes) {
return {
cl_crosshairgap: Int8Array.of(bytes[2])[0] / 10.0,
cl_crosshair_outlinethickness: (bytes[3] & 7) / 2.0,
cl_crosshaircolor_r: bytes[4],
cl_crosshaircolor_g: bytes[5],
cl_crosshaircolor_b: bytes[6],
cl_crosshairalpha: bytes[7],
cl_crosshair_dynamic_splitdist: bytes[8],
cl_fixedcrosshairgap: Int8Array.of(bytes[9])[0] / 10.0,
cl_crosshaircolor: bytes[10] & 7,
cl_crosshair_drawoutline: bytes[10] & 8 ? 1 : 0,
cl_crosshair_dynamic_splitalpha_innermod: ((bytes[10] & 0xF0) >> 4) / 10.0,
cl_crosshair_dynamic_splitalpha_outermod: (bytes[11] & 0xF) / 10.0,
cl_crosshair_dynamic_maxdist_splitratio: ((bytes[11] & 0xF0) >> 4) / 10.0,
cl_crosshairthickness: (bytes[12] & 0x3F) / 10.0,
cl_crosshairstyle: (bytes[13] & 0xE) >> 1,
cl_crosshairdot: bytes[13] & 0x10 ? 1 : 0,
cl_crosshairgap_useweaponvalue: bytes[13] & 0x20 ? 1 : 0,
cl_crosshairusealpha: bytes[13] & 0x40 ? 1 : 0,
cl_crosshair_t: bytes[13] & 0x80 ? 1 : 0,
cl_crosshairsize: (((bytes[15] & 0x1f) << 8) + bytes[14]) / 10.0
};
}
const decode = shareCode => {
if (!shareCode.match(SHARECODE_PATTERN)) {
throw new Error('Invalid share code');
}
shareCode = shareCode.replace(/CSGO|-/g, '');
const chars = Array.from(shareCode).reverse();
let big = new BigNumber(0);
for (let i = 0; i < chars.length; i++) {
big = big.multipliedBy(DICTIONARY_LENGTH).plus(DICTIONARY.indexOf(chars[i]));
}
return parseBytes(bigNumberToByteArray(big));
}
I'm trying to pass uv buffer as well as the normal buffer in webgl. But for some reason I get this warning vertexAttribPointer: index out of range when passing values. I don't get what I m doing wrong since the uv array seems to be good, same goes for the normals.
It seems like the errors only occured with normal and uv not with position.
enableVertexAttribArray: index out of range
vertexAttribPointer: index out of range
let canvas = document.querySelector("canvas");
let gl = canvas.getContext("webgl");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const vsSource = `
attribute vec4 position;
attribute vec2 uv;
attribute vec3 normal;
uniform mat4 modelViewMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = position;
}
`;
const fsSource = `
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vec4(1.0,0.0,1.0,1.0);
}
`;
// Shader setup
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(vertexShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
var log = gl.getShaderInfoLog(fragmentShader);
throw "Shader compilation failed\n\n" + log + "\n\n";
}
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
var log = gl.getProgramInfoLog(program);
throw "Program link failed\n\n" + log;
}
gl.useProgram(program);
let modelViewMatrix = gl.getUniformLocation(program, "modelViewMatrix");
let model = mat4.create();
gl.uniformMatrix4fv(modelViewMatrix, false, model);
var vertices = new Float32Array([
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
0.5,
-0.5,
0.5,
0.5,
0.5,
-0.5,
-0.5,
0.5,
-0.5,
0.5,
-0.5,
-0.5,
-0.5,
-0.5,
-0.5
]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
let position = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);
var uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0,
0,
1,
1,
1,
0,
0,
1,
0
]),
gl.STATIC_DRAW
);
let uv = gl.getAttribLocation(program, "uv");
gl.vertexAttribPointer(uv, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(uv);
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1,
0,
0,
-1
]),
gl.STATIC_DRAW
);
let normal = gl.getAttribLocation(program, "normal");
gl.vertexAttribPointer(normal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normal);
var indices = new Uint16Array([
0,
2,
1,
2,
3,
1,
4,
6,
5,
6,
7,
5,
8,
10,
9,
10,
11,
9,
12,
14,
13,
14,
15,
13,
16,
18,
17,
18,
19,
17,
20,
22,
21,
22,
23,
21
]);
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
<canvas></canvas>
Your shaders are not using uv or normal so your driver is optimizing out those attributes. In that case gl.getAttribLocation returns -1 for location (-1 = attribute by this name does not exist). -1 is out of range. Valid values are 0 to gl.getParameter(gl.MAX_VERTEX_ATTRIBS) - 1
In other words you need check the location of your attributes and if they don't exist, don't set them up.
This is one reason why it's good to write some helper functions for WebGL to kind of handle these issues for you so as you modify your shaders your code doesn't break.
Though I have been able to create and use animations for small demos in the past using the CreateJS library, i'm currently stumped in trying to understand why Nothing is displaying to the canvas even though I have verified that my animation tiles are all being added. I'm going senile from stepping through the debugger and seeing everything work properly, but getting a completely blank page on reloads.
Any ideas are much appreciated!
var stage, loader;
function tick() {
stage.update();
}
function generateMap(rekeyed_array, spriteSheet, row_length, col_length, tilesize) {
for (var x = 0; x < col_length; x++) {
for (var y = 0; y < row_length; y++) {
// z is a onedimentional value mapped from x and y iterators
spriteInstance = new createjs.Sprite(spriteSheet, rekeyed_array[z]);
var z = x * row_length + y;
spriteInstance.x = tilesize * x;
spriteInstance.y = tilesize * y;
spriteInstance.gotoAndPlay(rekeyed_array[z]);
spriteInstance = spriteInstance.clone();
stage.addChild(spriteInstance);
}
}
console.groupEnd();
stage.update();
}
//Replace Tiled's map data numbers with the actual Game Object's Names
function rekeyTiledMapData(spritemappings, array_to_reindex, rows, cols) {
var reindexedArray = new Array();
for (var y = 0; y < cols; y++) {
for (var x = 0; x < rows; x++) {
// z is a onedimentional value mapped from x and y iterators
var z = y * rows + x;
var currentItem = array_to_reindex[z];
if (typeof spritemappings[currentItem] === "string") {
reindexedArray.push(spritemappings[currentItem]);
} else {
reindexedArray.push(currentItem);
}
}
}
return reindexedArray;
}
function getSpriteData(loadedimg) {
var data = {
framerate: 60,
images: [loadedimg],
frames: [
/*middlearth*/
[592, 654, 70, 70, 0, 0, 0],
/*water*/
[562, 434, 70, 70, 0, 0, 0],
/*doormid*/
[146, 290, 70, 70, 0, 0, 0],
/*doortop*/
[218, 290, 70, 70, 0, 0, 0],
/*grass*/
[736, 362, 70, 70, 0, 0, 0]
],
animations: {
"sand": {
frames: 0,
next: "sand",
speed: 1
},
"water": {
frames: 1,
next: "water",
speed: 1
},
"doormid": [2, 2, "doormid", 1],
"doortop": [3, 3, "doortop", 1],
"grass": [4, 4, "grass", 1],
}
};
return data;
}
var mapdata = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5];
var spritemappings = {
'0': "water",
'8': "water",
'7': "water",
'5': "sand",
'6': "grass",
'10': "doortop",
'11': "doormid"
};
function loadLevel(event) {
var tileimage = loader.getResult("tiles");
levelanimations = rekeyTiledMapData(spritemappings, mapdata, 16, 10);
var spritesheet = new createjs.SpriteSheet(getSpriteData(tileimage));
generateMap(levelanimations, spritesheet, 16, 10, 70);
}
function init() {
stage = new createjs.Stage("gameCanvas");
createjs.Ticker.on("tick", tick);
createjs.Ticker.setFPS(60);
loader = new createjs.LoadQueue(false);
loader.addEventListener("complete", loadLevel)
loader.loadManifest({
id: "tiles",
src: "assets/images/level_tiles.png"
});
}
init();
</script>
</head>
<body>
<canvas id="gameCanvas" width="1600" height="900"></canvas>
</body>
If that script is a copy and paste, the script in the head is executed before the body is being created. Thats why you are seeing that it is executing correctly, but nothing is actually happening.
I would copy and paste the script tag in the header down below the canvas element.
http://www.google.com/chromebook/#features
When you hover the logo, you can see a shiny animation.
I have looked into the source code but it doesn't look like done with :hover
any idea about how they do it?
Thank you very much
It's using the CHEDDAR Canvas Animation Framework by Eric Lee. Cheddar is based off of Cake.js by Ilmari Heikkinen http://code.google.com/p/cakejs/
This file : http://www.gstatic.com/chromebook/js/third_party/chromeicons-main.min.js
Look at the HTML source. It's done using a <canvas>.
<div id="header-logo">
<noscript>
<a data-g-label="MAIN-NAV-HOME" href="index.html" id="header-logo-noscript">
<img alt="Chrome" src="static/images/chromelogo-124x34.png">
</a>
</noscript>
<canvas height="40" id="canvas-logo" width="123">
<a data-g-label="MAIN-NAV-HOME" href="index.html">
<img alt="Chrome" src="static/images/chromelogo-124x34.png">
</a>
</canvas>
</div>
The relevant script appears to be chromeicons-main.min.js.
It's done with a canvas element.
Firebug says it's a canvas, which means HTML5.
The script http://www.gstatic.com/chromebook/js/third_party/chromeicons-main.min.js appears to contain a "canvas animation framework" that does the job.
If you look sources, you will see they use CHEDDAR Canvas Animation Framework to animate this logo.
looks like some canvas stuff to me. (nice beginner tutorial here)
This appears to be the relevant portion of chromeicons-main.min.js. for the chrome logo itself.
ChromeLogo = CClass(CanvasNode, {
center_gradient: new Gradient({
type: "radial",
startX: 7,
startY: -7,
endRadius: 14,
colorStops: [
[1, "#005791"],
[0.62, "#2284DC"],
[0, "#86B9E2"]
]
}),
center_back: new Gradient({
type: "radial",
endRadius: 14,
colorStops: [
[0, "#D2D2D2"],
[1, "#FFFFFF"]
]
}),
top_gradient: new Gradient({
type: "radial",
endRadius: 16,
colorStops: [
[0.15, "#F37C65"],
[1, [243, 124, 90, 0]]
]
}),
highlight_gradient3: new Gradient({
type: "radial",
startX: 0,
startY: 0,
endRadius: 40,
colorStops: [
[1, "rgba(255,255,255,0)"],
[0.4, "rgba(255,255,255,.4)"],
[0, "rgba(255,255,255,0)"]
]
}),
highlight_gradient4: new Gradient({
type: "radial",
startX: 0,
startY: 0,
endRadius: 8,
colorStops: [
[1, "rgba(255,255,255,0)"],
[0.4, "rgba(255,255,255,.5)"],
[0, "rgba(255,255,255,0)"]
]
}),
highlight_gradient5: new Gradient({
type: "radial",
startX: 0,
startY: 0,
endRadius: 8,
colorStops: [
[1, "rgba(255,255,255,0)"],
[0.5, "rgba(255,255,255,.9)"],
[0, "rgba(255,255,255,0)"]
]
}),
initialize: function () {
CanvasNode.initialize.call(this);
this.scale = 0.78;
this.catchMouse = false;
this.textGlow = new Circle(30, {
fill: this.highlight_gradient5,
x: 22,
y: 23,
zIndex: 2
});
this.append(this.textGlow);
this.center = new Circle(7.5, {
fill: this.center_gradient,
x: 22,
y: 23,
zIndex: 4,
clip: true
});
this.centerBack = new Circle(9, {
fill: this.center_back,
x: 22,
y: 23,
zIndex: 3
});
this.border = new CanvasNode({
zIndex: 2
});
this.mask = new CanvasNode({
x: 22,
y: 23
});
this.ch3 = new Circle(8, {
fill: this.highlight_gradient4,
scale: 0.1,
opacity: 0,
compositeOperation: "lighter"
});
this.center.append(this.ch3);
this.red = _iconController.asset("logo_red");
this.red.childNodes[0].clip = true;
this.red.setProps({
x: -17,
y: -20,
clip: true
});
this.redShadow = _iconController.asset("shadow_red");
this.redShadow.setProps({
x: -17,
y: -13,
zIndex: 2
});
this.rh3 = new Circle(40, {
fill: this.highlight_gradient3,
scale: 0.1,
opacity: 1,
compositeOperation: "lighter",
x: 17,
y: 20,
zIndex: 4
});
this.red.childNodes[0].append(this.rh3);
this.yellow = _iconController.asset("logo_yellow");
this.yellow.setProps({
x: -1.5,
y: -9
});
this.yellow.childNodes[0].clip = true;
this.yellowShadow = _iconController.asset("shadow_yellow");
this.yellowShadow.setProps({
zIndex: 2,
x: 1,
y: -9
});
this.yh3 = new Circle(40, {
fill: this.highlight_gradient3,
scale: 0.1,
opacity: 1,
compositeOperation: "lighter",
x: 1.5,
y: 9,
zIndex: 4
});
this.yellow.childNodes[0].append(this.yh3);
this.green = _iconController.asset("logo_green");
this.green.setProps({
x: -20,
y: -11
});
this.green.childNodes[0].clip = true;
this.greenShadow = _iconController.asset("shadow_green");
this.greenShadow.setProps({
x: -2,
y: 5,
zIndex: 2
});
this.gh3 = new Circle(40, {
fill: this.highlight_gradient3,
scale: 0.1,
opacity: 1,
compositeOperation: "lighter",
x: 20,
y: 11.5,
zIndex: 4
});
this.green.childNodes[0].append(this.gh3);
this.top = new Circle(19, {
fill: false,
clip: true,
x: 24,
y: 23,
zIndex: 5
});
this.topGrad = new Circle(19, {
fill: this.top_gradient,
x: -2,
y: -24
});
this.mask.append(this.red, this.redShadow, this.yellow, this.yellowShadow, this.green, this.greenShadow);
this.border.append(this.mask);
this.top.append(this.topGrad);
this.append(this.border, this.centerBack, this.center, this.top);
this.text = _iconController.asset("logo_text");
this.text.setProps({
x: 49,
y: 8
});
for (var a = 0; a < this.text.childNodes[0].childNodes.length; a++) {
this.text.childNodes[0].childNodes[a].opacity = 1
}
this.append(this.text)
},
mouseOver: function () {
this.canvas.play();
_tw.removeTweensOf([this.textGlow, this.rh3, this.yh3, this.gh3, this.ch3]);
this.textGlow.scale = this.ch3.scale = this.rh3.scale = this.gh3.scale = this.yh3.scale = 0.1;
this.textGlow.opacity = this.rh3.opacity = this.gh3.opacity = this.yh3.opacity = 1;
var a = new Array(0, 0.1, 0.2, 0.3);
var b = shuffle(a);
_tw.addTween(this.center, {
time: 0.1,
scale: 1.02,
transition: "easeOutQuad"
});
_tw.addTween(this.centerBack, {
time: 0.1,
scale: 1.02,
transition: "easeOutQuad"
});
_tw.addTween(this.mask, {
time: 0.1,
scale: 1.02,
transition: "easeOutQuad",
onComplete: function (c) {
_tw.addTween(c.center, {
time: 0.5,
scale: 1,
transition: "easeInOutBack"
});
_tw.addTween(c.centerBack, {
time: 0.55,
scale: 1,
transition: "easeInOutBack"
});
_tw.addTween(c.mask, {
time: 0.55,
scale: 1,
transition: "easeInOutBack"
})
},
onCompleteParams: [this]
});
_tw.addTween(this.rh3, {
time: 2,
delay: b[0],
scale: 4,
opacity: 0,
transition: "easeOutCubic"
});
_tw.addTween(this.yh3, {
time: 2,
delay: b[1],
scale: 4,
opacity: 0,
transition: "easeOutCubic"
});
_tw.addTween(this.gh3, {
time: 2,
delay: b[2],
scale: 4,
opacity: 0,
transition: "easeOutCubic"
});
_tw.addTween(this.ch3, {
time: 0.2,
delay: b[3],
scale: 10,
opacity: 1,
transition: "linear",
onComplete: function (c) {
_tw.addTween(c.ch3, {
time: 0.25,
opacity: 0
})
},
onCompleteParams: [this]
});
_tw.addTween(this.textGlow, {
time: 10,
delay: 0.5,
scale: 120,
opacity: 0.2,
onComplete: function (c) {
c.canvas.stop()
},
onCompleteParams: [this]
})
},
mouseOut: function () {}
});
_iconController.initializeIcon("canvas-logo", ChromeLogo);