1
votes

I'm working on a Javascript/OpenGL(WebGL) program that's supposed to make a 3D cube with a texture colored to look like a Rubik's cube. So far, I have the texture mapped just fine, and every point in the cube seems to be showing properly.

However, I'm having a tough time getting the color to display on it without getting some errors from the fragment shader. At the moment, I get this one error I've been trying to figure out with no luck. Here's the error message.

Error: fragment shader compiler: ERROR: 0:11: 'constructor' : too many arguments

Here's my fragment shader code to look at specifically.

<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
    // extract the RGBA color from image at given coordinates.
	vec4 oldColor = texture2D( image0, textureCoordinatesV );
	vec4 newColor;
	newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
	gl_FragColor = newColor;
}
</script>

Here's the image I'm using for this program.

http://tinypic.com/view.php?pic=2rpbbqq&s=9#.Vkj3jPmrTIU

And here's my code in it's entirety. I am aware of three.js to render 3D objects in WebGL, but this current approach is for me to get a better understanding of how to render the object with existing tools. Also, if you're having trouble seeing the cube, try running this program in Firefox.

There is a Vector4.js and Matrix4.js I'm using with this program, but from what I understand, they don't have anything to do with the current error message I'm receiving. Vector4 is just a script that establishes a Vector4 structure for me to use to hold vertices to render, and Matrix4 is a script for moving those vertices once they're established. If need be, I will post these files in the comments.

Any and all help would be appreciated on figuring out why this error keeps coming up, thank you very much.

<html>
<head>
  <title>Template WebGL file</title>
</head>

<body onload="main()">

<canvas id="myCanvas" width="400" height="400"></canvas>

<!-- Load external file with helper setup functions. -->

<script src="webgl-utils.js"></script>
<script src="Vector4.js"></script>
<script src="Matrix4.js"></script>

<!-- vertex shader code -->

<script id="vertex-shader" type="x-shader">
attribute vec4 pointPosition;
uniform mat4 transformation;
attribute vec4 pointColorA;
varying vec4 pointColorV;
attribute vec2 textureCoordinatesA;
varying   vec2 textureCoordinatesV;
void main()
{
	gl_Position = transformation * pointPosition;
	textureCoordinatesV = textureCoordinatesA;
	pointColorV = pointColorA;
}
</script>

<!-- fragment shader code -->

<script id="fragment-shader" type="x-shader">
precision mediump float;
uniform sampler2D image0;
varying vec2 textureCoordinatesV;
varying vec4 pointColorV;
void main()
{
    // extract the RGBA color from image at given coordinates.
	vec4 oldColor = texture2D( image0, textureCoordinatesV );
	vec4 newColor;
	newColor = vec4(oldColor.r * pointColorV, oldColor.g * pointColorV, oldColor.b * pointColorV, 1.0);
	gl_FragColor = newColor;
}
</script>

<!-- main Javascript program -->

<script>

// DECLARE GLOBAL JAVASCRIPT VARIABLES
var canvas = document.getElementById('myCanvas');
var gl; // the WebGL context

var transformationData, transformationAddress;

var x, y, z, angle, scale, time;

