Print

Table of contents

0. About OGRE

 

0a. What is OGRE?

OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce applications utilising hardware-accelerated 3D graphics. The class library abstracts all the details of using the underlying system libraries like Direct3D and OpenGL and provides an interface based on world objects and other intuitive classes.

0b. What can it do?

Lots of things! See the features page for an up-to-date list of the current features. Also, take a look at the screenshots page to see for yourself the kinds of eye candy OGRE can pump out.

0c. Is OGRE a Game Engine?

No. OGRE can be (and indeed has been) used to make games, but OGRE is deliberately designed to provide just a world-class graphics solution; for other features like sound, networking, AI, collision, physics etc, you will need to integrate it with other libraries, something several frameworks have done, and we have a collision / physics reference integration library as an example in our distribution.

0d. Why it is not?

Well, one reason is that not everyone who needs a 3D engine wants to make games, so we don’t assume that you do – you can use OGRE for games, simulations, business applications, anything at all. Secondly, even within the games industry, requirements can vary widely; for example a MMORPG will need a very different kind of network library than an FPS, and a flight simulation will need a different kind of collision / physics system to fighting game. If OGRE included all these features, we would be enforcing a particular set of libraries on you, with an inbuilt set of assumed requirements, and that’s not good design. Instead, we provide a very integration friendly API and let YOU choose the other libraries, if you want them. Many experienced game developers have expressed their approval of this approach, because there are no inbuilt constraints. It can be more daunting for newer users who just want to build another FPS-style game, but for those people there are a growing number of existing frameworks using OGRE which provide a complete solution using a given combo of libraries; but it’s important to realise that OGRE itself will always remain separate, flexible enough to be incorporated into any of these. The principle is of collaboration and integration with other libraries, rather than assimilation of them, a standard tenet of component-based design.

0e. Why should I consider using OGRE (rather than the other zillion 3D engines out there)?

Many other engines, whilst technically impressive, lack the cohesive design and the consistent documentation to allow them to be used effectively. Many of them have long features lists, but have the feel of a bunch of tech demos lashed together with twine, with no clear vision to hold them together. Like any other software system this becomes their downfall as they become larger. Most other engines are also designed for one particular style of game or demo (e.g. first-person shooters, terrain roamers).

OGRE is different. OGRE is design-led rather than feature-led. Every feature that goes into OGRE is considered thoroughly and slotted into the overall design as elegantly as possible and is always fully documented, meaning that the features which are there always feel part of a cohesive whole. Quality is favored over quantity, because quantity can come later – quality can never be added in retrospect. OGRE uses sound design principles learned, tried and tested many times in commercial-grade software – the object-orientation mentioned in it’s moniker is just one of those approaches – frequent use of design patterns is another. The core development team is kept deliberately small, and all of its members are veteran software engineers with many years of real-world experience. Patches are welcomed from community, but they undergo a strict review for both quality and cohesion with the Ogre philosophy before being accepted.

OGRE does not assume what type of game or demo you want to make. It uses a flexible class hierarchy allowing you to design plugins to specialise the scene organisation approach taken to allow you to make any kind of scene you like. Want to render indoor levels fast? Fine, use the BSP/PVS plugin scene manager which has already been written. Want an outdoor landscape? Again, use another plugin scene manager. The rest of the engine continues to function exactly as before.

So the short answer is – if you favour design quality, flexibility and clear documentation, choose OGRE.

0f. Is it really free?

The Ogre source is made available under the MIT License, which basically means you can use it however you like as long as you include the content of our COPYING file somewhere in your application. The source to your application, or your modifications to Ogre do not have to be released (although it would be nice if you did). See the licensing page for full licensing terms.

0g. How do I find out more?

If you want to find out about the principles under which OGRE has been developed and to get a quick overview of the design, go to the OGRE Manual now. You can also read the tutorials to help you get started, and then reference the API documentation online.

The best way to appreciate OGRE is to use it. I recommend using Mercurial to download the latest version since the code is under constant improvement. If you don’t want to use Mercurial, a snapshot is released periodically for download. For both these options, see the download page(external link).

If you have any specific questions see the support page(external link) on how to get assistance.

 

