2010-05-05 66 views
5

我正在编写OpenGL ES 2.0(Webgl)。我正在使用VBOs绘制基元。我有顶点数组,颜色数组和索引数组。我已经看过示例代码,书籍和教程,但有一件事我没有得到 - 如果每个顶点定义了颜色,它会如何影响与这些顶点相邻的多边形曲面? (我是新手到的OpenGL(ES))颜色属性如何在VBO中工作?

我将用一个例子说明。我有一个立方体绘制。从我在OpenGLES书中读到的内容中,颜色被定义为一个顶点属性。在这种情况下,如果我想用6种不同颜色绘制立方体的6个面,我应该如何定义颜色。我的困惑之源是:每个顶点与3个面相同,那么它将如何帮助定义每个顶点的颜色? (或者应该为每个索引定义颜色?)。事实上,我们需要将这些面分成三角形,这让我很难理解这种关系是如何运作的。边缘也会出现同样的混乱。而不是绘制三角形,让我们说我想要使用LINES基元绘制边缘。每个边缘都有不同的颜色。在这种情况下,我应该如何定义颜色属性?

我见过很少的工作例子。具体来说,本教程:http://learningwebgl.com/blog/?p=370

我看在上面的例子中如何定义颜色数组来绘制一个具有6种不同颜色的面的立方体,但我不明白为什么这样定义。 (为什么每个彩色复印4次进入unpackedColors比如?)

有人可以解释颜色属性的VBO是如何工作的?

[上面的链接似乎难以接近,所以我将张贴在这里的相关代码]

cubeVertexPositionBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); 
vertices = [ 
    // Front face 
    -1.0, -1.0, 1.0, 
    1.0, -1.0, 1.0, 
    1.0, 1.0, 1.0, 
    -1.0, 1.0, 1.0, 

    // Back face 
    -1.0, -1.0, -1.0, 
    -1.0, 1.0, -1.0, 
    1.0, 1.0, -1.0, 
    1.0, -1.0, -1.0, 

    // Top face 
    -1.0, 1.0, -1.0, 
    -1.0, 1.0, 1.0, 
    1.0, 1.0, 1.0, 
    1.0, 1.0, -1.0, 

    // Bottom face 
    -1.0, -1.0, -1.0, 
    1.0, -1.0, -1.0, 
    1.0, -1.0, 1.0, 
    -1.0, -1.0, 1.0, 

    // Right face 
    1.0, -1.0, -1.0, 
    1.0, 1.0, -1.0, 
    1.0, 1.0, 1.0, 
    1.0, -1.0, 1.0, 

    // Left face 
    -1.0, -1.0, -1.0, 
    -1.0, -1.0, 1.0, 
    -1.0, 1.0, 1.0, 
    -1.0, 1.0, -1.0, 
]; 
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW); 
cubeVertexPositionBuffer.itemSize = 3; 
cubeVertexPositionBuffer.numItems = 24; 

cubeVertexColorBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer); 
var colors = [ 
    [1.0, 0.0, 0.0, 1.0],  // Front face 
    [1.0, 1.0, 0.0, 1.0],  // Back face 
    [0.0, 1.0, 0.0, 1.0],  // Top face 
    [1.0, 0.5, 0.5, 1.0],  // Bottom face 
    [1.0, 0.0, 1.0, 1.0],  // Right face 
    [0.0, 0.0, 1.0, 1.0],  // Left face 
]; 
var unpackedColors = [] 
for (var i in colors) { 
    var color = colors[i]; 
    for (var j=0; j < 4; j++) { 
    unpackedColors = unpackedColors.concat(color); 
    } 
} 
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(unpackedColors), gl.STATIC_DRAW); 
cubeVertexColorBuffer.itemSize = 4; 
cubeVertexColorBuffer.numItems = 24; 

cubeVertexIndexBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); 
var cubeVertexIndices = [ 
    0, 1, 2,  0, 2, 3, // Front face 
    4, 5, 6,  4, 6, 7, // Back face 
    8, 9, 10,  8, 10, 11, // Top face 
    12, 13, 14, 12, 14, 15, // Bottom face 
    16, 17, 18, 16, 18, 19, // Right face 
    20, 21, 22, 20, 22, 23 // Left face 
] 
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray(cubeVertexIndices), gl.STATIC_DRAW); 
cubeVertexIndexBuffer.itemSize = 1; 
cubeVertexIndexBuffer.numItems = 36; 
+0

好吧我想上面的例子代码定义了多个相同的顶点。正如你所看到的,一个立方体有8个顶点,但是这个代码有24个顶点。这就是它如何为同一个顶点指定3种不同的颜色,这取决于它是哪个面的一部分。这是唯一的方法吗?这不是太浪费吗? – Jayesh 2010-05-06 07:51:22

回答

7

我喜欢看它的方式是,每个顶点是不是在空间中的点,而是属性的包。这些通常(但不总是)包括其位置和可以包括它的颜色,纹理坐标,等等等等等等的三角形(或线,或其它原语)是通过指定一组顶点,然后生成定义通过对每个顶点值进行线性插值来为每个像素处的每个属性赋值。

正如Liam所说,并且正如您在评论中已经意识到的那样,这意味着如果您想在顶点使用多个基元的空间中使用点,例如多维数据集的角落, - 其他非位置属性根据每个基元的不同而不同,您需要为每个属性组合分别设置一个顶点。

这是浪费内存在一定程度上 - 但是参与做任何其他方式会使事情变得更糟的复杂性,并需要图形硬件做了很多工作,拆装包装等数据。对我来说,感觉就像浪费与通过为我们的视频内存中的每个像素使用32位RGBA值所获得的浪费相比,而不是保留我们要使用的每种颜色的“调色板”查找表,然后仅存储索引到每个像素(当然,这是我们在RAM更昂贵时用来做的)。

3

如果一组多边形的颜色是否相同,所有的多边形的共享,以及顶点它的颜色可以被定义一次并被多边形共享(使用索引)。

如果多边形的颜色是不同的,那么,即使一个顶点的位置可以是共同的,颜色不是,因此,顶点作为一个整体不能共享。您将需要为每个多边形定义顶点。