Nothing is being rendered in canvas - javascript

This is my code:
I am just trying to render the triangle in webgl, but I am not able to.
There is no error or warning in console whereas there is nothing being rendered in the canvas.
`use strict`;
const vsTriangle = `#version 300 es
in vec3 a_position;
out vec3 varying_color;
uniform mat4 u_vpMatrix;
void main(){
gl_Position = u_vpMatrix*vec4(a_position, 1.0);
varying_color = a_position;
}
`;
const fsTriangle = `#version 300 es
precision mediump float;
in vec3 varying_color;
out vec4 outColor;
void main(){
outColor = vec4(1.0, 0.0, 0.0, 0.7);
}
`;
const up = [0, 1, 0];
let modelDegree = 0;
let cameraYposition = 2.0;
const positionTriangle = [0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0];
(function() {
const canvas = document.querySelector("#main-canvas");
let gl = canvas.getContext("webgl2");
if (!gl) {
console.log("webgl2 not found");
return;
}
var ext = gl.getExtension("OES_element_index_uint");
let programTriangle = webglUtils.createProgramFromSources(gl, [
vsTriangle,
fsTriangle,
]);
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
let position = gl.getAttribLocation(programTriangle, "a_position");
let modelMatrixLocation = gl.getUniformLocation(programTriangle, "u_vpMatrix");
let posTriangleBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, posTriangleBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(positionTriangle),
gl.STATIC_DRAW
);
let cameraDegree = 0;
function degToRadian(deg) {
return (Math.PI / 180) * deg;
}
function initialCameraSetup(cameraPosition, up) {
let cameraMatrix = m4.lookAt(cameraPosition, [1, 0, 0], up);
return cameraMatrix;
}
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.5, 0.5, 0.5, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
let cameraRadian = degToRadian(cameraDegree);
let cameraMatrix = m4.yRotation(cameraRadian);
cameraMatrix = m4.translate(cameraMatrix, 0.0, 0.0, 1.5);
cameraPosition = [cameraMatrix[12], cameraMatrix[13], cameraMatrix[14]];
cameraMatrix = initialCameraSetup(cameraPosition, up);
viewMatrix = m4.inverse(cameraMatrix);
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
let fieldofView = degToRadian(90);
let projectionMatrix = m4.perspective(fieldofView, aspect, 0.01, 1000);
let vProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);
gl.bindBuffer(gl.ARRAY_BUFFER, posTriangleBuffer);
gl.enableVertexAttribArray(position);
gl.vertexAttribPointer(
position,
3,
gl.FLOAT,
false,
0,
0
);
gl.useProgram(programTriangle);
gl.uniformMatrix4fv(
modelMatrixLocation,
false,
vProjectionMatrix
);
gl.drawArrays(gl.TRIANGLES, 0, 3);
window.requestAnimationFrame(drawScene);
}
requestAnimationFrame(drawScene);
})();
#main-canvas {
width: 720px;
height: 360px;
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test !!!</title>
<link rel="stylesheet" href="./styles/main.css" />
</head>
<body>
<div class="canvas-container">
<canvas id="main-canvas"></canvas>
</div>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js"></script>
</body>
</html>

