I am trying to render multiple attribute buffers with drawElements:
var verteces = [1,1, 0,-1, -1,0];
var vBuffer = gl.createBuffer(gl.ARRAY_BUFFER);
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verteces), gl.DYNAMIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
var colors = [1,0,0,1, 0,1,0,1, 0,0,1,1];
var cBuffer = gl.createBuffer(gl.ARRAY_BUFFER);
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.DYNAMIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
var indices = [0,3,2];
var elBuffer = gl.createBuffer(gl.ELEMENT_ARRAY_BUFFER);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
If I run this code with gl.drawArrays(gl.TRIANGLES, 0, 3); it renders a beautiful triangle with rbg fill. But if I call gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0); I get
[.CommandBufferContext.Offscreen-MainThread-0AB44528]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1
Can’t figure out what is wrong here. drawElements without setting up colors buffer works alright.
Appreciate any help.
YOu proivide vertex data for 3 vertices, so the only valid vertex indices are 0,1,2. Yet, you try to render with an index array of 0,3,2, which will try to acces a fourth vertex, and would result in an out-of-bounds access to the vertex buffers.
I am trying to draw a simple circle using WebGL but am getting a few errors. I am very new to writing WebGL code and would love if anyone could explain this to me and what the problem is.
I can create a simple square using the same code but with 5 vertices and this works perfectly. But when I try to create an array using this method, it doesn't seem to like it. I am sorry if it is a trivial mistake but an explanation would be very helpful.
Thank you in advance.
Error: WebGL: bindBuffer: buffer already contains element data.
webgl-debug.js:232:20 Error: WebGL: vertexAttribPointer: invalid
element size webgl-debug.js:232:20 TypeError: value is undefined
These are shown in the console. Here is the code I am using.
function setupBuffers() {
//Setup the circle vertices
circleVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, circleVertexBuffer);
var r = 0.2;
var centre = 0;
var circleVertices = [];
var z = 0;
theta = 178;
circleVertices.push(centre);
circleVertices.push(r);
circleVertices.push(z);
for(var i = 0; i<theta; i++){
var rads2deg = i * (Math.PI/180);
var x = r * Math.cos(rads2deg);
var y = r * Math.sin(rads2deg);
circleVertices.push(x);
circleVertices.push(y);
circleVertices.push(z);
}
circleVertices.push(centre);
circleVertices.push(r);
circleVertices.push(z);
console.log(circleVertices);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(circleVertices), gl.STATIC_DRAW);
circleVertices.itemSize = 3;
circleVertices.numberOfItems = circleVertices.length/circleVertices.itemSize;
}
function draw() {
//set up a viewport that is the same as the canvas using function viewport (int x, int y, sizei w, sizei h) where x and y give the x and y window coordinates of the viewports width and height.
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
//fill the canvas with solid colour. Default is black. If other color is desiarible using function gl.clearColor (r,g,b,a)
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, circleVertexBuffer);
gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 1.0, 1.0, 1.0, 1.0);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, circleVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.LINE_STRIP, 0, circleVertexBuffer.numberOfItems);
}
The problem is this line
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, circleVertexBuffer);
There are 2 types of buffers in WebGL.
ELEMENT_ARRAY_BUFFER buffers
These buffers hold indices for gl.drawElements
ARRAY_BUFFER buffers.
These buffers hold attribute data (positions,normals,texcoords, etc)
When you create a buffer with gl.createBuffer it doesn't have a buffer type yet. The first time you bind that buffer with gl.bindBuffer it becomes whatever type of buffer you bound it to. If you bind it to ARRAY_BUFFER it's now an ARRAY_BUFFER buffer. If you bind it to ELEMENT_ARRAY_BUFFER it's now an ELEMENT_ARRAY_BUFFER buffer. Once it comes one of those types you can not change it's type or use it for the other type.
So, in your code you do this
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, circleVertexBuffer);
Which makes circleVertexBuffer an ELEMENT_ARRAY_BUFFER type buffer. But then in draw you have this
gl.bindBuffer(gl.ARRAY_BUFFER, circleVertexBuffer);
The buffer can't be both types. Change the first one in setupBuffers to
gl.bindBuffer(gl.ARRAY_BUFFER, circleVertexBuffer);
You might find this answer helpful
https://stackoverflow.com/a/27164577/128511
I'm trying to implement shadows using shadow maps, so I need to render a scene to a separate framebuffer (texture). I cannot get it to work properly, so after stripping down my codebase I'm left with a relatively simple set of instructions which should render a scene to a texture, and then simply render the texture.
The program consists of two programs:
Ground program
Teapot program
The first should render a rectangle, with a certain texture. The second one should render a teapot (with colors based on its position). Eech render step does the following (well, that's the idea anyway):
Switch to framebuffer
Render teapot
Switch to normal buffer
Render teapot
Render ground
Now, the ground fragment shader looks like:
gl_FragColor = texture2D(shadowMap, fTexCoord);
'shadowMap' is the texture I render to in step 2. I expect to see a floating teapot with a rectangle drawn under it. That indeed works. Now, I also expect to have the 'ground' to contain a teapot. After all, we rendered the scene we are looking at without the ground to the framebuffer/texture.
Code
var UNSIGNED_SHORT_SIZE = 2;
// Variables filled by setup()
var glCanvas;
var gl, teapotProgram, groundProgram;
var vBuffer, iBuffer, fBuffer;
var vertices, indices, textures;
var teapot = null;
var model;
var view;
var light;
var projection;
var BASE_URL = "https://hmbastiaan.nl/martijn/webgl/W08P02_SO/";
var WIDTH = 150, HEIGHT = 150;
function makeTeapot(){
var drawingInfo = teapot.getDrawingInfoObjects();
var indices = drawingInfo.indices;
for(var i=0; i < indices.length; i++){
indices[i] += 4; // Add offset for 'ground'
}
return {
indices: drawingInfo.indices,
vertices: drawingInfo.vertices
}
}
function makeRectangle(x1, x2, y1, y2, z1, z2){
var x1 = -2,
x2 = 2,
y1 = -1,
y2 = -1,
z1 = -1,
z2 = -5;
var vertices = [
vec4(x1, y2, z1, 1),
vec4(x2, y1, z1, 1),
vec4(x2, y1, z2, 1),
vec4(x1, y2, z2, 1)
];
var textures = [
vec2(-1.0, -1.0),
vec2( 1.0, -1.0),
vec2( 1.0, 1.0),
vec2(-1.0, 1.0)
];
var indices = [
0, 1, 2,
0, 2, 3
];
return {
indices: indices,
vertices: vertices,
textures: textures
}
}
function resetBuffers(){
vertices = [];
indices = [];
textures = [];
// Add rectangle
var rectangle = makeRectangle();
Array.prototype.push.apply(vertices, rectangle.vertices);
Array.prototype.push.apply(indices, rectangle.indices);
Array.prototype.push.apply(textures, rectangle.textures);
// Add teapot
var teapot = makeTeapot();
Array.prototype.push.apply(vertices, teapot.vertices);
Array.prototype.push.apply(indices, teapot.indices);
console.log(vertices);
console.log(indices);
console.log(textures);
// Send to GPU
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
}
function setup(){
$.get(BASE_URL + "teapot.obj", function(teapot_obj_data){
teapot = new OBJDoc(BASE_URL + "teapot.obj");
if(!teapot.parse(teapot_obj_data, 1)){
alert("Parsing teapot.obj failed.");
return;
}
setup2();
}).fail(function(){
alert("Getting teapot.obj failed.");
});
}
function setup2(){
glCanvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(glCanvas, {stencil: true, alpha: false});
gl.viewport(0, 0, WIDTH, HEIGHT);
teapotProgram = initShaders(gl, BASE_URL + "vshader-teapot.glsl", BASE_URL + "fshader-teapot.glsl");
groundProgram = initShaders(gl, BASE_URL + "vshader-ground.glsl", BASE_URL + "fshader-ground.glsl");
light = vec3(0.0, 2.0, -2.0);
view = lookAt(vec3(0, 0, 3), vec3(0,0,0), vec3(0,1,0));
projection = perspective(45, 1.0, 1, 100.0);
// Get teapot uniforms
gl.useProgram(teapotProgram);
teapotProgram.modelLoc = gl.getUniformLocation(teapotProgram, "Model");
teapotProgram.viewLoc = gl.getUniformLocation(teapotProgram, "View");
teapotProgram.projectionLoc = gl.getUniformLocation(teapotProgram, "Projection");
// Upload uniforms
gl.uniformMatrix4fv(teapotProgram.projectionLoc, false, flatten(projection));
gl.uniformMatrix4fv(teapotProgram.viewLoc, false, flatten(view));
gl.uniformMatrix4fv(teapotProgram.modelLoc, false, flatten(scalem(0.25, 0.25, 0.25)));
// Get teapot attributes
teapotProgram.vPosition = gl.getAttribLocation(teapotProgram, "vPosition");
// Get ground uniforms
gl.useProgram(groundProgram);
groundProgram.modelLoc = gl.getUniformLocation(groundProgram, "Model");
groundProgram.viewLoc = gl.getUniformLocation(groundProgram, "View");
groundProgram.projectionLoc = gl.getUniformLocation(groundProgram, "Projection");
groundProgram.shadowMap = gl.getUniformLocation(groundProgram, "shadowMap");
// Get ground attributes
groundProgram.vTexCoord = gl.getAttribLocation(groundProgram, "vTexCoord");
groundProgram.vPosition = gl.getAttribLocation(groundProgram, "vPosition");
// Allocate and fill vertices buffer
vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.vertexAttribPointer(teapotProgram.vPosition, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(teapotProgram.vPosition);
gl.vertexAttribPointer(groundProgram.vPosition, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(groundProgram.vPosition);
// Allocate indices buffer
iBuffer = gl.createBuffer();
// Setup FBO
fBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fBuffer);
fBuffer.renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, fBuffer.renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 512, 512);
fBuffer.texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, fBuffer.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 512, 512, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
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);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fBuffer.texture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fBuffer.renderbuffer);
// Sanity checking: framebuffer seems to throw now errors
if (!gl.isFramebuffer(fBuffer)) {
throw("Invalid framebuffer");
}
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
switch (status) {
case gl.FRAMEBUFFER_COMPLETE:
break;
case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
break;
case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
break;
case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
break;
case gl.FRAMEBUFFER_UNSUPPORTED:
throw("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
break;
default:
throw("Incomplete framebuffer: " + status);
}
// Set ground textures
gl.uniform1i(groundProgram.shadowMap, 0);
// Upload uniforms
gl.uniformMatrix4fv(groundProgram.projectionLoc, false, flatten(projection));
gl.uniformMatrix4fv(groundProgram.viewLoc, false, flatten(view));
gl.uniformMatrix4fv(groundProgram.modelLoc, false, flatten(mat4()));
// Restore default buffers
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// Set background colour
gl.clearColor(0.3921, 0.5843, 0.9294, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
resetBuffers();
window.requestAnimationFrame(render);
}
function render(){
var teapot = makeTeapot();
gl.useProgram(teapotProgram);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// Switch to framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, fBuffer);
// Draw teapot
teapot = makeTeapot();
gl.drawElements(gl.TRIANGLES, teapot.indices.length, gl.UNSIGNED_SHORT, 6 * UNSIGNED_SHORT_SIZE);
// Set framebuffer to defualt buffer (in-browser output)
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// Draw ground
gl.useProgram(groundProgram);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
// Render teapot
gl.useProgram(teapotProgram);
gl.drawElements(gl.TRIANGLES, teapot.indices.length, gl.UNSIGNED_SHORT, 6 * UNSIGNED_SHORT_SIZE);
}
setup();
<div>
<br/>
<canvas width="150" height="150" id="gl-canvas">Sorry :|</canvas>
</div>
<script type='text/javascript' src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type='text/javascript' src="https://hmbastiaan.nl/martijn/webgl/angel/webgl-utils.js"></script>
<script type='text/javascript' src="https://hmbastiaan.nl/martijn/webgl/angel/initShaders2.js"></script>
<script type='text/javascript' src="https://hmbastiaan.nl/martijn/webgl/angel/MV.js"></script>
<script type='text/javascript' src="https://hmbastiaan.nl/martijn/webgl/angel/objParser.js"></script>
Functions of interest:
setup2(): sets up all the buffers and uniforms.
render(): renders the scene.
Disclaimer: this is for an assignment, although this code is simplified enough to not look like the original assignment at all :).
At a glance there are several issues.
Texture bindings are global. Since in setup2 you unbind the 1 texture that means it's never used.
You need to bind whatever textures are needed before each draw call. In other words when you draw the ground you need to bind the teapot texture as in
gl.bindTexture(gl.TEXTURE_2D, fBuffer.texture);
Note: This is an over simplification of what's really needed. You really need to
Choose a texture unit to bind the texture to
var unit = 5;
gl.activeTexture(gl.TEXTURE0 + unit);
Bind the texture to that unit.
gl.bindTexture(gl.TEXTURE_2D, fBuffer.texture);
Set the uniform sampler to that texture unit
gl.uniform1i(groundProgram.shadowMap, unit);
The reason you don't need those extra steps is because (a) you only
have 1 texture so you're using texture unit #0, the default and (b) because
uniforms default to 0 so shadowMap is looking at texture unit #0.
Because you've made a mipmapped texture just rendering to level 0 will not update the mips.
In other words after you render the teapot you'll have a teapot in mip level 0 but mip levels 1, 2, 3, 4, 5 etc will still have nothing in them. You need to call
gl.generateMipmap(gl.TEXTURE_2D)
For that texture after you've rendered the teapot to it. Either that or stop using mips
You need to set the viewport every time you call gl.bindFramebuffer.
gl.bindFramebuffer should almost always be followed by a call to gl.viewport to make the viewport match the size of the thing you're rendering to
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
// set to size of fb
gl.viewport(0, 0, widthOfFb, heightOfFb);
renderSomething();
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// set to size of canvas's drawingBuffer
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
Attributes settings are global
You setup the teapot attributes. Then you draw a teapot to the texture. You then draw ground, but you're still using the teapot attributes.
Just like textures you need to setup attributes before each draw call.
I'm also guessing you really should not be calling makeTeapot in your render function but instead it should be called in setup.
You might find this article useful
You should also consider not putting properties on WebGL objects as it's arguably an anti-pattern.
Also synchronous XHR requests are not cool. You're getting this message in the JavaScript console
Synchronous XMLHttpRequest on the main thread is deprecated because
of its detrimental effects to the end user's experience. For more
help, check http://xhr.spec.whatwg.org/.
I've been following instructions for game development using webGL from this book, and in the chapter about cameras, it discusses and gives a very limited example of an orbital camera, but goes on to continue the rest of the book focusing on a simple first-person, free camera.
The orbital camera works very well, but if I try to create a controllable character object, and set the camera's orbit point to follow it, the camera seems to... get ahead of itself? It somehow moves faster than the character.
Here's the relevant method from the OrbitalCamera object:
OrbitCamera.prototype.setOrbitPoint = function (orbitPoint)
{
// get the distance the camera was from the orbit point.
var orbitPointToCam =vec3.create();
vec3.multiply(orbitPointToCam,this.dir, -this.getDistance());
this.orbitPoint[0] = orbitPoint[0];
this.orbitPoint[1] = orbitPoint[1];
this.orbitPoint[2] = orbitPoint[2];
vec3.add(this.pos,this.orbitPoint, orbitPointToCam);
}
And here is where the function is being called:
function animate(){
var lSpeed = 0;
var uSpeed = 0;
var distance = cam.getDistance();
if(stage.stageObjects.length != 0){
var pos = stage.stageObjects[0].location;
if (left) {
lSpeed = +0.05;
}
if (right) {
lSpeed = -0.05;
}
if (up) {
uSpeed = 0.05;
}
if (down) {
uSpeed = -0.05;
}
stage.stageObjects[0].location = [(uSpeed*Math.round(cam.dir[0]))+(lSpeed*Math.round(cam.left[0]))+pos[0], pos[1], (uSpeed*Math.round(cam.dir[2]))+(lSpeed*Math.round(cam.left[2]))+pos[2]]
cam.setOrbitPoint([stage.stageObjects[0].location[0],0,stage.stageObjects[0].location[2]]);
cam.setDistance(distance);
if (cup) {
cam.pitch(Math.PI*0.01);
}
if (cdown) {
cam.pitch(-Math.PI*0.01);
}
if (cleft) {
cam.yaw(-Math.PI*0.01);
}
if (cright) {
cam.yaw(Math.PI*0.01);
}
}
}
And here is the draw call:
function drawScene(){
gl.viewport(0,0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
setLightUniform();
pushMatrix();
calculateMvMatrix();
for (var i = 0; i<stage.stageObjects.length; i++){
pushMatrix();
mat4.translate(mvMatrix, mvMatrix, stage.stageObjects[i].location);
mat4.rotateX(mvMatrix, mvMatrix, stage.stageObjects[i].rotationX);
mat4.rotateY(mvMatrix, mvMatrix, stage.stageObjects[i].rotationY);
mat4.rotateZ(mvMatrix, mvMatrix, stage.stageObjects[i].rotationZ);
setMatrixUniforms();
gl.uniform3f(shaderProgram.materialDiffuseColor, stage.stageObjects[i].diffuseColor[0],stage.stageObjects[i].diffuseColor[1],stage.stageObjects[i].diffuseColor[2]);
gl.uniform3f(shaderProgram.materialAmbientColor, stage.stageObjects[i].ambientColor[0],stage.stageObjects[i].ambientColor[1],stage.stageObjects[i].ambientColor[2]);
gl.bindBuffer(gl.ARRAY_BUFFER, stage.stageObjects[i].vbo);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, stage.stageObjects[i].vbo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, stage.stageObjects[i].nbo);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, stage.stageObjects[i].nbo.itemSize, gl.FLOAT, false, 0,0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, stage.stageObjects[i].ibo);
gl.drawElements(gl.TRIANGLES, stage.stageObjects[i].geometry.indices.length, gl.UNSIGNED_SHORT,0);
popMatrix();
}
popMatrix();
}
I can post the whole code for the Camera object if the problem isn't in here. Any help is greatly appreciated, this has been driving me crazy
I'm trying to make an object in javascript to contain a 3dObject and everyting related to it:vertex positions, normals, texture coordonates etc + the methods needed to handle it: loading the object, drawing etc.
The problem is that when I try to parse the WebGL context object, in my case gl, wich is declared global, in order to use specific methods like createBuffer(), bindBuffer(), javascript give's me the following error: "Uncaught TypeError: Cannot call method 'createBuffer' of undefined"
This is the object code:
function object3D(gl){
this.vertexPositionBuffer = gl.createBuffer();
this.textureCoordBuffer = gl.createBuffer();
this.normalDirectionBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
this.loadVertices = function (vertices, itemSize, numItems){
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
this.vertexPositionBuffer.numItems = numItems;
this.vertexPositionBuffer.itemSize = itemSize;
}
this.loadNormals = function (normals, itemSize, numItems){
gl.bindBuffer(gl.ARRAY_BUFFER, this.normalDirectionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
this.normalDirectionBuffer.numItems = numItems;
this.normalDirectionBuffer.itemSize = itemSize;
}
this.loadIndex = function (indexArray, itemSize, numItems){
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array, gl.STATIC_DRAW);
this.indexBuffer.numItems = numItems;
this.indexBuffer.itemSize = itemSize;
}
this.loadTexture = function (textureCoord, itemSize, numItems){
gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoord), gl.STATIC_DRAW);
this.textureCoordBuffer.numItems = numItems;
this.textureCoordBuffer.itemSize = itemSize;
}
}
This is how I try to create an instance of this object:
var cube1 = new object3D(gl);
WebGL context assign:
var gl;
function initGL(canvas){
try{
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
}catch(e){
}
if(!gl){
alert("Could not initialise WebGL");
}
}
Outside any function and inside my object definition console.log(gl) says is undefined, but in other places it works just fine, altough it is declared global.
I have to mention that i have a solid background in c++ but i'm pretty new to javascript and handling objects in it.