Gfx
Documentation of the GFX.js library
The most recent GFX.js
is here:
https://rawgit.com/wolftype/200c/gh-pages/js/gfx_v02.js
<script src = "https://rawgit.com/wolftype/200c/gh-pages/js/gfx_v02.js"></script>
The previous GFX.js
is here:
https://rawgit.com/wolftype/200c/gh-pages/js/gfx_v01.js
Recent Changes to the API
In gfx_v02.js
I have renamed member variables of GFX.Frame
in order to distinguish between:
- Properties of a frame (
.position
,.orientation
, and.size
) - Transformations of those properties (
.translate()
,.rotate()
, and.scale()
)
.scale(sx,sy,sz)
is a function that changes the .size
property.
.rotate(t,x,y,z)
is a function that changes the .orientation
property.
.translate(x,y,z)
is a function that changes the .position
property.
So if you were changing frame properties directly using:
frame.rotation = ...
frame.scale = ...
instead use
frame.orientation = ...
frame.size = ...
Contents
- API Changes
- HTML File
- GFX.App
- GFX.Scene
- GFX.Mesh
- GFX.Frame
- GFX.Matrix
- GFX.MatrixStack
- GFX.Quaternion
- GFX.Vector
- GFX.Shader
- GFX.Buffer
Introduction
GFX.js is an ASAP (as-simple-as-possible) framework for experimenting with WebGL graphics.
Its goals are to be easy to use, minimally designed, and (hopefully) maintain backward compatibility when (only necessary) features are added. It is built to assist in introducing students to the modern, programmable OpenGL pipeline.
Keeping the code to under 2000 lines means it can be read (by you!) in full. Some assumptions were made in order to keep the code simple.
A current limitation is that the scene.draw(mesh)
method assumes you are only using one shader. This will likely change, likely by adding a feature which allows meshes to have their own shaders attached to them.
Pipeline Overview
A GFX.Mesh has buffers of data (vectors, indices, colors, uv texture coordinates), settings for how to draw these by a GFX.Scene, and a GFX.Frame for specifying an object’s position, orientation, and size.
A GFX.Scene has a GFX.Shader for processing mesh data, a GFX.Camera used to create view matrix based on the camera’s GFX.Frame and a projection matrix based on its field-of-view and the width and height of the screen. A scene also has its own frame, and its own transformation GFX.MatrixStack.
A GFX.Frame is composed of a GFX.Vector position, a GFX.Quaternion orientation, and another vector representing size.
The HTML file
Below is a shell of a script for creating a WebGL application using GFX.
We will have to add code to the onInit
and onRender
methods of the GFX.App
,
as well as a vertex shader and fragment shader.
GFX.App
GFX.App handles initialization of the webGL context, loads the scene’s shader from the scripts
Methods
.onInit()
: Setup GL objects and buffers..onRender()
: Called repeatedly by the animation loop..start()
: Begins the program.
Members
.scene
: A GFX.Scene.canvas
: The html canvas element to which we are rendering.
GFX.Scene
A GFX.Scene manages all the matrix information we need to transform our mesh data as it is sent over to the graphics card (GPU). It has its own frame of reference for rotating the scene, a camera for a stack of matrices to push, transform, and pop, and a shader to which all these matrices are sent, and which then processes mesh information.
- The
scene.camera
enables you to move your view in 3D space. - The
scene.matrix
stack enables you to push and pop your transformation matrices, which can be rotated, translated, and scaled. - The
scene.frame
enables you to translate, rotate, and scale the whole scene.
It also controls the background color
Inside app.onRender()
we will typically add the following code:
Methods
.begin()
: Binds the scene’s shader, and uploads model, view, and projection matrices to it. Also, it clears the screen and clears the matrix stack..draw(mesh)
: Draws a GFX.Mesh. See also how the model is calculated..end()
: Unbinds the scene shader..project(wc)
: Returns the screen coordinate vector in pixels of world coordinate GFX.Vector..unproject(sc)
: Returns the world coordinates vector of screen coordinate GFX.Vector.
Members
.width
: The width of the scene in pixels..height
: The height of the scene in pixels..color
: The background color (used inGL.clearColor
)..time
: An incrementing counter..camera
: A GFX.Camera for use in calculating the View matrix..shader
: A GFX.Shader defined by you in your.html
document..frame
: A GFX.Frame which encodes a global translation-rotation-scale matrix..matrix
: A GFX.MatrixStack for rotating, translating, and scaling in arbitrary order.
GFX.MatrixStack
GFX.Scene has a .matrix
member which is a stack (i.e. a list) of matrices that
enable us to compound transformations in interesting ways.
During scene.draw()
, the last entry of this matrix is used
as one of three matrices to calculate the model which is sent to the vertex shader.
The following code draws a circle of objects by manipulating the scene.matrix
stack.
For 100 iterations, we push
the matrix stack, making a copy of the last matrix, rotate
by an every increasing angle around the z axis, and translate
by a fixed amount along the x axis, then we pop
(discard) the matrix.
Compare that to the following code, where the push
and pop
happen outside the loop:
For 100 iterations, we rotate
by a fixed angle around the z axis, and then translate by an ever increasing amount in that new coordinate system. Then we repeat. What shape does this make?
Methods
.push()
: Copies the last entry in the stack and adds it to the stack.set(m)
: Sets the last entry in the stack to be matrixm
..translate(x,y,z)
: Multiplies the last entry in the stack by a transformation matrix..rotate(t,x,y,z)
: Multiplies the last entry in the stack by a rotation matrix..scale(sx,sy,sz)
: Multiplies the last entry in the stack by a scale matrix..pop()
: Removes the last entry in the stack.
Members
.stack
: A list of matrices
Calculating The Model
When drawing a Mesh in scene.draw()
, the model transformation sent to the shader is computed as:
1 - $A_{meshFrame}$: The Mesh Frame’s position, orientation, and size, converted into a translation-rotation-scale (TRS) matrix (in that order).
2 - $A_{stack}$: The current (i.e. last) entry in the Scene’s matrix stack.
3 - $A_{sceneFrame}$: The Scene’s own frame, converted into a TRS matrix.
GFX.Mesh
A collection of buffers of 3D data and specifications for how to render it. The following code creates a mesh, loads vertex and index information into buffers, and draws the mesh to the screen:
For now, one built-in Mesh is already included, GFX.Mesh.Frame
, which can be used:
var mesh;
app.onInit(){
mesh = GFX.Mesh.MakeFrame();
}
This creates the Mesh if it does not exist already, and returns a fresh copy if it does.
Methods:
.load(vertices,indices)
: Buffers Vertex and Index Data to the GPU
-vertices
is a list of 3D Vertex Coordinates.
-indices
is a list of integer indices into the vertex list.
- If a list of indices is passed in thenuseElements
is set to true..loadVertices(vertices, hint)
: Buffers Vertex Data only, with optional hint
-hint
is an optional value (GL.STATIC_DRAW
,GL.STREAM_DRAW
, orGL.DYNAMIC_DRAW
).loadIndices(vertices, hint)
: Buffers Index Data only, with optional hint
-hint
is an optional value (GL.STATIC_DRAW
,GL.STREAM_DRAW
, orGL.DYNAMIC_DRAW
).loadUV(texCoords,hint)
: Buffers Texture Coordinate Data to the GPU
-texCoords
is a list of 2D Texture Coordinates
-hint
is an optional value (GL.STATIC_DRAW
,GL.STREAM_DRAW
, orGL.DYNAMIC_DRAW
) - Sets.useUV
to true..loadColor(colors,hint)
: Buffers Color Data to the GPU
-colors
is a list of 3D Color values
-hint
is an optional value (GL.STATIC_DRAW
,GL.STREAM_DRAW
, orGL.DYNAMIC_DRAW
) - Sets.useColor
to true;
Members
.useElements
: A boolean value specifying whether to callGL.DrawElements
orGL.DrawArrays
. If set to true, then when the mesh is drawn byscene.draw(mesh)
, the.indexBuffer
is bound withGL.bindBuffer
and then used to specify the order in which the vertices are drawn withGL.drawElements
..useUV
: A boolean value specifying whether to enable uv mapping. - If set to true, the “uv” attribute on the shader is enabled during rendering withGL.enableVertexAttribArray
, the mesh’s.texBuffer
is bound withGL.bindBuffer
, and the attribute and buffer are bound withGL.vertexAttributePointer
..useColor
: A boolean value specifying whether to enable the “color” attribute on the shader. - If set to true, the “color” attribute on the shader is enabled during rendering withGL.enableVertexAttribArray
, the mesh’s.colorBuffer
is bound withGL.bindBuffer
, and the attribute and buffer are bound withGL.vertexAttributePointer
..vertexBuffer
: A buffer of 3D Vector data..indexBuffer
: A buffer of index data..texBuffer
: A buffer of UV data..colorBuffer
: A buffer of Color data.
GFX.Camera
Contains a frame of reference for calculating a view matrix, and some parameters for calculating a projection matrix.
GFX.Scene has a Camera.
The following code causes the scene’s camera to orbit around the origin, while always facing it.
Methods
- ‘.setTarget(v)’: Sets camera orientation so that it looks at
v
.
Members
.frame
: A GFX.Frame for position and orientation data. Used when calculating the view matrix inscene.begin()
. Note that the camera looks along its negative z axis..fovy
: The Field-of-View in degrees, used for calculating the Projection matrix..focalLength
: Parallax merge point (used in 3D Stereoscopic rendering)..eyeSep
: Eye Separation (used in 3D Stereoscopic rendering).
GFX.Frame
A frame of reference with .position
, .orientation
, and .size
member variables and .translate()
, .rotate()
, and .scale()
methods to transform those variables.
GFX.Mesh has a frame.
GFX.Camera has a frame.
GFX.Scene has a frame.
The following code would animate your mesh by moving it, rotating it, and scaling it repeatedly.
For frames, it is not important in which order these transformations are written in your code: the frame’s transformation is always converted into a matrix in TRS order:
For manipulating imagery with order-dependent coordinate system transformations, see the GFX.MatrixStack of GFX.Scene.
Features
The .orientation
of Frames can be specified by setting it directly using the methods from GFX.Quaternion, or by using helper functions like setTargetZ
which can lock a frame’s axis onto a target.
Frames can be interpolated between by using the static method GFX.Frame.FromTo
which takes two Frames as parameters, and a scalar amount by which to interpolate between them.
Frames can be composed together with .mult(f)
, to create new Frames that are a composition of the two.
Methods
.matrix()
: Calculates a Translation-Rotation-Scale matrix..translate(x,y,z)
: Moves the.position
vector..rotate(t,x,y,z)
: Spins the.orientation
quaternion byt
radians around the globalx,y,z
axis..scale(x,y,z)
: Dilates the.size
vector byx,y,z
..x()
: Get the local x axis GFX.Vector..y()
: Get the local y axis GFX.Vector..z()
: Returns the local z axis GFX.Vector..rotateX(t)
: Rotatet
radians about the local x axis..rotateY(t)
: Rotatet
radians about the local y axis..rotateZ(t)
: Rotatet
radians about the local z axis..setTargetX(v)
: Set orientation so that local x axis points towards GFX.Vector v..setTargetY(v)
: Set orientation so that local y axis points towards GFX.Vector v..setTargetZ(v)
: Set orientation so that local z axis points towards GFX.Vector v..setTarget(v)
: Set orientation so that local z axis points towards GFX.Vector v while keeping local y axis as close to vertical as possible..mult(relFrame)
: Returns a new Frame by composing this one with a transformation relative to it.
Static Methods
GFX.Frame.FromTo(fa,fb, t)
: Returns a Frame whose position, orientation, and size is an interpolated value betweenfa
andfb
by amountt
.
Members
.position
: A GFX.Vector encoding x,y,z coordinate position in the world..orientation
: A GFX.Quaternion encoding the orientation..size
: A GFX.Vector encoding the scale in each direction.
GFX.Vector
A 3D Vector.
OpenGL is right-handed, so this means:
The positive z axis points towards you.
The positive y axis points up.
The positive x axis points right.
Vectors can be rotated using the .apply(v)
method of GFX.Quaternion
Methods
.set(x,y,z)
: set values.add(v)
: Return a new Vector by summing of coordinate values with Vectorv
.sub(v)
: Return a new Vector by subtracting Vectorv
..mult(s)
: Return a new Vector by multiplying each coordinate value bys
..divide(s)
: Return a new Vector by dividing each coordinate value bys
..dot(v)
: Return the dot product withv
..cross(v)
: Return the cross product withv
..norm()
: Return the length..unit()
: Return the a new normalized vector..neg()
: Return negative vector.
Members
.x
: Coordinate along x axis;.y
: Coordinate along y axis;.z
: Coordinate along z axis;
GFX.Matrix
A 4x4 Matrix. Matrices in GFX are Row-Major, and so are transposed when sending values to the shader with shader.setUniformMatrix
.
Methods
.mult(m)
: Returns new Matrix by multiplication with matrix m..multVec(v)
: Returns a new 4D Vector by multiplying with v..transpose()
: Returns a new Matrix that by transposition..inverse()
: Inverse of Matrix.det()
: Determinant of Matrix
Static Methods
GFX.Matrix.identity()
: IdentityGFX.Matrix.translation(x,y,z)
: Translation byx,y,z
GFX.Matrix.rotation(angle,x,y,z)
: Rotation byangle
radians about axisx,y,z
.GFX.Matrix.scale(x,y,z)
: Scale byx,y,z
.GFX.Matrix.perspective(fovy, ratio, near, far)
: Generate Projection from Symmetrical Frustum.GFX.Matrix.frustum(l,r,t,b,near,far)
: Generate Projection from General Frustum.GFX.Matrix.lookAt(eye,target,up)
: Generate View Matrix.
Members
.val
: An array of 16 floating point numbers.
GFX.Matrix3
A 3x3 Matrix. Matrices in GFX are Row-Major, and so are transposed when sending values to the shader with shader.setUniformMatrix3
. 3x3 matrices are only used for Normal matrices, and so multiplication methods are not provided (use GFX.Matrix instead).
Methods
.inverse()
: Inverse of Matrix.det()
: Determinant of Matrix
Members
.val
: An array of 16 floating point numbers.
GFX.Quaternion
A Quaternion represents a rotation in 3D. It can be used to transform a GFX.Vector and can be multiplied with other quaternions to compose rotations. The following code creates a quaternion that rotates a vector 90 degrees around the y axis:
Quaternions can be created by specifying:
- An angle and an axis (
GFX.Quaternion.AxisAngle
,GFX.Quaternion.setAxisAngle
,GFX.Quaternion.Rotation
,GFX.Quaternion.setRotation
) - Euler angles (
GFX.Quaternion.Euler
,GFX.Quaternion.setEuler
) - a relative transformation from one vector to another (
GFX.Quaternion.Relative,
GFX.Quaternion.setRelative`) - a relative transformation from one quaternion to another (
GFX.Quaternion.Slerp
,GFX.Quaternion.setSlerp
) - a z direction at and an [optional] y target direction vector (
GFX.Quaternion.setForwardUp
,GFX.Quaternion.setForwardUp
)
A Quaternion is used to represent the .orientation
of a GFX.Frame.
It’s w,x,y,z
elements should not be set directly, but rather with methods like .setAxisAngle
and .setEuler
.
The following code interpolates an orientation in 3D:
Methods
.setAxisAngle(v,t)
: Returns a rotationt
radians around axis GFX.Vectorv
.setRotation(t,x,y,z)
: Returns a rotation int
radians around axisx,y,z
:.setEuler(yaw,pitch,roll)
: Returns a rotation in Euler angles..setRelative(va,vb,t)
: Returns a rotation that takes vectorva
tovb
, witht
an amount from (0-1)..apply(v)
: Returns a transformed position of GFX.Vectorv
..mult(q)
: Returns a new Quaternion encoding a transformation byq
, followed by a transformation by this..matrix()
: Returns a 4x4 GFX.Matrix encoding of the Quaternion. Used internally to calculate model matrices..scalarMult(s)
: Returns a new Quaternion multiplied by a scalar values
. Used internally to normalize quaternions..add(q)
: Returns a new Quaternion by summing the values of this andq
. Used internallly in shorthand versions of.Slerp()
;
Static Methods
GFX.Quaternion.Slerp(qa,qb,t)
: A rotation ofqa
toqb
, witht
an amount from (0-1).GFX.Quaternion.AxisAngle(v,t)
: A rotation oft
radians around axis GFX.Vectorv
.GFX.Quaternion.Rotation(t,x,y,z)
: A rotationt
radians around axisx,y,z
.GFX.Quaternion.Euler(yaw,pitch,roll)
: A rotation in Euler angles.
Note on Euler angles: Here, we consider “y” to be up/down and “z” to be forward/back (in some physics references this is the opposite).
-yaw
: y axis rotation (“heading”)
-pitch
: x axis rotation (“attitude”)
-roll
: z axis rotation (“bank”)
GFX.Shader
Creates, Loads, compiles, attaches, links and binds vertex and fragment shader programs.
var shader = new GFX.Shader();
shader.program(vertCode,fragCode);
Methods
.program(vert,frag)
: Create a program from shader source code..create()
: Creates a new program and new vertex and fragment shaders..load(vert,frag)
: Loads source text into vertex and fragment shaders..compile()
: Compiles vertex and fragment shaders with and checks for errors..checkCompilation()
: Checks for error when compiling..link()
: Attach vertex and fragment shaders to program, links program, and check for linking errors..checkLinking()
: Checks for error when linking..setUniformMatrix(uname, m)
: Set uniform 4x4 matrixuname
to float arraym
..setUniformFloat(uname, f)
: Set uniform floatuname
to scalar valuef
..getAttribute(aname)
: Get location id of attribute namedaname
..enableAttribute(aname)
: Enable attribute namedaname
..pointAttribute(aname, n)
: Pointn
-dimensional attributeaname
to currently bound buffer..printActiveAttributes()
: Print out all active attributes to the javascript console.
GFX.Buffer
Creates, allocates, and loads mesh data (vertex coordinates, indices, uv coordinates, colors) onto the GPU.
Typically accessed via GFX.Mesh which has a bunch of Buffers.
Constructor
Creates and binds a new buffer
var buffer = new GFX.Buffer(type)
with type
either GL.ARRAY_BUFFER
(default) or GL.ELEMENT_ARRAY_BUFFER
or unspecified (in which case default is used).
Methods
.create()
: Create a new buffer..bind()
: Bind the buffer..alloc(size,hint)
: Allocate memory withsize
in bytes andhint
.
-hint
is either GL.STATIC_DRAW, GL.STREAM_DRAW or GL.DYNAMIC_DRAW..data(d,offset)
: Sends datad
to buffer’soffset
position (default is 0)..load(data, hint)
: binds, allocates, and sendsdata
over to buffer..drawElements(mode,num)
: Draws coordinate data in currently bound array buffer by using indices in currently bound element array buffer.mode
is either GL.LINES, GL.TRIANGLES, etc.num
is an optional parameter specifying the number of elements in the index buffer (if unspecified, uses num set during data loading).drawArrays(mode,num)
: Draws coordinate data in currently bound array buffer.mode
is either GL.LINES, GL.TRIANGLES, etc.num
is an optional parameter specifying the number of elements in the array buffer (if unspecified, uses the number set during data loading)
Members
.num
: Length of buffer (set duringdata()
load).type
:GL.ARRAY_BUFFER
orGL.ELEMENT_ARRAY_BUFFER