Your "triangle" is not a triangle but a straight line. Change the vertex coordinates:
const positionTriangle = [0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0, 0.0, 0.0];
const positionTriangle = [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0];
The default winding order of fron faces is counter-clockwise. Since Face Culling is enabled, you need to make sure your triangle has counter clockwise winding order. See Face Culling
`use strict`;
const vsTriangle = `#version 300 es
in vec3 a_position;
out vec3 varying_color;
uniform mat4 u_vpMatrix;
void main(){
gl_Position = u_vpMatrix*vec4(a_position, 1.0);
varying_color = a_position;
}
`;
const fsTriangle = `#version 300 es
precision mediump float;
in vec3 varying_color;
out vec4 outColor;
void main(){
outColor = vec4(1.0, 0.0, 0.0, 0.7);
}
`;
const up = [0, 1, 0];
let modelDegree = 0;
let cameraYposition = 2.0;
const positionTriangle = [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0];
(function() {
const canvas = document.querySelector("#main-canvas");
let gl = canvas.getContext("webgl2");
if (!gl) {
console.log("webgl2 not found");
return;
}
var ext = gl.getExtension("OES_element_index_uint");
let programTriangle = webglUtils.createProgramFromSources(gl, [
vsTriangle,
fsTriangle,
]);
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
let position = gl.getAttribLocation(programTriangle, "a_position");
let modelMatrixLocation = gl.getUniformLocation(programTriangle, "u_vpMatrix");
let posTriangleBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, posTriangleBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(positionTriangle),
gl.STATIC_DRAW
);
let cameraDegree = 0;
function degToRadian(deg) {
return (Math.PI / 180) * deg;
}
function initialCameraSetup(cameraPosition, up) {
let cameraMatrix = m4.lookAt(cameraPosition, [1, 0, 0], up);
return cameraMatrix;
}
function drawScene() {
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.5, 0.5, 0.5, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
let cameraRadian = degToRadian(cameraDegree);
let cameraMatrix = m4.yRotation(cameraRadian);
cameraMatrix = m4.translate(cameraMatrix, 0.0, 0.0, 1.5);
cameraPosition = [cameraMatrix[12], cameraMatrix[13], cameraMatrix[14]];
cameraMatrix = initialCameraSetup(cameraPosition, up);
viewMatrix = m4.inverse(cameraMatrix);
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
let fieldofView = degToRadian(90);
let projectionMatrix = m4.perspective(fieldofView, aspect, 0.01, 1000);
let vProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);
gl.bindBuffer(gl.ARRAY_BUFFER, posTriangleBuffer);
gl.enableVertexAttribArray(position);
gl.vertexAttribPointer(
position,
3,
gl.FLOAT,
false,
0,
0
);
gl.useProgram(programTriangle);
gl.uniformMatrix4fv(
modelMatrixLocation,
false,
vProjectionMatrix
);
gl.drawArrays(gl.TRIANGLES, 0, 3);
window.requestAnimationFrame(drawScene);
}
requestAnimationFrame(drawScene);
})();
#main-canvas {
width: 720px;
height: 360px;
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test !!!</title>
<link rel="stylesheet" href="./styles/main.css" />
</head>
<body>
<div class="canvas-container">
<canvas id="main-canvas"></canvas>
</div>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js"></script>
</body>
</html>

Related

WebGL Unable to compile a basic vertex shader

