SOLVED: How to calculate ZOOMSPRITE relx# and rely# correctly?

Previous topic - Next topic

Cliff3D

While looking for a command to help sharpen up PolyVector, I noticed ZoomSprite would probably do what my ResizeSprite function did, but presumably faster and (I hoped) POSSIBLY sharper. But if I feed this code:

Code (glbasic) Select
LOADSPRITE "Checker.png", 1
CREATESCREEN 0, 2, 512, 512 // create temporary workscreen of desired resolution
USESCREEN 0
ZOOMSPRITE 1, 0, 0, 2, 2
SAVESPRITE "resized.png",2
USESCREEN -1


the same 256 * 256 bitmap that I fed ResizeSprite, I get a 384 * 384 image on a 512 * 512 bitmao, not a 512 * 512 image on a 512 * 512 bitmap. What am I doing wrong, please?



[attachment deleted by admin]

matchy

Quote from: Cliff3D on 2010-Sep-24
While looking for a command to help sharpen up PolyVector...

Try:

Code (glbasic) Select
SMOOTHSHADING FALSE  ::)

MrTAToad

I was going to suggest that  =D

With linear interpolation on, you will get slightly different results that if it was off, due to filling in bits with adaptive colours

Cliff3D

Quote from: matchy on 2010-Sep-24
Quote from: Cliff3D on 2010-Sep-24
While looking for a command to help sharpen up PolyVector...

Try:

Code (glbasic) Select
SMOOTHSHADING FALSE  ::)

Brilliant - you are a prince among men! :D Many thanks - that's done the job a treat with PolyVector :D

MrTAToad

It should be noted, that contrary to the documentation, ZOOMSPRITE uses a handle of the middle of the rescaled sprite - I used :

Code (glbasic) Select
ZOOMSPRITE 1, 128,128, 2, 2 for it all to be displayed correctly.

Ergo, SMOOTHSHADING may not have been the problem :)


Cliff3D

Quote from: MrTAToad on 2010-Sep-27
It should be noted, that contrary to the documentation, ZOOMSPRITE uses a handle of the middle of the rescaled sprite - I used :

Code (glbasic) Select
ZOOMSPRITE 1, 128,128, 2, 2 for it all to be displayed correctly.

Ergo, SMOOTHSHADING may not have been the problem :)

Different problem. The blurry/antialised problem was cured with SMOOTHSHADING. While I waited for boffins to supply that answer, I came across and tried ZOOMSPRITE, which had this weird offset thingy. Close attention to the manual clears this up:

QuoteThe center stays the same as it was when using DRAWSPRITE.

Though I have to say, that's rather unexpected. While more accurate than the Wiki, the manual could be somewhat clearer IMHO. I'll stick with PolyVector, I think, for my purposes.

MrTAToad

Yes, we had a discussion about this on the forums...

As the resulting sprite appeared to be only 384 x 384, Moru suggested moving the coordinates...

Ian Price

Yeah, the original position on ZOOMSPRITE has caught me out a couple of times too.
I came. I saw. I played.

Kitty Hello

It was designed to replace DRAWSPRITE with a factor o 1.0. If you rise the scaling, the sprite scales from the center of what you had with DRAWSPRITE.
For more control, use STRETCHSPRITE where you give top,left and width/height.

Cliff3D

This probably exemplifies my biggest issue with documentation - for example, the DRAWSPRITE documentation doesn't say that it operates from the centre of the sprite, so until trying it I would assume top left (as GLBasic uses top left as 0,0). But I'm now assumning it works from the centre of a sprite... which has definite uses, but...

There's a "shared context" which this community has from growing up with the language that a newbie like myself doesn't have, which can make it harder work than it feels it ought to be to wrestle GLBasic into submission. You guys already have that shared context, it's assumed - but to me coming in from the outside it just feels bewildering :(

Or I'm just dumb.

Kitty Hello

Wait - The DRAWSPRITE draws at the top,left position of a sprite.
ZOOMSPRITE does this:

Code (glbasic) Select

