Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: LINE_STIPPLE problem

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    15

    Red face LINE_STIPPLE problem

    I am drawing an array of lines.

    I have some lines that need to be stippled and the rest just regular lines.

    Im doing something like this (i just hand coded this obviously)

    while(thereAreLines)
    {

    glbegin(lines)

    //draw lines

    glend()

    glbegin

    glenable stipple

    //draw stipple lines

    gldisable stipple

    glend()
    }

    swapBuffer(my_openGL)


    If i comment out the enable stipple part then the program runs just fine just without my stippled lines....

    If i leave the enable stipple in there, then it draws everything just fine but crashes....

    Im using VC++ 6.0 over a remote desktop connection. Im assuming its crashing my laptop video card and not able to do much debugging. i won't have access to the main PC till after the new year. I can't seem to get any debug info. At the office it was giving me some kind of nVidia errors... I can't remember what the error was because i was working on other parts of the software at the time.

  2. #2
    Intern Newbie
    Join Date
    Nov 2012
    Posts
    33
    As far as I know, the problem is that you can't glEnable(GL_LINE_STIPPLE) inside of a glBegin()/glEnd() block. In immediate mode OpenGL doesn't like it much when you do anything except pass specific drawing commands.

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2012
    Posts
    15
    Quote Originally Posted by Aestivae View Post
    As far as I know, the problem is that you can't glEnable(GL_LINE_STIPPLE) inside of a glBegin()/glEnd() block. In immediate mode OpenGL doesn't like it much when you do anything except pass specific drawing commands.
    Besides that, is there a problem with calling the glBegin/glEnd say 6000 times? Otherwise, is there another way with doing the line stipple? I have thousands of lines to draw all in an array and a lot of them need to be stippled.

  4. #4
    Intern Newbie
    Join Date
    Nov 2012
    Posts
    33
    There's no reason you should call glBegin()/glEnd() that many times. OpenGL is a state machine at heart; when you call glBegin(GL_LINES) you go into immediate mode, where all subsequent calls are interpreted accordingly until glEnd(). In your case, if you must use immediate mode, you need to place your for loop inside glBegin() and glEnd().

    I don't have any definite reference to point you to, but generally it's not good to call any OpenGL functions more than a few hundred times per frame, since each call takes some CPU time and some bus transfer time. The point of OpenGL is hardware acceleration, so too many OpenGL function calls defeats the purpose, since it occupies the CPU.

    I'm bad at explaining in words, so I'll write code. You can do it somewhat like this (I'm assuming a lot of things, like orthographic projection). Unfortunately the closest thing I can write to C++ is C89, so please bear with me.

    Code :
    // Given line data in the following struct
    typedef struct {
        int x0;
        int y0;
        int x1;
        int y1;
        char stippled;    // Functions as a boolean, 1 true, 0 false
    } line;
    Code :
    // Given an array of lines "lines" and length "length"
    int i;
    glBegin(GL_LINES);
        for (i = 0; i < length; i++) {
            if (lines[i].stippled == 0) {
                glVertex2f(lines[i].x0, lines[i].y0);    // Each pair of vertices is interpreted as the beginning and end of a line,
                glVertex2f(lines[i].x1, lines[i].y1);    // so you can give OpenGL multiple pairs in each block
            }
        }
    glEnd();
     
    glEnable(GL_LINE_STIPPLE);
    // Do the glBegin()/glEnd() block + for loop again but testing for stipple flag
    glDisable(GL_LINE_STIPPLE);

    Of course, this way requires two semi-redundant passes, but since you can't enable stipple from inside a glBegin()/glEnd() block, it's pretty much the only immediate mode approach (assuming I guessed your structure correctly).

    However, a better way to do it would require restructuring your data. Separate the stippled lines from the regular lines, and make a primitive (probably float) array for each where (assuming lines from 0 to 1, 2 to 3, etc):

    Code :
    {x0, y0, x1, y1, x2, y2, x3, y3, ...}

    Then draw it with vertex arrays:

    Code :
    // Given float arrays "stippled" and "not_stippled" with lengths "length_s" and "length_n" respectively
    glEnableClientState(GL_VERTEX_ARRAY);
     
    glVertexPointer(2, GL_FLOAT, 0, not_stippled); // Where 2 is number of floats per vertex, GL_FLOAT is the type,  and 0 is the "stride" (how many to skip between vertices)
    glDrawArrays(GL_LINES, 0, length_n / 2); // Where GL_LINES is draw mode, 0 is start index, and length_s / 2 is how many vertices to draw
     
    glEnable(GL_LINE_STIPPLE);
    glVertexPointer(2, GL_FLOAT, 0, stippled);
    glDrawArrays(GL_LINES, 0, length_s / 2);
    glDisable(GL_LINE_STIPPLE);

    You could take a step further and use VBOs, but I've gone on long enough... I'll leave that to you to figure out, I suppose
    Last edited by Aestivae; 12-18-2012 at 10:20 AM. Reason: Repeated myself too often

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •