Having trouble rendering a sphere in WebGL - webgl

I'm learning WebGL and am trying to display a sphere. No textures, just each vertex coloured, but I'm getting the following error message in Opera and Chrome:
"[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 "
I don't understand what I'm doing wrong because the code looks fine to me, but I'm obviously missing something.
Thanks!
Michael
(It is adapted from lessons 4 and 11 from http://learningwebgl.com.)
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();
function mvPushMatrix() {
var copy = mat4.create();
mat4.copy(copy, mvMatrix);
mvMatrixStack.push(copy);
}
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
var sphereVertexPositionBuffer;
var sphereVertexColorBuffer;
var sphereVertexIndexBuffer;
function initBuffers() {
var latitudeBands = 10;
var longitudeBands = 10;
var radius = 2;
sphereVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
sphereVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
sphereVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
var vertexPositionData = [];
var colors = [];
var indexData = [];
for (var latNumber=0; latNumber <= latitudeBands; latNumber++) {
var theta = latNumber * Math.PI / latitudeBands;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
for (var longNumber=0; longNumber <= longitudeBands; longNumber++) {
var phi = longNumber * 2 * Math.PI / longitudeBands;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);
var x = cosPhi * sinTheta;
var y = cosTheta;
var z = sinPhi * sinTheta;
colors = [[1.0, 1.0, 0.3, 1.0]];
vertexPositionData.push(radius * x);
vertexPositionData.push(radius * y);
vertexPositionData.push(radius * z);
var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;
indexData.push(first);
indexData.push(second);
indexData.push(first + 1);
indexData.push(second);
indexData.push(second + 1);
indexData.push(first + 1);
}
}
var unpackedColors = [];
for (var i in colors) {
var color = colors[i];
for (var j=0; j < 4; j++) {
unpackedColors = unpackedColors.concat(color);
}
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
sphereVertexPositionBuffer.itemSize = 3;
sphereVertexPositionBuffer.numItems = vertexPositionData.length / 3;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColors), gl.STATIC_DRAW);
sphereVertexColorBuffer.itemSize = 4;
sphereVertexColorBuffer.numItems = unpackedColors.length / 4;
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
sphereVertexIndexBuffer.itemSize = 1;
sphereVertexIndexBuffer.numItems = indexData.length;
}
var rSphere = 0;
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(pMatrix, 60, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -5.0]);
mvPushMatrix();
mat4.rotate(mvMatrix, mvMatrix, degToRad(rSphere), [1, 1, 1]);
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, sphereVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, sphereVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES, sphereVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
mvPopMatrix();
}
var lastTime = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;
rSphere -= (75 * elapsed) / 1000.0;
}
lastTime = timeNow;
}
function tick() {
requestAnimFrame(tick);
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("lesson04-canvas");
initGL(canvas);
initShaders()
initBuffers();
gl.clearColor(0.0, 0.0, 0.1, 1.0);
gl.enable(gl.DEPTH_TEST);
tick();
}

I found the problem!
I included the index creation in the loops (less than or equal to):
for (var latNumber=0; latNumber <= latitudeBands; latNumber++)
for (var longNumber=0; longNumber <= longitudeBands; longNumber++)
Instead of its own loops (less than):
for (var latNumber=0; latNumber < latitudeBands; latNumber++)
for (var longNumber=0; longNumber < longitudeBands; longNumber++)

Related

Why is not WebGL drawing point?

