This JavaScript program demonstrates the default viewing orientation for a WebGL program. The default orientation is looking down the z-axis with the z-axis coming out of the view plane, the y-axis pointing straight up, and the x-axis pointing to the right. To make the orientation more clear, we circle the view around the z-axis to make the z-axis visible. Alternatively, the z-axis would just be visible as a point.
<!DOCTYPE html> <html> <head> <title>XoaX.net's WebGL</title> <script id="idVertexShader" type="c"> attribute vec4 av4Vertex; attribute vec4 av4Color; varying vec4 vv4Color; void main() { gl_Position = av4Vertex; vv4Color = av4Color; } </script> <script id="idFragmantShader" type="c"> precision mediump float; varying vec4 vv4Color; void main() { gl_FragColor = vv4Color; } </script> <script type="text/javascript"> var gqWebGL = null; function CreateProgramAndContext(qInstanceWebGL) { // Get the WebGL Context var qCanvas = document.querySelector("#"+qInstanceWebGL.msCanvasID); qInstanceWebGL.mqGL = qCanvas.getContext("webgl"); var qGL = qInstanceWebGL.mqGL; // Compile the vertex shader var sVertexShaderCode = document.querySelector("#"+qInstanceWebGL.msVertexShaderID).text; var qVertexShader = qGL.createShader(qGL.VERTEX_SHADER); qGL.shaderSource(qVertexShader, sVertexShaderCode); qGL.compileShader(qVertexShader); // Compile the fragment shader var sFragmentShaderCode = document.querySelector("#"+qInstanceWebGL.msFragmentShaderID).text; var qFragmentShader = qGL.createShader(qGL.FRAGMENT_SHADER); qGL.shaderSource(qFragmentShader, sFragmentShaderCode); qGL.compileShader(qFragmentShader); // Compile and link the program qInstanceWebGL.mqProgram = qGL.createProgram(); qGL.attachShader(qInstanceWebGL.mqProgram, qVertexShader); qGL.attachShader(qInstanceWebGL.mqProgram, qFragmentShader); qGL.linkProgram(qInstanceWebGL.mqProgram); qGL.useProgram(qInstanceWebGL.mqProgram); } function CreateBuffers(qInstanceWebGL) { var qGL = qInstanceWebGL.mqGL; var qVerticesBuffer = qGL.createBuffer(); qGL.bindBuffer(qGL.ARRAY_BUFFER, qVerticesBuffer); qGL.bufferData(qGL.ARRAY_BUFFER, qInstanceWebGL.mfaTransformedVertices, qGL.STATIC_DRAW); var qVertexLoc = qGL.getAttribLocation(qInstanceWebGL.mqProgram, 'av4Vertex'); qGL.vertexAttribPointer(qVertexLoc, 4, qGL.FLOAT, false, 0, 0); qGL.enableVertexAttribArray(qVertexLoc); var qColorsBuffer = qGL.createBuffer(); qGL.bindBuffer(qGL.ARRAY_BUFFER, qColorsBuffer); qGL.bufferData(qGL.ARRAY_BUFFER, qInstanceWebGL.mfaVertexColors, qGL.STATIC_DRAW); var qColors = qGL.getAttribLocation(qInstanceWebGL.mqProgram, 'av4Color'); qGL.vertexAttribPointer(qColors, 4, qGL.FLOAT, false, 0, 0); qGL.enableVertexAttribArray(qColors); } var gfaVertices = null; function Initialization() { var dCS = .25; // The cube side size gfaVertices = new Float32Array([ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, // x-axis 1.0, 0.0, 0.0, 1.0, 0.95, 0.02, -0.02, 1.0, // x-axis arrowhead 1.0, 0.0, 0.0, 1.0, 0.95, -0.02, 0.02, 1.0, // x-axis arrowhead 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, // y-axis 0.0, 1.0, 0.0, 1.0, 0.02, 0.95, -0.02, 1.0, // y-axis arrowhead 0.0, 1.0, 0.0, 1.0, -0.02, 0.95, 0.02, 1.0, // y-axis arrowhead 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, // z-axis 0.0, 0.0, 1.0, 1.0, 0.02, -0.02, 0.95, 1.0, // z-axis arrowhead 0.0, 0.0, 1.0, 1.0, -0.02, 0.02, 0.95, 1.0, // z-axis arrowhead // The cube around the origin. // These sides must be drawn back to front to render it correctly with the alpha blending -dCS, dCS, dCS, 1.0, -dCS, dCS, -dCS, 1.0, -dCS, -dCS, dCS, 1.0, -dCS, -dCS, -dCS, 1.0, // x = -dCS dCS, -dCS, dCS, 1.0, dCS, -dCS, -dCS, 1.0, -dCS, -dCS, dCS, 1.0, -dCS, -dCS, -dCS, 1.0, // y = -dCS dCS, dCS, -dCS, 1.0, dCS, -dCS, -dCS, 1.0, -dCS, dCS, -dCS, 1.0, -dCS, -dCS, -dCS, 1.0, // z = -dCS dCS, dCS, dCS, 1.0, dCS, -dCS, dCS, 1.0, dCS, dCS, -dCS, 1.0, dCS, -dCS, -dCS, 1.0, // x = dCS dCS, dCS, dCS, 1.0, dCS, dCS, -dCS, 1.0, -dCS, dCS, dCS, 1.0, -dCS, dCS, -dCS, 1.0, // y = dCS dCS, dCS, dCS, 1.0, -dCS, dCS, dCS, 1.0, dCS, -dCS, dCS, 1.0, -dCS, -dCS, dCS, 1.0 // z = dCS ]); gqWebGL = new CInstanceWebGL("idCanvas", "idVertexShader", "idFragmantShader", 42); CreateProgramAndContext(gqWebGL); CreateBuffers(gqWebGL); // Begin the animation loop. This should use requestAnimationFrame instead const kiIntervalId = setInterval(Render, 20); } function Render() { RenderModel(gqWebGL); } var gfAngle = 0.0; function RenderModel(qInstanceWebGL) { // The view source will rotate around the z-axis var dViewX = Math.sin(gfAngle); var dViewY = Math.cos(gfAngle); var faLookAtMatrix = CreateLookAtMatrix([.3*dViewX, .3*dViewY, .75],[0.0, 0.0, 0.0],[0, 1, 0]); var faVert = qInstanceWebGL.mfaTransformedVertices; var faClr = qInstanceWebGL.mfaVertexColors; gfAngle = ((gfAngle + .02 >= 2.0*Math.PI) ? (gfAngle + .02 - 2.0*Math.PI) : gfAngle + .02); // First copy the vertices before the transformation for (var i = 0; i < (18+24)*4; ++i) { faVert[i] = gfaVertices[i]; } // Transform the axes and color them for (var i = 0; i < 18; ++i) { MultiplyMatrixVertex(faLookAtMatrix, faVert, 4*i); // Set the colors too faClr[4*i] = 0.25; faClr[4*i + 1] = 0.25; faClr[4*i + 2] = 0.25; faClr[4*i + 3] = 1.0; // Make the x-axis red, the y-axis green, and the z-axis blue faClr[4*i + Math.floor(i/6)] = 1.0; } // Color the cube faces for (var iFace = 0; iFace < 6; ++iFace) { var fBrightness = 0.0; if (iFace % 3 == 0) { fBrightness = 1.0/7.0; } else if (iFace % 3 == 2) { fBrightness = 2.0/7.0; } else { fBrightness = 4.0/7.0; } var iBase = 18*4 + 16*iFace; for (var iVertex = 0; iVertex < 4; ++iVertex) { var iOffset = iBase + 4*iVertex; faVert[iOffset] = gfaVertices[iOffset]; faVert[iOffset + 1] = gfaVertices[iOffset + 1]; faVert[iOffset + 2] = gfaVertices[iOffset + 2]; faVert[iOffset + 3] = gfaVertices[iOffset + 3]; faClr[iOffset] = fBrightness; faClr[iOffset + 1] = fBrightness; faClr[iOffset + 2] = fBrightness; faClr[iOffset + 3] = .2; } } // Transform the cube for (var i = 18; i < 42; ++i) { MultiplyMatrixVertex(faLookAtMatrix, faVert, 4*i); } // We need to create the buffers afterward CreateBuffers(qInstanceWebGL); var qGL = qInstanceWebGL.mqGL; qGL.clearColor(0.0, 0.0, 0.0, 1.0); qGL.enable(qGL.DEPTH_TEST); qGL.clear(qGL.COLOR_BUFFER_BIT | qGL.DEPTH_BUFFER_BIT); // Enable alpha blending qGL.enable(qGL.BLEND); // Set blending function qGL.blendFunc(qGL.SRC_ALPHA, qGL.ONE_MINUS_SRC_ALPHA); for (var i = 0; i < 9; ++i) { qGL.drawArrays(qGL.LINES, i*2, 2); } // The six sides of the cube daXOrder = (dViewX > 0.0) ? [18, 30] : [30, 18]; daYOrder = (dViewY > 0.0) ? [22, 34] : [34, 22]; qGL.drawArrays(qGL.TRIANGLE_STRIP, daXOrder[0], 4); qGL.drawArrays(qGL.TRIANGLE_STRIP, daYOrder[0], 4); qGL.drawArrays(qGL.TRIANGLE_STRIP, 26, 4); qGL.drawArrays(qGL.TRIANGLE_STRIP, daXOrder[1], 4); qGL.drawArrays(qGL.TRIANGLE_STRIP, daYOrder[1], 4); qGL.drawArrays(qGL.TRIANGLE_STRIP, 38, 4); } // Multiply the four coordinate vertex in V at the start index function MultiplyMatrixVertex(faM, faV, iStart) { // V = M*V var faCopy = [0,0,0,0]; for (var i = 0; i < 4; ++i) { faCopy[i] = faV[iStart + i]; } for (iRow = 0; iRow < 4; ++iRow) { faV[iStart + iRow] = faM[iRow]*faCopy[0] + faM[iRow + 4]*faCopy[1] + faM[iRow + 8]*faCopy[2] + faM[iRow + 12]*faCopy[3]; } } function Normalize(faV) { var fL = Math.sqrt(faV[0]*faV[0] + faV[1]*faV[1] + faV[2]*faV[2]); faV[0] /= fL; faV[1] /= fL; faV[2] /= fL; } function Dot(faV1, faV2) { return (faV1[0]*faV2[0] + faV1[1]*faV2[1] + faV1[2]*faV2[2]); } function Cross(faV1, faV2) { return [faV1[1]*faV2[2]-faV1[2]*faV2[1], faV1[2]*faV2[0]-faV1[0]*faV2[2], faV1[0]*faV2[1]-faV1[1]*faV2[0]]; } function Difference(faV1, faV2) { return [faV1[0]-faV2[0], faV1[1]-faV2[1], faV1[2]-faV2[2]]; } function CreateLookAtMatrix(faEye, faObject, faUp) { var faViewDirection = Difference(faObject, faEye); Normalize(faViewDirection); var faRight = Cross(faViewDirection, faUp); Normalize(faRight); var faStraightUp = Cross(faRight, faViewDirection); var faMatrix = new Float32Array([ faRight[0], faStraightUp[0], faViewDirection[0], 0.0, faRight[1], faStraightUp[1], faViewDirection[1], 0.0, faRight[2], faStraightUp[2], faViewDirection[2], 0.0, -Dot(faObject, faRight), -Dot(faObject, faStraightUp), -Dot(faObject, faViewDirection), 1.0]); return faMatrix; } function CInstanceWebGL(sCanvasID, sVertexShaderID, sFragmentShaderID, iVertices) { this.mqGL = null; this.mqProgram = null; this.msCanvasID = sCanvasID; this.msVertexShaderID = sVertexShaderID; this.msFragmentShaderID = sFragmentShaderID; this.mfaTransformedVertices = new Float32Array(4*iVertices); this.mfaVertexColors = new Float32Array(4*iVertices); } </script> </head> <body onload="Initialization();"> <canvas id="idCanvas" width="400", height="400" style="border:1px solid lightgray"></canvas> </body> </html>
© 20072024 XoaX.net LLC. All rights reserved.