I am WebGL beginner and trying to draw multiple objects, I have already rendered one, now going for multiple. There are very less tutorial for multiple object rendering, the one that i could find was on this link http://webglfundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html
I tried changing code according to it but it do not work, Could some one please correct the problems and give the solution with explanation that what is wrong in my try ?
My full code is :
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script class="WebGL">
var gl;
function createProgram(gl, vertexShader, fragmentShader)
{
var vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, vertexShader);
gl.compileShader(vs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
alert(gl.getShaderInfoLog(vs));
//////
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, fragmentShader);
gl.compileShader(fs);
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
alert(gl.getShaderInfoLog(fs));
program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
alert(gl.getProgramInfoLog(program));
return program;
}
function createShaderFromScriptElement(gl , shaderName)
{
var Shader = document.getElementById(shaderName).firstChild.nodeValue;
return Shader;
}
function start()
{
var canvas = document.getElementById("canvas");
gl = canvas.getContext("experimental-webgl");
if (!gl) { alert("error while GL load"); }
var vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
var fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");
var program = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(program);
var colorMult = gl.getAttribLocation(program, "u_colorMult");
var colorLocation = gl.getUniformLocation(program, "u_color");
// Our uniforms for each thing we want to draw
var sphereUniforms = {
u_colorMult: [0.5, 1, 0.5, 1],
u_matrix: makeIdentity(),
};
var cubeUniforms = {
u_colorMult: [1, 0.5, 0.5, 1],
u_matrix: makeIdentity(),
};
var coneUniforms = {
u_colorMult: [0.5, 0.5, 1, 1],
u_matrix: makeIdentity(),
};
// The translation for each object.
var sphereTranslation = [0, 0, 0];
var cubeTranslation = [-40, 0, 0];
var coneTranslation = [40, 0, 0];
var sphereXRotation = time;
var sphereYRotation = time;
var cubeXRotation = -time;
var cubeYRotation = time;
var coneXRotation = time;
var coneYRotation = -time;
// ------ Draw the sphere --------
gl.useProgram(programInfo.program);
// Setup all the needed attributes.
setBuffersAndAttributes(gl, programInfo.attribSetters, sphereBufferInfo);
sphereUniforms.u_matrix = computeMatrix(
viewMatrix,
projectionMatrix,
sphereTranslation,
sphereXRotation,
sphereYRotation);
// Set the uniforms we just computed
setUniforms(programInfo.uniformSetters, sphereUniforms);
gl.drawArrays(gl.TRIANGLES, 0, sphereBufferInfo.numElements);
// ------ Draw the cube --------
// Setup all the needed attributes.
setBuffersAndAttributes(gl, programInfo.attribSetters, cubeBufferInfo);
cubeUniforms.u_matrix = computeMatrix(
viewMatrix,
projectionMatrix,
cubeTranslation,
cubeXRotation,
cubeYRotation);
// Set the uniforms we just computed
setUniforms(programInfo.uniformSetters, cubeUniforms);
gl.drawArrays(gl.TRIANGLES, 0, cubeBufferInfo.numElements);
// ------ Draw the cone --------
// Setup all the needed attributes.
setBuffersAndAttributes(gl, programInfo.attribSetters, coneBufferInfo);
coneUniforms.u_matrix = computeMatrix(
viewMatrix,
projectionMatrix,
coneTranslation,
coneXRotation,
coneYRotation);
// Set the uniforms we just computed
setUniforms(programInfo.uniformSetters, coneUniforms);
gl.drawArrays(gl.TRIANGLES, 0, coneBufferInfo.numElements);
}
</script>
<script id="2d-vertex-shader" type="x-shader/x-vertex">
// Passed in from the vertex shader.
varying vec4 v_color;
uniform vec4 u_colorMult;
void main()
{
gl_FragColor = v_color * u_colorMult;
}
</script>
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_color;
void main()
{
gl_FragColor = u_color; // green
}
</script>
</head>
<body onload="start()">
<div style="text-align: center">
</div>
<table style="width:100%; height: 10%;">
<tr>
<td style="width:200px; max-width:200px; ">
<canvas id="canvas" width="300" height="300"></canvas>
</td>
<td style="width:200px; max-width:200px; background-color:gray; ">
<canvas id="canvas2" width="300" height="300"></canvas>
</td>
</tr>
</table>
</body>
</html>
Please explain me the solution so that i will understand and it will remain with me for future. Thanks
GLSL shaders have 3 types of variables:
So here are some problems I can spot in your code:
makeIdentity
but I don't see them declared, edit your page to pull in the appropriate matrix library to supply these functions.The article you linked to in your question has a standalone demo that you can View source
on to see a complete working example. Note that it pulls in some matrix math helper libraries at the top, and calls functions like createCubeVertices
to create vertex data.
Also check out lesson 2 of Learning WebGL where they apply vertex colors to some polygons. You may want to work your way through all of the lessons there.
Also, most developers find they don't need to build their own 3D engine from scratch. Consider learning one of the existing WebGL frameworks that can hide the low-level details of WebGL. Of these, Three.js is a popular place to start. If you don't need a deep understanding of all the low-level details, this will save you a lot of time and effort.