GLBasic forum

Main forum => GLBasic - en => Topic started by: Wampus on 2010-Sep-17

Title: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-17
I've attached a small proggy with sourcecode. All it does is use Polyvector to draw tiles side by side, then scales them in and out.

At 1:1 ratio tiles are seemless. However, when not at 1:1 there are often clear divisions between the tiles. How can this be prevented?

(http://i904.photobucket.com/albums/ac242/wheeethefibble/webpics/example-division.jpg)

[attachment deleted by admin]
Title: Re: Seemless scaling with Polyvector
Post by: Scott_AW on 2010-Sep-17
Replace that inner loop with this one.

I turned into a triangle strip, put the start and end outisde the loop and added POLYNEWSTRIP.  This should be faster in general.  But the fix turned out to be simple, add 1 to your X start of texture and subtract 1 from your Y end of texture.

Code (glbasic) Select

    STARTPOLY 1,2
WHILE sprtemp > 0
        POLYNEWSTRIP

POLYVECTOR xstep, ystep+(ydim*zoomsize),  1, ydim-1, RGB (255, 255, 255)
POLYVECTOR xstep+(xdim*zoomsize), ystep+(ydim*zoomsize), xdim, ydim-1, RGB(255, 255, 255)
POLYVECTOR xstep+(xdim*zoomsize),  ystep, xdim,  0, RGB(255, 255, 255)
POLYVECTOR xstep, ystep,  1,  0, RGB(255, 255, 255)
POLYVECTOR xstep, ystep+(ydim*zoomsize),  1, ydim-1, RGB (255, 255, 255)

DEC sprtemp

INC xstep, (zoomsize * xdim)
INC xc
IF xc = horsprites

xstep = xmid-(gridxmid * zoomsize)
xc = 0
INC ystep, (zoomsize * ydim)
INC yc
IF yc = 11

xstep = xmid-(gridxmid * zoomsize)-1
ystep = ymid-(gridymid * zoomsize)-1
xc = 0
yx = 0

ENDIF

ENDIF

WEND
    ENDPOLY

Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-17
Scott_AQ you have saved me much head scratching yet again!  :happy: Your programming skills obviously far exceed mine but if there is anything I can ever do to help you out I'd only be too happy.

I have absolutely no idea why adding one and subtracting one from the x start and y end should work like this but the result is perfect. Polyvector is awesome but stuff like that confuses me. Until recently I hadn't even looked at Polyvector or the 3D functions of GLBasic. Anyway, I'm very slowly emerging from the darkened cave of the 16-bit era - the last time I tried games programming.

Thanks for suggesting Polynewstrip. I guess it would be faster if the same texture was used for each tile. Ultimately I'm aiming to create a map display routine that will scale and scroll in the classic iPhone manner so unless checking which tiles are identical and drawing all of them as a bunch is worth it to save CPU I'll probably be using standard FAN mode.
Title: Re: Seemless scaling with Polyvector
Post by: Scott_AW on 2010-Sep-17
Actually I had to figure it out with good old 'trial and error'.  Hasn't failed, just frustrated.

Another tricky thing with polyvector is how your order your vectors.

However if you have a large image as a tile map, you can position your texture points according to the tile's position.

For example, lets say you have a tilemap of 32x32 tiles.  To grab a new tile you'll just have to adjust the start and end of your texture points.

startx = 1+tile * 32
endx = -1+tile * 32

With the offset of course, this way one image for one map, much faster then many sprites and individual polyvector calls.
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-17
Well my 'trial and error' was leading me to create tiles that over-ran their borders. Terrible idea! So I'm glad you found that fix.

Its a simple thing to design a tilemap drawing routine to check the display area for identical tiles rather than sequentially draw each tile individually from left to right & top to bottom. I'll be doing that from now on since Polyvector is essential for ultra-smooth scrolling involving fractions of pixels. I've experimented with forcing to absolute pixels and it looks untidy by comparison.
Title: Re: Seemless scaling with Polyvector
Post by: Scott_AW on 2010-Sep-17
The only drawback I found if that if you use them and the computer is a POS with out-of-date opengl drivers and it's forced to do software, then its runs horribly slow.
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-21
I should mention that, through writing a testing app specifically for the purpose of testing Polyvector to draw tiles under many varied conditions on a 3rd generation iDevice, I've found out quite a lot about it. Summary: -


I will never use the various DRAWSPRITE commands again for anything where speed is critical!
Title: Re: Seemless scaling with Polyvector
Post by: Slydog on 2010-Sep-21
Using the 'STRIP' method, how often did you lift your pen using the 'POLYNEWSTRIP' command?
Each sprite? 
Each row? 
Never (drew all sprites with one connecting series of 'POLYVECTORS')?

If you did it per sprite, I wonder if your texture alignment problem could be fixed by never using 'POLYNEWSTRIP'?
Although, the code to draw one connecting series of polygons could be tricky!

Just curious.
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-22
Good idea about trying without using POLYNEWSTRIP.

Previously I was lifting the pen for every sprite. So, I changed it so that POLYNEWSTRIP was called every row instead to see what would happen. It didn't make any difference so I tried not using POLYNEWSTRIP at all. Unfortunately vertical and horizontal seams were still showing between each sprite.

The original problem stems from (necessarily for some purposes) using x,y screen co-ords that are often in fractions of a pixel instead of just integers. I don't mind using sprites with an extra pixel border if I want to do that. It seems an ok price to pay and I could write a little routine to automate the process of adding those borders for me.
Title: Re: Seemless scaling with Polyvector
Post by: Scott_AW on 2010-Sep-22
Interesting to hear about the alphamode, I'll have to test that out.

NEWPOLYSTRIP would be better for something like particle systems, or handling a bunch of objects in that share the same graphics.
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-22
I found out that the 'seams showing' problem is quite widespread.

Here is one of several threads from Cocos-2d iPhone forums about it: http://www.cocos2d-iphone.org/forum/topic/3290 (http://www.cocos2d-iphone.org/forum/topic/3290)

Using many sprites on TextureAtlas sheets requires that they all have 1 pixel of padding. With sprites that don't connect with other sprites this padding should be totally transparent. With sprites that connect with other sprites, i.e. tile-like sprites, the edges that connect to other sprites should be filled.

I'm going to partially convert my PowFish game so it uses a single TextureAtlas and Polyvector for the main sprites, background and some other bits & pieces. I'm guessing I should see quite an improvement in performance since it was previously using variations of the Drawsprite methods.
Title: Re: Seemless scaling with Polyvector
Post by: Slydog on 2010-Sep-22
I wonder if the problem comes from when GLBasic converts the tx, ty values (sometimes called 'UV') to be between 0 and 1 for OpenGL. (I think that conversion takes place!)

If your source coordinates divided by your texture dimensions doesn't result in only a few decimal places, rounding may occur.

Example:
A 32x32 sprite extracted from a 256x256 texture map results in:
32 / 256 = 0.125 (a fairly simple number)

But a 32x32 sprite extracted from a 600x600 texture map results in:
32 / 600 = 0.05333333333333333... (infinite decimal places, so rounding occurs)

But if your sizes are already fairly divisible, then I'm out of ideas.

BTW:
QuoteWith sprites that connect with other sprites, i.e. tile-like sprites, the edges that connect to other sprites should be filled.
What's best for the 'filled' pixels, just a repeat of its neighbor?
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-22
Still get the same seams problem taking a 128x128 sprite from a 256x256 texture map (aka texture atlas) unless I use borders.

Oddly, a 128x128 sprite from a 128x128 texture map doesn't cause any problems without a border. It looks smooth with no seams. (this doesn't work with 160 x 160. Seems it has to be a power-of-2 size)