FUNCTON WhatZoomDoes: id%, x%, y%, facx, facy
  LOCAL spx, spy
  GETSPRITESIZE id, spx, spy
  LOCAL w,h // dimension of drawn image
  w = facx * spx
  h = facy * spy

  LOCAL px, py // position where to draw (top left corner)
  px = x - (w - spx)/2
  py = y - (h - spy)/2
  STRETCHSPRITE id, px, py, w, h
ENDFUNCTION

Cliff3D

Quote from: Kitty Hello on 2010-Sep-28It was designed to replace DRAWSPRITE with a factor o 1.0. If you rise the scaling, the sprite scales from the center of what you had with DRAWSPRITE.

Quote from: Cliff3D on 2010-Sep-28DRAWSPRITE documentation doesn't say that it operates from the centre of the sprite

Quote from: Kitty Hello on 2010-Sep-28Wait - The DRAWSPRITE draws at the top,left position of a sprite.

My head hurts. Please don't explain any more to me today :(

(I really AM down with a cold, and I share <5% context with this forum AFAICS!)

MrTAToad

Does the X & Y coordinates plot from the top-left (accordining to my test it does) ?

I presume the commands act like the details in this list :


Command                  How X and Y coordinates are treated
DRAWSPRITE             X and Y draw from top-left coordinates
DRAWANIM                X and Y draw from top-left coordinates
ROTOSPRITE              X and Y draw from top-left coordinates
ROTOZOOMSPRITE     X and Y draw from top-left coordinates, unless scale is different from 1.0
ROTOZOOMANIM        X and Y draw from top-left coordinates, unless scale is different from 1.0
STRETCHSPRITE          X and Y draw from top-left coordinates
STRETCHANIM             X and Y draw from top-left coordinates
ZOOMSPRITE              X and Y draw from top-left coordinates, unless scale is different from 1.0

Cliff3D

I thought I'd try and time STRETCHSPRITE against my POLYVECTOR solution to see which ones I'd use going forward when just resizing a whole bitmap. While I failed to get comparative timings (the graphics card seems to buffer up the commands and then continues to execute them long after my timer has stopped) I did notice this slight oddity:



It seems to me that StretchSprite and PolyVector - as I am using them, at least - produce different results. Can anyonme show me how/why I'm getting this? Here's my code:

Code (glbasic) Select
// ------------------------------------------------------------- //
// ---  RESIZESPRITE  ---
// ------------------------------------------------------------- //
FUNCTION ResizeSprite: SourceSprite%, TargetSprite%, destWidth%, destHeight%, Smooth%
// Uses "virtual screen" 0
// These values are defined LOCAL:
// SourceSprite%,  TargetSprite%,  Width%,  Height%
//Resets smoothness to TRUE before exit

LOCAL spritewidth%, spriteheight%
GETSPRITESIZE SourceSprite%, spritewidth%, spriteheight%

CREATESCREEN 0, TargetSprite%, destWidth%, destHeight% // create temporary workscreen of desired resolution

USESCREEN 0

//Copy sprite #0 to target sprite and stretch to fit
SMOOTHSHADING Smooth%

//STARTPOLY SourceSprite% // Bitmap = No.SourceSprite%
//  POLYVECTOR  0,   0,  0,  0, RGB(255, 255, 255) // top left
//  POLYVECTOR   0, destHeight%-1,  0, spriteheight%-1, RGB (255, 255, 255) // bottom left
//  POLYVECTOR destWidth%-1, destHeight%-1, spritewidth%-1, spriteheight%-1, RGB(255, 255, 255) // bottom right
//  POLYVECTOR destWidth%-1,  0, spritewidth%-1,  0, RGB(  255, 255,   255) // top right
//ENDPOLY

STRETCHSPRITE SourceSprite%, 0, 0, destWidth%, destHeight%

//SAVESPRITE "PolyVector.png",TargetSprite%
SAVESPRITE "StretchSprite.png",TargetSprite%

SMOOTHSHADING TRUE
USESCREEN -1 // switch back to main screen
LOADSPRITE "", SourceSprite% // empty source sprite/release memory/resources
ENDFUNCTION // RESIZESPRITE


Obviously, I swap commented lines to produce the stretched bitmap one way or the other. I'd be quite keen to know where my error is, if I'm making one. Can anyone see a math error I'm making or anything? Or is GLBasic/OpenGL just doing the same task differently using the different commands?