1. ROOT - THE OBLIGATORY CLASS/ OBJECT.

Image
click to enlarge

 
Note: All those classes are Singletons except RenderSystem, SceneManager, RenderWindow. TextureManager is an abstract class, whose instance is created with RenderSystem.

INITIALIZATION

 

Image
click to enlarge

 

1a. Why do I have to allocate Ogre::Root on the heap, and not on the stack?

That is why I do have to write:

Root *root = new Root();

and not just:

Root root = Root();

 
Well, OGRE often holds Root inside a manager class so Root gets constructed as soon as the manager is. So it actually becomes:

class SomeManager
        {
        protected:
            Ogre::Root mOgreRoot;
        ...
        }

 
You might construct Root like that in your entry point before the frame loop is kicked off. When using the RAII technique (that is what this snippet does) you must just watch out that mOgreRoot won't be popped off from stack while the app is running. This is hard to do with the RAII, as with that the function call frames are deleted in the order opposite to how they were put onto the stack — that is the 'newest ' call frame first, but when using say threading the things get more complicated.

Note: This is actually the same consideration as making sure you don't call 'delete mOgreeRootPointer' during the program's main loop. Thus there really isn't a concrete need to manage Root using new/delete, although you can if you want.

1b. How to create similar class with getSingleton() method?

 
This pattern is called Singleton: http://en.wikipedia.org/wiki/Singleton_pattern(external link)

Deriving from Ogre::Singleton is merely a matter of doing this:

MyAwesomeClass :: public Ogre::Singleton<MyAwesomeClass>
        {
        //code omitted - obviously
        };
 
And in the implementation file:
 
        template<> MyAwesomeClass* Ogre::Singleton<MyAwesomeClass>::ms_Singleton = 0;

 
The Ogre3D's Singleton has been written by Scott Bilas, here's his blog entry discussing similar Singleton variant: http://scottbilas.com/publications/gem-singleton/(external link)

1b2. I need more than one window for my app, can I create more than one root object for that purpose?

 
Two instances of Ogre::Root is not possible/recommend/supported. Ogre uses Singletons, that is one instance of the object in the same application context) e.g. TextureManager, MeshManager and of course Ogre::Root, creating -> the second created root will "override" the first one.

Ogre supports having multiple windows, just don't use multiple Roots to achieve that purpose.

1b3. Can I run Ogre3D without actually initializing Ogre::Root? What functions I do have at hand then?

 
Yes. It is possible to run Ogre3D without initializing root, but having limited functionality.
The XMLConverter and the MeshUpgrader tools initialize the individual systems that they require to operate. Note that in some cases, you may need to initialize some systems that are indirectly used by the ones you need (like the LogManager).
Because this is very low level, we recommend that if you want to look into this, research the source code (particularly the mentioned tools) and do some experimentation.

1b4. But I have read the tutorial and source SDK, the Ogre::Root is created nowhere.

 
Most of the tutorials use the Ogre Wiki Tutorial Frameworkhttp://www.ogre3d.org/tikiwiki/Ogre+Wiki+Tutorial+Framework"(external link) class="wiki wikinew">?, which does a lot of behind-the-scenes stuff, including the creation of the Ogre::Root instance.

1c. Ogre::Root::initialise fails — the most common causes.

 

1d. Where is the main rendering loop ? How does it work ( diagram and scheme )

Image
click to enlarge

 

1d. Explicit 'delete root' causes application crash.

 
The most possible cause is: Your application must have deleted Ogre::Root explicitly or implicitly before your 'delete root'.

1d2. Explicit 'root->shutdown()' causes application crash.

 

1d3.Ways of properly shouting down the Ogre3d without leaking the resources.

 

1e. Ogre::Root extra parameters

 

1e2. Example Window without borders.

 
First assign misc"Border" to value "none" .

Next, make sure that when you initialise Ogre, you tell it NOT to create a default window (pass false as the first parameter). Then, create a render window, and assign it to the "window" member variable of your application.

// Create some custom attributes for our manually created window
Ogre::NameValuePairList misc;
misc["border"] = "none";
misc["monitorIndex"] = "0";  // I use two monitors, so I tell Ogre to draw on my main (#1) monitor
 
