Step on the pit:
1. The picture is not displayed: the picture resolution is not a power of 2, and the picture cannot be rendered.
The graph becomes the Nth power of black square 2: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096
... 2. Geometry configuration mapping method, vertex coordinates and texture coordinates need to pay attention, the construction order is related to the parity of the newly added vertices.
If the number of new vertices is odd, the order of the vertices is: T = [n-1 n-2 n];
if the number of new vertices is even, the order of the vertices is: T = [n-2 n-1 n];
Picture material:
Link: https://pan.baidu.com/s/1CQ2fZ36Ke8QfGFDytFkyQw
Extraction code: 3dh4
key code:
function initTexture(ctx) {
let texture = ctx.createTexture()
let u_sampler = ctx.getUniformLocation(ctx.program, "u_sampler")
let image = new Image()
image.crossOrigin = "anonymous"
image.src = "http://localhost:8080/upload/dog.webp"
//Asynchronous loading, execute the tasks in this function after the picture is loaded
image.onload = () => {
//Reverse the y-axis of the texture image, whether to flip
ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, true);
//By default, 8 pictures can be posted, starting from index 0, activate the first one here
ctx.activeTexture(ctx.TEXTURE0)
// Bind textures in TEXTURE_2D mode
ctx.bindTexture(ctx.TEXTURE_2D, texture)
//Set the parameters of the texture texParameteri (the type of texture, the name of the parameter, the specific value)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR)
//Set the texture map filling method (the pixel size of the texture map is smaller than the pixel size of the vertex drawing area)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR)
console.log(image)
//The texture is textured with that kind of picture
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image)
//Paste the 0th texture to u_sampler
ctx.uniform1i(u_sampler, 0)
draw(ctx)
}
}
html
<!DOCTYPE html>
<head>
<style>
*{
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id = 'webgl'>
Your browser does not support HTML5, please change your browser
</canvas>
<script src="./main.js"></script>
</body>
main.js
let canvas = document.getElementById('webgl')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let radio = window.innerWidth / window.innerHeight;
let ctx = canvas.getContext('webgl')
//Create vertex resource and pixel resource (color)
let vertexSource = `
attribute vec2 a_position;
attribute vec2 a_uv;
varying vec2 v_uv;
void main() {
v_uv = a_uv;
gl_Position = vec4(a_position, 0.0, 1.0);
gl_PointSize = 10.0;
}
`
let fragmentSource = `
precision mediump float;
varying vec2 v_uv;
uniform sampler2D u_sampler;
void main (){
vec4 color = texture2D(u_sampler, v_uv);
gl_FragColor = color;
}
`
//gl_FragColor = vec4(v_uv, 0.0, 1.0);
if (initShader(ctx, vertexSource, fragmentSource)) {
let box = [
-0.5, -0.5,
0.5, -0.5,
0.5, 0.5,
-0.5, 0.5
]
let boxFloat32Array = new Float32Array(box)
//Create buffer
let buffer = ctx.createBuffer()
//bind buffer
ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)
//Fill the value in the buffer and specify the purpose of the data
ctx.bufferData(ctx.ARRAY_BUFFER, boxFloat32Array, ctx.STATIC_DRAW)
//Get vertexShader specified variable memory
let a_Position = ctx.getAttribLocation(ctx.program, "a_position")
//Specify every two array elements as a point
/*
* When the array elements do not need to be split, the last two digits can be specified as 0, 0
*
*
*/
ctx.vertexAttribPointer(
a_Position, //location: the location of the attributes variable in the vertex Shader
2, ctx.FLOAT, //size: the length of the attribute variable vec2 length 2 vec3 length 3
false, //normalized: Orthogonalization true or false, [1, 2] => [1/root 5, 2/root 5]
2 * boxFloat32Array.BYTES_PER_ELEMENT, //stride: BYTES occupied by the information of each point
0 //offset: the information of each point, starting from the number of BYTES
)
ctx.enableVertexAttribArray(a_Position);
let color = [
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
]
let colorFloat32Array = new Float32Array(color)
let colorBuffer = ctx.createBuffer()
ctx.bindBuffer(ctx.ARRAY_BUFFER, colorBuffer)
ctx.bufferData(ctx.ARRAY_BUFFER, colorFloat32Array, ctx.STATIC_DRAW)
let a_uv = ctx.getAttribLocation(ctx.program, "a_uv")
ctx.vertexAttribPointer(a_uv, 2, ctx.FLOAT, false, 2 * colorFloat32Array.BYTES_PER_ELEMENT, 0)
ctx.enableVertexAttribArray(a_uv)
initTexture(ctx)
}
function draw(ctx) {
ctx.clearColor(0.0, 0.0, 0.0, 1.0)
ctx.clear(ctx.COLOR_BUFFER_BIT)
ctx.drawArrays(ctx.TRIANGLE_FAN,
0,//Start from the first point
4 //Draw a few points)
)
// ctx.drawArrays(ctx.TRIANGLE_FAN,
// 0,//Start from the first few points
// 4 // draw a few points)
// )
}
function initTexture(ctx) {
let texture = ctx.createTexture()
let u_sampler = ctx.getUniformLocation(ctx.program, "u_sampler")
let image = new Image()
image.crossOrigin = "anonymous"
image.src = "http://localhost:8080/upload/dog.webp"//Resource address needs to be changed
//Asynchronous loading, execute the tasks in this function after the picture is loaded
image.onload = () => {
/ / Invert the y-axis of the texture image
ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, 1);
//By default, 8 pictures can be posted, starting from index 0, activate the first one here
ctx.activeTexture(ctx.TEXTURE0)
// Bind textures in TEXTURE_2D mode
ctx.bindTexture(ctx.TEXTURE_2D, texture)
//Set the parameters of the texture texParameteri (the type of texture, the name of the parameter, the specific value)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR)
//Set the texture map filling method (the pixel size of the texture map is smaller than the pixel size of the vertex drawing area)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR)
console.log(image)
//The texture is textured with that kind of picture
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image)
//Paste the 0th texture to u_sampler
ctx.uniform1i(u_sampler, 0)
draw(ctx)
}
}
//Create vertex shadows and pixel shadows
function createShader(ctx, type, source) {
//Create shader
let shader = ctx.createShader(type)
//bind
ctx.shaderSource(shader, source)
//compile the shader
ctx.compileShader(shader)
//Get the compilation result
let compiler = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)
if (compiler) {
return shader
} else {
let log = ctx.getShaderInfoLog(shader)
console.log("compile shaders error", log)
//Delete the abnormal shader to prevent memory leaks
ctx.deleteShader(shader)
return null
}
}
function createProgram(ctx, vertexShader, fragmentShader) {
//Create program
let program = ctx.createProgram()
if (!program) {
return null
}
//Merge point resource and pixel resource
ctx.attachShader(program, vertexShader)
ctx.attachShader(program, fragmentShader)
ctx.linkProgram(program)
//Get the linked result
let linked = ctx.getProgramParameter(program, ctx.LINK_STATUS)
if (linked) {
return program
} else {
//Get link error message
let log = ctx.getProgramInfoLog(program)
console.log("link program error", log)
//delete to prevent memory leak
ctx.delete(program)
ctx.deleteShader(vertexShader)
ctx.deleteShader(fragmentShader)
return null
}
}
function initShader(ctx, vertexSource, fragmentSource) {
let vertexShader = createShader(ctx, ctx.VERTEX_SHADER, vertexSource)
let fragmentShader = createShader(ctx, ctx.FRAGMENT_SHADER, fragmentSource)
let program = createProgram(ctx, vertexShader, fragmentShader)
if (program) {
ctx.useProgram(program)
//Mount to ctx
ctx.program = program
return true
} else {
return false
}
}
renderings