To who doesn't develop videogame applications

Few weeks ago I posted to ask Which type of Video Card accelerate glLineStipple function.
None answered me. Someone give me appreciated suggestions to substitute this function in that cards(nvidia) didn’t implement it.

I discovered this:

ALL Nvidia CARDs (Consumer and Professional Quadro series!) DON’T accelerate this function.
ATI Radeon 7500 Ati Radeon 8500, FireGL2/4 (IBM chip), ALL wildcat Videocard series accelerate this function.

ALL CAD software use line stippling and then all CAD users that use a project with stippled lines can note terrible performance with Nvidia CArds.

With Specviewperf, enabling -lp (-linestipple) option, all can note the difference of performance between Nvidia and other OpenGL cards.

I know that this, for Videogame programmers is not felt as a ploblem, but the others? is it possible that is this only my problem?

Developping an OpenGL engine I cannot ignore Nvidia (that onestly has very good drivers) then…

Does Nvidia resolve this problem in their Future Chips ?(because I think this is not a driver problem but Hardware).

Does Nvidia feel this as a problem to solve?

Thank you

ND

P.s.

Someone tried to suggest using 1D Texture instead, but in my experience I’ve seen it is not usable to substitute glLineStipple function.

I’m a little surprised. nVidia claims that polygon stippling is done in hardware using texturing (somehow). Line stippling is not mentioned, but I would think that it would require only a subset of the hardware/software to do line stippling as opposed to polygon stippling.

Anyway, only nVidia can really answer this question… (?)

I’m not very experienced with stippling, but wouldn’t it be possible to “(un)project” the line so that it always lies on the screen plane, and then use texturing to simulate stippling? You would need to upload a 16-pixel 1D texture of alpha values (0 and 1), and use alpha-testing to discard the parts of the line which have alpha values of 0. Also, you would need to calculate the (on-screen) length of the line which is used for the second texture coordinate (the first is zero, the second is the length of the line), to avoid “stretching” of the stipple pattern.

This method should be possible to implement in the drivers, I think, and should not really need any additional hardware.

[This message has been edited by marcus256 (edited 02-07-2002).]

I’m not very experienced with stippling, but wouldn’t it be possible to “(un)project” the line so that it always lies on the screen plane, and then use texturing to simulate stippling? You would need to upload a 16-pixel 1D texture of alpha values (0 and 1), and use alpha-testing to discard the parts of the line which have alpha values of 0. Also, you would need to calculate the (on-screen) length of the line which is used for the second texture coordinate (the first is zero, the second is the length of the line), to avoid “stretching” of the stipple pattern.

Right!
it’s what I must do to draw a stippled line,
but:

  1. trasforming vertex into Screen coordiantes

  2. lenght calculations

too many time lost.

I think that this is what Nvidia Drivers done and infact It is very slow.

I think you can play with 1D textures and mipmaps with GL_NEAREST_MIPMAP_NEAREST (do not filter with LINEAR).

I’ve not been thinking it enough to say if it would give good results, but IMO it’s worth some tests.

using 1D texture there is a simple problem:

every vertex must be associated to a TexCoordinate. These TexCoordinates cannot be generated from the glTexGen automatically because they are dependent from the lenghts of the projected segments. Calculation of these TexCoordinates takes too many resources, then this method is not good for performance.

Anyway, texgen would not work correctly IMO since you could “only” define a coordinate in 3D coordinates, and it is a great problem since you don’t know what cooridnates will have your vertices.

But that’s not the method I meant.
I was thinking of using something like :
glTexCoord1f(0.0f);
glVertex3f(…);
glTexCoord1f(1000.0f);
glVertex3f(…);

and then let the mipmaps work for you.
The hard part is to configure the mipmaps to do what you want.

Originally posted by ND:
[b]using 1D texture there is a simple problem:

every vertex must be associated to a TexCoordinate. These TexCoordinates cannot be generated from the glTexGen automatically because they are dependent from the lenghts of the projected segments. Calculation of these TexCoordinates takes too many resources, then this method is not good for performance.

[/b]

You could easily find the projected length and use that to generate a texcoord in a short vertex program, which shouldn’t cause a performance problem if you have a GF3 or later.

– Zeno

Yes it could work, but it would not be portable.
I haven’t benchmarked it yet. Maybe it’s slow in fact…

ND: I just implemented “my” technique and it works pretty good !
You need to initialize a merely big texture, eg texture size might be at least as big as screen (or window) width or height I think.

/* Init */
register i, j;
static GLuint texture;
static const int texture_size = 1024;
static GLubyte texture_data[texture_size];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
for
(i = 0 ; i < texture_size ; i++)
{
texture_data[i] = i%4?0xFF:0x00; // 75% line is opaque, 25% invisible
}
for
(i = 0, j = texture_size ; j > 0 ; j /= 2, i++)
{
glTexImage1D(GL_TEXTURE_1D, i, GL_INTENSITY, j, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &texture_data[0]);
}

/* Usage */
glEnable(GL_TEXTURE_1D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_EQUAL, 1.0f);
glBegin(GL_LINE_LOOP);
glTexCoord1f(0.0f);
glVertex2f(-1.5f, 1.5f);
glTexCoord1f(1.0f);
glVertex2f( 1.5f, 1.5f);
glTexCoord1f(0.0f);
glVertex2f( 1.5f,-1.5f);
glTexCoord1f(1.0f);
glVertex2f(-1.5f,-1.5f);
glEnd();
glDisable(GL_TEXTURE_1D);

You can tweak the ‘texture_size’ parameter to see what happens (of course, set it as a power of 2).

This technique has the good point not to bothering textures too much because you can define a texutre 2D and just enable/disbale it with glEnable(GL_TEXTURE_2D) : there’s no need to bind the 2D texture after using the 1D texture.

Note that I use alpha test because it is faster than blending.

I might say something COMPLETELY stupid here but would there be a way to use the texture matrix to counter-effect the distortion due to the projection ?

I suppose you’d need to set it up for each line so that may not be practical at all…

On the other hand, that may be total BS !

Regards.

Eric

vincoof,
I have tried your code tonight.
your solution is nice but quality result is very different from using gllinestipple. How you know this technic is able to change stippling when “order of dimension” of the the lenght of segment changes, instead stippling must change when the lenght of segment changes.

Zeno maybe with opengl 2.0 but I must avoid this “card dependent” technics (and we must demonstrate it works).

Eric using matrix could accelerate a distortion processing but the problem remains the value of distorsion.

[This message has been edited by ND (edited 02-08-2002).]

I’m writing a CAD and mine solution was :

Build a 2D texture with a white checkerboard with alpha :

Xo
oX (where X is white, and o is alpha = 0)

Create it with GL_NEAREST filter…

Then I write my selection object (a quad usually, but it should work with everything else) in Polygon mode GL_LINE, leaving the texture enabled.
And I use GL_REPEAT as texture parameter instead of GL_CLAMP.
Then I use the exact vertex coordinate also for texture coordinates (so it repeats the texture on the lines instead of stretchign the texture).

So to draw a sel quad from -10,-10 to 10,10 i use :

glTexCoord2f(-10,-10);
glVertex3f(-10,-10,0);

glTexCoord2f(10,-10);
glVertex3f(10,-10,0);

glTexCoord2f(10,10);
glVertex3f(10,10,0);

glTexCoord2f(-10,10);
glVertex3f(-10,10,0);

That’s fast and easy.

just my 2 euro cents.

rIO.sK http://www.spinningkids.org/rio

I think it won’t give good results. sorry.
This line stipple rendering won’t be credible unless you compute le length of the lines (too slow).
You could try to set texture coordinate generation to eye_linear to help a bit, but it will only work for horizontal and vertical lines. (on diagonal lines, obviously the line will be either fully opaque or fully invisible).

Hmmm. I was just thinking that Eric’s texture matrix trick associated with 1D texture and eye_linear… hmm…

You can definitely undo perspective correction via projective texturing. Pass in (s,q) = (s*w, w). You’d need a vertex program do do this efficiently, though, I think. No way to rig the texture matrix to give you this automatically (that I can think of).

Cass

cass: your method seems ok, but not portable.

ND: I’ve played a bit with texture coordinate generation and texture 1D on eye_linear and I can get working horizontal stipple lines without specifying texture coordinates (eg never call glTexCoord) which is pretty handy.
It only works on horizontal lines, (thus making vertical lines awful) but I have an idea for the vertical axis that I’ll try after the WeekEnd.
I hope that you understood I meant “one axis” by “horizontal axis”. Of course I can make it work for the vertical axis, but horizontal lines will look awful.

vincoof,
in the past i tried to use gentex, i tried also to use stencil buffer , but only one direction has been satisfied (with the stencil buffer two directions).

hmmm. I’m getting v.good results for one direction, but can’t get them good enough for bi-directional stipple.
I’m sorry but I think I’m not going to spend more time on it, unless I have new ideas…