I can't understand what I do wrong, my mind going to blow
I just pushing value to list and want to draw point using this list like vertices(0)=x,vertices(1)=y and what to do if I have much point like
vertices(0)=x1,vertices(1)=y1,vertices(2)=x2,vertices(3)=y2 (about 600 points)?
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n'+'void main() {\n'+' gl_Position = a_Position;\n' + ' gl_PointSize = 10.0;\n' + '}\n';
var FSHADER_SOURCE='void main() {\n'+'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + '}\n';
function main() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if (!gl) {console.log('Failed to get the rendering context for WebGL');
return;}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.'); return; }
var n = initVertexBuffers(gl);
if (n < 0) {console.log('Failed to set the positions of the vertices');
return;}
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, n);
}
var vertices = [];
function initVertexBuffers(gl) {vertices.push(0.1);vertices.push(0.3);
var n = vertices.length/2; var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) { console.log('Failed to create the buffer object');
return -1; }
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {console.log('Failed to get the storage location of a_Position'); return -1; }
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position); return n; }
And file
initVertexBuffers
function initShaders(gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('Failed to create program');
return false;
} gl.useProgram(program);gl.program = program;return true; }
function createProgram(gl, vshader, fshader) {
var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) { return null;}
var program = gl.createProgram();
if (!program) {return null;}
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('Failed to link program: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
} return program;}
function loadShader(gl, type, source) {
var shader = gl.createShader(type);
if (shader == null) {console.log('unable to create shader');
return null;}
gl.shaderSource(shader, source);
gl.compileShader(shader);
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {var error = gl.getShaderInfoLog(shader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(shader);return null;}return shader;}
function getWebGLContext(canvas, opt_debug) {
var gl = WebGLUtils.setupWebGL(canvas);
if (!gl) return null;
if (arguments.length < 2 || opt_debug) {
gl = WebGLDebugUtils.makeDebugContext(gl);
} return gl; }
At a glance this code
var vertices = [];
function initVertexBuffers(gl) {
vertices.push(0.1);
vertices.push(0.3);
var n = vertices.length/2;
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log('Failed to create the buffer object');
return -1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
won't work because gl.bufferData does not take JavaScript native arrays. It only takes typed arrays.
You probably want this
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var VSHADER_SOURCE = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
gl_PointSize = 10.0;
}
`;
var FSHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
function main() {
var canvas = document.getElementById('webgl');
var gl = canvas.getContext("webgl");
if (!gl)
{
console.log('Failed to retrieve the <canvas> element');
return;
}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE))
{
console.log('Failed to intialize shaders.');
return;
}
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var n = initVertexBuffers(gl);
if (n < 0) {console.log('Failed to set the positions of the vertices');
return;}
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, n);
}
var vertices = [];
function initVertexBuffers(gl) {
vertices.push(0.1);
vertices.push(0.3);
var n = vertices.length/2;
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log('Failed to create the buffer object');
return -1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
return n;
}
// THIS IS A POORLY WRITTEN FUNCTION!!!!
// Normal WebGL pages use multiple shader programs
// therefore you should **NEVER** assign values to
// the gl object!!!
function initShaders(gl, vsrc, fsrc) {
gl.program = twgl.createProgram(gl, [vsrc, fsrc]);
gl.useProgram(gl.program);
return !!gl.program;
}
main();
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<canvas id="webgl"></canvas>

WebGL High GPU Usage

I am drawing thousand of colored quads by using WebGL (no any framework) and on my laptop, around 80k quads moves nicely in 60fps but more than 80K quads, fps starts waving regularly. Like a few frame 30fp, one frame 60 fps. When i check it Chrome's performance tools, i noticed that GPU is taking too much time.
This is how Chrome Performance tool look like when i run 100k quads
This is my example with no moving quads. Dynamic one also has same effect but STATIC one shows my problem better since no JS overhead.
My code here:
var objects = [];
var MAX_COUNT = 10000;
var projectionMatrix;
var gl;
var positionVertexBuffer;
var colorVertexBuffer;
var indicesBuffer;
{
gl = document.getElementById("renderCanvas").getContext("webgl", {preserveDrawingBuffer: false});
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.DEPTH_TEST);
document.getElementById("renderCanvas").onclick = createObjects;
createObjects();
requestAnimationFrame(updateScreen);
}
function createObjects () {
projectionMatrix = new Float32Array([
0.0033333333333333335,0,0,
0,-0.0033333333333333335,0,
0,0,1
]);
var rObject = {};
rObject.projectionMatrix = projectionMatrix;
createPrograms(rObject);
createAttributes(rObject);
createMoveObjects(rObject);
rObject.id = "id_" + objects.length ;
objects.push(rObject);
}
function createMoveObjects (outObject) {
outObject.points = [];
var k = 0;
for (var i = 0; i < MAX_COUNT; i++) {
var x = (Math.random() * 600) - 300;
var y = (Math.random() * 600) - 300;
var vx = (Math.random() * 10) - 5;
var vy = (Math.random() * 10) - 5;
var size = 30 + Math.random() * 1;
var w = 26 / 2;
var h = 37 / 2;
var p = {w:w, h:h, x:x, y:y, vx:vx, vy:vy, size:size};
outObject.points.push(p);
}
}
var shaderProgram;
function createPrograms(outObject) {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById("vertexShader").textContent );
gl.compileShader(vertexShader);
if ( !gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) ) {
let finfo = gl.getShaderInfoLog( vertexShader );
console.log("Vertex Shader Fail" , finfo);
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById("fragmentShader").textContent);
gl.compileShader(fragmentShader);
if ( !gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) ) {
let finfo = gl.getShaderInfoLog( fragmentShader );
console.log("Fragment Shader Fail" , finfo);
}
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
var pmlocation = gl.getUniformLocation(shaderProgram,"projectionMatrix");
gl.useProgram(shaderProgram);
gl.uniformMatrix3fv(pmlocation, false , outObject.projectionMatrix);
outObject.projectionMatrixLocation = pmlocation;
outObject.shaderProgram = shaderProgram;
}
function createAttributes(outObject) {
var vertices = new Float32Array(MAX_COUNT * 8);
var colors = new Float32Array(MAX_COUNT * 12);
var indices = new Uint16Array(6 * MAX_COUNT);
var index = 0;
for (var i = 0; i < indices.length; i+=6) {
indices[i ] = index;
indices[i + 1] = index + 1;
indices[i + 2] = index + 2;
indices[i + 3] = index + 1;
indices[i + 4] = index + 3;
indices[i + 5] = index + 2;
index += 4;
}
var r,g,b;
for (var i = 0; i < colors.length; i+=12) {
r = Math.random();
g = Math.random();
b = Math.random();
colors[i] = r;
colors[i + 1] = g;
colors[i + 2] = b;
colors[i + 3] = r;
colors[i + 4] = g;
colors[i + 5] = b;
colors[i + 6] = r;
colors[i + 7] = g;
colors[i + 8] = b;
colors[i + 9] = r;
colors[i + 10] = g;
colors[i + 11] = b;
}
var k = 0;
var w = 26 / 2;
var h = 37 / 2;
var x,y;
for (var i = 0; i < vertices.length; i++) {
x = (Math.random() * 600) - 300;
y = (Math.random() * 600) - 300;
vertices[k] = -w + x; vertices[k + 1] = h + y;
vertices[k + 2] = -w + x; vertices[k + 3] = -h + y;
vertices[k + 4] = w + x; vertices[k + 5] = h + y;
vertices[k + 6] = w + x; vertices[k + 7] = -h + y;
k +=8;
}
positionVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
positionVertexBuffer.location = gl.getAttribLocation(shaderProgram,"position");
gl.vertexAttribPointer(positionVertexBuffer.location,2 ,gl.FLOAT, false, 0,0);
gl.enableVertexAttribArray(positionVertexBuffer.location);
colorVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
colorVertexBuffer.location = gl.getAttribLocation(shaderProgram,"color");
gl.vertexAttribPointer(colorVertexBuffer.location,3 ,gl.FLOAT, false, 0,0);
gl.enableVertexAttribArray(colorVertexBuffer.location);
indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
outObject.positionVertexBuffer = positionVertexBuffer;
outObject.colorVertexBuffer = colorVertexBuffer;
outObject.indicesBuffer = indicesBuffer;
outObject.vertices = vertices;
outObject.indices = indices;
outObject.colors = colors;
outObject.colorVertexLocation = colorVertexBuffer.location;
outObject.positionVertexLocation = positionVertexBuffer.location;
}
function updateAllPoints() {
var points;
var p;
for (var i = 0; i < objects.length; i++) {
points = objects[i].points;
var k = 0;
for (var j = 0; j < points.length; j++) {
p = points[j];
p.x += p.vx;
p.y += p.vy;
if(p.x >= 300){
p.x = 300;
p.vx *= -1;
} else if(p.x <= -300) {
p.x = -300;
p.vx *= -1;
} else if(p.y >= 300){
p.y = 300;
p.vy *= -1;
} else if(p.y <= -300) {
p.y = -300;
p.vy *= -1;
}
var vertices = objects[i].vertices;
vertices[k] = -p.w + p.x; vertices[k + 1] = p.h + p.y;
vertices[k + 2] = -p.w + p.x; vertices[k + 3] = -p.h + p.y;
vertices[k + 4] = p.w + p.x; vertices[k + 5] = p.h + p.y;
vertices[k + 6] = p.w + p.x; vertices[k + 7] = -p.h + p.y;
k +=8;
}
}
}
function renderScene() {
// updateAllPoints();
var totalDraw = 0;
gl.clearColor(0.3,0.3,0.3,1);
gl.clear(gl.COLOR_BUFFER_BIT);
var rO;
for (var i = 0; i < objects.length; i++) {
rO = objects[i];
drawObjects(rO);
totalDraw += MAX_COUNT;
}
document.getElementById("objectCounter").innerHTML = totalDraw + " Objects"
}
function drawObjects (rO) {
gl.useProgram(rO.shaderProgram);
gl.bindBuffer(gl.ARRAY_BUFFER, rO.positionVertexBuffer);
// gl.bufferSubData(gl.ARRAY_BUFFER, 0, rO.vertices);
gl.vertexAttribPointer(rO.positionVertexLocation,2 ,gl.FLOAT, false, 0,0);
gl.bindBuffer(gl.ARRAY_BUFFER, rO.colorVertexBuffer);
gl.vertexAttribPointer(rO.colorVertexLocation,3 ,gl.FLOAT, false, 0,0);
gl.drawElements(gl.TRIANGLES,MAX_COUNT * 6 , gl.UNSIGNED_SHORT, 0);
}
function updateScreen() {
if(gl){
renderScene();
requestAnimationFrame(updateScreen);
}
}
<script id="vertexShader" type="x-shader/x-vertex">
uniform mat3 projectionMatrix;
attribute vec2 position;
attribute vec3 color;
varying vec3 colorData;
void main() {
colorData = color;
vec3 newPos = vec3(position.x, position.y, 1.0 ) * projectionMatrix;
gl_Position = vec4(newPos , 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision lowp float;
uniform sampler2D uSampler;
varying vec3 colorData;
void main() {
gl_FragColor = vec4(colorData, 1.0);
}
</script>
<canvas id="renderCanvas" width="200" height="200"></canvas>
<div id="objectCounter">10000 Objects</div>
<div>Evevy Click adds 10K Squares </div>
I also checked other examples and found PixiJS's Bunnymark test where you can run 120k bunnies in 60fps but no GPU overhead.
When comparing Bunnymark test, my GPU is taking too much time and I don't know why. I opimized it (of I think I did) but problem insists.
It turned out it is because of i left antialias default as context attributes which seems "true". Can't believe i did not notice.
This code worked for me
canvasDom.getContext("webgl", {antialias : false});
Use scene.remove(mesh) OR mesh.parent.remove(mesh)

Webgl Circle without using extrernal library

I am new to webgl and at this point I am able to create a triangle and square.
I am finding it difficult to understand how to create a circle with out any external scripts or libraries.
var vertexShaderText =
[
'uniform vec2 u_resolution;',
'',
'attribute vec2 a_position;',
'',
'void main()',
'{',
'',
'vec2 clipspace = a_position / u_resolution * 1.0 ;',
'',
'gl_Position = vec4(clipspace * vec2(2.5, 2.0), 0, 1);',
'}'
].join("\n");
var fragmentShaderText =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0, 0, 0, 1.0);',
'',
'}'
].join("\n");
var uni = function(){
var canvas = document.getElementById("game-surface");
var gl = canvas.getContext("webgl");
console.log("This is working");
gl.clearColor(0.412,0.412,0.412,1);
gl.clear(gl.COLOR_BUFFER_BIT);
var vertextShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertextShader,vertexShaderText);
gl.shaderSource(fragmentShader,fragmentShaderText);
gl.compileShader(vertextShader);
gl.compileShader(fragmentShader);
if(!gl.getShaderParameter(vertextShader,gl.COMPILE_STATUS)){
console.error("Error with vertexshader",gl.getShaderInfoLog(vertextShader));
return;
}
if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
console.error("Error with fragmentShader",gl.getShaderInfoLog(fragmentShader));
return;
}
var program =gl.createProgram();
gl.attachShader(program,vertextShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if(!gl.getProgramParameter(program,gl.VALIDATE_STATUS)){
console.error("Error validating",gl.getProgramInfoLog(program));
}
var circle = {x: 0, y:0, r: 75};
var ATTRIBUTES = 2;
var numFans = 64;
var degreePerFan = (2* Math.PI) / numFans;
var vertexData = [circle.x, circle.y];
for(var i = 0; i <= numFans; i++) {
var index = ATTRIBUTES * i + 2; // there is already 2 items in array
var angle = degreePerFan * (i+0.1);
vertexData[index] = circle.x + Math.cos(angle) * circle.r;
vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
}
var vertexDataTyped = new Float32Array(vertexData);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
gl.enableVertexAttribArray(positionLocation);
var positionLocation = gl.getAttribLocation(program, "a_position");
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);
};

WebGL: Simple Texture Rendering Issue ("Drawing to a destination rect smaller than the viewport rect.")

I am currently trying to render a simple texture with WebGL.
This is basically a port from normal system OpenGL.
It doesn't seem to work and I seriously have no idea what's wrong as it also seems very difficult to debug these thing.
I am getting an error on Firefox though:
"Error: WebGL: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once)"
The viewport / projection matrix / positions seem to be correct so why am I getting that error?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test</title>
<style>
.canstyle {
width: 800px;
height: 600px;
}
</style>
</head>
<body>
<canvas id="canvas0" class="canstyle">
</canvas>
<script type='text/javascript'>
var vertexShaderSrc = `
precision mediump float;
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat3 projectionMatrix;
varying vec2 vTextureCoord;
void main() {
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
}
`;
var fragmentShaderSrc = `
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main() {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
var img1 = new Image(); // HTML5 Constructor
img1.src = 'bunny.png';
img1.alt = 'alt';
img1.onload = function() {
render();
}
function render() {
var canvas = document.getElementById("canvas0");
var gl = canvas.getContext("webgl", {
alpha: false,
depth: false,
stencil: true,
premultipliedAlpha: false
});
var funcs = Object.getOwnPropertyNames(gl.__proto__).filter(function(p) {
return typeof gl[p] === 'function';
});
function HookFunction(func, callback) {
return function() {
var res = func.apply(this, arguments);
callback(arguments);
return res;
};
}
var endFrame = false;
var afterFrame = 8;
funcs.forEach(function(funcName) {
gl[funcName] = HookFunction(gl[funcName], function(args) {
if (endFrame) {
if (afterFrame == 0) {
return;
}
afterFrame -= 1;
}
if (funcName == "drawElements") {
endFrame = true;
}
var KK = [];
var dumpArr = [];
for (var item in args) {
var arg = args[item];
if (arg === null) {
KK.push("null");
} else if (arg instanceof ArrayBuffer || arg instanceof Float32Array || arg instanceof Uint8Array || arg instanceof Uint16Array) {
dumpArr.push(new Uint8Array(arg.buffer));
} else {
KK.push(arg);
}
}
console.log("WebGL Interceptor: ", funcName, "(", KK.join(', '), ")");
if (dumpArr.length) {
console.log(dumpArr);
}
});
});
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.disable(gl.STENCIL_TEST);
gl.enable(gl.BLEND);
gl.enable(gl.SCISSOR_TEST);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, 800, 600);
gl.scissor(0, 0, 800, 600);
gl.clearColor(0.06274509803921569, 0.6, 0.7333333333333333, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var vertexDataCount = 4;
var vertexByteSize = vertexDataCount * 4;
var BatchSize = 2000;
var totalIndices = BatchSize * 6;
var vertices = new ArrayBuffer(BatchSize * vertexByteSize * 4);
var indices = new ArrayBuffer(totalIndices * 2);
var indicesUint16View = new Uint16Array(indices);
var verticesFloat32View = new Float32Array(vertices);
var j = 0;
for (var i = 0; i < totalIndices; i += 6, j += 4) {
indicesUint16View[i + 0] = j + 0;
indicesUint16View[i + 1] = j + 1;
indicesUint16View[i + 2] = j + 2;
indicesUint16View[i + 3] = j + 0;
indicesUint16View[i + 4] = j + 2;
indicesUint16View[i + 5] = j + 3;
}
var indexBuffer = gl.createBuffer();
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicesUint16View, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesFloat32View, gl.DYNAMIC_DRAW);
function compileShader(shaderSource, shaderType) {
var shader = gl.createShader(shaderType);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!success) {
throw "could not compile shader:" + gl.getShaderInfoLog(shader);
}
return shader;
}
function createProgram(vertexShader, fragmentShader) {
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
var success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!success) {
throw ("program filed to link:" + gl.getProgramInfoLog(program));
}
return program;
}
var vertexShad = compileShader(vertexShaderSrc, gl.VERTEX_SHADER);
var fragShad = compileShader(fragmentShaderSrc, gl.FRAGMENT_SHADER);
var shaderProg = createProgram(vertexShad, fragShad);
gl.useProgram(shaderProg);
var vertLoc = gl.getAttribLocation(shaderProg, "aVertexPosition");
var texCoordLoc = gl.getAttribLocation(shaderProg, "aTextureCoord");
gl.enableVertexAttribArray(vertLoc);
gl.enableVertexAttribArray(texCoordLoc);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, vertexByteSize, 0);
gl.vertexAttribPointer(texCoordLoc, 2, gl.FLOAT, false, vertexByteSize, 2 * 4);
var currIndex = 0;
verticesFloat32View[currIndex++] = 174; // pos
verticesFloat32View[currIndex++] = 113; // pos
verticesFloat32View[currIndex++] = 0; // UV
verticesFloat32View[currIndex++] = 0; // UV
verticesFloat32View[currIndex++] = 226; // pos
verticesFloat32View[currIndex++] = 113; // pos
verticesFloat32View[currIndex++] = 1; // UV
verticesFloat32View[currIndex++] = 0; // UV
verticesFloat32View[currIndex++] = 226; // pos
verticesFloat32View[currIndex++] = 187; // pos
verticesFloat32View[currIndex++] = 1; // UV
verticesFloat32View[currIndex++] = 1; // UV
verticesFloat32View[currIndex++] = 174; // pos
verticesFloat32View[currIndex++] = 187; // pos
verticesFloat32View[currIndex++] = 0; // UV
verticesFloat32View[currIndex++] = 1; // UV
gl.bufferSubData(gl.ARRAY_BUFFER, 0, verticesFloat32View);
// | 2 / Width | 0 | -1
// | 0 | 2 / Height | -1
// | 0 | 0 | 1
var rawProjectionMat = new Float32Array([
0.00249999994, 0, 0, 0, -0.00333333341, 0, -1, 1, 1
]);
gl.uniformMatrix3fv(gl.getUniformLocation(shaderProg, "projectionMatrix"), false, rawProjectionMat);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.activeTexture(gl.TEXTURE0);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img1);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
}
</script>
</body>
</html>
EDIT:
I am using the following image:
https://raw.githubusercontent.com/pixijs/examples/gh-pages/_assets/bunny.png
I'm just guessing the issue is no where did you set the size of your canvas element's content.
The number of actual pixels in the canvas element defaults to 300x150. you can set that in HTML with
<canvas width="800" height="600"></canvas>
or you can set it in JavaScript with
someCanvasElement.width = 800;
someCanvasElement.height = 600;
Firefox is warning you that you set the viewport to 800x600 but it's larger than your canvas (300x150) which is very unusual and the warning was to help you notice the issue.
FYI: gl.viewport only does 2 things. It sets the conversion from clip space to screen space (or in this case canvas space) and it sets the clipping region for vertices. 'clipping vertices' means it does not clip pixels so drawing a gl_PointSize = 10.0 point at the edge of the viewport setting will draw outside the viewport setting.
To clip pixels use the scissor test. I see you're setting up a scissor test but since you apparently want to draw to the edge of the canvas you don't need to setup the scissor at all.