// Here we tell the system not to create a default rendering window by passing 'false'
mWindow = mRoot->initialise(false, "BasicTutorial7 Render Window");
 
// Now we need to create a render window manually. 
// For now, the dimensions are hardcoded to my desktop size so the window looks full screen
mWindow = mRoot->createRenderWindow("BasicTutorial7 Render Window", 1680, 1050, false, &misc); //pass our custom attributes in "misc"

 

1f. root->showConfigDialog displays an empty window.

 
First you might not have the plugins.cfg file present in your exec's directory. The error message might be quite cryptic though: The last message being some problems with GUI library, and the one about missing plugins.cfg is mysteriously hidden.

Ogre.log wrote:
./plugins.cfg not found, automatic plugin loading disabled.
*-*-* OGRE Initialising
*-*-* Version 1.9.0 (Ghadamon)
Creating resource group GUI
Added resource location './/gui' of type 'FileSystem' to resource group 'GUI' with recursive option
Added resource location './/gui/schemas' of type 'FileSystem' to resource group 'GUI' with recursive option
Creating resource group Graphics
Added resource location './/materials/RTShaderLib' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/materials' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/GLSL' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/Cg' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/scripts' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/textures' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/models' of type 'FileSystem' to resource group 'Graphics' with recursive option
Creating resource group Music
Added resource location './/music' of type 'FileSystem' to resource group 'Music' with recursive option
Creating resource group Sound
Added resource location './/sounds' of type 'FileSystem' to resource group 'Sound' with recursive option
Error: Shell widget menu has zero width and/or height

 
If you have no plugins.cfg, then create one. The following lines should at least be in there (adapt the path for non Linux systems):

plugins.cfg wrote:
# Define plugin folder
PluginFolder=/usr/lib/OGRE

 
If you have there a file say RenderSystem_GL.so (or with longer multiply extensions as on Unixes*) just paste the file name there:

plugins.cfg wrote:
Plugin=RenderSystem_GL

 
When everything is fine you should see in the Ogre.log (or any other file you log into) as well in terminal (if called from terminal):

Ogre.log wrote:
16:16:19: Loading library /usr/lib/OGRE/RenderSystem_GL
16:16:19: Installing plugin: GL RenderSystem
16:16:19: OpenGL Rendering Subsystem created.
16:16:19: Plugin successfully installed

 

1g. What are Root's important containers I would have to modify through it's methods? ( Diagram and Schemes )

 

1g. How the life cycle of handling FrameListeners look like? ( Diagram or Scheme )

 

Image
click to enlarge

 

2. RESOURCES, MATERIALS, AND RESOURCES' MANAGMENT

 
Image

2a. Do I need to use the Resource, ResouceManagers schemes?

2a2. Can I make my game without this mechanism?

 

2b. Why does my object display as white (or black) in Ogre?

2b2. Why does my resource creation or load fail in strange ways?

2b3. What is the Ogre::Resource's typical lifecycle ( diagram or scheme )?

Image
click to enlarge

2b4. What are usual methods of managing this lifecycle?

See the Legend in the picture above ...

2b5. Why is OgreCore.zip missing?

 

2b6. Is there any way to iterate through all resources in a ResourceGroup (for example not only from files)?

 
Unfortunately resource groups are protected members so you can't get to them directly, and only the file based resources are easily accessed by users (resources like a material file are stored in one container, the actual materials within it or manually created resources with no file are stored in a different container. Only the former can be queried by users via the ResourceGroupManager). Like:

Ogre::StringVectorPtr resInGroup =
    Ogre::ResourceGroupManager::getSingletonPtr()->listResourceNames("AResourceGroup");
The hard way of filtering out that is : iterate over all resources' managers , over all resources of each of them and call
Ogre::Resource::getGroup()
and at each check whether it is the searched group.

 

2c. Why it only service small part of assets' types needed to create game (e.g. no music, sound files, no third party data ).

2c2. How do I extend that mechanism for all assets in my game?

2c3. How do I write my own Resource type?

2c4. How do I write my own Resource manager?

 

3. SCENEMANAGERS AND SCENENODES

Inheritance diagram for abstract class Ogre::Node :
Image

