簡體   English   中英

如何使用WebGL2繪制3個矩形

[英]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條評論。

  1. 我不知道gl.createVertexArraygl.bindVertexArray的目的是什么。 解釋了它。
  2. 不知道如何在vertexArray構造頂點。
  3. 不知道如何在indexArray構造索引。

我已經看過很多教程,但是它們通常掩蓋了頂點/索引的創建和定義。 他們並沒有真正解釋他們是如何設計或構造它們的,或者為什么是這樣,所以我還不能真正重建它。 我想用drawElements與指數的,而不是drawArrays

想知道是否可以顯示如何繪制3個矩形,每個矩形具有不同的顏色(通過vertexArray傳遞)。 我正在想象將vertexArray的位置/顏色交織vertexArray ,但是我不知道如何正確地做到這一點,也不知道如何將數據與indexArray 所謂“正確”,我的意思是我不明白直觀又怎樣進入Float32Array為頂點和Uint32Array的指標。 如果是x, yx, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM