Hi.
I am using the following code to scroll along a graphic image. What I have is an image that is 6144 pixels by 768 - I am using a screen resolution of 1024x768 fullscreen.
I want to have this large image shown on the screen and to slowly scroll along the screen - once it gets to the end - it loops around smoothly to the beginning again.
To make it loop smoothly - I pasted the first 1024x768 pixels of the image onto the end again. The code below does the rest. Please take a look.
Now my questions...
Although this code works - its crude and I do want to stick to this method of doing it - i.e. as described above - but can anyone suggest a more efficient way of doing this that perhaps
is Kinder on memory usage or is faster - although this works fine - I do worry about this.. Anyone?
My code is below should anyone want to run it - comments very welcome. Thanks.
// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10
SETCURRENTDIR("Media") // go to media files
LOADSPRITE "Lullaby-6144x768.png", 0
//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music
CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768
CONSTANT GraphicWidth = 6144
GLOBAL XPos = 0
LIMITFPS 50
CLEARSCREEN RGB(0,0,0) // Set the backbuffer background colour to Black.
SHOWSCREEN // Show it.
REPEAT
VIEWPORT XPos,0,ScreenWidth+(-XPos),ScreenHeight
DRAWSPRITE 0,0,0
SHOWSCREEN
DEC (XPos)
IF XPos < -(GraphicWidth-ScreenWidth)
XPos = 0
ENDIF
UNTIL FALSE
[attachment deleted by admin]
Many devices have sprite lenght limited to 1024x1024 or 2048x2048. Even most of the PCs are at 2048.
So to be safe, you have to be limited to 1024x1024.
BTW, you dont need clearscreen 0, just use clearscreen -1. Why clear the screen if it is going to be overwritten? :P
also this will work:
cleascreen -1
repeat
for x=0 to 6144-1024
drawsprite 0,x,0
showscreen
next
until exit=true
Thanks for your reply.
The Clearscreen command was an oversight I copied/pasted from my previous project :-[
Given the size of the graphic file - and this content is just a test - I'd like to have non repeating elements so scrolling parallax layer style prob isn't what I want...
How can I then handle an image of this size - given that its 6000 plus pixels across and I want to display a fullscreen segment of that (1024x768) each frame..
I can't seem to find commands to cut out a rectangles area from a larger graphic image and show that...
I suppose what I am asking is what is the best approach to take to do this?
thanks again.
Get a tilemap editor. Can't say much else without seeing the picture you want to display...
You would split your 6144 wide image into 6 (or 3) smaller images.
I'm not sure what platform you are targeting, but if it's PC then you should be good at 2048 wide images.
Then to scroll it you need to determine which two images (of the 3, if they are 2048 wide) you need displayed currently.
To draw the portion of the two images you want, use POLYVECTORs and specify the x, y for each corner vertice of the source image.
Here's something I whipped up (NOT tested) to show you what I mean.
I used my Poly_Draw() function, and TXyXy TYPE to make things simple.
TYPE TXyXy
x1%
y1%
x2%
y2%
FUNCTION Set: x1%, y1%, x2%, y2%
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
ENDFUNCTION
ENDTYPE
CONSTANT ScreenWidth% = 1024
CONSTANT ScreenHeight% = 768
CONSTANT GraphicWidth% = 2048
CONSTANT BackgroundSprites% = 3
CONSTANT BackgroundWidth% = 2048 * 3 // GraphicWidth * BackgroundSprites
GLOBAL sp_background%[]
DIM sp_background[BackgroundSprites]
LOCAL xPos%=0
LOCAL x1%=0 // x Position where the two sprites are joined
LOCAL sp_current% // Current sprite we're working with
LOCAL xy_screen AS TXyXy // Screen x,y TL and BR corner locations
LOCAL xy_sprite AS TXyXy // Sprite x,y TL and BR corner locations
// Load the three images into the 3 sprites IDs
sp_background[0] = GENSPRITE
LOADSPRITE "Lullaby-1.png", sp_background[0]
sp_background[1] = GENSPRITE
LOADSPRITE "Lullaby-2.png", sp_background[1]
sp_background[2] = GENSPRITE
LOADSPRITE "Lullaby-3.png", sp_background[2]
// +---+------+
// |B1 |B2 |
// | | |
// +---+------+
// 0 x1 ScreenWidth
REPEAT
x1 = GraphicWidth - MOD(xPos, GraphicWidth)
sp_current = xPos / GraphicWidth // Will be either 0, 1, or 2
// Draw left background sprite
xy_screen.Set(0, 0, x1, ScreenHeight)
xy_sprite.Set(GraphicWidth-x1, 0, GraphicWidth, GraphicHeight)
STARTPOLY sp_current
Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
ENDPOLY
// Draw right background sprite
INC sp_current // Use next background sprite
IF sp_current > BackgroundSprites THEN sp_current = 0 // Cycle to first background sprite when at end
xy_screen.Set(x1+1, 0, ScreenWidth, ScreenHeight)
xy_sprite.Set(0, 0, ScreenWidth-x1, GraphicHeight)
STARTPOLY sp_current
Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
ENDPOLY
INC xPos
IF xPos > (BackgroundWidth - ScreenWidth) THEN xPos = 0
UNTIL FALSE
// (uv1) 0___2
// | /|
// | / |
// |/__|
// 1 3 (uv2)
// xy :: Top-Left and Bottom-Right screen location
// uv :: Top-Left and Bottom-Right texture location
FUNCTION Poly_Draw: xy AS TXyXy, uv AS TXyXy, colour%
POLYNEWSTRIP
POLYVECTOR xy.x1, xy.y1, uv.x1, uv.y1, colour // TL
POLYVECTOR xy.x1, xy.y2, uv.x1, uv.y2, colour // BL
POLYVECTOR xy.x2, xy.y1, uv.x2, uv.y1, colour // TR
POLYVECTOR xy.x2, xy.y2, uv.x2, uv.y2, colour // BR
ENDFUNCTION
Hi thanks.
I will check this new way out and report back..
My target device is probably going to be the iPad in landscape mode 1024x768 - what is the maximum safe size to use for that platform just out of interest - anyone know?
This code is simpler and does work... but as I originally discovered when writing my version - it scrolls the background the wrong direction left to right instead of right to left
cleascreen -1
repeat
for x=0 to 6144-1024
drawsprite 0,x,0
showscreen
next
until exit=true
I think to just reverse the direction, change the last two lines in the loop to:
DEC xPos
IF xPos < 0 THEN xPos = (BackgroundWidth - ScreenWidth) // -1 : May need the '-1' at the end if flickers when at end
Thanks Slydog - I haven't actually looked at your example code yet but it looks interesting - about to check it out now thanks.
I was still playing about with my own code - on the iPad it is stretching the aspect ratio for some weird reason I can't figure out - perhaps as the texture size is too big??
anyway- about to test your solution out..
thanks.
I should do something so:
// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10.209
SETCURRENTDIR("Media") // go to media files
LOADSPRITE "Lullaby-6144x768.png", map
//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music
CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768
CONSTANT GraphicWidth = 6144
GLOBAL map, exit
GLOBAL speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight
GLOBAL worldX, worldY ,MundoX, MundoY
GETSPRITESIZE map, imgWide, imgHeight
scrW=imgWide ; scrH= imgHeight
imgX=0 ;imgY=0 ; speedW=1
LIMITFPS 50
SHOWSCREEN // Show it.
CLEARSCREEN -1
REPEAT
imgX=imgX-speedW ; IF (imgX+scrW)<0 THEN imgX=imgX+scrW
MundoX = MOD (worldX,imgWide) ;MundoX = -imgX ; IF worldX < 0 THEN MundoX = imgX - imgWide
DRAWSPRITE map, imgX, imgY
DRAWSPRITE map, imgX, imgY+scrH
DRAWSPRITE map, imgX+scrW, imgY
DRAWSPRITE map, imgX+scrW, imgY+scrH
SHOWSCREEN
UNTIL exit=TRUE
Hi Slydog.
I have been trying to compile your code but get this error.
Could you possibly run attached file with your code and work out what I have done wrong?
Graphics are cut into 2048 by 768 sizes like you mentioned..
thanks
This is the error I get when compiling for windows.
*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.10.104 SN:1d5d2793 - 3D, NET
Wordcount:50 commands
compiling:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `int __GLBASIC__::__MainGameSub_()':
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp:130: error: `x1' was not declared in this scope
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***
[attachment deleted by admin]
oh! bug.
Either move the TYPE declaration below the "main" function, or don't use the same parameter name "x1" in the Set function as well as a LOCAL in "main". So sorry.
thanks
go code to compile but it locked up machine. I don't know the first thing about polyvectors so I added a show screen command to main loop and it didn't crash this time!
All it showed though was a scrolling in outline sort of like a moving pyramid single line - no graphic content just outline.. then another pyramid outline, followed by another..
Anyone?
Way over my head now... ;-(
Sorry, I've been away all Christmas week.
I ran the code and see there were a few bugs. (ha, I guess I should have tested it!)
I've fixed them as far as I can see, and it now scrolls continuously and smoothly.
See the attached project.
Oh, for testing, I put a red line at the bottom of the 2nd graphic (and a yellow on the 3rd) to help see where the scroll position is at.
You can switch the direction with the new 'direction' variable. (-1 for reverse)
You can set the scroll speed with the new 'speed' variable. (I guess these could be combined into one variable using a negative speed for the reverse direction!)
I'm not 100% sure this is pixel perfect yet.
It may skip the 1st or last pixel in the graphic, and/or overlap the joining pics by a pixel.
More testing would be needed. (ie. I would start and end each graphic file with a one pixel wide line, each file with a different colour, see if you notice both lines where the split is).
[Update] I fixed a bug with detecting the end (or start, depending on scroll direction) of the last/first image.
It looked like it was working, but it happens that the 1st half of the 1st image and 2nd half of the last image were identical so it appeared to connect back to back.
[attachment deleted by admin]
Hi Slydog..
A fantastic routine you have written there. It runs great on PC. Mac and iPad!
I added some iOS auto rotation code for iPad and it handles it all great.
Seems much more stable than my original Objective-C and first GLBasic version.
The iPad seems able to handle the 2048 pixel wide images no problem, glad to report.
Well, iPad 2 anyway - still to test on an iPad1.
Incidentally, I added a 6 pixel high vertical coloured line at both edges of each section and did the same in a different colour at the edges of the 2nd section etc.
The good news is I took screenshots and zoomed in and the pixels met perfectly, meaning your routine seems to be joining up perfectly!
I wish I understood more about what Polyvector is doing.
I'll get there..
Regards
Mr Plant.
Great! It seems together perfectly! (or appears to!)
But, I found a bug when it checks xPos for the start/end, it was one screen width off.
I updated the .zip file in my previous post.
It just so happens that the 1st and 3rd image have the same picture if you overlapped them one screen width.
The original yellow line should have scrolled out of view (when direction=1), but instead it suddenly skips to the 1st image, but was unnoticable as it was the same graphic.
Here's the udpated section:
IF direction = 1
IF xPos >= BackgroundWidth THEN xPos = 0
ELSE
IF xPos < 0 THEN xPos = BackgroundWidth - 1
ENDIF
Thanks again Slydog..
I hadn't noticed that but glad you found and fixed it - ran your code and its flying by very nicely and smoothly and all your test lines line up perfectly..
Ps. Where is best place to learn all about Polyvector and its use? Manual doesn't go into it in detail and I can guess why!
Why is it so much better than Drawsprite etc? I am taking it the answer is because it is a low level accelerated OpenGL feature?
Thanks again.
mr p.