In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article focuses on "how to run WebGL programs on HTML5 browsers". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to run WebGL programs on HTML5 browsers.
Preconditions and expected results
At present, only a few browsers support WebGL, please see my other article: Can I use WebGL?.
The following example is tested on Chrome 16 under Windows and Firefox 17 under Android. If you are using an incompatible browser, a warning will pop up.
Figure 1: animated WebGL cube containing Hello world text
On HTML5-compatible browsers, you will see the drawing cube shown in the following figure:
Figure 2: screenshot of the sample run
This code is based on Lighting in WebGL-How to simulate lighting effects in your WebGL context-Thank you very much for this tutorial. When the instance is initially run, the cube of the animation is rendered through a static Bitmap graphics object.
The following code demonstrates how to render text dynamically in a program:
XML/HTML Code copies content to the clipboard
/ / TODO # 1 New method to create a texture
Function createCubeTexture (text) {
...
}
The use of gl.pixelStorei (gl.UNPACK_FLIP_Y_WEBGL, true) here is very important to ensure that the text is not written backwards. The rest is easy to understand:
XML/HTML Code copies content to the clipboard
/ / TODO # 2 Assign the created texture for display
CubeTexture = createCubeTexture ("Hello World!")
Source code
/ / File # 1: webgl-demo.htm
XML/HTML Code copies content to the clipboard
WebGL-Hello World!
Varying highp vec2 vTextureCoord
Varying highp vec3 vLighting
Uniform sampler2D uSampler
Void main (void) {
Highp vec4 texelColor = texture2D (uSampler, vec2 (vTextureCoord.s, vTextureCoord.t))
Gl_FragColor = vec4 (texelColor.rgb * vLighting, texelColor.a)
}
Attribute highp vec3 aVertexNormal
Attribute highp vec3 aVertexPosition
Attribute highp vec2 aTextureCoord
Uniform highp mat4 uNormalMatrix
Uniform highp mat4 uMVMatrix
Uniform highp mat4 uPMatrix
Varying highp vec2 vTextureCoord
Varying highp vec3 vLighting
Void main (void) {
Gl_Position = uPMatrix * uMVMatrix * vec4 (aVertexPosition, 1.0)
VTextureCoord = aTextureCoord
/ / Apply lighting effect
Highp vec3 ambientLight = vec3 (0.6,0.6,0.6)
Highp vec3 directionalLightColor = vec3 (0.5,0.5,0.75)
Highp vec3 directionalVector = vec3 (0.85,0.8,0.75)
Highp vec4 transformedNormal = uNormalMatrix * vec4 (aVertexNormal, 1.0)
Highp float directional = max (dot (transformedNormal.xyz, directionalVector), 0.0)
VLighting = ambientLight + (directionalLightColor * directional)
}
Your browser doesn't appear to support the HTML5 element.
/ / File # 02: webgl-demo.js
XML/HTML Code copies content to the clipboard
Var canvas
Var gl
Var cubeVerticesBuffer
Var cubeVerticesTextureCoordBuffer
Var cubeVerticesIndexBuffer
Var cubeVerticesIndexBuffer
Var cubeRotation = 0.0
Var lastCubeUpdateTime = 0
Var cubeImage
Var cubeTexture
Var mvMatrix
Var shaderProgram
Var vertexPositionAttribute
Var vertexNormalAttribute
Var textureCoordAttribute
Var perspectiveMatrix
/ /
/ / start
/ /
/ / Called when the canvas is created to get the ball rolling.
/ /
Function start () {
Canvas = document.getElementById ("glcanvas")
InitWebGL (canvas); / / Initialize the GL context
/ / Only continue if WebGL is available and working
If (gl) {
Gl.clearColor (0.0,0.0,0.0,1.0); / / Clear to black, fully opaque
Gl.clearDepth (1.0); / / Clear everything
Gl.enable (gl.DEPTH_TEST); / / Enable depth testing
Gl.depthFunc (gl.LEQUAL); / / Near things obscure far things
/ / Initialize the shaders; this is where all the lighting for the
/ / vertices and so forth is established.
InitShaders ()
/ / Here's where we call the routine that builds all the objects
/ / we'll be drawing.
InitBuffers ()
/ / Next, load and set up the textures we'll be using.
/ / TODO#2 Start
CubeTexture = createCubeTexture ("Hello World!")
/ / TODO#2 End
/ / Set up to draw the scene periodically.
SetInterval (drawScene, 15)
}
}
/ /
/ / initWebGL
/ /
/ / Initialize WebGL, returning the GL context or null if
/ / WebGL isn't available or could not be initialized.
/ /
Function initWebGL () {
Gl = null
Try {
Gl = canvas.getContext ("experimental-webgl")
}
Catch (e) {
}
/ / If we don't have a GL context, give up now
If (! gl) {
Alert ("Unable to initialize WebGL. Your browser may not support it.")
}
}
/ /
/ / initBuffers
/ /
/ / Initialize the buffers we'll need. For this demo, we just have
/ / one object-a simple two-dimensional cube.
/ /
Function initBuffers () {
/ / Create a buffer for the cube's vertices.
CubeVerticesBuffer = gl.createBuffer ()
/ / Select the cubeVerticesBuffer as the one to apply vertex
/ / operations to from here out.
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesBuffer)
/ / Now create an array of vertices for the cube.
Var vertices = [
/ / Front face
-1.0.-1.0, 1.0.
1.0.-1.0, 1.0.
1.0, 1.0, 1.0
-1.0, 1.0, 1.0
/ / Back face
-1.0.-1.0.-1.0.
-1.0, 1.0.-1.0.
1.0, 1.0.-1.0.
1.0.-1.0.
/ / Top face
-1.0, 1.0.-1.0.
-1.0, 1.0, 1.0
1.0, 1.0, 1.0
1.0, 1.0.-1.0.
/ / Bottom face
-1.0.-1.0.-1.0.
1.0.-1.0.
1.0.-1.0, 1.0.
-1.0.-1.0, 1.0.
/ / Right face
1.0.-1.0.
1.0, 1.0.-1.0.
1.0, 1.0, 1.0
1.0.-1.0, 1.0.
/ / Left face
-1.0.-1.0.-1.0.
-1.0.-1.0, 1.0.
-1.0, 1.0, 1.0
-1.0, 1.0.-1.0.
]
/ / Now pass the list of vertices into WebGL to build the shape. We
/ / do this by creating a Float32Array from the JavaScript array
/ / then use it to fill the current vertex buffer.
Gl.bufferData (gl.ARRAY_BUFFER, new Float32Array (vertices), gl.STATIC_DRAW)
/ / Set up the normals for the vertices, so that we can compute lighting.
CubeVerticesNormalBuffer = gl.createBuffer ()
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesNormalBuffer)
Var vertexNormals = [
/ / Front
0.0, 0.0, 1.0
0.0, 0.0, 1.0
0.0, 0.0, 1.0
0.0, 0.0, 1.0
/ / Back
0.0, 0.0,-1.0
0.0, 0.0,-1.0
0.0, 0.0,-1.0
0.0, 0.0,-1.0
/ / Top
0.0, 1.0, 0.0
0.0, 1.0, 0.0
0.0, 1.0, 0.0
0.0, 1.0, 0.0
/ / Bottom
0.0.-1.0, 0.0.
0.0.-1.0, 0.0.
0.0.-1.0, 0.0.
0.0.-1.0, 0.0.
/ / Right
1.0, 0.0, 0.0
1.0, 0.0, 0.0
1.0, 0.0, 0.0
1.0, 0.0, 0.0
/ / Left
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
]
Gl.bufferData (gl.ARRAY_BUFFER, new Float32Array (vertexNormals))
Gl.STATIC_DRAW)
/ / Map the texture onto the cube's faces.
CubeVerticesTextureCoordBuffer = gl.createBuffer ()
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer)
Var textureCoordinates = [
/ / Front
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
/ / Back
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
/ / Top
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
/ / Bottom
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
/ / Right
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
/ / Left
0.0, 0.0
1.0, 0.0
1.0, 1.0
0.0, 1.0
]
Gl.bufferData (gl.ARRAY_BUFFER, new Float32Array (textureCoordinates))
Gl.STATIC_DRAW)
/ / Build the element array buffer; this specifies the indices
/ / into the vertex array for each face's vertices.
CubeVerticesIndexBuffer = gl.createBuffer ()
Gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer)
/ / This array defines each face as two triangles, using the
/ / indices into the vertex array to specify each triangle's
/ / position.
Var cubeVertexIndices = [
0, 1, 2, 0, 2, 3, / / front
4, 5, 6, 4, 6, 7, / / back
8, 9, 10, 8, 10, 11, / / top
12, 13, 14, 12, 14, 15, / / bottom
16, 17, 18, 16, 18, 19, / / right
20, 21, 22, 20, 22, 23 / / left
]
/ / Now send the element array to GL
Gl.bufferData (gl.ELEMENT_ARRAY_BUFFER
New Uint16Array (cubeVertexIndices), gl.STATIC_DRAW)
}
/ /
/ / initTextures
/ /
/ / Initialize the textures we'll be using, then initiate a load of
/ / the texture images. The handleTextureLoaded () callback will finish
/ / the job; it gets called each time a texture finishes loading.
/ /
/ / TODO#1 Start
Function createCubeTexture (text) {
/ / create a hidden canvas to draw the texture
Var canvas = document.createElement ('canvas')
Canvas.id = "hiddenCanvas"
Canvas.width = 512
Canvas.height = 512
Canvas.style.display = "none"
Var body = document.getElementsByTagName ("body") [0]
Body.appendChild (canvas)
/ / draw texture
Var cubeImage = document.getElementById ('hiddenCanvas')
Var ctx = cubeImage.getContext ('2d')
Ctx.beginPath ()
Ctx.rect (0,0, ctx.canvas.width, ctx.canvas.height)
Ctx.fillStyle = 'white'
Ctx.fill ()
Ctx.fillStyle = 'black'
Ctx.font = "65px Arial"
Ctx.textAlign = 'center'
Ctx.fillText (text, ctx.canvas.width / 2, ctx.canvas.height / 2)
Ctx.restore ()
/ / create new texture
Var texture = gl.createTexture ()
Gl.bindTexture (gl.TEXTURE_2D, texture)
Gl.texParameteri (gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
Gl.texParameteri (gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST)
Gl.pixelStorei (gl.UNPACK_FLIP_Y_WEBGL, true)
HandleTextureLoaded (cubeImage, texture)
Return texture
}
/ / TODO#1 End
Function handleTextureLoaded (image, texture) {
Gl.bindTexture (gl.TEXTURE_2D, texture)
Gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)
Gl.texParameteri (gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
Gl.texParameteri (gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST)
Gl.generateMipmap (gl.TEXTURE_2D)
Gl.bindTexture (gl.TEXTURE_2D, null)
}
/ /
/ / drawScene
/ /
/ / Draw the scene.
/ /
Function drawScene () {
/ / Clear the canvas before we start drawing on it.
Gl.clear (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
/ / Establish the perspective with which we want to view the
/ / scene. Our field of view is 45 degrees, with a width/height
/ / ratio of 640:480, and we only want to see objects between 0.1 units
/ / and 100 units away from the camera.
PerspectiveMatrix = makePerspective (45640.0max 480.0,0.1, 100.0)
/ / Set the drawing position to the "identity" point, which is
/ / the center of the scene.
LoadIdentity ()
/ / Now move the drawing position a bit to where we want to start
/ / drawing the cube.
MvTranslate ([0.0,0.0,-6.0])
/ / Save the current matrix, then rotate before we draw.
MvPushMatrix ()
MvRotate (cubeRotation, [1,0,1])
/ / Draw the cube by binding the array buffer to the cube's vertices
/ / array, setting attributes, and pushing it to GL.
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesBuffer)
Gl.vertexAttribPointer (vertexPositionAttribute, 3, gl.FLOAT, false, 0,0)
/ / Set the texture coordinates attribute for the vertices.
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer)
Gl.vertexAttribPointer (textureCoordAttribute, 2, gl.FLOAT, false, 0,0)
/ / Bind the normals buffer to the shader attribute.
Gl.bindBuffer (gl.ARRAY_BUFFER, cubeVerticesNormalBuffer)
Gl.vertexAttribPointer (vertexNormalAttribute, 3, gl.FLOAT, false, 0,0)
/ / Specify the texture to map onto the faces.
Gl.activeTexture (gl.TEXTURE0)
Gl.bindTexture (gl.TEXTURE_2D, cubeTexture)
Gl.uniform1i (gl.getUniformLocation (shaderProgram, "uSampler"), 0)
/ / Draw the cube.
Gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer)
SetMatrixUniforms ()
Gl.drawElements (gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0)
/ / Restore the original matrix
MvPopMatrix ()
/ / Update the rotation for the next draw, if it's time to do so.
Var currentTime = new Date) .getTime ()
If (lastCubeUpdateTime) {
Var delta = currentTime-lastCubeUpdateTime
CubeRotation + = (30 * delta) / 1000.0
}
LastCubeUpdateTime = currentTime
}
/ /
/ / initShaders
/ /
/ / Initialize the shaders, so WebGL knows how to light our scene.
/ /
Function initShaders () {
Var fragmentShader = getShader (gl, "shader-fs")
Var vertexShader = getShader (gl, "shader-vs")
/ / Create the shader program
ShaderProgram = gl.createProgram ()
Gl.attachShader (shaderProgram, vertexShader)
Gl.attachShader (shaderProgram, fragmentShader)
Gl.linkProgram (shaderProgram)
/ / If creating the shader program failed, alert
If (! gl.getProgramParameter (shaderProgram, gl.LINK_STATUS)) {
Alert ("Unable to initialize the shader program.")
}
Gl.useProgram (shaderProgram)
VertexPositionAttribute = gl.getAttribLocation (shaderProgram, "aVertexPosition")
Gl.enableVertexAttribArray (vertexPositionAttribute)
TextureCoordAttribute = gl.getAttribLocation (shaderProgram, "aTextureCoord")
Gl.enableVertexAttribArray (textureCoordAttribute)
VertexNormalAttribute = gl.getAttribLocation (shaderProgram, "aVertexNormal")
Gl.enableVertexAttribArray (vertexNormalAttribute)
}
/ /
/ / getShader
/ /
/ / Loads a shader program by scouring the current document
/ / looking for a script with the specified ID.
/ /
Function getShader (gl, id) {
Var shaderScript = document.getElementById (id)
/ / Didn't find an element with the specified ID; abort.
If (! shaderScript) {
Return null
}
/ / Walk through the source element's children, building the
/ / shader source string.
Var theSource = ""
Var currentChild = shaderScript.firstChild
While (currentChild) {
If (currentChild.nodeType = = 3) {
TheSource + = currentChild.textContent
}
CurrentChildcurrentChild = currentChild.nextSibling
}
/ / Now figure out what type of shader script we have
/ / based on its MIME type.
Var shader
If (shaderScript.type = = "x-shader/x-fragment") {
Shader = gl.createShader (gl.FRAGMENT_SHADER)
} else if (shaderScript.type = = "x-shader/x-vertex") {
Shader = gl.createShader (gl.VERTEX_SHADER)
} else {
Return null; / / Unknown shader type
}
/ / Send the source to the shader object
Gl.shaderSource (shader, theSource)
/ / Compile the shader program
Gl.compileShader (shader)
/ / See if it compiled successfully
If (! gl.getShaderParameter (shader, gl.COMPILE_STATUS)) {
Alert ("An error occurred compiling the shaders:" + gl.getShaderInfoLog (shader))
Return null
}
Return shader
}
/ /
/ / Matrix utility functions
/ /
Function loadIdentity () {
MvMatrix = Matrix.I (4)
}
Function multMatrix (m) {
MvMatrixmvMatrix = mvMatrix.x (m)
}
Function mvTranslate (v) {
MultMatrix ($V ([v [0], v [1], v [2]]) .ensure4x4 ())
}
Function setMatrixUniforms () {
Var pUniform = gl.getUniformLocation (shaderProgram, "uPMatrix")
Gl.uniformMatrix4fv (pUniform, false, new Float32Array (perspectiveMatrix.flatten ()
Var mvUniform = gl.getUniformLocation (shaderProgram, "uMVMatrix")
Gl.uniformMatrix4fv (mvUniform, false, new Float32Array (mvMatrix.flatten ()
Var normalMatrix = mvMatrix.inverse ()
NormalMatrixnormalMatrix = normalMatrix.transpose ()
Var nUniform = gl.getUniformLocation (shaderProgram, "uNormalMatrix")
Gl.uniformMatrix4fv (nUniform, false, new Float32Array (normalMatrix.flatten ()
}
Var mvMatrixStack = []
Function mvPushMatrix (m) {
If (m) {
MvMatrixStack.push (m.dup ())
MmvMatrix = m.dup ()
} else {
MvMatrixStack.push (mvMatrix.dup ())
}
}
Function mvPopMatrix () {
If (! mvMatrixStack.length) {
Throw ("Can't pop from an empty matrix stack.")
}
MvMatrix = mvMatrixStack.pop ()
Return mvMatrix
}
Function mvRotate (angle, v) {
Var inRadians = angle * Math.PI / 180.0
Var m = Matrix.Rotation (inRadians, $V ([v [0], v [1], v [2]]). Ensure4x4 ()
MultMatrix (m)
}
At this point, I believe you have a deeper understanding of "how to run WebGL programs on HTML5 browsers". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 210
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.