将颜色应用到单个顶点在OpenGL四(Applying color to single vertic

2019-07-20 04:28发布

我想要的颜色,通过绘制四边形的单一顶点glDrawElements ,我用cocos2d的 libray工作,所以我已经能够清除的源代码,以了解到底发生了什么,代码如下:

glBindVertexArray( VAOname_ );
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(indices_[0])) );
glBindVertexArray(0);

所以使用顶点数组对象。 我试图修改所传递的对象的单个顶点的颜色,它似乎工作,但与由下图描述的故障:

在这里,我试图改变左下和右下顶点的颜色。 其结果是不同的,我想这是因为四呈现为一对夫妇与驻留在从左下顶点更高的权顶点去对角线共享斜边三角形。 因此,这可能会导致不同的结果。

现在,我想有第二次的结果也为第一种情况。 有没有办法得到它?

Answer 1:

你的猜测是正确的。 OpenGL驱动程序tesselates你的四成两个三角形,其中顶点颜色barycentrically插值,这会导致你看到了什么。

解决这个通常的方法,是通过在片段着色器,考虑到目标拓扑,你的情况四执行插值“手动”。 或者总之你要对一个三角形,但在四不是基于执行重心插值。 您可能还需要应用透视校正。

我没有准备好,现在读手头的资源,但我会尽快,因为我有更新这个答案(实际上可能意味着,我必须写我自己)。

更新

首先,我们必须了解问题:大多数OpenGL实现分解更高元为三角形,并使其本土化,即没有对原始其余进一步了解,如四。 因此,我们必须做这我们自己。

这是我想做到这一点。

#version 330 // vertex shader

当然,我们还需要平时的制服

uniform mat4x4 MV;
uniform mat4x4 P;

首先,我们需要顶点由该着色器执行实例处理的位置

layout (location=0) in vec3 pos;

接下来,我们需要我们用它来形容四本身的一些顶点属性。 这意味着它的角落位置

layout (location=1) in vec3 qp0;
layout (location=2) in vec3 qp1;
layout (location=3) in vec3 qp2;
layout (location=4) in vec3 qp3;

和颜色

layout (location=5) in vec3 qc0;
layout (location=6) in vec3 qc1;
layout (location=7) in vec3 qc2;
layout (location=8) in vec3 qc3;

我们把那些进入varyings的片段着色器程序。

out vec3 position;
out vec3 qpos[4];
out vec3 qcolor[4];

void main()
{
    qpos[0] = qp0;
    qpos[1] = qp1;
    qpos[2] = qp2;
    qpos[3] = qp3;

    qcolor[0] = qc0;
    qcolor[1] = qc1;
    qcolor[2] = qc2;
    qcolor[3] = qc3;

    gl_Position = P * MV * position;
}

在片段着色器,我们使用这个实施对于彩色分量的距离加权:

#version 330 // fragment shader

in vec3 position;
in vec3 qpos[4];
in vec3 qcolor[4];

void main()
{
    vec3 color = vec3(0);

以下可以简化combinatorical,但为了清楚起见,我写出来:对于具有与作为混合因子它们之间的边缘位置的所有投影角点的颜色混合顶点的每个角点。

    for(int i=0; i < 4; i++) {
        vec3 p = position - qpos[i];
        for(int j=0; j < 4; j++) {
            vec3 edge = qpos[i] - qpos[j];
            float edge_length = length(edge);
            edge = normalize(edge);
            float tau = dot(edge_length, p) / edge_length;

            color += mix(qcolor[i], qcolor[j], tau);
        }
    }

因为我们看到在每个角落点4倍,缩减1/4

    color *= 0.25;

    gl_FragColor = color; // and maybe other things.
}

我们差不多完成。 在客户端,我们需要通过更多的信息。 当然,我们不希望重复数据。 为此,我们使用glVertexBindingDivisor使得顶点属性只能前进,每4个顶点(即四),对qp…qc…的位置,即位置1至8

typedef float vec3[3];
extern vec3 *quad_position;
extern vec3 *quad_color;

glVertexAttribute(0, 3, GL_FLOAT, GL_FALSE, 0, &quad_position[0]);

glVertexBindingDivisor(1, 4);
glVertexAttribute     (1, 3, GL_FLOAT, GL_FALSE, 0, &quad_position[0]);

glVertexBindingDivisor(2, 4);
glVertexAttribute     (2, 3, GL_FLOAT, GL_FALSE, 0, &quad_position[1]);

glVertexBindingDivisor(3, 4);
glVertexAttribute     (3, 3, GL_FLOAT, GL_FALSE, 0, &quad_position[2]);

glVertexBindingDivisor(4, 4);
glVertexAttribute     (4, 3, GL_FLOAT, GL_FALSE, 0, &quad_position[3]);

glVertexBindingDivisor(5, 4);
glVertexAttribute     (5, 3, GL_FLOAT, GL_FALSE, 0, &quad_color[0]);

glVertexBindingDivisor(6, 4);
glVertexAttribute     (6, 3, GL_FLOAT, GL_FALSE, 0, &quad_color[1]);

glVertexBindingDivisor(7, 4);
glVertexAttribute     (7, 3, GL_FLOAT, GL_FALSE, 0, &quad_color[2]);

glVertexBindingDivisor(8, 4);
glVertexAttribute     (8, 3, GL_FLOAT, GL_FALSE, 0, &quad_color[3]);

这是有道理的投入到上述顶点数组对象。 还采用VBO会是有意义的,但你必须手动计算偏移量的大小; 由于typedef float vec3的编译器数学为我们自动柜员机。

有了这一切被设置你终于可以镶嵌画独立的四。



文章来源: Applying color to single vertices in a quad in opengl