I find the same as the above with a 64x64 sprite. Taking it from a 256x256 or 128x128 texture map I get seams. Taking it from a 64x64 texture map I get no seams - perfect scaling.

Anyway, the best thing for the filled pixels is to use the next expected pixel. So, if you have a repeating tile of a ground texture then the rightmost border should be filled with pixels from the left of the sprite and so forth and so on. Example: -

(http://i904.photobucket.com/albums/ac242/wheeethefibble/webpics/example-tile.jpg)
Title: Re: Seemless scaling with Polyvector
Post by: Cliff3D on 2010-Sep-24
This issue has just hit me on my own project. It seems that when scaling up GLBasic is blurring the pixels with pixels to the left and above (so you probably don't need the right or bottom border) but of course at the very top and left edges there ARE no pixels above or to the left, so GLBasic (or OpenGL or whatever) guesses what colour to blend with (I guess it assumes a default).

A border to top and left won't work for my situation, but I THINK you may be able to omit the border to the bottom and right of tiles.
Title: Re: Seemless scaling with Polyvector
Post by: Cliff3D on 2010-Sep-24
a "PROPER" fix has been found by matchy :

Quote from: matchy on 2010-Sep-24

Try:

Code (glbasic) Select
SMOOTHSHADING FALSE  ::)

This should result in very sharp edges. Note though that as a reuls scaling up by a lot may look jagged.
Title: Re: Seemless scaling with Polyvector
Post by: Ian Price on 2010-Sep-24
D'oh - just posted exactly this in the other thread about this.
Title: Re: Seemless scaling with Polyvector
Post by: bigsofty on 2010-Sep-24
Hi,

The reason for the border is that the end texels don't know what is adjacent to them to calculates a decent anti-aliased pixel, as its on a separate tile .  What I have done here is to wrap to texture. I am not changing the UV coords or UV scale so the texture is not repeating but at the very edge, it uses the information at the opposite border to calculate a new smoother border.

This is done by IMPORTing the OPENGL "glTexParameteri" command and the required GL flags.

The result is no borders, yet retaining the smooth anti-aliased texture at any zoom level, for your tile maps.

Not sure if this is the standard way to do it but it seems to work.

Cheers,


Ian

P.S. I changed the demo to use a couple of textures to show how it works, a little more clearly too. Please see attached code.
Title: Re: Seemless scaling with Polyvector
Post by: bigsofty on 2010-Sep-24
Whoops... here's the correct zip...



[attachment deleted by admin]
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-26
Quote from: Cliff3D on 2010-Sep-24
Try:

Code (glbasic) Select
SMOOTHSHADING FALSE  ::)