3a. Is it necessary to use them in my game?

The scene manager is the primary part of ogre that deals with rendering the user's scene. It handles the creation and destruction of most classes (cameras, lights, renderables, etc). While it's possible to access Ogre's lower level render systems directly, that's not really recommended and isn't documented.
SceneNodes are needed because they hold the transform data for objects, are used for visibility culling and are the way that the scene manager knows which objects to render (anything that isn't attached to a scene node isn't part of the scene, so won't be drawn).
Well, mostly. Certain things don't need scene nodes. In Ogre 1.9 and below, cameras, static geometry and lights don't need scene nodes. They are still part of the scene manager though. In Ogre 2.0, things are a little different. Cameras get added to the root scene node automatically. Static geometry is done with static scene nodes and static entities. I think lights work the same though (not sure).

3b. How does it generally work ?

3b2. There seems to be very little transformations types, why so?

It depends on what you exactly mean by transform types. In the 3D computer graphics special kind of transformations is studied with a special care — Affine_transformation http://en.wikipedia.org/wiki/Affine_transformation(external link) , that is most of the "most necessary" operations are derived from it, also from almost two decades the graphical PC hardware is geared toward the fastest processing of that family of operations.
As to Ogre3d: It supports translation, scale and orientation in the transform of a scene node. The only other transform type that other engines might typically support is skew. Ogre doesn't support skew itself, but it can be done inside of a vertex shader. 3 out of 4 isn't really "very little".

3b3. What is the order of visiting the SceneNodes tree graph? Where does it happen in code?

OgreSceneNode.cpp wrote:
if (includeChildren)
{
ChildNodeMap::iterator child, childend;
childend = mChildren.end();
for (child = mChildren.begin(); child != childend; ++child)
{
SceneNode* sceneChild = static_cast(child-second);
sceneChild-_findVisibleObjects(cam, queue, visibleBounds, includeChildren,
displayNodes, onlyShadowCasters);
}
}

3c. Can I have more than one Entiety to a SceneNode attached?

 
You can have as many renderable objects of any type attached to one scene node. They will all share the same local origin however, as things like entities have no concept of world transforms, the scene node does that for them.

3d. Can I create cycles in the Ogre3d graph?

 
The Ogre scene manager uses a directed acyclic tree.

3e. Can I prevent from inheriting any property from parent to child?

 
The node class has setInheritOrientation() and setInheritScale() methods. These let you enable or disable inheriting those two properties from a parent node. There is no direct position equivalent (you can just use a second scene node instead).

 
If a parent-child relation is no option for you, then you are stuck with handling it yourself by either:

a) Keeping track of all changes of the node you want to follow yourself

b) Using an Ogre::Node::Listener that you can attach to the node you want to track (the "parent") and the once an update event is fired, you update the tracking ("child") node as well:

API: Ogre::Scenenode::setListener()
API: Ogre::Node::Listener::nodeUpated()

3f. When I attach / detach a node then the Ogre3d seems to have delays. Why is it so? Can I improve that?

 
That may depend on the scene manager implementation you're using (i.e. Default vs Octree vs BSP, etc). In some implementations attaching/detaching may be expensive. For this reason SceneNode::setVisible() was implemented (which calls MovableObject::setVisible() internally), which as its doxygen documentation states, is nice for toggling visibility quickly, whereas detaching-reattaching can be used when the node goes out of the scene for long terms.

If you're hierarchy is too vertical and deep (i.e. Node E is child of D, which is child of C, child of B, child of A, child of root), attaching and detaching costs tend to go up. So if you're having performance issues, try flattening your hierarchy.

In Ogre 2.0 the attaching/detaching cost has been greatly reduced; however if you happen to trigger a memory cleanup or a memory pool growth, there can be a significant delay (which can be mitigated by respecting LIFO order of operations and by telling Ogre to allocate a very large pool; respectively).

3g. Is it possible to make a SceneNode follow a specified path or spline curve ?

4. LIGHTING

What is the difference between lighting with fixed vs non-fixed pipeline ?

 
When the early graphic cards came into the market they contained a fixed but large set of functions with which you could influence how 3D object were rendered. These included influencing object positions using matrices, calculating the effect of textures on a pixel, calculating the effect of lights on vertices and so on. These set of functions and their implementation in hardware became later known as the graphic card fixed pipeline (or Fixed Function Pipeline).

