Author Topic: Hi there - Newb Question :)  (Read 6207 times)

Offline Stevester

  • Mc. Print
  • *
  • Posts: 12
    • View Profile
Hi there - Newb Question :)
« on: 2011-Jun-14 »
Hi there,

I'm looking at GLBasic as a replacement to DBPro and have downloaded and been playing with it tonight.

Love some of the sample games out there, especially those with the vector style 'glowy' graphics (glowingrocksfromouterspace, scramble, etc)! I'm a ways off from anything like that tho. :)

Anyhoo, I'm made my first 'Hello World' program and am well on the way but have a question on my second (and most complex program to date) . . . .

I'm trying to display lots of random rectangles on the screen, adding one with each loop but I'm finding the SHOWSCREEN command appears to be getting in the way as its clearing the screen on every loop. What I'm wanting is to add a rectangle to screen on every loop rather than draw, show, clear, repeat.

This is what I have so far:

REPEAT
      DRAWRECT RND(800), RND(600), RND(100), RND(100), RGB(RND(255), RND(255), RND(255))
      SHOWSCREEN
UNTIL KEY(28)
MOUSEWAIT
END

I don't want the showscreen command to clear the backscreen every time, I want the rectangles to randomly overlap and fill the screen. Is there an alternative command to use to draw to the main screen or prevent the backscreen from wiping?

Any help would be appreciated. :)

Steve.

MrTAToad

  • Guest
Re: Hi there - Newb Question :)
« Reply #1 on: 2011-Jun-14 »
You could use CLEARSCREEN -1 for a blurry effect.  However, unlike DBPro, you do have to render all graphics for each display loop, which does give you the power to change the order of rendering.

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #2 on: 2011-Jun-14 »
What you can do is render each rectangle to a sprite/screen and then display that.

Code: (glbasic) [Select]
// Set screen resolution (Windowed mode=0 - full screen=1)
SETSCREEN 800,600,0

// Create a virtual screen and use it as sprite #999
CREATESCREEN 1,999,640,480

// Repeat until ESC pressed
WHILE TRUE

 // Switch all drawing processes to the virtual screen
 USESCREEN 1

 // Draw rectangles ONTO the virtual screen sprite
 DRAWRECT RND(800), RND(600), RND(100), RND(100), RGB(RND(255), RND(255), RND(255))

 // Switch back to normal screen
 USESCREEN -1

 // Draw the virtual screen sprite
 DRAWSPRITE 999,0,0

 // Update the screen
 SHOWSCREEN

// Repeat loop if WEND condition is not met
WEND

:)
I came. I saw. I played.

Offline Moru

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1793
    • View Profile
    • Homepage
Re: Hi there - Newb Question :)
« Reply #3 on: 2011-Jun-14 »
Or USEASBMP

Oh, and welcome to the boards :-)

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #4 on: 2011-Jun-14 »
USEASBMP will capture the entire screen and ANY and ALL changes. This would be OK for the example above, as there's no moving elements and you just want to update the rectangles. IIRC it also takes CPU time to use this.

My code above will only capture what is drawn onto the virtual screen, so you can have other things moving over/on/behind the sprite image and they won't appear repeatedly in the scene. Obviously the request was only for DRAWRECTs and this would work fine (as I said above), but if you want anything else moving on screen as well, then avoid USEASBMP (or you can end up with some very funky and cool effects).

And yes, welcome :)
I came. I saw. I played.

Offline ampos

  • Prof. Inline
  • *****
  • Posts: 1600
    • View Profile
    • AMpostata Website
Re: Hi there - Newb Question :)
« Reply #5 on: 2011-Jun-14 »
Code not tested, just typing "online" :)
Code: (glbasic) [Select]
type r
 x;y;w;h
endtype

dim rect[] as r

repeat
 s=bounds(rect[],0)
 redim rect[s]
 rect[s].x=rnd(100) rect[s].y=rnd(100) rect[s].w=rnd(100) rect[s].h=rnd(100)
 for each box in rect[]
   drawrect box.x,box.y,box.w,box.h
 next
 showscreen
until exit=true
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

Offline quangdx

  • Mr. Polyvector
  • ***
  • Posts: 233
  • work hard / play hard
    • View Profile
    • Asobi tech
Re: Hi there - Newb Question :)
« Reply #6 on: 2011-Jun-14 »
I second Ian Price on his solution,
as I was about to suggest the exact same thing.


What you can do is render each rectangle to a sprite/screen and then display that.

Code: (glbasic) [Select]
// Set screen resolution (Windowed mode=0 - full screen=1)
SETSCREEN 800,600,0

// Create a virtual screen and use it as sprite #999
CREATESCREEN 1,999,640,480

// Repeat until ESC pressed
WHILE TRUE

 // Switch all drawing processes to the virtual screen
 USESCREEN 1

 // Draw rectangles ONTO the virtual screen sprite
 DRAWRECT RND(800), RND(600), RND(100), RND(100), RGB(RND(255), RND(255), RND(255))

 // Switch back to normal screen
 USESCREEN -1

 // Draw the virtual screen sprite
 DRAWSPRITE 999,0,0

 // Update the screen
 SHOWSCREEN

// Repeat loop if WEND condition is not met
WEND

:)
Asobi tech - the science of play.
Spare time indiegame developer.

Offline Stevester

  • Mc. Print
  • *
  • Posts: 12
    • View Profile
Re: Hi there - Newb Question :)
« Reply #7 on: 2011-Jun-14 »
Thanks for the responses (and the welcomes) :)

So i can draw to a virtual screen then show the results. The virtual screen isn't cleared and can be added to and flipped back to the realscreen (if I got that correct!). Will have a play when i get home tonight.

Am i right in thinking Ampos' solution is building an array on each loop and redrawing rects to the screen on each sync?

It's gonna take me a while to get my head round the ins and outs but I'm liking the simplicity/clarity so far.

Cheers,

Steve.


Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #8 on: 2011-Jun-14 »
Yes, ampos is building an array of Types and then every loop iterating through them to draw the rect. This is not a good idea, as eventually you'll have to iterate through thousands of rects, which will significantly slow down the system.

The virtual screen solution will never have any slowdown, as it's only ever drawing one rect per loop to the virtual screen (which has all the old rects on it) and displaying that to the actual screen.
I came. I saw. I played.

Offline Moru

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1793
    • View Profile
    • Homepage
Re: Hi there - Newb Question :)
« Reply #9 on: 2011-Jun-14 »
USEASBMP will capture the entire screen and ANY and ALL changes. This would be OK for the example above, as there's no moving elements and you just want to update the rectangles. IIRC it also takes CPU time to use this.

Not entirely true, it will only capture the content of the screen at the time of the call. Everything you add after this is not captured and will be cleared the next time. Perfect for paint-programs or for a background-effect. And simple to understand for a newbie :-)

I'm not saying it's the only way of doing it, just another way of getting static content on the screen.

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #10 on: 2011-Jun-14 »
Quote
Not entirely true, it will only capture the content of the screen at the time of the call. Everything you add after this is not captured and will be cleared the next time.

Actually, just using the BMP image from calling USEASBMP takes longer than displaying a full-screen sprite (I tested this a long while back and it may have changes since then). Calling the USEASBMP before a main loop slowed the actual FPS for the main loop by a fraction, and that was only calling it once. Calling it every frame may have a more dramatic effect.
I came. I saw. I played.

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 932
  • KodeSource
    • View Profile
    • KodeSource
Re: Hi there - Newb Question :)
« Reply #11 on: 2011-Jun-14 »
This is a fun one!

Updating ampos's code, you could have a maximum rectangles allowed in the array at once, with the older ones getting overwritten in the array.  This could be updated to allow for effects for the older rectangles such as fading away, or slowly moving off the screen.

But even at 1000, DRAWRECT could get slow.  I would recommend using POLYVECTORS for anything real.

Code: (glbasic) [Select]
TYPE TRectangle
  left%
  top%
  width%
  height%
  colour%
 
  FUNCTION Set: l%, t%, w%, h%, colour%
self.left = l
self.top = t
self.width = w
self.height = h
self.colour = colour
  ENDFUNCTION

  FUNCTION Draw:
    // Exit if rectangle hasn't been initialized
    IF (self.left=0) AND (self.top=0) AND (self.width=0) AND (self.height=0) THEN RETURN
    DRAWRECT self.left, self.top, self.width, self.height, self.colour
  ENDFUNCTION

ENDTYPE

CONSTANT RECT_MAX% = 1000
GLOBAL rects[] AS TRectangle
GLOBAL pos%
GLOBAL rx%
DIM rects[RECT_MAX]

REPEAT
  // New Rectangle
  INC pos
  IF pos>=RECT_MAX THEN pos=0
  rects[pos].Set(RND(100), RND(100), RND(100), RND(100),  RGB(RND(255),RND(255),RND(255)) )

  // Draw all rectangles in the reverse order they were added, this controls the 'z-order' so latest is on top
  // . . . draw the ones at the end of the array first
  FOR rx = pos+1 TO RECT_MAX-1
    rects[rx].Draw()
  NEXT
  // . . . draw the ones at the start of the array next
  FOR rx = 0 TO pos
    rects[rx].Draw()
  NEXT
