[英]How to draw 3 rectangles with WebGL2
我可以手工將完整的樣板寫到WebGL2,並且可以完成很多工作。
const canvas = document.createElement('canvas') document.body.appendChild(canvas) const gl = canvas.getContext('webgl2', { antialias: true }) const width = 800 const height = 500 canvas.width = width canvas.height = height const vertexShader = gl.createShader(gl.VERTEX_SHADER) const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) gl.shaderSource(vertexShader, `#version 300 es in vec3 position; in vec4 color; out vec4 thecolor; void main() { gl_Position = vec4(position, 1.0); thecolor = color; } `) gl.shaderSource(fragmentShader, `#version 300 es precision mediump float; in vec4 thecolor; out vec4 color; void main() { color = thecolor; } `) gl.compileShader(vertexShader) var success = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) if (!success) throw new Error(gl.getShaderInfoLog(vertexShader)) gl.compileShader(fragmentShader) var success = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) if (!success) throw new Error(gl.getShaderInfoLog(fragmentShader)) const program = gl.createProgram() gl.attachShader(program, vertexShader) gl.attachShader(program, fragmentShader) gl.linkProgram(program) gl.useProgram(program) const positionAttribute = gl.getAttribLocation(program, 'position') const colorAttribute = gl.getAttribLocation(program, 'color') gl.viewport(0, 0, width, height) gl.clearColor(0, 0, 0, 0) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // I don't know what the purpose of this is. const positionVAO = gl.createVertexArray() gl.bindVertexArray(positionVAO) const vertexBuffer = gl.createBuffer() const indexBuffer = gl.createBuffer() const vertexArray = [ // don't know how to structure this on my own. ] const indexArray = [ // don't know how to structure this either. ] gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer) gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexArray), gl.DYNAMIC_DRAW) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW) gl.enableVertexAttribArray(positionAttribute) gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0) gl.enableVertexAttribArray(colorAttribute) gl.vertexAttribPointer(colorAttribute, 4, gl.FLOAT, false, 0, 0) gl.drawElements(gl.TRIANGLES, indexArray.length, gl.UNSIGNED_SHORT, 0)
但是,其中有3條評論。
gl.createVertexArray
和gl.bindVertexArray
的目的是什么。 vertexArray
構造頂點。 indexArray
構造索引。 我已經看過很多教程,但是它們通常掩蓋了頂點/索引的創建和定義。 他們並沒有真正解釋他們是如何設計或構造它們的,或者為什么是這樣,所以我還不能真正重建它。 我想用drawElements
與指數的,而不是drawArrays
。
想知道是否可以顯示如何繪制3個矩形,每個矩形具有不同的顏色(通過vertexArray
傳遞)。 我正在想象將vertexArray
的位置/顏色交織vertexArray
,但是我不知道如何正確地做到這一點,也不知道如何將數據與indexArray
。 所謂“正確”,我的意思是我不明白直觀又怎樣進入Float32Array
為頂點和Uint32Array
的指標。 如果是x, y
或x, y, r, g, b, a
在這種情況下為a)或其他值。 我不了解矩形是如何閉合的,其“表面”是彩色的。 想知道是否可以幫助解釋和演示這張由3種不同顏色的矩形組成的圖。 這將有助於鞏固如何繪制WebGL!
我嘗試繪制它們的方法是:
const vertexArray = [
1, 1, 1, 1, 1, 1, // x y r g b a
0, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1
]
const indexArray = [
1,
2,
3,
4
]
但是它什么也沒做。
關鍵是gl.vertexAttribPointer
的最后兩個參數。
第5個參數指定連續的通用頂點屬性集之間的字節偏移。 在您的情況下,每組屬性都由6個類型為float的值(xyrgba)組成。 因此字節偏移為6 * 4 = 24。
第6個參數指定數組中第一個通用頂點屬性的第一個組件的字節偏移量(如果綁定了命名數組緩沖區對象)。
頂點坐標的偏移為0,因為這是前2個值。
顏色屬性的偏移量為2 * 4 = 8,因為顏色屬性從第3個位置開始。
因此,頂點數組的規范必須為:
const vertexArray = [
1, 1, 1, 1, 1, 1, // x y r g b a
0, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1
]
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexArray), gl.DYNAMIC_DRAW)
gl.enableVertexAttribArray(positionAttribute)
gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 6*4, 0)
gl.enableVertexAttribArray(colorAttribute)
gl.vertexAttribPointer(colorAttribute, 4, gl.FLOAT, false, 6*4, 2*4)
您要繪制2個三角形:
2 0
+--------+ 0: (1, 1)
| /| 1: (0, 1)
| / | 2: (1, 0)
| / | 3: (0, 0)
+ -------+
3 1
每個三角形由3個索引組成,因此索引數組必須為:
const indexArray = [ 0, 2, 3, 0, 3, 1 ]
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW)
如果使用基本類型TRIANGLES
繪制此TRIANGLES
,
gl.drawElements(gl.TRIANGLES, indexArray.length, gl.UNSIGNED_SHORT, 0)
那么這將形成兩個具有坐標的三角形:
1st : (1, 1) -> (1, 0) -> (0, 0)
2nd : (1, 1) -> (0, 0) -> (0, 1)
當然,可以繪制三角形帶( TRIANGLE_STRIP
)或三角形扇形( TRIANGLE_FAN
)來代替:
const indexArray = [ 2, 0, 3, 1 ]
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW)
gl.drawElements(gl.TRIANGLE_STRIP, indexArray.length, gl.UNSIGNED_SHORT, 0)
const indexArray = [ 0, 2, 3, 1 ]
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW)
gl.drawElements(gl.TRIANGLE_FAN, indexArray.length, gl.UNSIGNED_SHORT, 0)
var canvas = document.getElementById('my_canvas'); const gl = canvas.getContext('webgl2', { antialias: true }) const width = 800 const height = 500 canvas.width = width canvas.height = height const vertexShader = gl.createShader(gl.VERTEX_SHADER) const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) gl.shaderSource(vertexShader, `#version 300 es in vec3 position; in vec4 color; out vec4 thecolor; void main() { gl_Position = vec4(position, 1.0); thecolor = color; } `) gl.shaderSource(fragmentShader, `#version 300 es precision mediump float; in vec4 thecolor; out vec4 color; void main() { color = thecolor; } `) gl.compileShader(vertexShader) var success = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) if (!success) throw new Error(gl.getShaderInfoLog(vertexShader)) gl.compileShader(fragmentShader) var success = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) if (!success) throw new Error(gl.getShaderInfoLog(fragmentShader)) const program = gl.createProgram() gl.attachShader(program, vertexShader) gl.attachShader(program, fragmentShader) gl.linkProgram(program) gl.useProgram(program) const positionAttribute = gl.getAttribLocation(program, 'position') const colorAttribute = gl.getAttribLocation(program, 'color') gl.viewport(0, 0, width, height) gl.clearColor(0, 0, 0, 0) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // I don't know what the purpose of this is. const positionVAO = gl.createVertexArray() gl.bindVertexArray(positionVAO) const vertexBuffer = gl.createBuffer() const indexBuffer = gl.createBuffer() const vertexArray = [ 1, 1, 1, 1, 0, 1, // xyrgba 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1 ] const indexArray = [0, 2, 3, 0, 3, 1] gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer) gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexArray), gl.DYNAMIC_DRAW) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), gl.STATIC_DRAW) gl.enableVertexAttribArray(positionAttribute) gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 6*4, 0) gl.enableVertexAttribArray(colorAttribute) gl.vertexAttribPointer(colorAttribute, 4, gl.FLOAT, false, 6*4, 2*4) gl.drawElements(gl.TRIANGLES, indexArray.length, gl.UNSIGNED_SHORT, 0)
<canvas id="my_canvas"></canvas>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.