3

Alright- going nuts here. I'm doing some WebGL and I'm trying to make an isometric cube. I don't want to use Three.js. I want to first understand what is going wrong in my code. I've been researching and the only tutorials I can find seem to be for OpenGL

At any rate- here's my drawScene function:

function drawScene() {

this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, this.gl.viewportWidth / this.gl.viewportHeight, 0.1, 100.0, pMatrix);
mvMatrix = mat4.lookAt([0,0,40], [0, 0, 0], [0, 1, 0]);

_globalNext = this._first;

    while(_globalNext) {
    _globalNext.render();
    }

}

and the render function is

function render() {

mvPushMatrix();

//transform. order matters.
mat4.translate(mvMatrix, [this._x, this._y, this._z]);
mat4.rotate(mvMatrix, 0.01745*this._rot, [this._axisX, this._axisY, this._axisZ]);
mat4.scale(mvMatrix,  [this._scaleX,this._scaleY,this._scaleZ]);

//bind the buffers.
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._positionBuff);
this.gl.vertexAttribPointer(this._shader.vertexPositionAttribute, this._positionBuff.itemSize,   this.gl.FLOAT, false, 0, 0);

this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._colorBuff);
this.gl.vertexAttribPointer(this._shader.vertexColorAttribute, this._colorBuff.itemSize, this.gl.FLOAT, false, 0, 0);

this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this._indexBuff);
this.setMatrixUniforms(this.gl);
this.gl.drawElements(this.gl.TRIANGLES, this._indexBuff.numItems, this.gl.UNSIGNED_SHORT, 0);

    if(this._usePopper == false) {
    mvPopMatrix();
    } 

_globalNext = this._nextSib;
}

Fairly pedestrian. I'm using it to draw cubes. Anyway, in the OpenGL examples they seem to do away with the perspective function, but here if I leave it out, my scene is blank. I know that the lookAt function is working properly, and I have to do something with the perspective matrix. A little help would be appreciated. Thank you!

CodeOwl
  • 662
  • 2
  • 9
  • 23

1 Answers1

6

All that the projection matrix does is map your scene's coordinate system to a [-1, 1] range on the X and Y axes, which is the space that is used when rendering fragments to your window. It is possible to construct your scene in such a way that it renders to that [-1, 1] space directly, in which case no projection matrix is needed (which may be what you were referring to with the examples leaving it out, but this is typically not the case.

When using a perspective matrix as your projection matrix, the X and Y coordinates are scaled by the Z value, giving them an appearance of depth. If that effect is undesirable, you can eliminate the depth scaling by using an orthographic matrix, like so:

mat4.ortho(left, right, bottom, top, 0.1, 100.0, pMatrix);

What left/right/top/bottom are is up to you, but typically these will correspond in some way with the dimensions of your WebGL viewport. For example, if your WebGL window was 640x480 you could do:

mat4.ortho(0, 640, 0, 480, 0.1, 100.0, pMatrix);

Which would cause any vertex placed at (0, 0) to render in the bottom left corner of the window, and any vertex placed at the (648, 480) to render in the top right. The z component of those vertices would have no effect. This is a popular technique to use for rendering GUI elements, sprites, or isometric graphics like you are attempting to do.

Hope that helps!

Toji
  • 33,927
  • 22
  • 105
  • 115
  • rock on! I was messing around with ortho, but my only mistake was that there was a negative sign in the zFar parameter, and nothing was showing up. I'm so glad that works! – CodeOwl Jun 19 '12 at 20:53