I'm following Cherno's OpenGL course on YouTube,
I think I have a case of code blindness since I cant see anything wrong with my program.
Can someone help me out and tell me what I'm doing wrong or where the typo is..
I think the problem is the vertex shader or the way im linking it to the vertex attribute pointer, but im not sure; Any help would be great
The console outputs warnings:
WebGL warning: linkProgram: Must have a compiled vertex shader attached:
SHADER_INFO_LOG:
ERROR: 0:2: 'layout' : syntax error
WebGL warning: useProgram: Program must be linked successfully.
WebGL warning: drawArraysInstanced: The current program is not linked.
function main() {
const glCanvas = document.getElementById("glCanvas");
const gl = glCanvas.getContext("webgl") || glCanvas.getContext("experimental-webgl")
if (!gl) throw ("Your browser does not support WebGL");
initWebGL();
function initWebGL() {
gl.clearColor(0.7, 0.7, 0.0, 1.0);
gl.resize = function(width, height) {
glCanvas.width = width;
glCanvas.height = height;
gl.viewport(0, 0, width, height);
}
const bufferData = new Float32Array([
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * bufferData.BYTES_PER_ELEMENT, 0);
const vertexShader = `
layout(location = 0) in vec4 position;
void main(){
gl_Position = position;
}
`;
const fragmentShader = `
layout(location = 0) out vec4 color;
void main(){
color = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
const program = createShader(vertexShader, fragmentShader);
gl.useProgram(program);
gl.resize(500, 500)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
function createShader(vertexShader, fragmentShader) {
const program = gl.createProgram();
const _vertexShader = compileShader(gl.VERTEX_SHADER, vertexShader);
const _fragmentShader = compileShader(gl.FRAGMENT_SHADER, fragmentShader);
gl.attachShader(program, _vertexShader);
gl.attachShader(program, _fragmentShader);
gl.linkProgram(program);
gl.validateProgram(program);
gl.deleteShader(_vertexShader);
gl.deleteShader(_fragmentShader);
return program;
}
function compileShader(type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
}
body {
margin: 0px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body onload="main()">
<canvas id="glCanvas"></canvas>
</body>
</html>

WebGL perspective projection matrix not working

Trying to write basic WebGL program, which draws a triangle to the screen. Without any projection matrix it works just right, as well as with identity matrix. But when it comes to perspective projection matrix it just shows nothing. Here is my code:
const canvas = document.getElementById("viewport");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const gl = canvas.getContext("webgl2");
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
const vs = gl.createShader(gl.VERTEX_SHADER);
const fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vs, document.getElementById("vs").innerText);
gl.shaderSource(fs, document.getElementById("fs").innerText);
gl.compileShader(vs);
gl.compileShader(fs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)){
const info = gl.getShaderInfoLog(vs);
throw new Error("Error compiling vertex shader:\n\n" + info);
}
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)){
const info = gl.getShaderInfoLog(fs);
throw new Error("Error compiling fragment shader:\n\n" + info);
}
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
gl.validateProgram(program);
gl.useProgram(program);
const position = [
-0.5, -0.5, 0.0,
0.0, 0.5, 0.0,
0.5, -0.5, 0.0,
];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(position), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
const projectionMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
const FOV = 70;
const NEAR_PLANE = .1;
const FAR_PLANE = 1000;
const aspectRatio = canvas.width / canvas.height;
const yScale = (1.0 / Math.tan((FOV / 2.0) * (Math.PI / 180.0))) * aspectRatio;
const xScale = yScale / aspectRatio;
const frustumLength = FAR_PLANE - NEAR_PLANE;
projectionMatrix[0] = xScale;
projectionMatrix[5] = yScale;
projectionMatrix[10] = ((FAR_PLANE + NEAR_PLANE) / frustumLength) * -1.0;
projectionMatrix[11] = -1.0;
projectionMatrix[14] = ((2.0 * NEAR_PLANE * FAR_PLANE) / frustumLength) * -1;
projectionMatrix[15] = 0;
gl.uniformMatrix4fv(gl.getUniformLocation(program, "u_Projection"), false, projectionMatrix)
const loop = () => {
gl.clearColor(0.0, 0.0, 0.0, 0.8);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(loop);
}
loop();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script id="vs" type="x-shader/x-vertex">#version 300 es
precision highp float;
precision highp int;
layout(location=0) in vec3 a_Position;
out vec4 v_Position;
uniform mat4 u_Projection;
void main()
{
gl_Position = u_Projection * vec4(a_Position, 1.0);
v_Position = gl_Position;
}
</script>
<script id="fs" type="x-shader/x-fragment">#version 300 es
precision highp float;
precision highp int;
in vec4 v_Position;
out vec4 out_Color;
void main()
{
out_Color = v_Position;
}
</script>
<canvas id="viewport"></canvas>
<script src="main.js"></script>
</body>
</html>
I have also tried this solution, but id didn`t work either.
Have you tried moving the triangle back a bit? Based on your NEAR_PLAIN, the triangle is too close. Try:
const position = [
-0.5, -0.5, -1.0,
0.0, 0.5, -1.0,
0.5, -0.5, -1.0,
];
Just as an aside, I'm not sure I agree with the math that you're using to create your projection matrix. I think it would be worth comparing against https://glmatrix.net/docs/mat4.js.html#line1508, which I believe gives a different result.

Rotating Robotic Arm

OBJECTIVE: The objective to the below code is to make a moving robot arm that has three layer's(upper, lower and middle) all of them being attach to the base. Given are the 4 sliders that can move each part indipendently except the base that will move all the arms.
PROBLEM: The problem I am having is when I try to run this code I don't get any visuals on the screen and there is no error in the console, I can't find the issue whats causing it. I have also attached a pic of the output.
SOLUTION: Haven't found yet.
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var vertexColors = [
vec4( 0.0, 0.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").onchange = function(event) {
theta[0] = event.target.value;
};
document.getElementById("slider2").onchange = function(event) {
theta[1] = event.target.value;
};
document.getElementById("slider3").onchange = function(event) {
theta[2] = event.target.value;
};
document.getElementById("slider4").onchange = function(event) {
theta[3] = event.target.value;
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], 0, 1, 0 );
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], 0, 0, 1 ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], 0, 0, 1) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], 0, 0, 1) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
The first thing I did was add webgl-lint
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
That immediately got the error
Uncaught Error: https://greggman.github.io/webgl-lint/webgl-lint.js:2843:
error in
uniformMatrix4fv(WebGLUniformLocation("modelViewMatrix"),
false,
[5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, NaN, NaN, NaN, NaN]): element 12 of argument 2 is NaN
: trying to set uniform 'modelViewMatrix'
at reportError (webgl-lint.js:2163)
at reportFunctionError (webgl-lint.js:2924)
at checkArrayForUniformImpl (webgl-lint.js:2843)
at webgl-lint.js:2869
at checkArgs (webgl-lint.js:2972)
at WebGLRenderingContext.ctx.<computed> [as uniformMatrix4fv] (webgl-lint.js:3016)
at base (js:230)
at render (js:267)
at init (js:223)
Looking in your code the issue is rotate does not take 4 arguments, it takes 2 arguments, an angle and an axis
r = rotate(angle, x, y, z); // BAD!
r = rotate(angle, [x, y, z]); // Good
Fixing that webgl-lint printed a new error. The issue is scale4 takes 4 arguments.
s = scale4(x, y, z); // BAD!
s = scale4(x, y, z, w); // good
you want to pass 1 for w.
That fixed rendering. As for the sliders you probably want to call render in each onchange function. You also probably want to use oninput instead of onchange
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var vertexColors = [
vec4( 0.0, 0.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 0.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").oninput = function(event) {
theta[0] = event.target.value;
render();
};
document.getElementById("slider2").oninput = function(event) {
theta[1] = event.target.value;
render();
};
document.getElementById("slider3").oninput = function(event) {
theta[2] = event.target.value;
render();
};
document.getElementById("slider4").oninput = function(event) {
theta[3] = event.target.value;
render();
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH, 1);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], [0, 1, 0]);
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], [0, 0, 1] ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], [0, 0, 1]) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], [0, 0, 1]) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

