Page 1 of 2

Set Origin?

Posted: Fri May 01, 2009 3:41 pm
by eVAPor8
I've a search through the help file and forums and maybe it's not possible BUT...

In the Good Ol' Days of the BBC Model B you could set the graphics origin. So, for instance, on an 800x600 screen, you could pseudo the following

[pseudocode]
SetOrigin( 400, 300 )
Plot( Colour("white"), MathsX(), MathsY() )
[/pseudocode]

...to plot a white point in the centre of the screen. It was a fantastic feature for stuff like plotting +/- waveforms, animations, etc. Now I can't find a similar function in PB but I can't beleive it doesn't exist or else every Plot() function will have to be

ScrW.l = 800
ScrH.l = 400
Plot((ScrW / 2) + MathsX(), (ScrW / 2) + MathsY())

Does a SetOrigin() type function exist? It just seems overcomplex code and more CPU intensive to me otherwise. :?

Re: Set Origin?

Posted: Fri May 01, 2009 4:11 pm
by Fluid Byte
eVAPor8 wrote:Does a SetOrigin() type function exist?
No but you could probably do it with DirectX API though.

Posted: Fri May 01, 2009 4:35 pm
by Kaeru Gaman
I don't know about such, but you can easily do it with a formula function or a macro.

Setting an Origin alone is of no use, because you would also need to set a scale and a direction.

for the most mathematical plottings you would inverse the y-axis,
and depending on what function you want to plot you would apply a big scale, like 20-100 pixels per Unit.

Posted: Fri May 01, 2009 5:35 pm
by eVAPor8
@Fluid Byte

Yeah, I was afraid of that, but it adds yet another layer of complication and also kicks any cross-platform code into the long grass.

@ Kaeru

I realise that the 0, 0 is top-left on a PB Screen, however the exercise I have in mind is to plot and animate a number of pixels, each in a (near) circler orbit around the centre of the display, so Dims and trajectories would be handled by formula code anyway. ;)

[EDIT] And thanks to both for your input! :D [/EDIT]

Posted: Fri May 01, 2009 6:17 pm
by srod
On windows you can change the mapping mode if you wish via the SetMapMode_() function.

Posted: Fri May 01, 2009 6:19 pm
by Fluid Byte
srod wrote:On windows you can change the mapping mode if you wish via the SetMapMode_() function.
Dat works for Screens?

Posted: Fri May 01, 2009 6:20 pm
by srod
Whoops.... teach me to only scan through! :)

Posted: Fri May 01, 2009 10:11 pm
by eVAPor8
srod wrote:Whoops.... teach me to only scan through! :)
:lol:

Not that I've ever done the same thing... of course... errrm... :oops:

Posted: Sat May 02, 2009 12:46 am
by idle
Even if the function did exist, it's not magic, it'd still have to apply the transform, so you may as well set a couple of vars instead.

In homers Simpson's words - hmm donuts!

Code: Select all


Procedure drawElipse(hdc,ox.f,oy.f,majoraxis,minoraxis,sfx.f,sfy.f,orient.f)

Protected dx.f,dy.f,px.i,py.i

;draw elipse 
For alpha = 1 To 3600   
   
   dx = ox + (Sin(alpha) * majoraxis) * sfx
   dy = oy + (Cos(alpha) * minoraxis) * sfy
   px = ox + (((dx - ox) * Sin(orient))) - (((dy - oy) * Cos(orient))) 
   py = oy + (((dx - ox) * Cos(orient))) + (((dy - oy) * Sin(orient))) 
   SetPixel_(hdc, px, py, RGB(255,0,0))
        
Next
 

EndProcedure 

OpenWindow(0,0,0,800,600,"")

hdc = StartDrawing(WindowOutput(0))
 
For a = 1 To 905 Step 5

drawelipse(hdc,400,300,300,100,0.5,0.5,a)

Next 

StopDrawing()

Repeat 

 event = WaitWindowEvent() 
 
Until event = #WM_CLOSE  


Posted: Sat May 02, 2009 1:44 am
by eVAPor8
Idle,

Very nice code, but it's using the same "Plot((ScrW / 2) + MathsX(), (ScrW / 2) + MathsY())" that I mentioned in the OP and I'm trying to avoid. Also, it's using an hDC to a window rather than a Screen (though it should be easy enough to convert).

I'm trying to eventually model (in 2D at first, 3D later) a black-hole spiral galaxy, where each star's orbit decays to the centre... Bearing in mind there will be (tens of?) thousands of stars I'd require a double-buffered Screen.

Now if you recall my BBC Model B nostalgia in the OP you'll realise it's been years since I've even plotted a Cos/Sin circle but all recollections of building mentalist animations like this involved algorithms generating negative x/y values.

It just seems to me that the extra CPU overhead per "star" is mad!

And just to make the challenge easier I want it to be cross-platform, so goodbye DX.

I guess I'll just have to learn Ogre, RTFM yet again and start again from scratch.

Posted: Sat May 02, 2009 1:59 am
by Kaeru Gaman
1.) don't calculate (ScrW / 2) and (ScrW / 2) every call.
it's a constant, make it a constant.

2.) a simple subtraction is no "overhead".

3.) the sine is time intensive.
when you need it for a lot of elements, build a lookup table on startup, use the table in the critical loops.

4.) the way to display makes the edge between performance and slideshow.
on Windows, Plotting with colorvalue uses DSA.
when not mixing it up with other Draw commands, it's fastest to plot.
but at the end, using tiny Sprite3D stars would be even faster.
all of those use a standard grid with 0/0 in the upper left corner.
use it.
it's sufficent.
don't bother about one subtraction more or less.