This should result in very sharp edges. Note though that as a reuls scaling up by a lot may look jagged.

Thanks for pointing that out. In most situations I would probably go with smoothness on with scaling but this is good to know.

Quote from: bigsofty on 2010-Sep-24
Hi,

The reason for the border is that the end texels don't know what is adjacent to them to calculates a decent anti-aliased pixel, as its on a separate tile .  What I have done here is to wrap to texture. I am not changing the UV coords or UV scale so the texture is not repeating but at the very edge, it uses the information at the opposite border to calculate a new smoother border.

This is done by IMPORTing the OPENGL "glTexParameteri" command and the required GL flags.

The result is no borders, yet retaining the smooth anti-aliased texture at any zoom level, for your tile maps.

Not sure if this is the standard way to do it but it seems to work.

Cheers,

That's great Ian. Very interesting. I played around a bit and the only thing I will say is that the extra-pixel border method looks a wee bit smoother on my PC. For some reason there is a slight yellow tinge at the edges the tiles using your routine. Its barely noticeable and can only really be seen when enlarging with the lighter tiles. I'll attach a modification of your routine to demonstrate. Press space to change between border method and glTexParameteri method. The method currently being used is displayed at the top left of the screen.

[attachment deleted by admin]
Title: Re: Seemless scaling with Polyvector
Post by: bigsofty on 2010-Sep-29
I can't quite see it, it looks OK to me but I am viewing on a very small netbook screen here?

Cheers,


Ian
Title: Re: Seemless scaling with Polyvector
Post by: Wampus on 2010-Sep-29
Quote from: bigsofty on 2010-Sep-29
I can't quite see it, it looks OK to me but I am viewing on a very small netbook screen here?
That's good because no one is going to be seeing it on a tiny iPhone or iPod screen.  =D
Title: Re: Seemless scaling with Polyvector
Post by: bigsofty on 2010-Sep-29
Ha, that logical I suppose!  : :good: