glLineStipple

BlitzMax Forums/OpenGL Module/glLineStipple

jkrankie(Posted 2009) [#1]
I'm finding glLineStipple really slows down my game. Is there any way to make it quicker? i've had some luck playing with the pattern parameter, but it's still slow. I'm using it with Minib3d, although i don't suppose that makes a huge difference...

This is an example of how i'm using it in my code, and theres also a working example here: http://www.blitzbasic.com/Community/posts.php?topic=82829#956103
glEnable(GL_LINE_STIPPLE)
gllinewidth(2)
gllinestipple(3,$0A0C0F)
glDisable(GL_TEXTURE_2D)	
glBegin(GL_LINES)
	glVertex3f(1,1,1)
	glVertex3f(0,0,0)
glEnd()
glEnable(GL_TEXTURE_2D)



ImaginaryHuman(Posted 2009) [#2]
Dunno. It's not a feature used very much I think, maybe it isn't accelerated as well. You might be better off trying a textured line and using a texture to store the line pattern.


jkrankie(Posted 2009) [#3]
that's what i figured. It's a shame it's not a bit faster as is, because it can look really cool.

Cheers
Charlie


ImaginaryHuman(Posted 2009) [#4]
With stipple you can only decide which pixels are/are not written, whereas with a textured line you can give alpha values to every pixel and also every pixel can have its own color.

Btw I was just thinking about you - I have been playing your Bullet Candy game in the past week or so, which you kindly awarded as a competition prize, and it's a lot of fun. Reminds me much of LLamatron on the Amiga which was also a robotron clone. Your game can get pretty intense which is good, makes it exciting. How is your sequel coming along? :-)


skidracer(Posted 2009) [#5]
To speed it up try drawing all stippled lines in a loop inside the glBegin glEnd block.


jkrankie(Posted 2009) [#6]
Ok, well that does improve things, but not by enough unfortunately. I'll resort to using textures, or failing that just lines.

@ImaginaryHuman, the sequel is coming on at a cracking pace, with the exception of not being able to use the nice stippled lines how i wanted ;). It really offers much more than the original, not just in looks but in gameplay too :) My main dev machine is at the repair shop at the moment, but once i get it back i'll make some new videos and put them on my website. I'm aiming for a mid to late summer release.

Cheers
Charlie


ImaginaryHuman(Posted 2009) [#7]
to make it even faster have you tried using vertex arrays? it's not too difficult to set up and I have seen a 200% or more speedup on drawing quads etc. You can use it to draw lots of lines all in one function call.


Uncle(Posted 2009) [#8]
Interesting Thread :)

@ jkrankie... do you have a routine for 3d textured lines? btw nice demo you did reworking the 3D line routine I posted. It was much nicer than my poor efforts.

@ ImaginaryHuman... I've been reading up on vertex arrays, but haven't found any bmax code showing it working? Do you have any examples :) Also do you know if the lines / polys are drawn in the order you populate the array or is it z sorted? Also do you know if vertex arrays are supported by all graphics cards, or do we need a fall back method for older cards?

[Edit] Found this tutorial... http://www.blitzbasic.com/Community/posts.php?topic=66184#739561

Sorry for lots of questions :)


ImaginaryHuman(Posted 2009) [#9]
Here's some code for textured lines..

With no vertex colors (handy if you don't need a tint and can use GL_REPLACE as the texture environment for added speed):
glEnableClientState(GL_VERTEX_ARRAY)								'Switch on use of vertex array
glEnableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch on use of texure coordinate array
glVertexPointer(2,GL_FLOAT,0,Varptr(VertexCoordArray[0]))				'Point to the vertex array
glTexCoordPointer(2,GL_FLOAT,0,Varptr(TextureCoordArray[0]))			'Point to the texture coordinate array
glDrawArrays(GL_LINES,0,NumberOfLines)								'Draw the lines!
glDisableClientState(GL_VERTEX_ARRAY)								'Switch off use of vertex array
glDisableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch off use of texture coordinate array


With flat-shaded vertex colors (needs GL_MODULATE texture environment):
glEnableClientState(GL_VERTEX_ARRAY)								'Switch on use of vertex array
glEnableClientState(GL_COLOR_ARRAY)								'Switch on use of color array
glEnableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch on use of texure coordinate array
glVertexPointer(2,GL_FLOAT,0,Varptr(VertexCoordArray[0]))				'Point to the vertex array
glColorPointer(4,GL_UNSIGNED_BYTE,0,Varptr(VertexColorArray[0]))		'Point to the color array
glTexCoordPointer(2,GL_FLOAT,0,Varptr(TextureCoordArray[0]))			'Point to the texture coordinate array
glDrawArrays(GL_LINES,0,NumberOfLines)								'Draw the lines!
glDisableClientState(GL_VERTEX_ARRAY)								'Switch off use of vertex array
glDisableClientState(GL_COLOR_ARRAY)								'Switch off use of color array
glDisableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch off use of texture coordinate array


You basically just need to pass it some arrays populated with data. Vertexes must be floats - and here I used just X and Y per vertex. Vertex color array must be 4 unsigned bytes per vertex, like stored in an integer $RRGGBBAA. The texture coord array must also be 2 floats per vertex - X and Y, which is in texture-space coordinates, which ranges from 0 (top edge or left edge of texture) to 1.0 (right edge or bottom edge of texture). Calculate all your colors and texture coords ahead of time then you only need to move the lines around by updating the vertex coord array.

This requires the standard v1.1 of OpenGL which comes with BlitzMax, it doesn't need any extensions or higher versions. I have no idea how compatible it is with graphics cards but since it was in OpenGL 1.1 I expect it is quite widely supported.

The lines will be drawn in the order they appear in the array, and you must have two sets of coordinates for each line since it isn't a line loop, ie startx,starty,endx,endy. If you were doing joined lines you'd set it up a bit differently and be more efficient.

If you wanted to do some kind of Z sorting, you'd need to use glDrawElements or similar, and pass it `index` array(s) which just list the sort order for the lines.

Doing this for quads and traingles and all that is similar .... here's some textured smooth-shaded per-vertex-color quads - since you have to have an X,Y pair of vertex coordinates for each corner of each quad, you can warp the quads somewhat, but they would warp better using a triangle fan or triangle strip using a balanced center point:

glEnableClientState(GL_VERTEX_ARRAY)								'Switch on use of vertex array
glEnableClientState(GL_COLOR_ARRAY)								'Switch on use of color array
glEnableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch on use of texure coordinate array
glVertexPointer(2,GL_FLOAT,0,Varptr(VertexCoordArray[0]))				'Point to the vertex array
glColorPointer(4,GL_UNSIGNED_BYTE,0,Varptr(VertexColorArray[0]))		'Point to the color array
glTexCoordPointer(2,GL_FLOAT,0,Varptr(TextureCoordArray[0]))			'Point to the texture coordinate array
glDrawArrays(GL_QUADS,0,NumberOfQuads)							'Draw the quads!
glDisableClientState(GL_VERTEX_ARRAY)								'Switch off use of vertex array
glDisableClientState(GL_COLOR_ARRAY)								'Switch off use of color array
glDisableClientState(GL_TEXTURE_COORD_ARRAY)					'Switch off use of texture coordinate array



ImaginaryHuman(Posted 2009) [#10]
I can confirm that glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE) gives between a 2-5% speedup compared to the standard glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)

ie if you do not need per-vertex colors or a tint, (as if all vertices modulate with white), then setting the texture environment to GL_REPLACE (ie don't multiply each pixel's texture value by a vertex color value), it saves about 5%.

This is in debug mode - didn't test in release mode yet. Tested drawing 1 million untextured rectangles 50x50 at random positions.

When I tested with texturing on, the percentage was about 3%