Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (542)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (604)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LWJGL Antialiased lines  (Read 4104 times)
0 Members and 1 Guest are viewing this topic.
Offline roland
« Posted 2013-10-04 13:18:53 »

Hi, I am making a minimap for my game. (See top right corner of below image)



Everything is perfect, except for the jagged outline. I draw lines around the edges of the map, but they aren't smooth.

I've played around with the following settings:
GL11.glEnable(GL11.GL_LINE_SMOOTH);
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

and they just make the lines look worse. Searching on google, I came across something called multisampling, I'm not sure if this is what I want though.

Note, this is rendering to a seperate texture. I don't want full-scene antialiasing, just for the lines that make up the background of the minimap.

Can anyone help me?
Thanks,
Roland
Offline Mac70
« Reply #1 - Posted 2013-10-04 13:51:52 »

You are not using 3d here, so
1  
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
is useless.

Try adding this:
1  
2  
GL11.glEnable(GL_BLEND);
GL11.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Check out my Devblog! Smiley
Offline Danny02
« Reply #2 - Posted 2013-10-04 14:39:38 »

@Mac70
Blending doesn't help with geometry like lines.

@roland

when you only want to activate multisampling aka. anti-aliasing for some geometrie like your minimap, you can do it like this.

1. create a multisamples RenderBuffer
2. render to that buffer
3. copy/blit the result to the screen or texture which you want to render

Code should look like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
// creating a multisampled renderbuffer
int samples = 4;//you can query the max supported samples by glGetIntegerv(GL_MAX_SAMPLES, out, 0);

int[] id = new int[1];
glGenRenderbuffers(1, i, 0);
glBindRenderbuffer(GL2ES2.GL_RENDERBUFFER, id[0]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);

//blitting the buffer to the screen or a texture
 //bind the renderbuffer as colorbuffer to a FBO
  glBindFramebuffer(GL_READ_FRAMEBUFFER, id);//bind this FBO as read buffer
  //now bind the default Framebuffer(0: the screen) or a FBO with the texture
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id2);

  //and as a last step copy the content of the multisampled renderbuffer
  glBlitFramebuffer(0, 0, width, height, 0, 0, dstWidth, dstHeight,  GL_COLOR_BUFFER_BIT, GL_LINEAR);


In your case I would do the rendering like this.
Clear the multisampled renderbuffer to some semi transparent black(like in your screenshot)
Render the minimap into it
Copy the renderbuffer into a texture(this step is needed to resolve the multisampling)
render the texture into the top right corner of your screen.

The thing is if you wouldn't need a transparent minimap background, you could directly copy the minimap onto the screen.


ps:
Some googling unearthed this nice trick: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #3 - Posted 2013-10-04 15:48:50 »

Anti-aliased lines is actually pretty challenging in OpenGL.

You could use GL_LINES and line smoothing. Unfortunately, it won't look the same across all platforms. Some will use anti-aliasing, and others will not.

If you want truly consistent smooth lines in OpenGL, you have some options:

1. Use software rendering to draw the lines to a texture. If you are only targeting desktop, you can make use of Java2D to do the rasterization for you. Basically the step is just to render your Graphics to a BufferedImage, and then copy the pixels to a ByteBuffer and upload them to a GL texture.

https://github.com/mattdesl/lwjgl-basics/wiki/LibGDX-&-Java2D

This is really slow, and not something you should be doing every frame.


2. Use multi-sampling like Danny02 said.

3. Use triangles and calculate the anti-aliasing in a shader. This sounds a little daunting, but it just requires a little bit of vector math and a decent grasp of shaders. It also produces really high-quality lines, and gives way to other effects like stippling patterns, outer glows, and smooth color interpolation.

You can also achieve this without a shader, just by using a lookup texture to create a blurry line edge. The problem with this is that the anti-aliasing isn't as accurate and doesn't scale.

