text:
GeForce 3D Vision: Stereoscopic 3D From NVIDIAby Derek Wilson on 1/8/2009 2:30 PM EST
- Posted in
- GPUs
54 Comments
Back to Article
roop452 - Wednesday, February 03, 2010 - linkAshu Rege is coming this February to India's first and independent annual summit for the game development ecosystem - India Game Developer Summit (http://www.gamedevelopersummit.com/)">http://www.gamedevelopersummit.com/) to talk about the novel uses of GPU computing for solving a variety of problems in game computing including game physics, artificial intelligence, animation, post-processing effects and others. Reply
Webster4 - Wednesday, January 28, 2009 - linkSonicIce has left links that, according to WOT Firefox extension, redirect you to a malware website called jord.nm.ru. I wouldn't go there, especially if you're using IE. Just thought I'd warn you. There's nothing of interest in his links anyway in my opinion. Reply
has407 - Sunday, January 11, 2009 - linkIf this is the chicken needed to to get us the eggs we need and increases stereo/3D adoption and support to critical mass, wonderful. However, a truly immersive experience--something that puts it beyond a novelty--is going to require much more, such as HMD's with decent resolutions, FOV, binocular overlap, etc. The price/performance/quality of those has improved significantly as OLED and related microdisplay technology advances, so we may be close... *IF* the game/app support is there. Unfortunately, I don't see much compelling about NVIDIA's offering, but if nothing else, they deserve an E for effort. IMHO I expect this will be at best a waypoint; in a couple years we'll have truly immersive HMD/VR systems that are affordable and will provide a compelling improvement in experience (again, IF the game/app support is there). Reply
quanta - Friday, January 09, 2009 - linkAs I recalled, NVIDIA has made a lot of reference cards with stereoscopic outputs since the earlist Quadro. And who can forget all those ASUS TNT(2) cards that came with stereo glasses options? Considering that virtually ZERO game developers even care about making games using 3D glasses since the day of Descent, I fail to see how will NVIDIA suddenly able to convince game developers to make games that require people to by a $200 accessory on top of $400 video card for optimal experience. That kind of market is too small to be viable for any commercial game developers. Reply
Beoir - Friday, January 09, 2009 - linkI can understand NVIDIA wanting to branch out to the gamer in 3D rendering, but what I don't understand is why they don't leverage off of their strengths and do a Joint venture. What I'm getting at is this:
1) NVIDIA is exceptional in creating Graphics rendering processing. Nvidia is not so good at developing physical Optical systems and understanding the Human Eye.
2)Vuzix is an expert in HUDs, and also has a viable (competitive) commercial HUD for watching movies. I speaking with a rep last year they were also interested in stereoscopic displays but could not pursue it since there was not a lot of market support or venture capital
These two guys sound like a great match to me. Toss in the fact that Vuzix is Rochester, NY where they have the University of Rochester institute of optics, and RIT's imagaing science center.
Have I painted a decent enough picture yet Nvidia? I can flowchart it out for the corporate suits if you like. Reply
nubie - Friday, January 09, 2009 - linkThis is what nVidia used to support:
That is a picture of the driver panel from my nVidia drivers before they dropped support for real 3D.
I would love to spend $1000 on these glasses, and a new system, Vista, new video cards, and of course a new monitor to use them on.
I find this stupid because the quickest way to get this product a success is to appeal to people who have been vocal about their previous good 3D support, not pull the rug out from under these people with no warning, no comment, and no incentive. Reply
quanta - Friday, January 09, 2009 - linkI believe you can still use it on Quadro (which NVIDIA still design video cards with stereo connectors). Just use the softquadro feature in RivaTuner to turn it on. Reply
nubie - Saturday, January 10, 2009 - linkI wish, and I don't need any stereo connectors for my dual polarized LCD display. Just dual outputs (vga or dvi, or one of each).
I haven't been able to successfully soft-quadro my g92 or g80 card, and I don't think the drivers are for DirectX games anyway. Reply
strikeback03 - Friday, January 09, 2009 - linkActually, one of my friends does have to take dramamine before playing FPS games. And this is just with a PS3 and an LCD TV, no stereo anything. Reply
DerekWilson - Friday, January 09, 2009 - linkI believe Gary turned us all on to ginger root -- taking a good bit of it before playing Left 4 Dead with it's disorienting source engine FOV is the only way I can survive normally ... actually, you know what? I was able to play the game without taking anything with the glasses and I didn't even think of that til now. It seems the 3D Vision may have actually fixed my nausea with tight fov games ... I'll have to do some more testing to see if this pans out ... Reply
jkostans - Friday, January 09, 2009 - linkSo how is this different from my ELSA 3d shutter glasses from 1999? The glasses I paid $50 for back then are just as good as this $200 setup in 2009? Great job re-inventing the wheel and charging more for it nVIDIA.
There is a reson shutter glasses didn't catch on. Ghosting being the worst problem, along with compatibility, loss of brightness/color accuracy, performance hits, the need for high refresh rate, etc etc etc.
If you are thinking of buying these, don't. You will use them for a few weeks, then just toss them in a drawer due to lack of game support and super annoying ghosting. Reply
nubie - Friday, January 09, 2009 - linkIt is different because these are likely ~$400 - $500 quality glasses.
Check out my setup with high resolution, no ghosting, high compatibility, minimal performance hit:
Running on iZ3D of course, no need for nVidia at all, buy any card you like, and keep running XP until Microsoft releases another OS worth spending money for. Reply
jkostans - Friday, January 09, 2009 - linkNo ghosting?
I can see it there and thats not even a high contrast situation.
Shutter glasses are shutter glasses, they all suck regardless of price. Reply
nubie - Saturday, January 10, 2009 - linkOK have a closed mind, technology never advances.
PS, that picture was taken through a linear polarized lens, and I am holding the camera and the glasses, so they may not have been lined up.
Also the contrast is automatically set by the camera, in person there isn't any ghosting. Reply
Shadowdancer2009 - Friday, January 09, 2009 - linkCan they PLEASE kill this tech soon?
It was 100% crap the first time, and it won't get better no matter how awesome the drivers are.
The glasses eat 50% of the brightness when "open" and doesn't kill 100% when "closed"
They never did, and your review says the same thing.
This was crap ten years ago, and it's crap now.
Give us dual screen highres VR goggles instead. Reply
nubie - Friday, January 09, 2009 - linkMaybe you don't understand the technology, these are ~$400 - $500 glasses, wireless with about a week of li-ion battery power.
Don't compare them to the $10 ones you can get anywhere, at least try them for yourself.
There are much better reasons to bash nVidia, like dropping support for 90% of the displays they used to support, and making support Vista only. Reply
gehav - Friday, January 09, 2009 - linkI'm perfectly satisfied with the current refresh rate of LCD-panels (60Hz). However what you forgot is the following: if the 3D glasses open and shut 60 times per second (for a 120Hz Panel) the old flicker of CRTs is effectively back. Therefore raising the refresh rate of the monitor to 240Hz would reduce the per eye flicker to an acceptable 120Hz. Not the monitor itself is the culprit here but the 3D glasses reintroduce flickering like in the old days of CRTs (and they are directly dependent on the refresh rate of the monitor).
Georg Reply
gehav - Friday, January 09, 2009 - linkbtw: 200Hz displays are already on the way, it seems:
http://www.engadget.com/2008/09/02/sony-samsung-bo...">http://www.engadget.com/2008/09/02/sony...-both-cl... Reply
gehav - Friday, January 09, 2009 - linkJust a thought I had while reading the article:
Wouldn't a ray traced image work far better for stereoscopic viewing? From what I understand the rasterizing technique used by today's graphics cards uses all kinds of tricks and effects to create the perception of a "real 3D world". That's why the drivers have to be customized for every game.
Ray tracing uses a far simpler algorithm to get good results. Every light ray is calculated separately and every game that uses ray tracing should therefore - in principle - easily be customizable for stereoscopic viewing.
I'm thinking of the announced Intel Larrabee which will maybe offer ray tracing acceleration for games and could therefore be much better suited for stereoscopic viewing.
Not sure if I'm right with these thoughts but it would be interesting to see if games that are already available in a ray tracing version (like Quake 4) could be easily adapted to support stereoscopic viewing and what the result would look like.
Apart from that I also think we would need faster LCD-panels (240Hz) to get non-flickering pictures for each eye.
Georg Reply
nubie - Friday, January 09, 2009 - linkCheck out some of the other initiatives, notably iZ3D, who have offered a free driver for all AMD products and XP support (double check the nVidia support for XP, non-existent much?)
nVidia's idea is too little, too expensive, too late. I have built my own dual-polarized passive rig that works great with $3 glasses, unfortunately nVidia has dropped all support (the last supported card is from the 7 series, so "gaming" isn't really an option.)
Thankfully iZ3D has stepped up to provide drivers, but thanks to nVidia's lack of support I have lost so much money on unsupported 8 series hardware that I haven't looked at a game in a couple years.
nVidia has killed my will to game. Dropping support of 3D is not the way to sell 3D (do some research, nvidia has dropped XP, supports only vista, and not even any of the cool displays you can cobble together yourself for less than the $200 this stupid package costs.)
My proof of concept, before nvidia pulled the plug:
My gaming rig, before nvidia dropped support for ~3 years:
nVidia needs to do better than this, and they should know better. Reply
marc1000 - Thursday, January 08, 2009 - linkI had one of these... and I had it with the 3d glasses!!! it was a 8bit console, with bad-looking games, the 3d glass was conected to the console via a cable, and the pace of changing the eyes was so slow you could se it if you pay enough attention. but it worked. and worked with any simple TV out there. however it was only FUN, no good images in reality... it's nice to see this technology come back to life! Reply
JonnyDough - Thursday, January 08, 2009 - link60hz should be the MINIMUM. Not the STANDARD. Even @ 60hz you tend to get a good bit of eye strain. I don't know how the monitor/tv industries get away with the mere 60hz. I for one STILL get headaches. Doesn't anyone else? Reply
ViRGE - Thursday, January 08, 2009 - linkOn an LCD? No. Which is why all this talk of strain is silly; the strain was a product of the flickering in a CRT, there's no reason anyone should be straining on a LCD. Reply
PrinceGaz - Thursday, January 08, 2009 - link120hz LCD panel is probably enough to say where your testing went wrong and your problems with ghosting and other issues began.
You must use a display with a native almost instant response, and no LCD panel to date can provide that (regardless of how much overdrive is given to nasty poor-quality but fast-response TN panels). You should have went old-school and used a high-quality CRT at 120hz refresh-rate, like many pro-gamers still use, or if available an OLED display as they would also be able to cope properly with 120hz refresh. Hell, I've got an old 15" CRT sitting on my desk which is capable of 640x480 @ 120hz which would almost certainly have done a better job of testing your 3D goggles than whichever LCD panel you used.
Ghosting would almost certainly have been a non-issue with a CRT running at 120hz, and having the left and right-eye images not having some of the other eye image also still visible (because of LCD response-time) would almost certainly have made it look a lot better. Reply
DerekWilson - Friday, January 09, 2009 - linkNot that kind of ghosting ... it didn't have to do with the panel -- everything looked fine on that end. I'm using the samsung 5ms 120Hz 1680x1050 monitor. the image looked smooth.
after talking with nvidia, it seems the ghosting issues were likely from convergence being off (where the look at points for each eye camera are set) causing problems. convergence can be adjusted with hot keys as well, but i didn't play with this.
eye strain didn't appear to be from flicker either -- it's more about the exercise of focusing on things that aren't there ... tweaking the depth (separation) and your distance from the monitor can make a big difference here. a CRT would not have made a difference. i do have a sony gdm f520, but its just not at the lab ... Reply
ssiu - Thursday, January 08, 2009 - linkYes you can use the NVIDIA glasses with analog CRT monitors with 100Hz-120Hz refresh rate. Reply
ssiu - Thursday, January 08, 2009 - linkAnyone interested in this should also check out and compare it with the competitor solution from iZ3D http://www.iz3d.com/">http://www.iz3d.com/ The 2 solutions each have their pros and cons, but iZ3D is significantly cheaper (MSRP $400 versus $600 ($200 glasses + $400 120Hz monitor)). iZ3D works with both ATI and NVIDIA video cards, and ATI users get an extra $50 rebate. Reply
simtex - Thursday, January 08, 2009 - linkThis looks very promising, if nvidia really want to push this rather old technology forward again I'm sure they can do so.
OpenGL have had built in support for the buffers you need to create stereoscopic images for years, in fact since version 1.1 if im not mistaken, so that is really no excuse for developers not using it.
And the suggestion that nvidia should just make a 3d monitor, what technology do are you refering to here, because as far as I know there is no technology capable of creating 3d images on a tradiional flat 2d monitor. Reply
crimson117 - Thursday, January 08, 2009 - linkI can only find one, and it's bundled with these glasses :)
ssiu - Thursday, January 08, 2009 - linkThe other announced 120Hz monitor is Viewsonic VX2265wm.
Matt Campbell - Thursday, January 08, 2009 - linkOne of my roommates in college had a VR helmet he used to play Descent, and was interning at a company designing (then) state-of-the-art updates to it. It was pretty wild to try, and hysterical to watch the person in the chair dodging and moving as things flew at them. It was really dodgy on support though, and gave most of us a headache after about 10 minutes. Now it's over 10 years later, and it doesn't sound like much has changed. Reply
crimson117 - Thursday, January 08, 2009 - linkVR helmets were more about making your real head's position guide your avatar's head's position than about providing stereoscopic 3D. Reply
Holly - Thursday, January 08, 2009 - linkThey did the both. It had tiny screen for each eye...
.. reminds me lovely days of System Shock :'( Reply
Dfere - Thursday, January 08, 2009 - linkSo. Mediocre equipment with mediocre drivers. Gee, why would anyone want us to buy it?
Am I the only one getting a feeling this is a start of something designed to suck up more GPU power and/or sell SLI as a mainstream requirement? After all, resolutions and FPS increases can't alone fuel the growth Nvidia and ATI would like. Reply
PrinceGaz - Thursday, January 08, 2009 - linkI think you are being hopelessly negative about why nVidia would be doing this.
What advantage do they gain by a move towards stereoscopic 3D glasses? Okay, increased 3D rendering power is needed as each frame has to be rendered twice to maintain the same framerate, but GPU power is increasing so quickly that is almost a non-issue, so SLI is irrelevant... NOT.
The main problem with stereoscopic rendering is each consecutive frame has to be rendered from a different perspective, and only every second frame is directly related to the one before it. That seems to be so nicely connected to what SLI AFR mode provides that it is too good to be true. One card does the left-eye in SLI AFR, the other the right-eye, and with suitably designed drivers, you get all the normal effects which rely on access to the previous frame (motion-blur etc) but in a "3D graphics system" sell twice as many cards as one card is doing each eye. They're not daft-- stereoscopic display is going to make dual GPU cards not just a luxury for the high-end gamer, but a necessity for normal gamers who want a satisfactory 3D experience. Reply
Gannon - Thursday, January 08, 2009 - link... for nvidia to co-operate with monitor manufacturers and implement 3D in the display itself instead of these half-baked attempts at depth. Nobody really wants to wear special glasses so they can have 3D depth perception on their computer.
The only way you are going to standardize something like this (because people are lazy and ignorant, lets face it) is to do it at the point where everybody gets it so it is standardized - everyone needs a monitor with their computer, so it would make sense to work towards displays that either:
1) Are natively 3D or
2) Built the costly stereoscopy into the monitor itself, thereby reducing costs through economies of scale.
I really think current shutter based stereoscopic 3D is a hold-over until we start to get real 3D displays. If I was nvidia I'd want to do it on the monitor end, not as an after-market part targetted towards gamers at a $200 price point. Reply
nubie - Friday, January 09, 2009 - linkTry Passive glasses, weight is next to nothing, no moving parts, no batteries.
Just polarization that works off of native LCD tech:
nVidia dropped support for this, boo/hiss. Reply
rcr - Thursday, January 08, 2009 - linkIs there the possibility to just use an SLI-system to get rid of these problems about the visual quality. So would it be possible to let every Graphiccard do the calculations for every eye and so you could the same Quality as on one card? Reply
wh3resmycar - Thursday, January 08, 2009 - link
what do you guys think? how about ViiBii? Reply
JonnyDough - Thursday, January 08, 2009 - linkNo, actually the picture says "AT" just in case anyone couldn't see it. :-) Reply
fishbits - Thursday, January 08, 2009 - link"What we really need, rather than a proprietary solution, is something like stereoscopic support built in to DirectX and OpenGL that developers can tap into very easily."
Would be nice, but whatever works and is actually implemented.
Nvidia could come up with a "3d glasses thumbs-up" seal of approval for games that get it right, and it could be displayed on the packaging. This would furter encourage developers to get on board. Heck, NV could have traveling demo rigs that sit in a Gamestop/Best Buy for a week, playing games that have superior compliance. Good for sales of the game(s), good for sales of the glasses.
I've done the old shutter glasses, was a neat novelty, but wears thin as Derek says. Sounds like these are currently only a bit better with current titles in most cases. *IF* they get this right and all major titles released support the system well, I'd buy the glasses right away. The new monitor too. But they have to get it right first.
This might work for the next generation of consoles too, albeit if hooked up to a high-refresh monitor possibly. Great selling point, another reason to get this right and off the ground. Of course Sony/Nintendo/MS might just make their own solution, but whatever gets the job done. If only one had this feature implemented well, it could be a big tie-breaker in winning sales to their camp. Reply
Judgepup - Thursday, January 08, 2009 - linkBeen waiting for the next revolution in gaming and after all the bugs have been worked out, this looks like it could be a contender. I'm typically an early adopter, but I'm fairly happy with a physical reality LCD at this point. Will wait in the wings on this one, but I applaud the Mighty nVidia for taking this tech to the next level. Reply
Holly - Thursday, January 08, 2009 - linkAlthough I am great supporter of 3Ding of virtual worlds, there are really huge drawbacks in this technology nVidia presented.
First of all, the reason why LCDs did not need to keep as high refresh rate as CRTs was the fact that LCD screen intensity doesn't go from wall to wall - 100% intensity to 0% intensity before another refresh (the way of CRT). This intensity fluctuation is what hurts our eyes. LCDs keep their intensity much more stable (some say their intensity is totaly stable, though I have seen some text describing there is some minor intensity downfall with LCDs as well, can't find it though). Back back on topic... we either went 100Hz+ or LCD to save our eyes.
Even if we ignore software related problems there is still problem... The flickering is back. Even if the screen picture is intensity stable these shutter glasses make the intensity go between 0-100% and we are back to days of old 14" screens and good way to get white staff sooner or later. Even if we have 120Hz LCDs, every eye has to go with 60Hz pretty much same as old CRTs. This just won't work. For longer use (gaming etc.) you really need 85Hz+ of flickering not to damage your eyes.
Another point I am curious about is how the GeForce 3D Vision counts in screen latency. It's not that long AT presented review of few screens with some minor whine about S-PVA latency coming way up to like 40ms. Thing is this latency could very easily cause that the frame that was supposed for left eye gets received by right eye and vice versa. I can imagine nausea superfast TM out of that (kind of effect when you drink too much and those stupid eyes just can't both focus on one thing).
I believe this stereoscopy has a future, but I don't believe it would be with shutter glasses or other way to switch 'seeing' eye and 'blinded' eye. Reply
PrinceGaz - Thursday, January 08, 2009 - linkThe answer is simple, move from LCD technology to something faster, like OLED or SED (whatever happened to SED?).
Both of those technologies are quite capable of providing a true 200hz refresh that truly changes the display every time (not just changes the colour a bit towards something else). A 200hz display refresh (and therefore 100hz per eye refresh) should be fast enough for almost anyone, and most people won't have a problem with 170hz display (85hz flickering per eye).
I do think 120hz split between two eyes would quite quickly give me a serious headache as when I used a CRT monitor in the past and had to look at the 60hz refresh before installing the graphics-card driver, it was seriously annoying. Reply
Rindis - Friday, January 09, 2009 - link"A 200hz display refresh (and therefore 100hz per eye refresh) should be fast enough for almost anyone, and most people won't have a problem with 170hz display (85hz flickering per eye)."
Almost is the key word here. I'm okay with 75Hz CRTs unless I'm staring at a blank white screen (Word), and by 85 I'm perfectly fine.
However, my roommate trained as a classical animator (which means hours of flipping through almost identical drawings) and could perceive CRT refresh rates up to about 115Hz. (She needed expensive monitors and graphics cards....) Which would demand a 230+Hz rate for this technology. Reply
paydirt - Friday, January 09, 2009 - linkIt's strange. I definitely notice when a CRT has a 60 Hz refresh rate. I have been gaming with a 29" LCD with 60 Hz refresh rate for about 4 years now and don't notice the refresh rate. Reply
DerekWilson - Friday, January 09, 2009 - linkThat's because the CRT blanks while the LCD stays on. With an LCD panel, every refresh the color changes from what it was to what it is. With a CRT, by the time the electron gun comes around every 60Hz, the phosphorus has dimmed even if it hasn't gone completely dark. 60Hz on a CRT "flashes" while 60Hz on an LCD only indicates how many times per second the color of each pixel is updated. Reply
SlyNine - Thursday, January 08, 2009 - linkYes but LCD's have ghosting, unless you can purge that image completely the right eye would see a ghost of the left eye. If you ever looked at the stills from testing LCD ghosting, you will see that even the best LCD's ghosts last for 2 frames.
The best TV I can think of to use this with is the 7000$ Laser TV from Mitsubishi.
Why can they not use dual videocards for this, Have one frame buffer be the left eye and the other be the right, then even if the car has yet to finish rendering the other image just flip to the last fully rendered frame. Reply
Holly - Thursday, January 08, 2009 - linkI think the result would be quite bad. You could easily end up in situation where one eye card runs 50 FPS while other eye card would be on 10FPS (even with the same models... the different placement of camera might invalidate big part of octree causing the FPS difference. Not sure how the brain would handle such a difference between two frames, but I think not well... Reply
SlyNine - Thursday, January 08, 2009 - linkYou know what, I skimmed every thing you wrote, and rereading it I realize the error I made.
My bad. Reply
7Enigma - Thursday, January 08, 2009 - linkComon guys, you could have made a cool logo.....like the one at the top of the page...
:) Reply
wushuktl - Thursday, January 08, 2009 - linkno screenshots? Reply
GaryJohnson - Thursday, January 08, 2009 - linkyou understand they would just look like normal screen shots? Reply
SonicIce - Thursday, January 08, 2009 - linkTheres zillions of screenshots if you can master the free viewing technique. Nvidia's old driver had a screenshot button that would grab both left and right views too.
Heres a few I have:
They're skinny because it's easier to do it if the image isn't too wide. These pics are for PARALLEL viewing (left eye sees left image, right eye sees right image.) If you use the CROSS-EYE technique you need to flip the images. Reply


