2014-11-24 368 views
4

我想渲染一個動態變化半徑的實心圓,它們的二維座標存儲在一個VBO中。到目前爲止,我使用的是GL_POINT_SMOOTH,但現在已經轉向OpenGL 4.0,此選項不再可用。我已經看到類似的問題here,但這並不完全符合我的需要,因爲該示例中圓圈的中心在片段着色器中被硬編碼。我將如何做到這一點?渲染現代OpenGL中的大圓點

此刻,我的頂點着色器看起來是這樣的:

#version 400 

layout(location=0) in vec2 in_Position; 
layout(location=1) in vec4 in_Color; 
out vec4 ex_Color; 

uniform vec4 bounds; 

void main(void){ 
    float x = -1+2/(bounds.y-bounds.x)*(in_Position.x-bounds.x); 
    float y = -1+2/(bounds.w-bounds.z)*(in_Position.y-bounds.z); 
    gl_Position = vec4(x,y,0,1); 
    ex_Color = in_Color; 
} 

我的片段着色器看起來是這樣的:

#version 400 

in vec4 ex_Color; 
out vec4 out_Color; 

void main(void){ 
    out_Color = ex_Color; 
} 

有了這些着色器,我越來越多百分點。

回答

11

「現代」 的畫點的方式是這樣的:

  1. 啓用程序點大小模式:

    glEnable(GL_PROGRAM_POINT_SIZE); 
    
  2. 渲染GL_POINTS原始模式的頂點。

  3. 在頂點着色器,設置內置變量gl_PointSize個別點所需的大小:

    gl_Position = ...; 
    gl_PointSize = ...; 
    

    用於此點大小的值可以是恆定的,如果它總是一樣的,如果您希望能夠在繪製調用之間進行調整,或者如果點大小每點可變,則使用頂點屬性。

  4. 這會爲由gl_PointSize的值指定的大小的方形點生成碎片。在片段着色器中,可以使用內置的gl_PointCoord變量,該變量爲您提供點內片段的相對座標。它與紋理座標非常類似,在每個方向上提供[0,1]範圍。

    例如,如果你想紋理點,這是粒子系統是非常有用的,片段着色器代碼可能包含:

    outColor = texture(particleTex, gl_PointCoord); 
    

    或者,如果你想圓點,可以基於一個圓外丟棄一切距離中心的距離:

    vec2 circCoord = 2.0 * gl_PointCoord - 1.0; 
    if (dot(circCoord, circCoord) > 1.0) { 
        discard; 
    } 
    

    或者類似的,你可以使圓圈外的碎片透明,並且啓用混合,以得到圓點。

請注意,支持點大小的範圍取決於實現。您可以查詢可用範圍:

GLfloat sizeRange[2] = {0.0f}; 
glGetFloatv(GL_POINT_SIZE_RANGE, sizeRange); 
+0

完美!我的混淆源於對片段着色器缺乏瞭解。現在我明白這是如何工作的!非常感謝你。 – jaideep777 2014-11-24 13:25:42