5.) cross-platform back or forth...
when you want performance, don't simply stick to a crossplat engine and use the same code allover.
this will be the tunnel that steals you the performance.
write seperated includes for each platform that makes your GPU burn.

6.) stick to simple plotting first.

PS:
and I'm sorry if it sounds rude. it's not meant rude. take it easy.

Posted: Sat May 02, 2009 2:16 am
by idle
There's no avoiding the math you just need to avoid the overheads of calculating what you don't need.

This is a bit faster using lookups and pre calculating the orientation.

Code: Select all


Global Dim arCos.f(360)
Global Dim arSin.f(360)

Procedure drawElipse(hdc,ox.f,oy.f,majoraxis,minoraxis,sfx.f,sfy.f,orient.i)

Protected dx.f,dy.f,px.i,py.i,cosOrient.f,sinOrient.f,dx1.f,dy1.f,color.i 

cosOrient = ArCos(orient%360)
sinOrient = ArSin(orient%360) 
color = RGB(Random(196)+59,Random(196)+59,Random(196)+59) 
 
;draw elipse
For alpha = 1 To 3600   
   
   dx = ox + (ArSin(alpha%360) * majoraxis) * sfx
   dy = oy + (ArCos(alpha%360) * minoraxis) * sfy
   dx1 = dx - ox
   dy1 = dy - oy
   px = ox + (dx1 * sinOrient - dy1 * cosorient)
   py = oy + (dx1 * cosOrient + dy1 * sinorient)
   SetPixel_(hdc, px, py,color)
       
Next
 

EndProcedure

OpenWindow(0,0,0,800,600,"")
SetWinBackgroundColor(WindowID(0),RGB(0,0,0))
For a = 0 To 360 
  ArCos(a)=Cos(a)
  ArSin(a)=Sin(a)
Next 

hdc = StartDrawing(WindowOutput(0))
 
For a = 1 To 905 Step 5

drawelipse(hdc,400,300,300,100,0.5,0.5,a)

Next

StopDrawing()

Repeat

 event = WaitWindowEvent()
 
Until event = #WM_CLOSE  


Posted: Sat May 02, 2009 2:19 am
by eVAPor8
Kaeru Gaman wrote:1.) don't calculate (ScrW / 2) and (ScrW / 2) every call.
it's a constant, make it a constant.

2.) a simple subtraction is no "overhead".

3.) the sine is time intensive.
when you need it for a lot of elements, build a lookup table on startup, use the table in the critical loops.

4.) the way to display makes the edge between performance and slideshow.
on Windows, Plotting with colorvalue uses DSA.
when not mixing it up with other Draw commands, it's fastest to plot.
but at the end, using tiny Sprite3D stars would be even faster.
all of those use a standard grid with 0/0 in the upper left corner.
use it.
it's sufficent.
don't bother about one subtraction more or less.

5.) cross-platform back or forth...
when you want performance, don't simply stick to a crossplat engine and use the same code allover.
this will be the tunnel that steals you the performance.
write seperated includes for each platform that makes your GPU burn.

6.) stick to simple plotting first.

PS:
and I'm sorry if it sounds rude. it' not mean rude. take it easy.
1. I was using the Pseudocode to explain the problem. Of course I use a const.

2. A simple subtraction * 100,000 (or more) = added CPU cycles and overhead.

3. Since the "orbits" will eventually be slightly randomised, the Cos/Sin equations will have to be dynamic

4. I didn't know that. I'd have thought a Sprite3D would be slower than plotting a pixel. Thanks for the heads-up. ;)

5. Listen mate, I don't have the time or inclination to learn and build seperate libraries and builds per platform. Besides, if you take that route then the sourcecode isn't truly cross-platform anyway.

6. No offence, but that's exactly what I'm doing. It's just a plain fact that the ability to plot negative values makes life easier and code more simple and literate.

Posted: Sat May 02, 2009 2:34 am
by eVAPor8
PS, Sorry if that last post sounds shirty on re-reading. It's late, I'm tired and probably not at my diplomatic best!

Posted: Sat May 02, 2009 2:38 am
by Kaeru Gaman
a sine function is not more dynamic than a lookup table.
A simple subtraction * 100,000 (or more) = added CPU cycles and overhead.
the basic DC or DSA uses a left-top-origin surface.

when you have a SetOrigin command, it will be within a Framework, and the overhead will be in the framework.
what do you think the framework will do when you have a SetOrigin command?
it will add a subtraction for every plot within the command.

better keep it in your own code where you have control over the amount of "overhead".

it's just...
why worry about the overhead of having one or two subtractions per element,
but not worry about using a big fat framework that may eat performance like a Mafiaboss eats noodles?

this is simply the wrong way round!

when you don't need to worry about the big fat framework, just don't care about the tiny billion subtractions either.
it will be the smaller problem. promise.


>> PS, Sorry if that last post sounds shirty on re-reading. It's late, I'm tired and probably not at my diplomatic best!

no problem. I take it easy. ;)


PS:
after having thought it over a bit...
it can be the fastest way to use OGRE, when you use it the right way.
not because it avoids a billion subtractions (it won't),
but because it accesses the modern graphics hardware the best way.

nowadays, the whole 3D stuff is Hardcoded into the Grafix Cards.
using 2D stuff is just an emulation build upon 3D internals, so it isn't any longer fast as it could be.
using a 2D surface already wastes a lot of power into a transforming framework.

best choice would perhaps be coding everything in openGL directly.