text:
Drusy Tree of Life Love and Light Necklace by leighswiccanboutique
This Lovely Necklace features a beautiful Drusy Agate stone in pink and and brown with the Tree of life. The middle features a Dove to represent Love and Light. This Necklace will help aid the wearer with health and long life, and to attract the love of others. Increasing courage, intelligence, strength and modesty and to benefit the heart. Necklace also features the following stones: Rose Quartz, Amethyst, Hematite, Crystal, Dark Blue Goldstone, and Crackeled Glass. Stone Metaphysical Properties can be found at: http://mandileighs.blogspot.com/p/gemstone-metaphysical-properties.html Find more necklaces listed: http://www.etsy.com/shop/leighswiccanboutique?section_id=6978558 Or visit my Antique Vintage shop at: http://www.etsy.com/shop/mandileighs

subset: commoncrawl


text:
Building An OTP Application
From ErlangCentral Wiki
Martin Logan
Building an OTP Application Overview
Erlang is a clean, simple language, and it is easy to learn. That's Erlang, now lets talk OTP. The learning curve goes up significantly when getting into OTP. Questions arise, such as; how do I start an application, what is the function of a supervisor, and how do I make use of gen_server? That is just the beginning it gets far more confusing... "what is a .app file, what is a release, and can someone please tell me what .script and .boot files do?"
This tutorial will walk you through creating a new OTP application called location_server. This application will store the location of clients, allow others to query for that location from connected node, and allow clients to subscribe to notifications that are sent in the event of a change of location. Over the course of creating the location_server I will answer all of the above questions on OTP applications and quite a few more besides.
Part One: Building the Server
The following instructions may be inaccurate, as otp_base has been deprecated: https://github.com/erlware-deprecated/otp-base.
You will need to download the reference build system for this tutorial, this can be found at www.erlware.org under downloads otp_base-<vsn> Once you have the code on your local Unix/Linux machine extract the build system.
> tar -xzfv otp_base-R1.tgz > cd otp > ls build lib licence.txt Makefile README release tools
The first thing we are going to do is make an initial build of our build system, this is done by typing "make" in the otp directory. Note: if you have Erlang installed in any place other than /usr/local/lib/erlang then you can either create a symlink there pointing to your install, or you can set the environment variable ERL_RUN_TOP to point to your installation (make sure you use an absolute path).
The second thing to do is create a skeleton for the application. Once we do I will dissect that skeleton and explain the meaning of all its parts. To create the location_server application skeleton we use the "appgen" utility.
> cd tools/utilities > ./appgen location_server ls > cd -
We have just created an application under lib/location_server and a release under release/location_server_rel. We will now cd into lib/location_server and see what we have made.
> cd lib/location_server > ls include Makefile src vsn.mk
The include directory contains a file called location_service.hrl. This is the place we will put all our shared macro and record definitions. The src directory contains all of our Erlang (.erl) files. The vsn.mk file contains the make variable LOCATION_SERVER_VSN=1.0 which is the initial version of our application (feel free to change this). This version plays a role in how releases are handled, more on this later.
> cd src > ls location_server.app.src location_server.erl ls_sup.erl location_server.appup.src ls_server.erl Makefile
The src directory contains a file called location_server.erl. Notice that this Erlang source file has the same name as our application. By convention this file contains the API for our application. This file also contains the -behaviour(application) directive. This means that this file can be used as the entry point for the OTP application structure.
%%%------------------------------------------------------------------- %%% Author : martinjlogan <email@example.com> %%% @doc The entry point into our application. %%% @end %%%------------------------------------------------------------------- -module(location_server). -behaviour(application). %%-------------------------------------------------------------------- %% Include files %%-------------------------------------------------------------------- -include("location_server.hrl"). %%-------------------------------------------------------------------- %% External exports %%-------------------------------------------------------------------- -export([ start/2, shutdown/0, stop/1 ]). %%==================================================================== %% External functions %%==================================================================== %%-------------------------------------------------------------------- %% @doc The starting point for an erlang application. %% @spec start(Type, StartArgs) -> {ok, Pid} | {ok, Pid, State} | {error, Reason} %% @end %%-------------------------------------------------------------------- start(Type, StartArgs) -> case ls_sup:start_link(StartArgs) of {ok, Pid} -> {ok, Pid}; Error -> Error end. %%-------------------------------------------------------------------- %% @doc Called to shudown the auction_server application. %% @spec shutdown() -> ok %% @end %%-------------------------------------------------------------------- shutdown() -> application:stop(location_server). %%==================================================================== %% Internal functions %%==================================================================== %%-------------------------------------------------------------------- %% Called upon the termination of an application. %%-------------------------------------------------------------------- stop(State) -> ok.
The start/2 function is a callback function used by the OTP application system to start applications specified by the OTP release system. This function must take two arguments (you can read the docs on supervision for more info on the args) and it must return {ok, Pid} or {ok, Pid, State}, the former being more typical, for a successful application startup. Notice that the start/2 function calls ls_sup:start_link/1. ls_sup.erl contains our top level supervisor. Notice the prefix "ls" in the name ls_sup it is the first two letters of the two words that make up our application name; location_server. This prefix is a convention and it is used in lieu of a package structure in Erlang to avoid name conflicts within a release. You can use anything for your prefix, I only offer the first letter of each word in your application name as a suggestion.
The top level supervisor starts all the workers and lower level supervisors that our application will require. It specifies a strategy detailing how its processes will be restarted when they crash. This a key concept in Erlang and I suggest reading the design principles on supervision located at www.erlang.org.
%%%------------------------------------------------------------------- %%% Author : martinjlogan <email@example.com> %%% @doc The top level supervisor for our application. %%% @end %%%------------------------------------------------------------------- -module(ls_sup). -behaviour(supervisor). %%-------------------------------------------------------------------- %% External exports %%-------------------------------------------------------------------- -export([start_link/1]). %%-------------------------------------------------------------------- %% Internal exports %%-------------------------------------------------------------------- -export([init/1]). %%-------------------------------------------------------------------- %% Macros %%-------------------------------------------------------------------- -define(SERVER, ?MODULE). %%==================================================================== %% External functions %%==================================================================== %%-------------------------------------------------------------------- %% @doc Starts the supervisor. %% @spec start_link(StartArgs) -> {ok, pid()} | Error %% @end %%-------------------------------------------------------------------- start_link(StartArgs) -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %%==================================================================== %% Server functions %%==================================================================== %%-------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, {SupFlags, [ChildSpec]}} | %% ignore | %% {error, Reason} %%-------------------------------------------------------------------- init([]) -> RestartStrategy = one_for_one, MaxRestarts = 1000, MaxTimeBetRestarts = 3600, SupFlags = {RestartStrategy, MaxRestarts, MaxTimeBetRestarts}, ChildSpecs = [ {ls_server, {ls_server, start_link, []}, permanent, 1000, worker, [ls_server]} ], {ok,{SupFlags, ChildSpecs}}.
This file exports two functions start_link/1 and init/1. These are both functions used to conform to the supervisor behaviour, note the -behaviour(supervisor) directive which is present at the top of the file. Naming a function start_link is a convention in OTP that means the function will spawn a process and that the caller of the function, the parent process, will be linked (see link/1) to the child process. In this case the OTP application structure will be linked to the supervisor process.
The init/1 function is where the true guts of the supervisor are. Remember that you should never put any program logic in your supervisor, it should be as simple as possible and never fail, the fate of your application depends on this. Lets break our super down:
RestartStrategy = one_for_one, MaxRestarts = 1000, MaxTimeBetRestarts = 3600,
The RestartStrategy one_for_one means that for each process that dies simply restart that process without affecting any of the others. There are two other restart strategies, one_for_all and rest_for_one, you can read about these in the supervisor documentation. MaxRestarts is the maximum number of restarts allowed within MaxTimeBetweenRestarts seconds.
{ls_server, {ls_server, start_link, []}, permanent, 1000, worker, [ls_server]}
This supervisor has one ChildSpec which means it will start exactly one process. Going in order down the data structure ls_server is the name of the process to be started, {ls_server, start_link, []} is the module function and args that is called to start the child, permanent refers to the fact that the process should never be allowed to die without being restarted (there are other options, see the docs on supervision at erlang.org), 1000 is the time the process should be given to shutdown before being brutally killed, worker means the child is not a supervisor, [ls_server] is a list of module dependencies of the child.
The supervisor callback module function init/1 returns all of this information and the supervisor behaviour takes care of starting all the children in the order that they were specified in the child specs.
Now we move on to the ls_server.erl file. This file exhibits the behaviour gen_server. This means that it follows the callback prescription for that behaviour and exports the following callback functions:
%%-------------------------------------------------------------------- %% gen_server callbacks %%-------------------------------------------------------------------- -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
Additionally we are also going to create the following external functions:
%%-------------------------------------------------------------------- %% External exports %%-------------------------------------------------------------------- -export([ start_link/0, stop/0, store_location/3, fetch_location/2, alert_to_change/2 ]).
Lets get started. It is important to document all of your external functions. The OTP Base build system supports "edoc" with the "make docs" target which will automatically go through and compile all of your documentation and place it in your application directory under the directory doc (location_server/doc). On to our functions:
%%-------------------------------------------------------------------- %% @doc Starts the server. %% @spec start_link() -> {ok, pid()} | {error, Reason} %% @end %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
This function starts the server, registers it locally as ?SERVER (see source for -define(SERVER, ?MODULE).) and indicates to the gen_server behaviour that the current module exports the needed callback functions.
%%-------------------------------------------------------------------- %% @doc Stops the server. %% @spec stop() -> ok %% @end %%-------------------------------------------------------------------- stop() -> gen_server:cast(?SERVER, stop).
Stop is simple, but notice the use of gen_server:cast/2. This function is about the same as using the "!" operator. It is used to send an asynchronous message to a gen server. In this case we send the atom 'stop' to a locally registered process identified by the macro ?SERVER.
%%-------------------------------------------------------------------- %% @doc Stores the location of a client. %% <pre> %% Types: %% Node = node() %% Id = atom() %% Location = string() %% </pre> %% @spec store_location(Node, Id, Location) -> ok %% @end %%-------------------------------------------------------------------- store_location(Node, Id, Location) when is_atom(Id), is_list(Location) -> gen_server:cast({?SERVER, Node}, {store_location, {Id, Location}}).
store_location/3 is a very simple function but there is a lot for us to pay attention to here. Notice that we use the guard expressions, is_atom/1, and is_list/1. We are making sure that the types of the variables passed in are correct. This is an example of not trusting our borders. We check the types here so that we will never again have to check them. Did you notice that the name of the function is the same as the "tag" on the message we are sending? No? I will explain;
gen_server:cast({?SERVER, Node}, {store_location, {Id, Location}}).
store_location in the line above is our "tag" and will differentiate this message from others that this server understands (its alphabet). {Id, Location} is the payload that we are sending with the tag store_location. Messages sent in the gen_server should follow this convention of {Tag, Value}. There is an even more important thing to notice about the line above. Notice that the first argument to this function is {?SERVER, Node} instead of just ?SERVER as we saw in cast. This is the case because we want to be able to contact a process on any node in the network not just our own. To message a remotely registered process we can use the syntax {RegisteredName, Node} where node can be any node in the network including the local node.
%%-------------------------------------------------------------------- %% @doc Fetches the location of a client by its Id. %% <pre> %% Types: %% Node = node() %% Id = atom() %% </pre> %% @spec fetch_location(Node, Id) -> {ok, Location} | {error, Reason} | EXIT %% @end %%-------------------------------------------------------------------- fetch_location(Node, Id) -> gen_server:call({?SERVER, Node}, {fetch_location, Id}).
The things to notice here is that we no longer use guards, we don't care, this function will not change the state of our server and if it fails it does not matter much to us. Most importantly notice the use of gen_server:call/2. This function makes a synchronous (blocking) call to a gen_server.
%%-------------------------------------------------------------------- %% @doc Subscribes the caller to notifications of location change for %% the given Id. When a location changes the caller of this function %% will be sent a message of the form {location_changed, {Id, NewLocation}}. %% <pre> %% Types: %% Node = node() %% Id = atom() %% </pre> %% @spec alert_to_change(Node, Id) -> bool() | EXIT %% @end %%-------------------------------------------------------------------- alert_to_change(Node, Id) -> gen_server:call({?SERVER, Node}, {alert_to_change, {Id, self()}}).
Now that we have all of our external functions finished lets flesh out our server. One thing that those new to Erlang often get confused by is the idea that these external functions are called in the process space of the calling process but that the messages they generate are received by clauses in the same module but that exist in an entirely different process. It is important to use modules to encapsulate server protocols when possible.
%%==================================================================== %% Server functions %%==================================================================== %%-------------------------------------------------------------------- %% Function: init/1 %% Description: Initiates the server %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%-------------------------------------------------------------------- init([]) -> error_logger:info_msg("ls_server:init/1 starting~n", []), {ok, dict:new()}.
The init function is used to setup process state before the process can be accessed from the outside. Here our state is embodied by a dict. This dict will be used to store key value pairs of the form {Id, {Location, ListOfSubscribers}}. The init function is also logging the fact that the ls_server process is starting up. The location and management of log files will be covered in the second part of this tutorial covering how to create a release for your application.
%%-------------------------------------------------------------------- %% Function: handle_call/3 %% Description: Handling call messages %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- handle_call({fetch_location, Id}, From, State) -> case dict:find(Id, State) of {ok, {Location, ListOfSubscribers}} -> {reply, {ok, Location}, State}; error -> {reply, {error, no_such_id}, State} end; handle_call({alert_to_change, {Id, Subscriber}}, From, State) -> case dict:find(Id, State) of {ok, {Location, ListOfSubscribers}} -> NewListOfSubscribers = [Subscriber|lists:delete(Subscriber, ListOfSubscribers)], NewState = dict:store(Id, {Location, NewListOfSubscribers}, State), {reply, true, NewState}; error -> {reply, false, State} end.
%%-------------------------------------------------------------------- %% Function: handle_cast/2 %% Description: Handling cast messages %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- handle_cast(stop, State) -> {stop, normal, State}; handle_cast({store_location, {Id, Location}}, State) -> % Remember that State is a dict() NewState = case dict:find(Id, State) of {ok, {OldLocation, ListOfSubscribers}} -> lists:foreach(fun(Subscriber) -> Subscriber ! {location_changed, {Id, Location}} end, ListOfSubscribers), dict:store(Id, {Location, ListOfSubscribers}, State); error -> dict:store(Id, {Location, []}, State) end, {noreply, NewState}.
We are done with the server and all the functionality of our location_server application, but we have one last step to take. It is clearly awkward and ugly to have clients of our application calling ls_server:store_location etc... What we need is a well defined external API for clients. The place to put that API is in the module that has the same name as our application, our application behaviour module, location_server.erl.
%%-------------------------------------------------------------------- %% @doc Stores the location of a client. %% <pre> %% Types: %% Node = node() %% Id = atom() %% Location = string() %% </pre> %% @spec store_location(Node, Id, Location) -> ok %% @end %%-------------------------------------------------------------------- store_location(Node, Id, Location) -> ls_server:store_location(Node, Id, Location). %%-------------------------------------------------------------------- %% @doc Fetches the location of a client by its Id. %% <pre> %% Types: %% Node = node() %% Id = atom() %% </pre> %% @spec fetch_location(Node, Id) -> {ok, Location} | {error, Reason} | EXIT %% @end %%-------------------------------------------------------------------- fetch_location(Node, Id) -> ls_server:fetch_location(Node, Id). %%-------------------------------------------------------------------- %% @doc Subscribes the caller to notifications of location change for %% the given Id. When a location changes the caller of this function %% will be sent a message of the form {location_changed, {Id, NewLocation}}. %% <pre> %% Types: %% Node = node() %% Id = atom() %% </pre> %% @spec alert_to_change(Node, Id) -> bool() | EXIT %% @end %%-------------------------------------------------------------------- alert_to_change(Node, Id) -> ls_server:alert_to_change(Node, Id).
Of course the functions must be exported.
%%-------------------------------------------------------------------- %% External exports %%-------------------------------------------------------------------- -export([ start/2, shutdown/0, store_location/3, fetch_location/2, alert_to_change/2, stop/1 ]).
Now we are done with the coding of location_server, all we have to do is change directories into our application directory, type "make" and "make docs", and wait for a successful source and documentation compile.
> cd .. > make > make docs > ls doc ebin include Makefile src vsn.mk
Notice that there are two new directories in our application root directory "doc" and "ebin". location_server/doc contains html documentation of everything we have done. All of our external functions are present in these docs. Lets explore the ebin directly a little more deeply.
> cd ebin > ls location_server.app location_server.beam ls_sup.beam location_server.appup ls_server.beam
The ebin contains a single .beam byte-code compiled file for each of our .erl source files. The ebin directory also contains a .app and a .appup file. The .appup file is used for release upgrade handling and is beyond the scope of this tutorial. The .app file is essential for creating and installing OTP releases so we will look at it in depth.
{application, location_server, [ % A quick description of the application. {description, "An Erlang Application."}, % The version of the application {vsn, "1.0"}, % All modules used by the application. {modules, [ location_server, ls_server, ls_sup ]}, % All of the registered names the application uses. This can be ignored. {registered, []}, % Applications that are to be started prior to this one. This can be ignored % leave it alone unless you understand it well and let the .rel files in % your release handle this. {applications, [ kernel, stdlib ]}, % OTP application loader will load, but not start, included apps. Again % this can be ignored as well. To load but not start an application it % is easier to include it in the .rel file followed by the atom 'none' {included_applications, []}, % configuration parameters similar to those in the config file specified % on the command line. can be fetched with gas:get_env {env, []}, % The Module and Args used to start this application. {mod, {location_server, []}} ] }.
The comments in the above code pretty much explain it all. This .app file is created dynamically by the make process from the location_server/src/location_server.app.src file. This means that you should pretty much never have to manually edit this file.
Congratulations you have just created your first beautiful OTP application. Now lets move on to the second part of our tutorial and create a release in order to run and deploy our OTP application.
Part Two: Crafting a Release
From the otp directory:
> cd release/location_server_rel > ls location_server_rel.config.src Makefile yaws.conf.src location_server_rel.rel.src vsn.mk
This directory contains a vsn.mk file which serves to store the version string for this release. It contains a yaws.conf.src file which will be used to generate a yaws.conf file should you choose to include the yaws web server in your release. The two files we are going to concentrate on right now are the location_server_rel.config.src file and the location_server.rel.src file. The .config.src file is what make will translate into a .config file. This file includes all of the configuration the different applications in our release require to do things such as truncate and rotate our log files. The .rel.src file is what the make process will turn into a .rel file which will inturn be used to create our .script and .boot files, the files that tell the Erlang system what code to load when starting up. Here is our .rel.src file.
{release, {"location_server_rel", "%REL_VSN%"}, erts, [ kernel, stdlib, sasl, fslib, gas, location_server ] }.
This file specifies the name of our release followed by a version string that will be filled in when we do a make with the version string present in our vsn.mk file. Following that we specify that we want erts to be present in our release and the kernel, stdlib, sasl, fslib, gas, and finally our own custom application the location_server. For more details on fslib and gas, the two applications that together provide configuration and log rotation and truncation for our release you can go to erlware.org and see full documentation about them. Alternatively you can cd to either otp/lib/fslib or otp/lib/gas and run "make docs" and just generate all of the docs locally. When we run make this rel.src file will be turned into an actual .rel file which contains all the version numbers associated with the applications in the .rel.src file. For more info on the .rel.src structure take a look at the docs for the fslib file fs_boot_smithe.
Time to build and run our release.
> make > ls local location_server_rel.rel Makefile location_server_rel location_server_rel.rel.src vsn.mk location_server_rel.boot location_server_rel.rel.src.tmp yaws.conf.src location_server_rel.config.src location_server_rel.script
Quite a number of files and two directories have been generated. We can see a .rel file, a .script file, and a .boot file. Take a look at the contents of each, well, the .boot file might not prove to be too interesting because it is just a binary version of the .script file. Pay attention to the two directories that have been created; local and location_server_rel. location_server_rel is a staging area for installation and production releases of our application, for more info reference OTP Base documentation at erlware.org. We are going to focus on the local directory here. This directory allows us to run our release interactively. If we wanted to run it as a daemon it would be easy enough to invoke local/location_server_rel.sh with the -detached flag to accomplish that. For now we are going to cd into local and just run our application as is.
> cd local > ./location_server_rel.sh Erlang (BEAM) emulator version 5.4.12 [source] [hipe] INFO REPORT 14-Oct-2006::00:18:33 gas_sup:init INFO REPORT 14-Oct-2006::00:18:33 ls_server:init/1 starting Eshell V5.4.12 (abort with ^G) (firstname.lastname@example.com)1> We have successfully started the location_server release. Can you see where the log message we placed in ls_server to indicate its having reached the init/1 function has shown up on the console? That is not the only place our message shows up: <code caption="Code listing 2.4"> > ls log/1.0/ err_log sasl_log
The err_log file contains all the logs that get printed via the sasl error_logger with info_msg or error_msg. The other log, sasl_log, is where you will find all the sasl error reports. If your release crashes the first place to look is the sasl_log. By default the build system has wired in the use of fs_elwrap_h via the G.A.S application that is part of your release in order to truncate and rotate log-files. This prevents the log files from growing indefinitely. To configure or remove this functionality you can use the location_server.config file located in the "local" directory.
{gas, [ % Tell GAS to start elwrap. {mod_specs, [{elwrap, {fs_elwrap_h, start_link}}]}, % elwrap config. {err_log, "/home/martinjlogan/work/otp/release/location_server_rel/local/log/1.0/err_log"}, {err_log_wrap_info, {{err,5000000,10},{sasl,5000000,10}}}, {err_log_tty, true} % Log to the screen ]},
The mod_specs inform the GAS application as to how and what services to start up for a release. Following that are the actual config tuples elwrap uses to do its job. Starting with the location of the err_log and followed by the wrap specs which indicate for both the sasl and error logs how large a file can get before it is rotated out and just how many files there may be for a given logger before old files start getting deleted. The last bit of config toggles whether or not the error logger writes to the screen.
Part Three: Testing What We Have Built
To test our project we are going to start 3 separate Erlang named nodes. Open three terminal windows and start three nodes
- is the location server as started by local/location_server.sh
- is started with erl -name a -pz <path to location_server ebin>
- is started with erl -name b -pz <path to location_server ebin>
The -pz option on both tells the interpreter to add the specified path to the code loader search path. This means that we will have the location_server interfaces available for our use in node a and b. (This loading of code without starting an application can be accomplished by adding the tuple 'none' after an included application in the .rel.src file.) So now we have three nodes a@hostname, b@hostname, and username_location_server@hostname. To connect our nodes execute net_adm:ping('a@hostname') from the other two nodes. After this is complete running nodes() on any of the nodes should yield a complete list of the other nodes in our cloud. Run the following commands on your nodes. Make sure you pay attention to the node names in the following example because the commands are not all run on the same node.
(a@hostname)1> location_server:store_location('username_location_server_rel@hostname', john, "at work"). ok (b@hostname)1> location_server:alert_to_change('username_location_server_rel@hostname', john). true (b@hostname)2> receive Msg -> io:format("Msg: ~p~n", [Msg]) end. (a@hostname)2> location_server:store_location('username_location_server_rel@hostname', john, "at home"). ok (b@hostname)2> Msg: {location_changed,{john,"at home"}} ok (a@hostname)3> location_server:fetch_location('username_location_server_rel@hostname', john). {ok,"at home"}
Here is what happened above, we started a location server as the node 'username_location_server_rel@hostname' via the location_server_rel.sh start-up script. Then we started two nodes a@hostname and b@hostname. We then followed these steps:
- At prompt count 1 on "a" we did a store location with the key 'john' and the value "at work"
- At prompt count 1 on "b" we did an alert to change for the key 'john'
- At prompt count 2 on "b" we drop into a receive for a Msg which we will print on receipt
- At prompt count 2 on "a" we do a store location, which changes the location for 'john' to "at home" and causes "b" to exit the receive clause printing the message: Msg: {location_changed,{john,"at home"}}. Subscription works!
- Finally at prompt count 3 on "a" we prove that fetch_location works.
You can download the code for this tutorial here (link currently dead) That's it, happy Erlanging.


