Drawing round points using modern OpenGL
Asked Answered
L

2

15

I know how to draw round points using fixed pipeline. However I need to do the same using modern OpenGL. Is it possible, or should I use point sprites and textures?

For the interested.Here is how it is done with fixed pipeline:

        glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_NOTEQUAL, 0);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable( GL_POINT_SMOOTH );
    glPointSize( 8.0 );

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(myMatrix);
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(myAnotherMatrix);

    glBegin(GL_POINTS);
    glColor3f(1,1,1);

    glVertex3fv(position);


    glEnd();
    glDisable(GL_POINT_SMOOTH);
    glBlendFunc(GL_NONE, GL_NONE);
    glDisable(GL_BLEND);
Layout answered 24/6, 2013 at 11:52 Comment(2)
How did you draw round points using the fixed pipeline, though, if not using point sprites and textures? Dis you use glPointSize together with GL_POINT_SMOOTH? I don't think that has ever been a reliable method.Trek
There is a hack ;) See the update.Layout
U
7
Underplay answered 24/6, 2013 at 11:58 Comment(4)
In fact I have asked if it's possible without doing vodoo in the shaders...But +1 for the links :)Layout
In modern OpenGL nothing is possible without doing anything in the shaders, though. I'd rather call the weird behaviour of GL_POINT_SMOOTH voodoo.Trek
"voodoo in the shaders" -- not how you should think about it, and not just with respect to drawing circles, either. Better get with the program, cuz this is how it gets done from here on out. Fixed function is legacyLankester
while this answer can be useful , you should append more explanation in it because the extern links can be expired later and the answer become uselessCobelligerent
T
14

One way would be to draw point sprites with a circle-texture and a self-made alpha test in the fragment shader:

uniform sampler2D circle;

void main()
{
    if(texture(circle, gl_PointCoord).r < 0.5)
        discard;
    ...
}

But in fact you don't even need a texture for this, since a circle is a pretty well-defined mathematical concept. So just check the gl_PointCoord only, which says in which part of the [0,1] square representing the whole point your current fragment is:

vec2 coord = gl_PointCoord - vec2(0.5);  //from [0,1] to [-0.5,0.5]
if(length(coord) > 0.5)                  //outside of circle radius?
    discard;
Trek answered 24/6, 2013 at 12:8 Comment(5)
Why do I need self made alpha test?If the texture comes with alpha then hardware alpha blending should suffice. Shouldn't it?Layout
@MichaelIV But alpha testing is deprecated and not part of the core profile anymore. Maybe alpha blending suffices for you, but usually alpha testing would be preferred if possible, since it doesn't pollute the depth buffer with "invisible" fragments (and might also be slightly faster, since discard is an early out). And like said, the method without a texture would be better anyway.Trek
@MichaelIV Imagine you want to draw many many opaque but round particles (yay, confetti time!). When using alpha testing instead of just alpha blending, then there is absolutely no need to depth-sort your particles. If the particles are transparent anyway, though, you would still need to sort them and use alpha blending, so there might really not be a functionality improvement from the discard.Trek
@ChristianRau: Alpha-testing alone (without alpha-blending) will result in jagged edges.Repetition
@Repetition Right indeed, but there are solutions for this, too. Anything drawn to a discrete pixel grid will result in jagged edges. The solution for this is using multisampling, and together with alpha-to-coverage that will take care of this problem, too (you still need actual alpha, but no need for alpha blending and depth-sorting).Trek
U
7
Underplay answered 24/6, 2013 at 11:58 Comment(4)
In fact I have asked if it's possible without doing vodoo in the shaders...But +1 for the links :)Layout
In modern OpenGL nothing is possible without doing anything in the shaders, though. I'd rather call the weird behaviour of GL_POINT_SMOOTH voodoo.Trek
"voodoo in the shaders" -- not how you should think about it, and not just with respect to drawing circles, either. Better get with the program, cuz this is how it gets done from here on out. Fixed function is legacyLankester
while this answer can be useful , you should append more explanation in it because the extern links can be expired later and the answer become uselessCobelligerent

© 2022 - 2024 — McMap. All rights reserved.