2017-02-19 307 views
0

我是WebGL的新手,想知道如何在不同对象的颜色之间切换。WebGL - 改变对象之间的颜色

我在一个数组中有一个圆和一个字段的数据。我想以绿色显示该字段,并以蓝色显示该字段的圆圈。

我正在为我的vColor属性错误(不不显示我的圈子里,只有场):
[.Offscreen-For-WebGL-05A18588]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 1

然而,当我删除代码来设置vColor属性,我可以看到圆圈,但圆圈和圆圈都显示为黑色。任何线索我哪里出错了?

shader代码:

<script id="vertex-shader" type="x-shader/x-vertex"> 
     attribute vec4 vPosition; 
     attribute vec4 vColor; 
     varying vec4 fColor; 

     void main() { 
      fColor = vColor; 
      gl_Position = vPosition; 
     } 
    </script> 

    <script id="fragment-shader" type="x-shader/x-fragment"> 
     precision mediump float; 
     varying vec4 fColor; 

     void main() { 
      gl_FragColor = fColor; 
     } 
    </script> 

JS代码:

//cirlce data 
var pi = 3.14159; 
var x = 2*pi/100; 
var y = 2*pi/100; 
var r = 0.5; 
var center = vec2(0.0, 0.0); 
//data for gpu 
var vertices = [ 
    vec2(-7.0,-1), 
    vec2(-0.6, 0), 
    vec2(0.6, 0), 
    vec2(6.0, -1) 
]; 

var vertexColors = [ 
    vec4(0.0, 0.0, 0.0, 0.0), // black 
    vec4(1.0, 0.0, 0.0, 0.0), // red 
    vec4(1.0, 1.0, 0.0, 1.0), // yellow 
    vec4(0.0, 1.0, 0.0, 1.0), // green 
    vec4(0.0, 0.0, 1.0, 1.0), // blue 
    vec4(1.0, 0.0, 1.0, 0.0), // magenta 
    vec4(0.0, 1.0, 1.0, 0.0) // cyan 
]; 

window.onload = function init() 
{ 
    canvas = document.getElementById("gl-canvas"); 

gl = WebGLUtils.setupWebGL(canvas); 
if (!gl) { alert("WebGL isn't available"); } 

vertices.push(center); 
for(var i = 0; i < 100; i++) { 
    vertices.push(add(center, vec2(r*Math.cos(x*i), r*Math.sin(y*i)))); 
} 

console.log(flatten(vertices)); 

// 
// Configure WebGL 
// 
gl.viewport(0, 0, canvas.width, canvas.height); 
gl.clearColor(1.0, 1.0, 1.0, 1.0); 

// Load shaders and initialize attribute buffers 

var program = initShaders(gl, "vertex-shader", "fragment-shader"); 
gl.useProgram(program); 

// Load the data into the GPU 

var colorBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); 
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertexColors), gl.STATIC_DRAW);  

var vColor = gl.getAttribLocation(program, "vColor"); 
gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0); //error produced here 
gl.enableVertexAttribArray(vColor); 

var buffer2 = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, buffer2); 
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW); 

var vPosition = gl.getAttribLocation(program, "vPosition"); 
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0); 
gl.enableVertexAttribArray(vPosition); 

// Associate out shader variables with our data buffer 

render(); 
}; 

function render() { 
    gl.clear(gl.COLOR_BUFFER_BIT); 
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);//draw the field - field coordinates start at 0-4 
    gl.drawArrays(gl.TRIANGLE_FAN, 5, 100);//draw the circle - circle coordinates start at 5-100 
} 
+1

只有7种颜色,但你的绘制调用试图访问100 – tkausl

+0

@tkausl,谢谢您设置形状的颜色。这摆脱了错误,我使用'drawArrays(gl.TRIANGLE_FAN,0,7)'然而,我的'drawArrays()'现在只画几个点。我如何只用7种颜色绘制我的所有点? – ethane

回答

1

如果你使用顶点颜色属性,而影响了你的形状,你需要一个顶点颜色逐顶点。换句话说,如果你有1000个顶点,每个顶点需要一个位置和一个颜色。

如果您使用的是每个形状的恒定颜色,那么您可以执行其中的一种。

  1. 使用恒定的顶点属性

    // disabling the array means this attribute uses a constant value 
    gl.disableVertexAttribArray(vertexColorLocation); 
    
    // set the constant value 
    gl.vertexAttrib4f(vertexColorLocation, r, g, b, a); 
    

    注:在属性中使用的常量值是不常见的使用情况

  2. 使用统一的,而不是

    改变你的着色器

    <script id="vertex-shader" type="x-shader/x-vertex"> 
        attribute vec4 vPosition; 
    
        void main() { 
         gl_Position = vPosition; 
        } 
    </script> 
    
    <script id="fragment-shader" type="x-shader/x-fragment"> 
        precision mediump float; 
        uniform vec4 fColor;  // <=- changed 
    
        void main() { 
         gl_FragColor = fColor; 
        } 
    </script> 
    

    现在,你可以通过设置fColor均匀

    // at init time 
    var fColorLocation = gl.getUniformLocation(program, "fColor"); 
    
    // at render time 
    gl.uniform4f(fColorLocation, r, g, b, a); 
    
+0

谢谢@gman。这解释了我正在尝试做什么,它的工作。 – ethane