As graphic cards became more powerful and graphic application became more complex, a need for new ways to manipulate the rendering of 3D models became apparent. This need saw the introduction of shaders.

Shaders are small custom made programs that run directly on the graphics card. Using these programs, one could replace the calculations that were made by the fixed pipeline and add new functionality. However there was a catch: If shaders are used on an object, the object can no longer use any of the functionality of the fixed pipeline. Any calculation that was used in the fixed pipeline needed to be recreated in the shaders. With early graphics applications this was not problematic. Shaders were simple and their numbers were kept low. However as applications grew in complexity this meant that the need for shaders grew as well. As a programmer you were left with 2 choices, both bad. Either create an exuberant amount of small shaders that soon became too many to effectively maintain. Or create an uber shader, a huge complex shader, that soon became too complex to effectively maintain as well.

The RTSS seeks to fix those problems by automatically generating shaders based on the operations previously required from the fixed pipeline and new capabilities required by the user.

With the introduction of the version 11 of Direct3D, a new reason for having an RTSS like system became apparent. With D3D11 support for fixed pipeline functionality was removed. Meaning, you can only render objects using shaders. The RTSS becomes an excellent tool for this purpose.

The Run Time Shader System, or RTSS for short, is a component of Ogre. This component is used to generate shaders on the fly based on object material properties, scene setup and other user definitions.

Lighting — general questions and fixed pipeline.

 

Which lighting models the Ogre3d supports ?

 
In fixed function (no shaders), Ogre does Blinn-Phong lighting using either Flat or Gouraud shading.
Using shaders, the lighting model is entirely up to you to implement however you want.

