HYRY
HYRY

Reputation: 97331

Draw circles with center out of view in OpenGL

I am using vispy to draw many circles, here is the reference program:

http://vispy.org/examples/basics/gloo/display_points.html

When the center of the circle is out of the range (-1, -1) - (1, 1), the whole cirlce disappeared.

Here is a simple example:

from vispy import gloo
from vispy import app
import numpy as np

VERT_SHADER = """
attribute vec3  a_position;

void main (void) {
    /*the square will disappeared when change 1.0 to 1.01*/
    gl_Position = vec4(1.0, 0, 0, 1); 
    gl_PointSize = 100;
}
"""

FRAG_SHADER = """
void main() {
    gl_FragColor = vec4(0, 0, 0, 1);
}
"""

class Canvas(app.Canvas):

    def __init__(self):
        app.Canvas.__init__(self, keys='interactive')

    def on_initialize(self, event):
        self.program = gloo.Program(VERT_SHADER, FRAG_SHADER)
        self.program["a_position"] = np.zeros((10, 3))
        gloo.set_state(clear_color='white', blend=True,
                       blend_func=('src_alpha', 'one_minus_src_alpha'))

    def on_resize(self, event):
        w, h = event.size
        s = min(w, h)
        gloo.set_viewport(0, 0, s, s)

    def on_draw(self, event):
        gloo.clear(color=True, depth=True)
        self.program.draw('points')


if __name__ == '__main__':
    c = Canvas()
    c.show()
    app.run()

The square will disappeared when the center is (1.01, 0):

enter image description here

Upvotes: 0

Views: 667

Answers (2)

Fatih
Fatih

Reputation: 11

Code for using the example but with a single red circle in the center:


    from vispy import gloo
    from vispy import app
    import numpy as np

    # Create vetices
    n = 1
    #f_position = 0.25 * np.random.randn(n, 2).astype(np.float32)
    v_position = np.float32([[0,0]])
    #v_color = np.random.uniform(0, 1, (n, 3)).astype(np.float32)
    v_color = np.float32([[1,0,0]]) #red
    #v_size = np.random.uniform(2, 12, (n, 1)).astype(np.float32)
    v_size = np.float32([[10]])

    VERT_SHADER = """
    attribute vec3  a_position;
    attribute vec3  a_color;
    attribute float a_size;

    varying vec4 v_fg_color;
    varying vec4 v_bg_color;
    varying float v_radius;
    varying float v_linewidth;
    varying float v_antialias;

    void main (void) {
        v_radius = a_size;
        v_linewidth = 1.0;
        v_antialias = 1.0;
        v_fg_color  = vec4(0.0,0.0,0.0,0.5);
        v_bg_color  = vec4(a_color,    1.0);

        gl_Position = vec4(a_position, 1.0);
        gl_PointSize = 2.0*(v_radius + v_linewidth + 1.5*v_antialias);
    }
    """

    FRAG_SHADER = """
    #version 120

    varying vec4 v_fg_color;
    varying vec4 v_bg_color;
    varying float v_radius;
    varying float v_linewidth;
    varying float v_antialias;
    void main()
    {
        float size = 2.0*(v_radius + v_linewidth + 1.5*v_antialias);
        float t = v_linewidth/2.0-v_antialias;
        float r = length((gl_PointCoord.xy - vec2(0.5,0.5))*size);
        float d = abs(r - v_radius) - t;
        if( d  v_radius)
                gl_FragColor = vec4(v_fg_color.rgb, alpha*v_fg_color.a);
            else
                gl_FragColor = mix(v_bg_color, v_fg_color, alpha);
        }
    }
    """


    class Canvas(app.Canvas):

        def __init__(self):
            app.Canvas.__init__(self, keys='interactive')

        def on_initialize(self, event):
            self.program = gloo.Program(VERT_SHADER, FRAG_SHADER)
            # Set uniform and attribute
            self.program['a_color'] = gloo.VertexBuffer(v_color)
            self.program['a_position'] = gloo.VertexBuffer(v_position)
            self.program['a_size'] = gloo.VertexBuffer(v_size)
            gloo.set_state(clear_color='white', blend=True,
                           blend_func=('src_alpha', 'one_minus_src_alpha'))

        def on_resize(self, event):
            gloo.set_viewport(0, 0, *event.size)

        def on_draw(self, event):
            gloo.clear(color=True, depth=True)
            self.program.draw('points')


    if __name__ == '__main__':
        c = Canvas()
        c.show()
        app.run()

Upvotes: 0

ratchet freak
ratchet freak

Reputation: 48216

That is normal behavior from openGL, the rasterizer is allowed to skip a primitive if it is outside the view box and points are only defined by the center point regardless of gl_PointSize.

If you want to ensure the "circle" is drawn then you should render little quads.

Upvotes: 2

Related Questions