Image
object, which is an img
tag in the HTML document.src
field of the image object to the file name that you want.
This starts loading the image, but does not finish before continuing. This
is why we need a callback function.
var cornellImage = new Image(); cornellImage.onload = function() { runWebGL(cornellImage); }; cornellImage.src = "cornell-logo.jpg";
runWebGL
function takes the image instance and proceeds to run WebGL
with it (creating the WebGL 1 context, starting the rendering loop, etc.). It is important
that the image is loaded before we proceed with WebGL; otherwise, we cannot transfer it to
the GPU.// Step 1: Create the texture object. var cornellTexture = gl.createTexture(); // Step 2: Bind the texture object to the "target" TEXTURE_2D gl.bindTexture(gl.TEXTURE_2D, cornellTexture); // Step 3: (Optional) Tell WebGL that pixels are flipped vertically, // so that we don't have to deal with flipping the y-coordinate. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // Step 4: Send the image data to the GPU. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, cornellImage); // Step 5: Clean up. Tell WebGL that we are done with the target. gl.bindTexture(gl.TEXTURE_2D, null);
TEXTURE_2D
target tells us that we are dealing with the 2D texture system,
that is, we are reading from an image where each pixel is indexed with two coordinates.
There are other targets such as TEXTURE_CUBE_MAP
, and WebGL 2 has
TEXTURE_3D
.
texImage2D
sends the image data to the GPU.
void gl.texImage2D(target, level, internalformat, format, type, HTMLImageElement? pixels);
pixels
can just be the Image
object. This already knows the size of the image, so these arguments are omitted.sampler2D
in your fragment shader.
uniform sampler2D texture;
texture2D(<sampler2D>, <texCoord>)
function.
<texCoord>
parameter must be a vec2
.vec4
, so it has the 4 RGBA channels.precision highp float; varying vec2 geom_texCoord; uniform sampler2D texture; void main() { gl_FragColor = texture2D(texture, geom_texCoord); }
geom_texCoord
)
comes from the vertex shader:
attribute vec3 vert_position; attribute vec2 vert_texCoord; varying vec2 geom_texCoord; void main() { gl_Position = vec4(vert_position, 1.0); geom_texCoord = vert_texCoord; }
if (gl.getUniformLocation(program, "texture") != null) { // Step 1: Activate a "texture unit" of your choosing. gl.activeTexture(gl.TEXTURE0); // Step 2: Bind the texture you want to use. gl.bindTexture(gl.TEXTURE_2D, cornellTexture); // Step 3: Set the uniform to the "index" of the texture unit you just activated. var textureLocation = gl.getUniformLocation(program, "texture"); gl.uniform1i(textureLocation, 0); }