Both approaches are discussed here:
http://www.java-gaming.org/topics/circular-health-bar/29791/msg/274139/view.html#msg274139

(There is code at the end of the Swiper tutorial that should give you smooth lines.)

For each point in your line, you simply 'extrude' it along the perpendicular depending on the line thickness. Using triangle strips, you only need 2 vertices for every point in your line. A more complex approach would be to use a miter join, with one technique described here:
https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader#23286000001269127

More advanced still would be to support different types of joins.
http://artgrammer.blogspot.ca/search/label/opengl

4. Another solution which might work for you case is to apply FXAA or another AA technique done in the fragment shader. Since you are rendering your mini-map to a small texture, the impact shouldn't be too significant.

Offline Nate

« JGO Bitwise Duke »


Medals: 159
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #4 - Posted 2013-10-04 20:24:46 »

I made a Soldat CTF map once, called Crusade. Smiley

Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #5 - Posted 2013-10-05 00:51:10 »

LWJGL's Display.create() has an overloaded version that takes a PixelFormat. One of the PixelFormat's constructors allows you to turn on anti-aliasing and set how many samples you want.

Here is an example using 4 samples:
1  
2  
// parameters: 0 alpha bits, 8 depth bits, 0 stencil bits, 4 samples
Display.create(new PixelFormat(0, 8, 0, 4));

Offline roland
« Reply #6 - Posted 2013-10-05 11:38:34 »

Thanks for the replies everyone!

I made a Soldat CTF map once, called Crusade. Smiley
Smiley

LWJGL's Display.create() has an overloaded version that takes a PixelFormat. One of the PixelFormat's constructors allows you to turn on anti-aliasing and set how many samples you want.

Here is an example using 4 samples:
1  
2  
// parameters: 0 alpha bits, 8 depth bits, 0 stencil bits, 4 samples
Display.create(new PixelFormat(0, 8, 0, 4));

Is there a way I can check support for this? GLContext etc. Doesn't seem to work until the display is actually created.

@Mac70
Blending doesn't help with geometry like lines.

@roland

when you only want to activate multisampling aka. anti-aliasing for some geometrie like your minimap, you can do it like this.

1. create a multisamples RenderBuffer
2. render to that buffer
3. copy/blit the result to the screen or texture which you want to render

Code should look like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
// creating a multisampled renderbuffer
int samples = 4;//you can query the max supported samples by glGetIntegerv(GL_MAX_SAMPLES, out, 0);

int[] id = new int[1];
glGenRenderbuffers(1, i, 0);
glBindRenderbuffer(GL2ES2.GL_RENDERBUFFER, id[0]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);

//blitting the buffer to the screen or a texture
 //bind the renderbuffer as colorbuffer to a FBO
  glBindFramebuffer(GL_READ_FRAMEBUFFER, id);//bind this FBO as read buffer
  //now bind the default Framebuffer(0: the screen) or a FBO with the texture
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id2);

  //and as a last step copy the content of the multisampled renderbuffer
  glBlitFramebuffer(0, 0, width, height, 0, 0, dstWidth, dstHeight,  GL_COLOR_BUFFER_BIT, GL_LINEAR);


In your case I would do the rendering like this.
Clear the multisampled renderbuffer to some semi transparent black(like in your screenshot)
Render the minimap into it
Copy the renderbuffer into a texture(this step is needed to resolve the multisampling)
render the texture into the top right corner of your screen.

The thing is if you wouldn't need a transparent minimap background, you could directly copy the minimap onto the screen.


ps:
Some googling unearthed this nice trick: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html
Will creating a multisampled renderbuffer simply achieve the same effect as using full screen antialiasing overriding the default Display.create()? (apart from being faster due to only being applied to the minimap) If so, unfortunately the results aren't too great. I will need to go for a more complicated technique.

Anti-aliased lines is actually pretty challenging in OpenGL.