text:
Model trains are a hobby that captivates fanatics and brings in admirers from around the world. When occupying this interesting hobby, some idea needs to enter what kind of model train line you wish to construct as model trains for beginners could be frustrating if you simply dive in. This innovative hobby is the excellent method to show ability, creativity, as well as catch the remarkable essence of historic trains and also trains with nostalgic memories of the past.
Whatever your vision is, spend some time planning your version railway as well as join a local enthusiasts club where you will locate lots of useful ideas and also tips to obtain you began. Many little model train line projects in Elk Creek MO begin little as well as broaden into complex systems efficient in operating several trains simultaneously in all type of various terrain. The pointers in this short article will help you intend and consider how to start your own version train line.
Motif and Era in Missouri
Display Space
Model trains for newbies should not end enthusiastic and should permit enough room to show off the layout without overwhelming the area for a very first time model. You could consistently expand or start a brand-new job that is wall to wall.All version railways are a work of love, and it is advisable to start small due to all the information involved in Elk Creek MO.
RangeIf you have a tiny display room, after that a smaller scale model train will certainly function far better although even more influence is required from the scenery and also setting. Larger range models are simpler to deal with, yet are much more expensive.
Plan of the Track
Your track layout has a number of alternatives, and it is advisable to attract some different setups on chart paper. When you are satisfied with the design of your track, you can use your sketch to create it into your setting.
Notice the following video in regard to modeltrains in Elk Creek MO on this website:
Which Track Kind to Make use of
There are many different brand names of track on the marketplace with varying rail dimensions, roadbed connected track pieces as well as track just. Customized curves can be made from a flex track item. Review and attempt different kinds to see just what matches you.
Show Table or Bench
Prior to selecting the dimension of display area for your model train line, you can do a dummy run with your track on the flooring. This will certainly provide you a concept of overall dimension required. Price quote how much added will be required for scenery as well as additionals. This will provide you the size of board, bench, or table for your display screen in Elk Creek MO.
Electronics and Wiring
The operation of your version train line could be extremely innovative with digital command control (DCC) that enables you to run 2 or three trains at the same time. Locomotives are digital, yet many various other elements as well as devices are likewise electronic which will certainly give you a genuine reproduction of a genuine train line with lights, switching of tracks, vapor and smoke, whistles as well as various other audios. You could also get small video cameras to tape-record your train's journey around your individual format, which is great fun to enjoy in Elk Creek.
Starting a model railway could develop into a life lengthy encounter with something new as well as different to be added every day as your imagination updates your vision. Model trains for newbies are a fulfilling and fascinating pastime that not just offers complete satisfaction to the modeller, however likewise to individuals that see it. Simply remember to intend very carefully for a design you will have for life.
A bunch of the conditions you could want to simulate on your model train automobiles are the results of weather condition, dust, age, or even bumps and blemishes. To do this, you'll require paint and also paint brushes, hard-wire brushes, chalk, crayons, toothpicks, and also either photos of genuine aged railway vehicles or accessibility to real-life vehicles to see where as well as exactly how precisely they age.
The even more the far better, so you can select several different try to find various autos, or perhaps different components of vehicles. Remember that no two vehicles will certainly age in the same way, or at the same rate.
Painting different colors will vary relying on what impact you're going for, however friendly colors will be corrosion, orange, browns, black, earth tones, white; you could blend and also match, or integrate shades to obtain the colors or impacts you want.
Also if you utilize a shade called corrosion, keep in mind that there is a variety of rust, so you could intend to have it darker in one place, as well as lighter in another.


