1

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 Answer 1

2

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! This has been a big help, everything works just fine now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.