Multiple Shader Programs to give different textures

little lost here. trying to set different textures on different vertices. WebGL makes this extremely unnecessarily difficult. Basically I have a text file with matrices of the vertices I want, which works. (example here: http://jdmdev.net/Foundation/index.html)
But to now set different textures I would need to do something called 'texture atlassing' which there is absolutely zero documentation on how to implement that online... anywhere.
I am very new to WebGL but have an extensive programming background so I am able to understand any concepts given to me.. if I can just see something working or at the very least some documentation on it.
So I think texture atlassing is out of the picture. However, if I am understadning the WebGL pipeline as well as I think I am. Can't I just create multiple shader/vertex programs? If so, how can I go about that? I don't need a direct example, but just some code will do wonders. I just need to see this one time and I will get it, but it's impossible to find any useful stuff on the web, due to this being so new. I appreciate any help given.
Not sure how any code would help with answering this question, but here's my code that I basically used from learningwebgltutorials.com
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D uSampler2;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
<script id="shader2-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D uSampler2;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>
<script id="shader2-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
<script type="text/javascript">
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
}
function handleLoadedTexture(texture) {
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
}
var mudTexture;
var rockTexture;
function initTexture() {
mudTexture = gl.createTexture();
mudTexture.image = new Image();
mudTexture.image.onload = function () {
handleLoadedTexture(mudTexture)
}
mudTexture.image.src = "mud.gif";
rockTexture = gl.createTexture();
rockTexture.image = new Image();
rockTexture.image.onload = function () {
handleLoadedTexture(rockTexture)
}
rockTexture.image.src = "rockstar.gif";
}
var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();
function mvPushMatrix() {
var copy = mat4.create();
mat4.set(mvMatrix, copy);
mvMatrixStack.push(copy);
}
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
var currentlyPressedKeys = {};
function handleKeyDown(event) {
currentlyPressedKeys[event.keyCode] = true;
}
function handleKeyUp(event) {
currentlyPressedKeys[event.keyCode] = false;
}
var pitch = 0;
var pitchRate = 0;
var yaw = 0;
var yawRate = 0;
var xPos = 10;
var yPos = 0.4;
var zPos = 10;
var speed = 0;
function handleKeys() {
if (currentlyPressedKeys[33]) {
// Page Up
pitchRate = 0.1;
} else if (currentlyPressedKeys[34]) {
// Page Down
pitchRate = -0.1;
} else {
pitchRate = 0;
}
if (currentlyPressedKeys[37] || currentlyPressedKeys[65]) {
// Left cursor key or A
yawRate = 0.1;
} else if (currentlyPressedKeys[39] || currentlyPressedKeys[68]) {
// Right cursor key or D
yawRate = -0.1;
} else {
yawRate = 0;
}
if (currentlyPressedKeys[38] || currentlyPressedKeys[87]) {
// Up cursor key or W
speed = 0.01;
} else if (currentlyPressedKeys[40] || currentlyPressedKeys[83]) {
// Down cursor key
speed = -0.01;
} else {
speed = 0;
}
}
var worldVertexPositionBuffer = null;
var worldVertexTextureCoordBuffer = null;
function handleLoadedWorld(data) {
var lines = data.split("\n");
var vertexCount = 0;
var vertexPositions = [];
var vertexTextureCoords = [];
for (var i in lines) {
var vals = lines[i].replace(/^\s+/, "").split(/\s+/);
if (vals.length == 6 && vals[0] != "//") {
// It is a line describing a vertex; get X, Y and Z first
vertexPositions.push(parseFloat(vals[0]));
vertexPositions.push(parseFloat(vals[1]));
vertexPositions.push(parseFloat(vals[2]));
//document.write(vertexPositions[0]);
// And then the texture coords
vertexTextureCoords.push(parseFloat(vals[3]));
vertexTextureCoords.push(parseFloat(vals[4]));
//document.write(vals[4]) + "<br/>");
vertexCount += 1;
}
}
worldVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW);
worldVertexPositionBuffer.itemSize = 3;
worldVertexPositionBuffer.numItems = vertexCount;
worldVertexTextureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexTextureCoords), gl.STATIC_DRAW);
worldVertexTextureCoordBuffer.itemSize = 2;
worldVertexTextureCoordBuffer.numItems = vertexCount;
document.getElementById("loadingtext").textContent = "";
}
function loadWorld() {
var request = new XMLHttpRequest();
request.open("GET", "world.txt");
request.onreadystatechange = function () {
if (request.readyState == 4) {
handleLoadedWorld(request.responseText);
}
}
request.send();
}
function loadTextureValues() {
var request = new XMLHttpRequest();
request.open("GET", "world.txt");
request.onreadystatechange = function () {
if (request.readyState == 4) {
getCorrectTexture(request.responseText);
}
}
request.send();
}
var matchWithTexture = {};
function getCorrectTexture(data)
{
var lines = data.split("\n");
var vertexCount = 0;
var vertexTextureValueCoords = [];
for (var i in lines) {
var vals = lines[i].replace(/^\s+/, "").split(/\s+/);
if (vals.length == 6 && vals[0] != "//")
{
//document.write(vertexTextureValueCoords.push(parseFloat(vals[1])) + "</br>");
vertexTextureValueCoords.push(parseFloat(vals[5]));
matchWithTexture[vertexCount] = vertexTextureValueCoords[vertexCount];
vertexCount++;
}
}
}
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (worldVertexTextureCoordBuffer == null || worldVertexPositionBuffer == null) {
return;
}
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.rotate(mvMatrix, degToRad(-pitch), [1, 0, 0]);
mat4.rotate(mvMatrix, degToRad(-yaw), [0, 1, 0]);
mat4.translate(mvMatrix, [-xPos, -yPos, -zPos]);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, mudTexture);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, rockTexture);
loadTextureValues();
for(var key in matchWithTexture)
{
//document.write(matchWithTexture[key] + "<br/>");
if(matchWithTexture[key] == 1)
{
gl.uniform1i(shaderProgram.samplerUniform, 0);
}
else {
gl.uniform1i(shaderProgram.samplerUniform, 1);
}
}
gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, worldVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, worldVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, worldVertexPositionBuffer.numItems);
}
var lastTime = 0;
// Used to make us "jog" up and down as we move forward.
var joggingAngle = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;
if (speed != 0) {
xPos -= Math.sin(degToRad(yaw)) * speed * elapsed;
zPos -= Math.cos(degToRad(yaw)) * speed * elapsed;
joggingAngle += elapsed * 0.6; // 0.6 "fiddle factor" - makes it feel more realistic :-)
yPos = Math.sin(degToRad(joggingAngle)) / 20 + 0.4
}
yaw += yawRate * elapsed;
pitch += pitchRate * elapsed;
}
lastTime = timeNow;
}
function tick() {
requestAnimFrame(tick);
handleKeys();
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("lesson10-canvas");
initGL(canvas);
initShaders();
initTexture();
loadWorld();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
document.onkeydown = handleKeyDown;
document.onkeyup = handleKeyUp;
tick();
}
</script>
So all I did was create a 2nd shader/vertex program, and it still works. So how can I go about implementing them with different information from the first shader/vertex programs?
And a last question would be: would it just be worth it more to use a library instead of trying to do everything in webgl? I mean, with all the google searches I have done on webgl, most of all the examples/tutorials are all done using three.js, or babylon.js..etc. I'm just wondering if it's even worth it to try to do what I am doing. I guess what the question would be is, would professional settings want me to do straight up webgl, or would I (most likely) be using a library? I don't ever even plan on programming webgl, but just to know if it ever comes up in an interview.
SOLUTION VIA NO-TEXTURE ALIASING
https://github.com/jordmax12/WebGL/blob/master/Foundation%205/foundation_2.js
Since I was already parsing information from a text file for vertices and texture coordinates, there MUST be a way to do this for the texture itself (without texture aliasing).
You can use different textures and shaders on different vertices if you draw them one by one. The problem is that this is quite inefficient. So for good performance, I don't think there is a way around atlasing -- that's why everybody is doing this.
I am not aware of any three.js util to simplify atlasing (but I am not very familiar with three.js).
It should be straight forward to implement a utility that draws the textures to a big canvas, creating the atlas on the fly at runtime and keeping track of the coordinates. After setup, the tool would basically transform coordinates and texture names or ids to a pure coordinate array (including texture coordinates).
Whether you should use a library really depends on what you plan to do. If a retained mode API works for your use case, it's probably a good idea and more convenient to use three.js.

Resources