Reputation: 34087
I wrote a simple WebGL page (well, as simple as I could make it) and can't figure out why normalized coordinates aren't working. That is, I'm trying to draw a square from (-0.5, -0.5) to (0.5, 0.5) via two triangles, and instead I get a large rectangle that goes off screen.
I'm completely unsure what I am doing wrong, so I pasted it into a jsFiddle:
Notice how I define my verts and indices correctly (right?) and my shader and fragment programs are as simple as they come.
Why is it drawing as a weird large off-screen rectangle?
Upvotes: 2
Views: 346
Reputation:
Same as other elements the size something is displayed is separate from the size it is. Examples:
Display a 4x4 JPGs as 4x4 pixels
<img src="some4x4pixel.jpg" />
Display a 4x4 JPGs at 16x16 pixels
<img src="some4x4pixel.jpg" width="16" height="16" />
Display a 4x4 JPG at 16x16 pixels
<img src="some4x4pixel.jpg" style="width:16px; height:16px;"/>
Display a 4x4 JPG at whatever size it's container is
<img src="some4x4pixel.jpg" style="width:100%; height:100%;"/>
Display a 300x150 pixel canvas (the default size) at 300x150 pixels
<canvas></canvas>
Display a 4x4 canvas at 4x4 pixels
<canvas width="4" height="4"></canvas>
Display a 4x4 canvas at 16x16 pixels
<canvas width="4" height="4" style="width:16px; height:16px;"/></canvas>
Display a 4x4 canvas at whatever size it's container is
<canvas width="4" height="4" style="width:100%; height:100%;"/></canvas>
If you're doing 3D and using the fairly common perspective function found in most 3D math libraries you generally want to set the aspect ratio to the display size, not the actual size.
// 45degrees, assumes math library uses radians
var fieldOfView = Math.PI / 4;
// Use the size the canvas is displayed, NOT the size it actually is.
var aspectRatio = canvas.clientWidth / canvas.clientHeight;
var zNear = 0.1;
var zFar = 1000;
var matrix = someMathLibrary.perspective(fieldOfView, aspectRatio, zNear, zFar, ...)
If you want the size the canvas exists to be the same size as it's displayed use
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
Though note, a WebGL canvas is not required to be the size you request since various GPUs have limits on size. If you want to know the size you actually got vs the size you requested check
gl.drawingBufferWidth
gl.drawingBufferHeight
For the perspective matrix used by most 3D apps the actual size of the canvas is not that important. For certain kinds of effects or for 2D it is often important.
The reason this is hard to find documentation for is because it's taken for granted that people know that CSS decides the display size for all elements regardless of the actual size of their content.
Upvotes: 0
Reputation: 34087
Okay I finally got help from someone in #webgl on Freenode: the <canvas>
element needs a width and height attribute, whereas I'm setting them via CSS. Apparently the actual width and height attributes determine the width and height of the OpenGL buffer.
I was not able to find this documented anywhere else, except that WebGL examples have the width and height attribute on the canvas tag.
Upvotes: 2