WebGL(OpenGL ES2.0)
绘制红色的三角形
import { Button, Container } from "@mui/material";
import { useRef } from "react";
let vs_src = `
attribute vec2 pos;
void main() {
gl_Position = vec4(pos, 1.0, 1.0);
}
`
let fs_src = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`
// 创建渲染流水线
function createProgram(gl: WebGLRenderingContext) {
let prog = gl.createProgram()!
// 创建并编译Vertex Shader
let vs = gl.createShader(gl.VERTEX_SHADER)!
gl.shaderSource(vs, vs_src)
gl.compileShader(vs)
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vs))
gl.deleteShader(vs)
}
gl.attachShader(prog, vs)
// 创建并编译Fragment Shader
let fs = gl.createShader(gl.FRAGMENT_SHADER)!
gl.shaderSource(fs, fs_src)
gl.compileShader(fs)
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fs))
gl.deleteShader(fs)
}
gl.attachShader(prog, fs)
// 链接Program
gl.linkProgram(prog)
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(prog))
}
gl.useProgram(prog)
return prog
}
export default function () {
let canvas_ref = useRef<HTMLCanvasElement>(null)
return (
<Container>
<canvas ref={canvas_ref} width={400} height={400} />
<Button onClick={() => {
let elt = canvas_ref.current!
let gl = elt.getContext('webgl')!
let prog = createProgram(gl)
// 创建Vertex Buffer Object
let buf = gl.createBuffer()!
gl.bindBuffer(gl.ARRAY_BUFFER, buf)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1]), gl.STATIC_DRAW)
// 描述VBO的数据排列
let loc = gl.getAttribLocation(prog, 'pos')
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(loc)
// 清除背景色
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
// 设置视窗
gl.viewport(0, 0, elt.width, elt.height)
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3)
}}>Render</Button>
</Container>
)
}
WebGL2(OpenGL ES3.0)
绘制顶点颜色不同的三角形
import { Button, Container } from "@mui/material";
import { useRef } from "react";
let vs_src = `#version 300 es
precision mediump float;
layout(location = 0) in vec2 pos;
layout(location = 1) in vec3 color;
out vec3 _color;
void main() {
gl_Position = vec4(pos, 1.0, 1.0);
_color = color;
}
`
let fs_src = `#version 300 es
precision mediump float;
in vec3 _color;
out vec4 fragColor;
void main() {
fragColor = vec4(_color, 1.0);
}
`
let gl: WebGL2RenderingContext
let vbo: WebGLBuffer
let vbo2: WebGLBuffer
let vao: WebGLVertexArrayObject
// 创建渲染流水线
function createProgram(gl: WebGLRenderingContext) {
let prog = gl.createProgram()!
// 创建并编译Vertex Shader
let vs = gl.createShader(gl.VERTEX_SHADER)!
gl.shaderSource(vs, vs_src)
gl.compileShader(vs)
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vs))
gl.deleteShader(vs)
}
gl.attachShader(prog, vs)
// 创建并编译Fragment Shader
let fs = gl.createShader(gl.FRAGMENT_SHADER)!
gl.shaderSource(fs, fs_src)
gl.compileShader(fs)
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fs))
gl.deleteShader(fs)
}
gl.attachShader(prog, fs)
// 链接Program
gl.linkProgram(prog)
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(prog))
}
gl.useProgram(prog)
return prog
}
export default function () {
let canvas_ref = useRef<HTMLCanvasElement>(null)
return (
<Container>
<canvas ref={canvas_ref} width={400} height={400} />
<Button onClick={() => {
let elt = canvas_ref.current!
gl = elt.getContext('webgl2')!
let prog = createProgram(gl)
// 创建Vertex Array Object(VAO)
vao = gl.createVertexArray()!
// 创建Vertex Buffer Object(VBO)
vbo = gl.createBuffer()!
gl.bindBuffer(gl.ARRAY_BUFFER, vbo)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 1, 1]), gl.STATIC_DRAW)
vbo2 = gl.createBuffer()!
gl.bindBuffer(gl.ARRAY_BUFFER, vbo2)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]), gl.STATIC_DRAW)
// 绑定VAO记录操作
gl.bindVertexArray(vao)
gl.bindBuffer(gl.ARRAY_BUFFER, vbo)
gl.enableVertexAttribArray(0)
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0)
gl.bindBuffer(gl.ARRAY_BUFFER, vbo2)
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(1)
gl.bindVertexArray(null)
gl.bindBuffer(gl.ARRAY_BUFFER, null)
}}>Init</Button>
<Button onClick={() => {
let elt = canvas_ref.current!
gl.bindVertexArray(vao)
// 清除背景色
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
// 设置视窗
gl.viewport(0, 0, elt.width, elt.height)
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3)
}}>Render</Button>
</Container>
)
}