function main() 
{
	// STANDARD STARTUP CODE
	gl = setupWebGL(canvas);
	var program = initShaders( gl, "vertex-shader", "fragment-shader" );
	gl.useProgram( program );
	gl.enable(gl.DEPTH_TEST);
	  
    // WRITE MAIN JAVASCRIPT CODE HERE
	
	// [x,y,z,  r,g,b] 
	
	
	var v0 = [0,0,0]; // back; black
	var v1 = [0,0,1]; // z axis; blue
	var v2 = [0,1,0]; // y axis; green
	var v3 = [0,1,1]; // y+z; cyan
	
	var v4 = [1,0,0]; // x axis; red
	var v5 = [1,0,1]; // x+z; magenta
	var v6 = [1,1,0]; // x+y; yellow
	var v7 = [1,1,1]; // all; white
	
	var uv0 = [0,0];
	var uv1 = [0,1];
	var uv2 = [1,0];
	var uv3 = [1,1];
	
	var cr = [1,0,0]; //red
	var cg = [0,1,0]; //green
	var cb = [0,0,1]; //blue
	var cy = [1,1,0]; //yellow
	var co = [1,0.5,0]; //orange
	var cw = [1,1,1]; //white
	
	
	
	
	var data = [];
	
	// left x2, right x2, front x2, back x2, up x2, down x2
	data = data.concat( v7,uv3,cr,v3,uv1,cr,v1,uv0,cr, v7,uv3,cr,v1,uv0,cr,v5,uv2,cr,     // front
 						v3,uv3,cy,v2,uv1,cy,v0,uv0,cy, v3,uv3,cy,v0,uv0,cy,v1,uv2,cy,     // left
						v6,uv3,cb,v2,uv1,cb,v3,uv0,cb, v6,uv3,cb,v3,uv0,cb,v7,uv2,cb,     // up
						v2,uv3,co,v6,uv1,co,v4,uv0,co, v2,uv3,co,v4,uv0,co,v0,uv2,co,     // back
						v6,uv3,cw,v7,uv1,cw,v5,uv0,cw, v6,uv3,cw,v5,uv0,cw,v4,uv2,cw,     // right
						v5,uv3,cg,v1,uv1,cg,v0,uv0,cg, v5,uv3,cg,v0,uv0,cg,v4,uv2,cg, v0 );  // down
	
	var attributeArray = new Float32Array( data );
		
	var attributeBuffer = gl.createBuffer();
	gl.bindBuffer( gl.ARRAY_BUFFER, attributeBuffer );
	gl.bufferData( gl.ARRAY_BUFFER, attributeArray, gl.STATIC_DRAW );
	
	var pointPositionAddress = 
		gl.getAttribLocation( program, "pointPosition" );
	var textureCoordinatesAddress =
	    gl.getAttribLocation( program, "textureCoordinatesA" );
	var pointColorAddress = 
		gl.getAttribLocation( program, "pointColorA" );		
	
	var BPE = attributeArray.BYTES_PER_ELEMENT;
	
	gl.vertexAttribPointer(
		pointPositionAddress, 3, gl.FLOAT, false, 8*BPE, 0*BPE );
	gl.enableVertexAttribArray( pointPositionAddress );
	
	gl.vertexAttribPointer(
		textureCoordinatesAddress, 3, gl.FLOAT, false, 8*BPE, 3*BPE );
	gl.enableVertexAttribArray( textureCoordinatesAddress );
	
	gl.vertexAttribPointer(
		pointColorAddress, 3, gl.FLOAT, false, 8 * BPE, 4*BPE);
	gl.enableVertexAttribArray(pointColorAddress);
	
	transformationAddress =	gl.getUniformLocation( program, "transformation" );
	transformationData = new Matrix4().setIdentity();
	
	x = 0;
	y = 0;
	z = 0;
	angle = 0;
	scale = 1;
	time = 0;
	
	// set up texture buffer
	var textureBuffer = gl.createTexture();

	var imageAddress = gl.getUniformLocation( program, "image0" );
	var imageData = new Image();
	
	// when image is done loading run some code (load into GPU)
	imageData.onload = function() { 
		loadTexture0(textureBuffer, imageData, imageAddress);  }
	
	// start loading the image
	imageData.src = "DDBingoGrid.png";
	
	gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
	
	loop();
}

// OTHER FUNCTIONS

function loadTexture0( tb, id, ia )
{
	gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
	gl.activeTexture( gl.TEXTURE0 );
	gl.bindTexture(gl.TEXTURE_2D, tb);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, 
		gl.UNSIGNED_BYTE, id);
    gl.uniform1i( ia, 0 );
}

function loop()
{
	update();
	render();
	setTimeout( loop, 16 );
}

// update JavaScript variables; send new data to GPU
function update()
{
	time += 0.016;  // 60 FPS!
	
	x += 0.00;
	y += 0.00;
	z += 0.00;
	angle += 0.01;
	scale += 0.00;
	
	var model = new Matrix4();
	
	var t = new Matrix4();
	t.setTranslation(-1/2, 0, -1/2);
	var rx = new Matrix4();
	rx.setRotationX( angle );
	var ry = new Matrix4();
	ry.setRotationY(angle);
	
	model = rx.multiply(ry).multiply(t);
	
	
	var camera = new Matrix4();
	camera.setTranslation(0,0,6);
	
	var view = camera.inverse();
	
	var projection = new Matrix4();
	projection.setPerspective( 45, 1, 0.1, 100 );
	
	transformationData = projection.multiply(view).multiply(model);
	
	gl.uniformMatrix4fv( transformationAddress, false, transformationData.toArray() );
}

// draw all the things
function render()
{
	gl.clear( gl.COLOR_BUFFER_BIT );
	gl.clear( gl.DEPTH_BUFFER_BIT );
	gl.drawArrays( gl.TRIANGLES, 0, 36 );
}


</script>

</body>
</html>
1

1 Answers

2
votes

The problem lies in this line:

newColor = vec4(oldColor.r * pointColorV,
                oldColor.g * pointColorV,
                oldColor.b * pointColorV,
                1.0);

In glsl, the float*vector operation returns a vector. Since pointColorV is a vector, you try to pass three vec4 objects into the vec4 constructor, which is not possible. You can solve that by adding the correct swizzle operator .r/.g/.b after pointColorV. But the better option is to write the whole thing as one operation:

newColor = vec4(oldColor.rgb * pointColorV.rgb, 1.0);