更新顶点着色器(glVertexAttrib3f)中的属性变量,作为glVertex

时间:2013-04-09 20:51:11

标签: opengl shader fragment-shader vertex-shader geometry-shader

我无法使用属性变量将值输入到顶点着色器中。我想为几何着色器提供上一个基元(线)中的一个点进行一些计算。我使用vec3属性变量(Ppoint)进入顶点着色器,然后使用顶点着色器中的out变量和几何着色器中的in变量(pointPass)使用几何着色器。

问题是当我在绘制线条时更新glBegin()/ glEnd()块中的属性变量时,glVertexAttrib3f中的值被视为顶点,并且还会向这些点渲染线条。这会导致显示一些额外的线条,并且所有几何着色器功能都会受到干扰。

这是我所有着色器和我的opengl程序的代码,用于绘制线条。

顶点着色器

#version 330 compatibility
out vec3 pointPass;
attribute vec3 Ppoint;
void main()
{ 
    pointPass = Ppoint;
    gl_Position = gl_Vertex;
}

几何着色器

#version 330 compatibility
in vec3 pointPass[]; 
out vec4 colorFrag; 
layout(lines) in;
// 100 vertices are not actually required specified more for trial
layout(triangle_strip, max_vertices=100) out;

vec3 getA(vec3 axis){ 
    vec3 a; 
    a.x = 1.0;
    a.y = 1.0; 
    a.z = -(axis.x + axis.y)/axis.z; 
    a = normalize(a); 
    return a;
}
vec3 getB(vec3 axis, vec3 a){ 
    vec3 b;
    b.x = (a.y*axis.z - a.z*axis.y);
    b.y = (a.z*axis.x - a.x*axis.z);
    b.z = (a.x*axis.y - a.y*axis.x );
    b = normalize(b);
    return b;
}

void main()
{ 
    vec3 axis0, axis1, v0, v1, v2; 
    float radius = 0.5;
    float rotation = 0.0f;
    float pi = 3.1416; 
    int numPoints = 15;
    vec3 p1, p2, p3, p4;
    int count = 0, i;
    float increment = 2*pi/numPoints;
    v0 = pointPass[0];
    v1 = gl_in[0].gl_Position.xyz;
    v2 = gl_in[1].gl_Position.xyz;

    axis1 = v1 - v2;
    axis1 = normalize(axis1);
    vec3 a1 = getA(axis1);
    vec3 b1 = getB(axis1, a1);

    axis0 = v0-v2;
    axis0 = normalize(axis0);
    vec3 a0 = getA(axis0);
    vec3 b0 = getB(axis0, a0);

    // Rotation with theta
    for(rotation = 0; rotation<=2*pi; rotation+=increment){

    p1 = v1 + radius*cos(rotation)*a0 + radius*sin(rotation)*b0; 
    p2 = v1 + radius*cos(rotation + increment)*a0 + radius*sin (rotation + increment)*b0;
    p3 = v2 + radius*cos(rotation)*a1 + radius*sin(rotation)*b1; 
    p4 = v2 + radius*cos(rotation + increment)*a1 + radius*sin(rotation + increment)*b1;
    // FIRST Triangle 
    // FIRST vertex 
    gl_Position = (gl_ModelViewProjectionMatrix*vec4(p3,1.0) );
    EmitVertex(); 
    // SECOND vertex
    gl_Position = (gl_ModelViewProjectionMatrix*vec4(p1, 1.0) ); 
    EmitVertex();
    // THIRD vertex
    gl_Position = (gl_ModelViewProjectionMatrix*vec4(p4, 1.0) );
    EmitVertex();
    // SECOND Triangle
    // FIRST vertex 
    gl_Position = (gl_ModelViewProjectionMatrix*vec4(p2, 1.0) ); 
    EmitVertex();

    }
    EndPrimitive(); 
}

片段着色器

#version 330 compatibility
in vec4 colorFrag;
void main()
{ 
    gl_FragColor = colorFrag;
} 

用于绘制线条的OpenGL程序

// vPoints is a std::vector of 3d vector class created by me.
void drawLines(){
     float angle =0.0f;
     int numLines = 30;
     int count = 0;
     float disp = 0.30f;
     float radius_x = 5.0;
     float radius_y = 5.0;
     vPoints.resize(numLines+2);
    // Loop around in a circle and specify even points along the spiral
    float increment = (float)(2*GL_PI/numLines);
    for(angle = 0.0f; angle < (2.0f*GL_PI); angle += increment)
    {   
        // Calculate x and y position of the next vertex
        float x1 = radius_x*sin(angle);
        float y1 = radius_y*cos(angle);
        float z1 = count*disp;
        vPoints[count].SetVector(x1, y1, z1);
        count ++;
    }

    // Drawing only first two line segments for testing
    glBegin(GL_LINES);
        int pointPassLocation = glGetAttribLocation(programID, "Ppoint");
      // This is also considered as a vertex and a line is drawn from this point to  vPoints[1]
        glVertexAttrib3f(pointPassLocation, vPoints[0].GetX(), vPoints[0].GetY(), vPoints[0].GetZ());

        glVertex3d(vPoints[1].GetX(), vPoints[1].GetY(), vPoints[1].GetZ());
        glVertex3d(vPoints[2].GetX(), vPoints[2].GetY(), vPoints[2].GetZ());
        // Again this is also considered as a point and a line is drawn from vPoints[2] to this point.
        glVertexAttrib3f(pointPassLocation, vPoints[1].GetX(), vPoints[1].GetY(), vPoints[1].GetZ());

        glVertex3d(vPoints[2].GetX(), vPoints[2].GetY(), vPoints[2].GetZ());
        glVertex3d(vPoints[3].GetX(), vPoints[3].GetY(), vPoints[3].GetZ());
    glEnd();
}

因此,我想从vPoints [1]到vPoints [2]和vPoints [2]到vPoints [3]绘制2行而不是2行,考虑到两个glVertexAttrib3f语句作为顶点,我得到3行6个顶点。

我做得对吗,还是有更好的方式或其他方式来做到这一点。

0 个答案:

没有答案