You could use GL_LINES and line smoothing. Unfortunately, it won't look the same across all platforms. Some will use anti-aliasing, and others will not.

If you want truly consistent smooth lines in OpenGL, you have some options:

1. Use software rendering to draw the lines to a texture. If you are only targeting desktop, you can make use of Java2D to do the rasterization for you. Basically the step is just to render your Graphics to a BufferedImage, and then copy the pixels to a ByteBuffer and upload them to a GL texture.

https://github.com/mattdesl/lwjgl-basics/wiki/LibGDX-&-Java2D

This is really slow, and not something you should be doing every frame.


2. Use multi-sampling like Danny02 said.

3. Use triangles and calculate the anti-aliasing in a shader. This sounds a little daunting, but it just requires a little bit of vector math and a decent grasp of shaders. It also produces really high-quality lines, and gives way to other effects like stippling patterns, outer glows, and smooth color interpolation.

You can also achieve this without a shader, just by using a lookup texture to create a blurry line edge. The problem with this is that the anti-aliasing isn't as accurate and doesn't scale.

Both approaches are discussed here:
http://www.java-gaming.org/topics/circular-health-bar/29791/msg/274139/view.html#msg274139

(There is code at the end of the Swiper tutorial that should give you smooth lines.)

For each point in your line, you simply 'extrude' it along the perpendicular depending on the line thickness. Using triangle strips, you only need 2 vertices for every point in your line. A more complex approach would be to use a miter join, with one technique described here:
https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader#23286000001269127

More advanced still would be to support different types of joins.
http://artgrammer.blogspot.ca/search/label/opengl

4. Another solution which might work for you case is to apply FXAA or another AA technique done in the fragment shader. Since you are rendering your mini-map to a small texture, the impact shouldn't be too significant.
Thanks, I'll have a look  Smiley

Offline Danny02
« Reply #7 - Posted 2013-10-05 11:51:04 »

Will creating a multisampled renderbuffer simply achieve the same effect as using full screen antialiasing overriding the default Display.create()? (apart from being faster due to only being applied to the minimap) If so, unfortunately the results aren't too great. I will need to go for a more complicated technique.

Display.create creates a standard renderbuffer with or without anti-aliasing, your renderbuffer is totally independent from the default renderbuffer. If 4,8 or even 16 MSAA isn't enough you could also do super-sampling. Let's say your mini-map is 150x75 pixel, you could create a renderbuffer twice the size (300x150). The blitting operation will then scale down the image with linear interpolation, which would give you even more quality.
Offline lukasz1985

Senior Newbie





« Reply #8 - Posted 2013-10-05 12:45:28 »

I would help if this wasn't another stupid killing-shooting game.
Offline nerb
« Reply #9 - Posted 2013-10-05 15:24:03 »

I would help if this wasn't another stupid killing-shooting game.

Great attitude and valuable post. Thanks very much for your contribution.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd

« JGO Bitwise Duke »


Medals: 366
Projects: 2
Exp: 8 years



« Reply #10 - Posted 2013-10-06 12:43:22 »

If you have any shader experience it's pretty easy to implement your own version of line smoothing by simply modifying alpha based on distance from the mathematical line.

Myomyomyo.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Elsealabs (11 views)
2014-12-28 10:39:27

CopyableCougar4 (17 views)
2014-12-28 02:10:29

BurntPizza (21 views)
2014-12-27 22:38:51

Mr.CodeIt (14 views)
2014-12-27 04:03:04

TheDudeFromCI (19 views)
2014-12-27 02:14:49

Mr.CodeIt (26 views)
2014-12-23 03:34:11

rwatson462 (57 views)
2014-12-15 09:26:44

Mr.CodeIt (47 views)
2014-12-14 19:50:38

BurntPizza (94 views)
2014-12-09 22:41:13

BurntPizza (115 views)
2014-12-08 04:46:31
How do I start Java Game Development?
by gouessej
2014-12-27 19:41:21

Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!