在WebGL中绘制多种形状
我在读学校的教程在WebGL中绘制多种形状,webgl,Webgl,我在读学校的教程 var-gl; 函数initGL(){ //获取WebGL上下文 var canvas=document.getElementById(“canvas”); gl=getWebGLContext(画布); 如果(!gl){ 返回; } } 变量位置; var分解定位; var颜色定位; var转换定位; 变量旋转定位; var换算=[50,50]; 变量旋转=[0,1]; var角=0; 函数initShaders(){ //安装GLSL程序 vertexShader=cre
var-gl;
函数initGL(){
//获取WebGL上下文
var canvas=document.getElementById(“canvas”);
gl=getWebGLContext(画布);
如果(!gl){
返回;
}
}
变量位置;
var分解定位;
var颜色定位;
var转换定位;
变量旋转定位;
var换算=[50,50];
变量旋转=[0,1];
var角=0;
函数initShaders(){
//安装GLSL程序
vertexShader=createShaderFromScriptElement(gl,“2d顶点着色器”);
fragmentShader=createShaderFromScriptElement(gl,“2d片段着色器”);
program=createProgram(gl,[vertexShader,fragmentShader]);
gl.useProgram(程序);
//查找顶点数据需要去的地方。
positionLocation=gl.GetAttriblLocation(程序,“a_位置”);
//查找制服
resolutionLocation=gl.getUniformLocation(程序,“u_分辨率”);
colorLocation=gl.getUniformLocation(程序,“u_颜色”);
translationLocation=gl.getUniformLocation(程序,“u_翻译”);
rotationLocation=gl.getUniformLocation(程序,“u_旋转”);
//制定决议
gl.uniform2f(分辨率位置、画布宽度、画布高度);
}
函数initBuffers(){
//创建一个缓冲区。
var buffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,BUFFER);
gl.EnableVertexAttributeArray(位置位置);
gl.VertexAttribute指针(位置位置,2,gl.FLOAT,false,0,0);
//设置几何图形。
集合几何(gl);
}
功能设置颜色(红色、绿色、蓝色){
gl.uniform4f(颜色位置,红色、绿色、蓝色,1);
}
//画场景。
函数drawsecene(){
//清理画布。
总账清除(总账颜色缓冲位);
//设置翻译。
gl.uniform2fv(翻译位置,翻译);
//设置旋转。
gl.uniform2fv(旋转位置,旋转);
//绘制几何图形。
gl.绘图阵列(gl.三角形,0,6);
}
//用定义字母“F”的值填充缓冲区。
函数集几何(gl){
/*假设声明了size1*/
变量顶点=[
-尺寸1/2,-尺寸1/2,
-尺寸1/2,尺寸1/2,
尺寸1/2,尺寸1/2,
尺寸1/2,尺寸1/2,
尺寸1/2,-尺寸1/2,
-尺寸1/2,-尺寸1/2];
缓冲数据(
gl.ARRAY\u缓冲区,
新的浮点数组(顶点),
gl.静态(U形图);
}
函数animate(){
平移[0]+=0.01;
翻译[1]+=0.01;
角度+=0.01;
旋转[0]=数学cos(角度);
旋转[1]=数学sin(角度);
}
函数tick(){
请求帧(勾号);
drawScene();
制作动画();
}
函数start(){
initGL();
initShaders();
initBuffers();
setColor(0.2,0.5,0.5);
勾选();
}
属性向量2 a_位置;
均匀vec2u_分辨率;
统一vec2u_翻译;
均匀vec2u_旋转;
void main(){
vec2旋转位置=vec2(
a_位置.x*u旋转.y+a_位置.y*u旋转.x,
a_位置.y*u旋转.y-a_位置.x*u旋转.x);
//加上翻译。
vec2位置=旋转位置+u_平移;
//将位置从像素转换为0.0到1.0
vec2 zeroToOne=位置/u_分辨率;
//从0->1转换为0->2
vec2 zeroToTwo=zeroToOne*2.0;
//从0->2转换为-1->+1(剪辑空间)
vec2 clipSpace=zeroToTwo-1.0;
gl_位置=vec4(clipSpace,0,1);
}
精密中泵浮子;
均匀的vec4 u_颜色;
void main(){
gl_FragColor=u_颜色;
}
我的1号形状WebGL程序的工作原理如下:
drawsecene()
:调用gl.drawArrays()
tick()
中同时调用drawsecene()
,以便重复调用它drawsecene()
一次绘制所有对象
[或]
我是否应该重复调用
requestAnimFrame()
中的initBuffer
和drawsecene()
,在一个缓冲区中使用多个网格(并按照您的建议使用单个gl.drawArrays()
渲染它们)在复杂场景中产生更好的性能,但显然在这一点上,您无法更改每个网格的着色器统一(例如变换)
如果要使网格独立运行,则必须分别渲染每个网格。您仍然可以将所有网格保留在一个缓冲区中,以避免调用
gl.bindBuffer()
时产生的一些开销,但这不会有多大帮助,至少在简单场景中不会如此。为场景中想要的每个对象分别创建缓冲区,否则它们将无法单独移动和使用着色器效果
但这是为了防止对象不同。从我这里得到的信息来看,我想你只是想在不同的位置上多次绘制相同的形状,对吗
这样做的方法是,在第一次绘制形状后,使用不同的平移矩阵将translationLocation
设置为一致。这样,当您再次绘制形状时,它将位于其他位置,而不是位于另一个形状的顶部,以便您可以看到它。您可以以不同的方式设置所有这些转换矩阵,然后只需再次调用gl.drawerelements
,因为您将绘制已经在使用的相同缓冲区。在伪代码中
在初始时间
- 从canvas元素获取上下文(gl)
- 对于每个着色器
- 创建着色器
- 查找属性和统一位置
- 对于每个形状
- 使用形状初始化缓冲区
- 对于每个纹理
<script class = "WebGL"> var gl; function initGL() { // Get A WebGL context var canvas = document.getElementById("canvas"); gl = getWebGLContext(canvas); if (!gl) { return; } } var positionLocation; var resolutionLocation; var colorLocation; var translationLocation; var rotationLocation; var translation = [50,50]; var rotation = [0, 1]; var angle = 0; function initShaders() { // setup GLSL program vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader"); fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader"); program = createProgram(gl, [vertexShader, fragmentShader]); gl.useProgram(program); // look up where the vertex data needs to go. positionLocation = gl.getAttribLocation(program, "a_position"); // lookup uniforms resolutionLocation = gl.getUniformLocation(program, "u_resolution"); colorLocation = gl.getUniformLocation(program, "u_color"); translationLocation = gl.getUniformLocation(program, "u_translation"); rotationLocation = gl.getUniformLocation(program, "u_rotation"); // set the resolution gl.uniform2f(resolutionLocation, canvas.width, canvas.height); } function initBuffers() { // Create a buffer. var buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.enableVertexAttribArray(positionLocation); gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); // Set Geometry. setGeometry(gl); } function setColor(red, green, blue) { gl.uniform4f(colorLocation, red, green, blue, 1); } // Draw the scene. function drawScene() { // Clear the canvas. gl.clear(gl.COLOR_BUFFER_BIT); // Set the translation. gl.uniform2fv(translationLocation, translation); // Set the rotation. gl.uniform2fv(rotationLocation, rotation); // Draw the geometry. gl.drawArrays(gl.TRIANGLES, 0, 6); } // Fill the buffer with the values that define a letter 'F'. function setGeometry(gl) { /*Assume size1 is declared*/ var vertices = [ -size1/2, -size1/2, -size1/2, size1/2, size1/2, size1/2, size1/2, size1/2, size1/2, -size1/2, -size1/2, -size1/2 ]; gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); } function animate() { translation[0] += 0.01; translation[1] += 0.01; angle += 0.01; rotation[0] = Math.cos(angle); rotation[1] = Math.sin(angle); } function tick() { requestAnimFrame(tick); drawScene(); animate(); } function start() { initGL(); initShaders(); initBuffers(); setColor(0.2, 0.5, 0.5); tick(); } </script> <!-- vertex shader --> <script id="2d-vertex-shader" type="x-shader/x-vertex"> attribute vec2 a_position; uniform vec2 u_resolution; uniform vec2 u_translation; uniform vec2 u_rotation; void main() { vec2 rotatedPosition = vec2( a_position.x * u_rotation.y + a_position.y * u_rotation.x, a_position.y * u_rotation.y - a_position.x * u_rotation.x); // Add in the translation. vec2 position = rotatedPosition + u_translation; // convert the position from pixels to 0.0 to 1.0 vec2 zeroToOne = position / u_resolution; // convert from 0->1 to 0->2 vec2 zeroToTwo = zeroToOne * 2.0; // convert from 0->2 to -1->+1 (clipspace) vec2 clipSpace = zeroToTwo - 1.0; gl_Position = vec4(clipSpace, 0, 1); } </script> <!-- fragment shader --> <script id="2d-fragment-shader" type="x-shader/x-fragment"> precision mediump float; uniform vec4 u_color; void main() { gl_FragColor = u_color; } </script>