UNTIL FALSE
« Last Edit: 2011-Jun-14 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #12 on: 2011-Jun-14 »
Yep, POLYVECTOR should be faster than multiple DRAWRECTS. And you can add extra effects to them.

You have to remember though that the OP has limited experience with GLB, so that's perhaps pushing him a bit too far and too fast. Let him get the basics down first! :P
I came. I saw. I played.

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 932
  • KodeSource
    • View Profile
    • KodeSource
Re: Hi there - Newb Question :)
« Reply #13 on: 2011-Jun-14 »
Ya, I understand he's new to GLB, and was just trying to introduce him to some useful GLB concepts.   :good:

Pushing it a bit too far would be this:  (my attempt of fading the older rects!)     :O
Code: (glbasic) [Select]
TYPE TRectangle
  left%
  top%
  width%
  height%
  colour%
 
  FUNCTION Set: l%, t%, w%, h%, colour%
self.left = l
self.top = t
self.width = w
self.height = h
self.colour = colour
  ENDFUNCTION

  FUNCTION Draw:
// Exit if rectangle hasn't been initialized
    IF (self.left=0) AND (self.top=0) AND (self.width=0) AND (self.height=0) THEN RETURN
    DRAWRECT self.left, self.top, self.width, self.height, self.colour
  ENDFUNCTION

  FUNCTION Expand: amount%=1
    DEC self.left, amount
    DEC self.top, amount
    INC self.width, amount*2;  IF (self.width<1) THEN self.width=0
    INC self.height, amount*2; IF (self.height<1) THEN self.height=0
  ENDFUNCTION

ENDTYPE

CONSTANT RECT_MAX% = 100
GLOBAL rects[] AS TRectangle
GLOBAL pos%
GLOBAL rx%
DIM rects[RECT_MAX]

ALLOWESCAPE TRUE

REPEAT
  // New Rectangle
  INC pos
  IF pos>=RECT_MAX THEN pos=0
  rects[pos].Set(RND(200), RND(200), RND(200)+20, RND(200)+20,  RGB(RND(255),RND(255),RND(255)) )

  // Draw all rectangles in reverse order they were added, this controls the 'z-order' so latest is on top
  // . . . draw the ones at the end of the array first
  FOR rx = pos+1 TO RECT_MAX-1
    rects[rx].colour = Fade(rects[rx].colour, rx, pos)
    rects[rx].Expand(-1)
    rects[rx].Draw()
  NEXT
  // . . . draw the ones at the start of the array next
  FOR rx = 0 TO pos
    rects[rx].colour = Fade(rects[rx].colour, rx, pos)
    rects[rx].Expand(-1)
    rects[rx].Draw()
  NEXT

  SLEEP 50
  SHOWSCREEN
UNTIL FALSE

FUNCTION Fade%: colour%, rx%, pos%
  LOCAL colour_new%
  LOCAL age#
  age = pos - rx
  IF age < 0 THEN age = age + RECT_MAX
  // Set 'age' to range: [0.0] - [1.0]
  age = age / (RECT_MAX * 1.0)
  colour_new = Colour_Brightness(colour, -(age * 100))
  RETURN colour_new
ENDFUNCTION

// colour_new = Colour_Brightness(colour,  25) // new colour 25% brighter
// colour_new = Colour_Brightness(colour, -50) // new colour 50% darker
FUNCTION Colour_Brightness%: colour%, increase%
LOCAL r%, g%, b%, percent#
    percent = increase / 100.0
r=bAND(colour,0xff)
g=bAND(colour/0x100,0xff)
b=bAND(colour/0x10000,0xff)
//a=bAND(colour/0x1000000,0xff)
    IF percent >= 0
    r = INTEGER((255 - r) * percent + r)
    g = INTEGER((255 - g) * percent + g)
    b = INTEGER((255 - b) * percent + b)
    ELSE
    r = INTEGER(r * ABS(-1 - percent))
    g = INTEGER(g * ABS(-1 - percent))
    b = INTEGER(b * ABS(-1 - percent))
    ENDIF
    RETURN RGB(r, g, b)
ENDFUNCTION

[Edit] Updated to shrink rectangles as they get older, they appear to get further away.
« Last Edit: 2011-Jun-14 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline Ian Price

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 4176
  • On the shoulders of giants.
    • View Profile
    • My Apps
Re: Hi there - Newb Question :)
« Reply #14 on: 2011-Jun-14 »
That's a good effect =D
I came. I saw. I played.