text:
I was just planning to make some plaster bats. Why did you make a double groove for the foot ring? In my mind I'm thinking a single groove. Could you please elaborate? Also, did you cut the rings with a loop tool? Thanks,
A double ring foot on a plate helps prevent sagging in the middle . . . which, on a large plate, would be less supported. Some potters also put a wad, perhaps with their chop mark or stamp, in the center of the plate to provide support against slumping during glaze firing.


text:
Malena Morgan Aurielee Summers and Two Nobodies in Lesbian Foursome !!
These pretty girls
Shemale cutie licks asshole and hard cock
Shavedpussy teen fucks grandpa
handjob in the swimming pool. branlette sous l'eau
Hot Babe Welcomes Pleasure With Well Stretched Legs
Amateur girl satisfied with a Male Doll
Gangbang for a slave
Dakota Fanning, Carla Juri, Vera Vitali - Brimstone (2016)
Pride 'n' Preju - The Keira edit
its a booty call cheating housewife with bbc
This new cutie is pretty shy about it
Freckled teen masturbates her wet pussy
Gorgeous amateur home sex
No.., I want to see your pussy
Haarscharf Gangbang Teen Fucking
Busty blonde bangs for cash outdoor
Sexy Firebush Redhead Masturbates Clit to Pussy Contractions
Filling her face hole with a boner delights naughty honey
TrafficHolder.com - Buy and Sell Adult Traffic|Trafficshop.com - Let your business grow|Contact Us|Webmaster
All content, including images, text, graphics, video and audio content contained in the website is protected under the laws of copyright, owned or under license to company or its designees,and represents proprietary and valuable intellectual property.
Contact Webmaster 18 U.S.C. 2257 Record-Keeping Requirements Compliance Statement
Powered by Stream Rotator