(The ogre RTSS might generate other models, I haven't used it — Kojack )

Note: There's a third shading option: Phong (not to be confused with Blinn-Phong lighting). This is a feature of both DirectX and OpenGL. However, no GPU maker ever supported it. It was added to the API's, was unsupported by hardware for years, then was removed in DirectX 10 and above. So you can set ogre to Phong, but it just does Gouraud (not our fault).

Modern lighting techniques are done in shaders. Ogre has no direct support for them, you just do it yourself with the shaders.

Is there limit on Light's number ?

The traditional limit on number of hardware vertex lights using the fixed function pipeline is far and by 8 .

The same is with the ogre3d's max number of vertex lights which can affect a mesh defaults to 8 (OGRE_MAX_SIMULTANEOUS_LIGHTS in ogreconfig.h), but can be changed per material using max_lights in the material script.
Doing per pass lighting or shaders should let you handle more than 8 even on hardware which is limited to 8.

What are ways of avoiding that (supposing I want to stay with vertex lighting of fixed pipeline) ?

 

Light culling (exclude lights which contribution is to little to change the color), and this is determined using light properties (distance, cone, attenuation, point of view and obstructing objects).

Static lighting, which uses textures to emulate lighting on objects which never moves.

How do I achieve light culling with Ogre3d ?

 
A range value can be set on a light (well, not directional lights, they don't have a position) so that the light won't be used on meshes that are outside of the range.

How do I achieve static lighting with Ogre3d ?

 
Static lighting (also called baked lighting) can be generated by modellers like 3ds max, blender, etc.
https://www.youtube.com/watch?v=YOqwwCTfNgk(external link) (Blender)
https://www.youtube.com/watch?v=frPuPNA0daY(external link) (Max)
From ogre's point of view, it's just a mesh with textures. It doesn't know the textures happen to have light embedded in them.

How do I achieve additional number of lights with shaders ?

 
Setting a material to pass per light (http://www.ogre3d.org/docs/manual/manual_16.html#iteration) lets you use infinite lights. However the mesh is rendered with additive lighting for every light within range. If you have 20 lights near an object, then that object will be rendered over the top of itself 20 times.

Using shaders, you can have as many lights in a single pass as you want, limited by the number of constants available in the shader model.

5. RENDERSYSTEM

 

Image
click to enlarge

 

6. MESHES AND MESHMANAGERS

Image


How to ensure a tight bounding box in Ogre3D ?

 
By default, Ogre adds a padding factor to bounding boxes when it loads meshs (to help with culling). The default padding is 0.01.
It finds the size of the object, multiplies that by the pad factor, then extends the box by that amount on every side (subtract from the min, add to the max).
So a bounding box of (-1,-1,-1) to (1,1,1) has a size of (2,2,2). That means the padding will be (0.02,0.02,0.02).
The new corners become (-1.02,-1.02,-1.02) and (1.02,1.02,1.02), so the total bounding box size is now (2.04,2.04,2.04).

You can turn off the padding by calling MeshManager::getSingleton().setBoundsPaddingFactor(0); before loading any meshes.

 

99. LICENSING FAQ

 

Is OGRE really free?

If you abide by the open source licensing conditions, yes.

Do I have to release my own source code if I use OGRE?

A: No.

Do I have to release changes I make to OGRE?

A: From Ogre 1.7 we use the MIT license, which does not require you to do this. However, you should consider the maintenance overhead of keeping your own custom version of OGRE, versus the advantages you might get from participating in the community (such as bugfixes and extensions that others may make on top of yours).

What do I need to do to abide by the MIT license?

A: Simply include our license text somewhere in your own software distribution; this could be in a text file, in a printed manual, in the credits, etc.

Do I have to display an OGRE logo in my application, in splash screen or startup sequence for example?

A: No, although we appreciate the publicity if you would like to do this!

At what point do I have to ensure that I’ve complied with the license?

A: When you distribute any part of your application to a third party.

==================

100. OGRE3D CODING STYLE:

paul424 asks, dark_sync answers

 

1. Is the Ogre3d error-liberal or error-conservative engine ?

 
Ogre treats important and fatal user/input errors... as fatal. They will raise an exception. Exceptions can be caught and program execution will continue while leaving the error in the log. Minor errors often just leave a warning in the log.
Sometimes it is Ogre itself which raised and caught the exception.
Other times it's the user who may try to catch it or decide to leave it uncaught forcing program termination.
For example in Ogre Meshy I catch most of the errors to prevent crashing, making the mesh viewer tool very stable even with rare meshes.
But in my game, I often don't catch these, just catch them at the top level main(), leave a message box and terminate the program, so that asset problems don't start piling up silently until I check the log.

2. Extensive use of objects' retrival mechanism by their name set on the application code side ( programmer ? ) .

 
I hate this pattern from 1.x as it is inefficient. In 2.x, names are optional, and we're favouring the pattern of storing the pointer when you create it. Other retrieval mechanism exists, and now every object has a unique ID at least.

3. Use of smart pointers (achieved by it's own cooked templates).

 
Use with care. Materials, textures and shaders in Ogre are smart pointers. While one Entity refereces they won't be destroyed. But smart pointers have non-negligent overhead.
Often it's better to have a good design of the lifetime of an object.

4. All complex declarations are hidden behind the typdef directive. Internal type system which is independent of what compiler / c++ std library you are using.

 

5. Extensive use of Managers ( in OO pattern nomenclature : Factories ) when comes to object creation.

 

6. Extensive use of Singleton patterns for main objects ( managers ).

 
No. God no!. Using singletons was one huge mistake. Taking them out requires a huge undertaking, so they're staying. But we're not adding more and we discourage singletons.

7. All rendering operations which require API's calls of 3d libs ( DirectX, OpenGL) are realized in external plugins.

 
Yes. Sadly history showed us this wasn't perhaps the best choice (it wasn't a mistake though). A RenderSystem chosen at compile-time has many more optimization opportunities, while a RenderSystem chosen at runtimes through plugins has little advantages (users rarely change render system at all, unless the app is well written, switching may not be painless i.e. crash; and you can provide multiple binaries for each RS if you want diversity).

 

101. Common Rendering Artifacts Gallery :

UNDER HEAVY CONSTRUCTION ; DO NOT READ THAT YET :\


Image

 


Contributors to this page: paul42456 points  , spacegaier6073 points  and dark_sylinc1400 points  .
Page last modified on Sunday 02 of April, 2017 14:45:17 UTC by paul42456 points .


The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.