WebGL的繪製線段
前言
最近想整合曲線( Curve )到引擎,需要將曲線( Curve )繪製出來,曲線( Curve )要繪製出來就需要靠繪製大量的直線來實現,但想想自己只有在 OpenGL 與 Direct3D 繪製線段, WebGL 的繪製方法也一樣嗎?在此做個紀錄。內容
WebGL 繪製線段的方法和 OpenGL 差不多,有一點不太一樣,就是 WebGL 的繪製線段不能控制線段寬度,這裡提供一個繪製線段的範例,方便日後實驗繪製曲線( Curve )HTML 的部分
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <canvas id="myCanvas1" width=400 height=300></canvas> <br> <input id="btnUpdate"type="button" value="Update"/> </body> </html>
Javascript 的部分
let canvas1 = document.getElementById('myCanvas1'); let glCTX1 = canvas1.getContext('webgl'); let vboPrimitiveCon = 0; let vbo=createDynamicBuffer(glCTX1); let shaderProg = createShader(glCTX1); // function createShader(glContext){ let vertShader = glContext.createShader(glContext.VERTEX_SHADER); glContext.shaderSource( vertShader , 'attribute vec3 pos;void main(void){gl_Position=vec4(pos, 1.0);}' ); glContext.compileShader(vertShader); let fragShader = glContext.createShader(glContext.FRAGMENT_SHADER); glContext.shaderSource( fragShader, 'void main(void){gl_FragColor=vec4(1,1,1,1);}' ); glContext.compileShader(fragShader); let prog = glContext.createProgram(); glContext.attachShader(prog, vertShader); glContext.attachShader(prog, fragShader); glContext.linkProgram(prog); glContext.useProgram(prog); return prog; } function createDynamicBuffer(glContext){ let vertexBuf = glContext.createBuffer(); glContext.bindBuffer(glContext.ARRAY_BUFFER, vertexBuf); let dataArray=new Float32Array([ 0.0, 0.5, 0.0, -0.5,-0.5, 0.0, -0.5,-0.5, 0.0, 0.5,-0.5, 0.0, 0.5,-0.5, 0.0, 0.0, 0.5, 0.0 ]); glContext.bufferData( glContext.ARRAY_BUFFER, dataArray, glContext.DYNAMIC_DRAW ); vboPrimitiveCon = dataArray.length / 3; return vertexBuf; } function simpleDraw(glContext){ glContext.useProgram(shaderProg); // glContext.viewport(0,0,glContext.canvas.width,glContext.canvas.height); glContext.clearColor(0, 0, 1, 1); glContext.clear(glContext.COLOR_BUFFER_BIT); // glContext.bindBuffer(glContext.ARRAY_BUFFER, vbo); let posLoc = glContext.getAttribLocation(shaderProg, "pos"); glContext.vertexAttribPointer(posLoc, 3, glContext.FLOAT, false, 0, 0); glContext.enableVertexAttribArray(posLoc); glContext.drawArrays(glContext.LINES, 0, vboPrimitiveCon); } function myRender(){ simpleDraw(glCTX1); // window.requestAnimationFrame(myRender); } document.getElementById("btnUpdate").onclick=function(evt){ let dataArray=new Float32Array([ 0.0,-0.5, 0.0, -0.5, 0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5, 0.5, 0.0, 0.0,-0.5, 0.0 ]); glCTX1.bindBuffer(glCTX1.ARRAY_BUFFER, vbo); glCTX1.bufferSubData(glCTX1.ARRAY_BUFFER,0,dataArray); vboPrimitiveCon = dataArray.length / 3; } window.onload = function(){ window.requestAnimationFrame(myRender); }
這次的範例從 解決多個 WebGLRenderContext 之間無法共享資源的問題 的範例修改而來,Vertex buffer 的部分採用動態的方式來建造,初始化時會給一個正三角的線段資料,畫面如下
範例執行畫面 |
範例有個 Update 的按鈕,按下去後會填充倒三角形的資料到 Vertex buffer ,畫面如下
更改Vertex buffer 的線段資料 |
這次的範例是個開端,之後會再推出繪製曲線( Curve )的範例。
沒有留言:
張貼留言