text:
The latest volley in the war of words between the 1992 U.S. Olympic men's basketball team and the 2012 edition comes from Patrick Ewing.
Ewing, one of the 1992 team's centers, said this year's Olympic team would not lose to this year's group.
"They're a lot smaller than we were," Ewing said Saturday night on NBA TV network. "(The current team is) kind of light in the middle. Myself and David Robinson, we would have had a field day. ... I'm not saying we would have creamed them. Best out of 10, I'd say we'd have beaten them 10 out of 10."
Ewing, the former New York Knicks center, was one of 11 eventual members of Basketball Hall of Fame to play on the 2012 team.
The friendly rivalry began last month when 2012 member Kobe Bryant said his team would beat the 1992 team. After negative reaction from 1992 members, 2012 teammate LeBron James backed up Kobe's boast last week.
The 1992 team regularly points to the average victory margin of more than 43 points during their Olympic run.
The 2012 team opened Olympics first-round play Sunday with a 98-71 victory over France.


text:
on orders $75+
Read 315 Tetra reviews, with an average rating of 4.7 out of 5 stars, to help determine which pet products are right for you.
Are you a fish enthusiast? Do you love going out and finding the latest topical fish and aquarium plants? With thousands of people enjoying an aquarium in their home or office, its clear that there is something special about a perfectly assembled aquarium with multi colored fish, a coral decorated bottom and that familiar filter sound humming in the background. Keeping a healthy, productive aquarium is part art, part science and all fun, but with Tetra Pet supplies, it becomes a lot easier.
Pet Mountain has a wide variety of Tetra Aquariums, aquarium care products and reptile and fish food. We have Tetra Aquarium Heaters, Air Pumps, Algae Control products, Power Filters and Filter Cartridges. We also have a nice selection of fish and reptile food, including Tetra Fish Flake Food, Iguana, Turtle and Cichlid Food as well as Tetra Vacation Blocks, to keep your supply up.Looking for aquarium decor? We have it all, including Tetra Aquarium Backgrounds, Caves, Huts and Waterfalls to aquarium care products like Tetra Aquarium Internal Filters, Air Pump Parts and Power Filter Parts. Keep your aquariums temperature perfect with our Tetra Aquarium and Reptile Heaters. If you have a pet iguana, turtle, snake or lizard, they are sure to be happy. Looking for easy and convenient? Get the Tetra Whisper Power Filter. Need bio bags and cleaning supplies? Check out the Tetra Bio Bag as well as Tetra Brushes and Scrapers and Nets and Tongs. Keep your fish or reptile clean and healthy.And of course, you have to ensure they have the nutrition they need. You can do that easily with Tetra Reptile Bowls and Feeders, Tetra Betta Food and other Tetramin foods and supplements. Whether you need granules or flakes, our affordable food products are here, ready to ship.Ready to see all the great deals on Tetra aquarium heaters, pumps, filters and food? Choose from our big selection. Youll find everything you need to keep your pet happy. Cant find something? Let us know; wed be happy to help. Be sure to check out our online coupons and discount shipping on all your favorite products.Pet Mountain your have everything, online low price leader for all Tetra supplies!
Free shipping on all orders over $75, even the BIG STUFF that weighs a ton. No code. No hassle.
We want you to be happy with all your purchases at PetMountain. If not, we will make things right.
We won't be beat on price. Always shop with confidence with our low price guarantee.
We guarantee that every brand we sell is new and 100% authentic. Shop over 300 trusted pet brands.
We're confirming your subscription now. We want to make sure your email isn't already on the list.


text:
You have just clicked on a link. If you continue, you will leave the Underage Drinking
Resource Portal Web site and look at a Web site not necessarily operated by the
Federal Agencies that created this site. We do not review, nor do we monitor, the
content on third party Web sites. Links are provided as a service to our visitors;
however, the views and opinions expressed are those of the various governmental
departments, schools, and agencies and their officials, and are not necessarily
those of the agencies that created the Underage Drinking Resource Portal and/or
its members. The Underage Drinking Resource Portal is not responsible for the content
of other Web sites. Your use of these Web sites is subject to the terms and conditions
of those sites.