How do I change Image(any texture) on each side of the triangle?

I am trying to render a 3D rotating triangle, in which all the sides of the triangle has a different texture. I have made all the necessary changes but my triangle is a bit out of shape and I have tried to change the texture on each side of the triangle but I was able to do only one side of the triangle and no matter what I do it only changes one side. I am not looking to get a specific texture as it can be anything but different on all sides. Not sure what I am doing wrong.
var canvas;
var gl;
var numVertices = 36;
var texSize = 256;
var numChecks = 8;
var program;
var texture1, texture2;
var t1, t2;
var c;
var flag = true;
var image1 = new Uint8Array(4*texSize*texSize);
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
var patchx = Math.floor(i/(texSize/numChecks));
var patchy = Math.floor(j/(texSize/numChecks));
if(patchx%2 ^ patchy%2) c = 255;
else c = 0;
//c = 255*(((i & 0x8) == 0) ^ ((j & 0x8) == 0))
image1[8*i*texSize+8*j] = c;
image1[5*i*texSize+5*j+3] = c;
image1[6*i*texSize+6*j+4] = c;
image1[4*i*texSize+4*j+3] = 255;
}
}
var image2 = new Uint8Array(4*texSize*texSize);
// Create a checkerboard pattern
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
image2[6*i*texSize+6*j+1] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+3] = 255;
}
}
var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var vertices = [
vec4(0.5, -0.2722, 0.2886),
vec4(0.0, -0.2722, -0.5773),
vec4(-0.5, -0.2722, 0.2886),
vec4(0.5, -0.5443, 0.0)
];
var vertexColors = [
vec4( 0.0, 1.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 1.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 0.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];
var thetaLoc;
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
function quad(a, b, c) {
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[1]);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[3]);
}
function colorCube()
{
quad( 0, 1, 2 ); // bottom
quad( 1, 0, 3 ); // side0
quad( 1, 2, 3 ); // side1
quad( 2, 0, 3 ); // side3
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable(gl.DEPTH_TEST);
//
// Load shaders and initialize attribute buffers
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
configureTexture();
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.uniform1i(gl.getUniformLocation( program, "Tex0"), 0);
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.uniform1i(gl.getUniformLocation( program, "Tex1"), 1);
thetaLoc = gl.getUniformLocation(program, "theta");
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
render();
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame(render);
}
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform vec3 theta;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
// Remeber: thse matrices are column-major
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, s.x, 0.0,
0.0, -s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = rz * ry * rx * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform sampler2D Tex0;
uniform sampler2D Tex1;
void
main()
{
gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="texture.js"></script>
<body>
<canvas id="gl-canvas" width="1024" height="1024">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
I'm not sure what kind of help you are looking for.
The normal way to put a different image on each side of a pyramid is to use a texture atlas. Here's an article that covers it.
Effectively you put all the images in to one texture and then use texture coordinates on each face of the pyramid to select one of the images.
The reason I ask if that's what you want is because using a texture atlas is pretty much how 99% of all WebGL apps and 3D graphics apps in general would solve the issue of putting a different texture on each face of a pyramid.
Solving it by actually using multiple textures is possible but it's generally not considered a good solution since then you'd need a different shader to shade a cube (8 textures) from a 4 sides pyramid (4 textures) and again different shaders for every number of textures. Further, there's a limit to the number of textures a single shader can use in one draw call.
Otherwise, the code you posted seems to only make 2 textures and multiplies them together
gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));
So there's nothing in your code to select one texture or the other. You need to add some data to select the texture.
One way would be to add another attribute to your shaders to select the texture. You'd set that attribute to 0 to select Tex0 and 1 to select Tex1
varying float mixAmount; // passed in from vertex shader via attributes
...
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color = mix(color0, color1, mixAmount);
gl_FragColor = fColor * color;
Where it selects texture 0 when mixAmount = 0 and texture 1 when mixAmount = 1
var canvas;
var gl;
var numVertices = 24;
var texSize = 256;
var numChecks = 8;
var program;
var texture1, texture2;
var t1, t2;
var c;
var flag = true;
var image1 = new Uint8Array(4*texSize*texSize);
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
var patchx = Math.floor(i/(texSize/numChecks));
var patchy = Math.floor(j/(texSize/numChecks));
if(patchx%2 ^ patchy%2) c = 255;
else c = 0;
//c = 255*(((i & 0x8) == 0) ^ ((j & 0x8) == 0))
image1[8*i*texSize+8*j] = c;
image1[5*i*texSize+5*j+3] = c;
image1[6*i*texSize+6*j+4] = c;
image1[4*i*texSize+4*j+3] = 255;
}
}
var image2 = new Uint8Array(4*texSize*texSize);
// Create a checkerboard pattern
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
image2[6*i*texSize+6*j+1] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+3] = 255;
}
}
var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var mixAmountsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var vertices = [
vec4(0.5, -0.2722, 0.2886),
vec4(0.0, -0.2722, -0.5773),
vec4(-0.5, -0.2722, 0.2886),
vec4(0.5, -0.5443, 0.0)
];
var vertexColors = [
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 0.0, 1.0, 1.0, 1.0 ), // cyan
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];
var thetaLoc;
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
function quad(a, b, c, mixAmount) {
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[0]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[1]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[2]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[0]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[2]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[3]);
mixAmountsArray.push(mixAmount);
}
function colorCube()
{
quad( 0, 1, 2, 0 ); // bottom
quad( 1, 0, 3, 1 ); // side0
quad( 1, 2, 3, 0 ); // side1
quad( 2, 0, 3, 1 ); // side3
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable(gl.DEPTH_TEST);
//
// Load shaders and initialize attribute buffers
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
var mBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, mBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(mixAmountsArray), gl.STATIC_DRAW );
var vMixAmount = gl.getAttribLocation( program, "vMixAmount" );
gl.vertexAttribPointer( vMixAmount, 1, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vMixAmount );
configureTexture();
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.uniform1i(gl.getUniformLocation( program, "Tex0"), 0);
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.uniform1i(gl.getUniformLocation( program, "Tex1"), 1);
thetaLoc = gl.getUniformLocation(program, "theta");
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
render();
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame(render);
}
canvas { border: 1px solid black; }
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
attribute float vMixAmount;
varying vec4 fColor;
varying vec2 fTexCoord;
varying float mixAmount;
uniform vec3 theta;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
// Remeber: thse matrices are column-major
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, s.x, 0.0,
0.0, -s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
mixAmount = vMixAmount;
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = rz * ry * rx * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
varying float mixAmount;
uniform sampler2D Tex0;
uniform sampler2D Tex1;
void
main()
{
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
gl_FragColor = fColor * mix(color0, color1, mixAmount);
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="texture.js"></script>
<body>
<canvas id="gl-canvas" width="200" height="200">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
That's only 2 textures. To do 4 textures you'd have to do more math and maybe have your mixAmount be 0 to 3
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color2 = texture2D(Tex2, fTexCoord);
vec4 color3 = texture2D(Tex3, fTexCoord);
vec4 color = color0 * clamp(mixAmount, 0, 1) +
color1 * clamp(abs(1 - mixAmount, 0, 1) +
color2 * clamp(abs(2 - mixAmount, 0, 1) +
color3 * clamp(abs(3 - mixAmount, 0, 1);
gl_FragColor = fColor * color;

WebGL using gl-matrix library mat4.translate not running

I have this segment of code:
function setupWebGL() {
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0,0,400,300);
mat4.perspective(45, 400 / 300, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -2.0]);
}
And everything in the code runs except the very last line
mat4.translate(mvMatrix, [0, 0, -2.0]);
I know this because I put alert functions after every line until they failed to run (I need a better way of debugging in chrome, any suggestions?)
I'm using the gl-Matrix library found here https://github.com/toji/gl-matrix/blob/master/dist/gl-matrix-min.js
Any ideas on why that line is stopping the code execution?
Here is the full code:
<!doctype html>
<html>
<head>
<title>WebGL - Chapter One - Lol</title>
<style>
body{ background-color: grey; }
canvas{ background-color: white; }
</style>
<script src = "gl-matrix-min.js"></script>
<script src = "raf_polyfill.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying highp vec4 vColor;
void main(void){
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = vec4(aVertexColor, 1.0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec4 vColor;
void main(void){
gl_FragColor = vColor;
}
</script>
<script>
var gl = null,
canvas = null,
glProgram = null,
fragmentShader = null,
vertexShader = null;
var vertexPositionAttribute = null,
trianglesVerticeBuffer = null,
vertexColorAttribute = null,
trianglesColorBuffer = null;
var angle = 0.0;
var mvMatrix = mat4.create(),
pMatrix = mat4.create();
function initWebGL(){
var canvas = document.getElementById("my-canvas");
try{
gl = canvas.getContext("experimental-webgl");
}catch(e){}
if(gl){
initShaders();
setupBuffers();
getMatrixUniforms();
animLoop();
}else{
alert("Error: Your browser does not appear to support WebGL.");
}
}
function animLoop(){
setupWebGL();
setupDynamicBuffers();
setMatrixUniforms();
drawScene();
requestAnimationFrame(animLoop,canvas);
}
function setupWebGL() {
//sets the clear color to red lol
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0,0,400,300);
mat4.perspective(45, 400 / 300, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0, 0, -2.0]);
}
function initShaders(){
var fs_source = document.getElementById("shader-fs").innerHTML;
var vs_source = document.getElementById("shader-vs").innerHTML;
//compile shaders
vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER);
//create program
glProgram = gl.createProgram();
//attach and link shaders to the program
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.");
}
//use program
gl.useProgram(glProgram);
}
function makeShader(src, type) {
//compile the vertex shader
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 getMatrixUniforms(){
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix");
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix");
}
function setMatrixUniforms(){
gl.unifromMatrix4fv(glProgram.pMatrixUniform, false, pMatrix);
gl.unifromMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix);
}
function setupBuffers() {
var triangleVerticeColors = [
1.0, 0.0, 0.0,
1.0, 1.0, 1.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 1.0,
0.0, 0.0, 1.0
];
trianglesColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW);
}
function setupDynamicBuffers(){
var xTran = Math.sin(angle)/2.0;
var triangleVertices = [
-0.5 + xTran, 0.5, -0.5,
0.0 + xTran, 0.0, -0.5,
-0.5 + xTran, -0.5, -0.5,
0.5 + xTran, 0.5, -0.5,
0.0 + xTran, 0.0, -0.5,
0.5 + xTran, -0.5, -0.5
];
angle += 0.05;
trianglesVerticeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.DYNAMIC_DRAW);
}
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.drawArrays(gl.TRIANGLES, 0, 6);
}
</script>
</head>
<body onload="initWebGL()">
<canvas id="my-canvas" width="400" height="300">
Your browser does not support the HTML5 canvas element.
</canvas>
</body>
</html>
Use the new API:
Old API
mat4.translate(mvMatrix, [0, 0, -2.0]);
New API
var translation = vec3.create();
vec3.set (translation, 0, 0, -2.0);
mat4.translate (mvMatrix, mvMatrix, translation);
You have a typo:
unifromMatrix4fv should be uniformMatrix4fv in function setMatrixUniforms.
I'm not sure if this fixes your problem or not, or why you thought your problem was with mat4.translate. You can always open the JavaScript console (F12 if you're running Chrome in Windows) and it'll tell you what the error is.

Categories