I've been working on a WebGl animation program where there are buttons that you can choose to alter a triangle vertice location based on where you click on the screen as well as a slider that runs a recursive function that divides the triangle based on the input. The part i'm stuck on is my last radio button that is supposed to constantly rotate my triangle including the edits to whatever previous changed were made to the triangle with the buttons. Every time I run my application it gives me a warning pointing to javascript line 149 my render2 function: gl.uniform1f(thetaLoc, theta);
saying: sierpinski-extended.js:149 WebGL: INVALID_OPERATION: uniform1f: location not for current program. The code below isn't going to work because I need to add external libraries and i'm not sure how to. Though I have uploaded my project on my website: https://www.cis.gvsu.edu/~nunezjo/labs/sierpinski-extended/sierpinski-extended.html Here's an example of my working rotation with no other attributes or buttons added to the mix. https://www.cis.gvsu.edu/~nunezjo/labs/triangle-rotate/triangle-rotate.html You can inspect element there if needed. Any help would be awesome! I'm so stuck.
JAVASCRIPT
"use strict";
var canvas;
var gl;
var points = [];
var numTimesToSubdivide = 0;
var theta = 0.0;
var thetaLoc;
var x1 = -1;
var y1 = -1;
var x2 = 0;
var y2 = 1;
var x3 = 1;
var y3 = -1;
function init() {
canvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
if (!gl) {
alert("WebGL isn't available");
}
//
// Initialize our data for the Sierpinski Gasket
//
// First, initialize the corners of our gasket with three points.
var vertices = [
vec2(x1, y1),
vec2(x2, y2),
vec2(x3, y3)
];
divideTriangle(vertices[0], vertices[1], vertices[2],
numTimesToSubdivide);
//
// Configure WebGL
//
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Load shaders and initialize attribute buffers
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, 50000, gl.STATIC_DRAW);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(points));
// Associate out shader variables with our data buffer
var vPosition = gl.getAttribLocation(program, "vPosition");
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);
document.getElementById("slider").onchange = function(event) {
numTimesToSubdivide = parseInt(event.target.value);
};
canvas.addEventListener("mouseup", function(event) {
var rect = gl.canvas.getBoundingClientRect();
var newx = (event.clientX - rect.left) / canvas.width * 2 - 1;
var newy = (event.clientY - rect.top) / canvas.height * -2 + 1;
console.log(newx, newy);
var vertex_id = document.querySelector('input[name="vertex"]:checked').value;
if (vertex_id == 0) {
x1 = newx;
y1 = newy;
} else if (vertex_id == 1) {
x2 = newx;
y2 = newy;
} else if (vertex_id == 2) {
x3 = newx;
y3 = newy;
} else {
thetaLoc = gl.getUniformLocation(program, "theta");
render2(vertex_id);
}
});
render1();
};
function triangle(a, b, c) {
points.push(a, b, c);
}
function divideTriangle(a, b, c, count) {
// check for end of recursion
if (count === 0) {
triangle(a, b, c);
} else {
//bisect the sides
var ab = mix(a, b, 0.5);
var ac = mix(a, c, 0.5);
var bc = mix(b, c, 0.5);
--count;
// three new triangles
divideTriangle(a, ab, ac, count);
divideTriangle(c, ac, bc, count);
divideTriangle(b, bc, ab, count);
}
}
window.onload = init;
function render1() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length);
points = [];
requestAnimFrame(init);
}
function render2(button_id) {
gl.clear(gl.COLOR_BUFFER_BIT);
theta += 0.092;// this is the amount that will be rotating the object the bigger the number the faster.
gl.uniform1f(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, points.length);
while (button_id == 3) { // while rotate button is pressed run loop on render 2 else call init
init(); // running init first so it can keep track if the button_id changes.
requestAnimFrame(render2);
}
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title> Sierpinski Extended</title>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition; uniform float theta; void main() { gl_Position = vPosition; float s = sin( theta ); float c = cos( theta ); gl_Position.x = -s * vPosition.y + c * vPosition.x; gl_Position.y = s * vPosition.x + c * vPosition.y; gl_Position.z
= 0.0; gl_Position.w = 1.0; }
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float; void main() { gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); }
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="sierpinski-extended.js"></script>
</head>
<body>
<div>
recursive steps 0 <input id="slider" type="range" min="0" max="6" step="1" value="0" /> 6
</div>
<div>
Vertex:
<input type="radio" name="vertex" value="0" checked> 0
<input type="radio" name="vertex" value="1"> 1
<input type="radio" name="vertex" value="2"> 2
<input type="radio" name="vertex" value="3"> rotate
</div>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
Comments
Post a Comment