<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1245195918198356162</id><updated>2012-01-24T09:02:26.099+01:00</updated><category term='3d graphics game engine opengl reality factory'/><title type='text'>Wunderwerk Engine Development Blog</title><subtitle type='html'>Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It comes with a powerful game editor which enables its users to create high quality computer games without having to touch its source code. The engine exposes most of its functionality through a simple C-style scripting API.

The engine is targeted at aspiring game designers who want to transform their ideas into a game but lack the programming skills. Wunderwerk Engine will make this possible.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-1349849740472438370</id><published>2012-01-23T10:59:00.000+01:00</published><updated>2012-01-23T11:09:39.853+01:00</updated><title type='text'>Material system</title><content type='html'>I've been working on the material system lately. A material handles the textures and shaders used when rendering a mesh. Every material has its own shading program, which consists of a vertex shader, a fragment shader and an optional geometry shader. Some of the material's properties, like its number of texture layers, are compiled directly into the shaders, while others, like material colors, can be updated at run-time using uniform variables.&lt;br /&gt;&lt;br /&gt;Materials can be made up of several layers which are blended on top of each other with a variety of blend modes, very similar to Photoshop. A texture layer can contain a diffuse texture with an optional alpha channel (for transparency effects), a normal map with a height component stored in the alpha channel (for parallax mapping and similar effects) and a specular map. Internally, texture layers are represented by &lt;a href="http://www.opengl.org/wiki/Array_Texture"&gt;array textures&lt;/a&gt;. This brings the advantage that only one texture object has to be bound per layer, effectively reducing the number of texture binds by two thirds (diffuse, normal and specular maps are all adressed by the same sampler in the shader).&lt;br /&gt;&lt;br /&gt;In addition, texture layers can be scrolled, stretched or rotated for effects like animated computer screens etc. This was heavily used in Quake 3, for example. I'll show an example of that later (if I don't forget as usual).&lt;br /&gt;&lt;br /&gt;The wall on the screenshot is composed of four images (as seen on the left). You can see the material definition in the upper left corner.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-NMHTTr7Z7mE/Tx0uFjbIbwI/AAAAAAAAALo/WrDL7PjXg4A/s1600/material-system%255B1%255D.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://1.bp.blogspot.com/-NMHTTr7Z7mE/Tx0uFjbIbwI/AAAAAAAAALo/WrDL7PjXg4A/s320/material-system%255B1%255D.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-1349849740472438370?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/1349849740472438370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2012/01/material-system.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1349849740472438370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1349849740472438370'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2012/01/material-system.html' title='Material system'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-NMHTTr7Z7mE/Tx0uFjbIbwI/AAAAAAAAALo/WrDL7PjXg4A/s72-c/material-system%255B1%255D.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-560091441879621947</id><published>2012-01-09T16:24:00.005+01:00</published><updated>2012-01-09T18:40:04.906+01:00</updated><title type='text'>Level export and portal rendering</title><content type='html'>I've been a busy bee these past months even though I failed, as usual, to report on my progress.. so here's a short recap.&lt;br /&gt;&lt;br /&gt;I designed the engine's level format and wrote a Blender script which creates levels from prepared .blend files. Levels use portals and bounding volume hierarchies for fast visibility detection. This way, both indoor and outdoor scenes can be rendered&amp;nbsp;reasonably fast and, most importantly, mixed. For now, portals have to be set manually in Blender. It works like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The artist creates an indoor level as a series of connected rooms. Every room must be a separate object.&lt;/li&gt;&lt;li&gt;Portal polygons are created for every door, window, etc. which connects two rooms or a room with the outside. Every portal polygon must be kept as a separate object, its name must begin with "p_" to tell the export script it's a portal.&lt;/li&gt;&lt;li&gt;The export script creates a list of rooms and portals and their connections. In addition, a bounding volume hierarchy is created from the rooms and free objects (landscapes, detail meshes, etc.)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;This way, portals are merely an optional optimization; if the scene you're working with it rather simple or you simply want to preview a complex level and don't care to much about speed, you can simply skip portal creation; potential rooms will then be placed in the bounding volume hierarchy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A portal's definition in the level file may look like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; portal02                       // portal's name&lt;br /&gt; room02                         // target room's name  &lt;br /&gt; 4                              // number of vertices&lt;br /&gt; -2.947355 0.001296 -4.529554   // vertex #1   &lt;br /&gt; -2.947347 3.001296 -4.529551   // vertex #2    &lt;br /&gt; -4.947346 3.001301 -4.529550   // vertex #3    &lt;br /&gt; -4.947354 0.001301 -4.529554   // vertex #4   &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The next step was to put the new information to use. When a camera's render routine is called, it first determines the smallest sector&amp;nbsp;it is in. Then it traverses the portals connected with this&amp;nbsp;sector and recursively performs the following steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If it is not completely visible, the portal is clipped to the screen.&lt;/li&gt;&lt;li&gt;If the clipped portal has more or less than four vertices, it is replaced by its projected bounding rectangle.&lt;/li&gt;&lt;li&gt;A new view frustum is computed from the clipped portal, using the portal's plane as the new near clipping plane.&lt;/li&gt;&lt;li&gt;The sector is rendered using the new frustum.&lt;/li&gt;&lt;li&gt;The entity components (meshes, sprites, etc.) contained in the sector are rendered.&lt;/li&gt;&lt;li&gt;Sub-sectors are rendered.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Here's a screenshot with debug visualizations of the portals created during the recursive process:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-8eASONJvXgM/TwsHDgoucCI/AAAAAAAAALc/wQAYZ4zKDEg/s1600/portals.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="360" src="http://4.bp.blogspot.com/-8eASONJvXgM/TwsHDgoucCI/AAAAAAAAALc/wQAYZ4zKDEg/s640/portals.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The player's camera sees what is displayed in the top-right viewport. It is positioned in the first room. The doorway acts as a portal to the adjacent corridor, which in turn acts as a portal to the next room, and so on. This means that only parts of all rooms following the first are visible from the camera's current position, and only these parts and the entities they contain have to be rendered.The white frustum visualizes the camera's perspective from the first room, the turquoise frustum its perspective from the adjacent corridor, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-560091441879621947?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/560091441879621947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2012/01/level-export-and-portal-rendering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/560091441879621947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/560091441879621947'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2012/01/level-export-and-portal-rendering.html' title='Level export and portal rendering'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-8eASONJvXgM/TwsHDgoucCI/AAAAAAAAALc/wQAYZ4zKDEg/s72-c/portals.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-1413226983908909081</id><published>2011-10-12T22:20:00.003+02:00</published><updated>2011-10-12T22:21:07.509+02:00</updated><title type='text'>AABB vs. OBB</title><content type='html'>The lack of posts in the last weeks was not due to a lack of progress on the engine.. what I've been working on is just not very interesting: I've ported the frustum culling and collision detection code from the old framework into the new engine and it's finally all working as it should.&lt;br /&gt;&lt;br /&gt;I've been struggling to implement culling and intersection tests for oriented bounding boxes (OBB) and discarded them eventually; instead, I simply rotate the eight corner points of an entity's axis-alinged bounding box to dynamically compute a larger AABB which encompasses the rotated entity. This is still pretty fast and works just as well.&lt;br /&gt;&lt;br /&gt;Next task: Bullet integration.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4TxP4H59Sfo/TpX2GUULruI/AAAAAAAAAKg/x4FsRzUkjoA/s1600/culling.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="360" src="http://3.bp.blogspot.com/-4TxP4H59Sfo/TpX2GUULruI/AAAAAAAAAKg/x4FsRzUkjoA/s640/culling.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-1413226983908909081?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/1413226983908909081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2011/10/just-quick-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1413226983908909081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1413226983908909081'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2011/10/just-quick-update.html' title='AABB vs. OBB'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-4TxP4H59Sfo/TpX2GUULruI/AAAAAAAAAKg/x4FsRzUkjoA/s72-c/culling.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-9032460878760335654</id><published>2011-09-06T14:03:00.002+02:00</published><updated>2011-09-06T14:05:27.580+02:00</updated><title type='text'>Just a small update</title><content type='html'>I've added project serialization using &lt;a href="http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/index.html"&gt;boost::serialization&lt;/a&gt;; although it was rather easy to implement, it took some time until I fully understood how to serialize classes which inherit from one or several base classes. For example, all entity components inherit from a base class &lt;i&gt;EntityComponent &lt;/i&gt;which among others serializes the component's parent transform. Similarily, all resources inherit from a common base class &lt;i&gt;Resource&lt;/i&gt;, which stores the resource's file path. In order to make sure that the desired inherited class members are serialized properly as well, one should use the BOOST_CLASS_EXPORT_GUID macro, which has to be defined for every class at the top of each source file from which these classes are serialized:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; BOOST_CLASS_EXPORT_GUID( EntityComponent, "EntityComponent" )  &lt;br /&gt; BOOST_CLASS_EXPORT_GUID( ModelController, "ModelController" )  &lt;br /&gt; BOOST_CLASS_EXPORT_GUID( CameraController, "CameraController" )  &lt;br /&gt; BOOST_CLASS_EXPORT_GUID( SkeletonController, "SkeletonController" )  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If not used, your program may simply crash without telling you where and why. At least that's what happened to me, ruining an otherwise perfectly fine Saturday afternoon :/ &lt;br /&gt;&lt;br /&gt;Also, it's now possible to create and attach cameras to entities through the editor. In addition to their primary free-fly camera, all 3D viewport can then select and preview all available cameras. This is useful to set up and test in-game cameras. The screenshot illustrates how a third person camera may be set up for a mech game:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-G6HfdsB5OqE/TmYHB24jjnI/AAAAAAAAAKc/22_H2m7au4I/s1600/cam.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="340" src="http://2.bp.blogspot.com/-G6HfdsB5OqE/TmYHB24jjnI/AAAAAAAAAKc/22_H2m7au4I/s640/cam.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-9032460878760335654?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/9032460878760335654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2011/09/just-small-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/9032460878760335654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/9032460878760335654'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2011/09/just-small-update.html' title='Just a small update'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-G6HfdsB5OqE/TmYHB24jjnI/AAAAAAAAAKc/22_H2m7au4I/s72-c/cam.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-7450441031814248409</id><published>2011-09-02T13:09:00.001+02:00</published><updated>2011-09-02T13:25:46.332+02:00</updated><title type='text'>A Transform class</title><content type='html'>When listing all the third party libraries I'm using for the new framework, I forgot to mention one library that has become indispensable in development: &lt;a href="http://glm.g-truc.net/"&gt;GLM&lt;/a&gt;, a mathematics library for graphics software 			based on the &lt;a href="http://www.opengl.org/documentation/glsl/"&gt;OpenGL Shading Language (GLSL)&lt;/a&gt; specification, written and maintained by Christophe Riccio.&lt;br /&gt;&lt;br /&gt;Despite its excellent design it may be tricky to use sometimes, so I've decided to post my &lt;i&gt;Transform&lt;/i&gt; class which is the engine's base class for all translation, rotation and scaling transformations and also computes a view matrix to be used in vertex shaders. Complex hierachies can be created by providing the view matrix of a superordinate &lt;i&gt;Transform&lt;/i&gt;'s view matrix to the &lt;i&gt;update()&lt;/i&gt; routine. The &lt;i&gt;m_timePassed&lt;/i&gt; variable may prove useful for physics simulation.&lt;br /&gt;&lt;br /&gt;Transform.h&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: 250px; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;class &lt;/b&gt;Transform  &lt;br /&gt; {  &lt;br /&gt;      &lt;b style="color: #073763;"&gt;public:&lt;/b&gt;  &lt;br /&gt;   &lt;br /&gt;           Transform();  &lt;br /&gt;   &lt;br /&gt;           Transform( &lt;b style="color: #073763;"&gt;const &lt;/b&gt;quat &amp;amp;rotation );  &lt;br /&gt;           Transform( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation );  &lt;br /&gt;   &lt;br /&gt;           Transform( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation, &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation );  &lt;br /&gt;   &lt;br /&gt;      &lt;b style="color: #073763;"&gt;public:&lt;/b&gt;  &lt;br /&gt;   &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;getScaling() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;getRotation() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;getTranslation() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt;   &lt;br /&gt;           &lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;setScaling( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;scaling );  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;setRotation( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation );  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;setTranslation( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation );  &lt;br /&gt;   &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;scale( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;scaling );  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;rotate( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation );  &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;translate( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation, &lt;b&gt;&lt;span style="color: #073763;"&gt;bool &lt;/span&gt;&lt;/b&gt;global = &lt;b style="color: #073763;"&gt;false &lt;/b&gt;);  &lt;br /&gt;   &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;setScaling( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;float &lt;/b&gt;&amp;amp;scaling )  &lt;br /&gt;           {  &lt;br /&gt;                setScaling( vec3(scaling) );  &lt;br /&gt;           }  &lt;br /&gt;   &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;scale( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;float &amp;amp;scaling )  &lt;br /&gt;           {  &lt;br /&gt;                scale( vec3(scaling) );  &lt;br /&gt;           }  &lt;br /&gt;   &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;public:&lt;/span&gt;&lt;/b&gt;  &lt;br /&gt;   &lt;br /&gt;           &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;mat4 &amp;amp;getModelMatrix() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt;   &lt;br /&gt;           &lt;b&gt;&lt;span style="color: #073763;"&gt;virtual void&lt;/span&gt;&lt;/b&gt; update( double deltaTime, &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;mat4 &amp;amp;modelMatrix = mat4(), &lt;b&gt;&lt;span style="color: #073763;"&gt;bool &lt;/span&gt;&lt;/b&gt;force = false );  &lt;br /&gt;   &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;private: &lt;/span&gt;&lt;/b&gt; &lt;br /&gt;   &lt;br /&gt;           vec3 m_scaling;  &lt;br /&gt;           quat m_rotation;  &lt;br /&gt;           vec3 m_translation;  &lt;br /&gt;             &lt;br /&gt;           &lt;b&gt;&lt;span style="color: #073763;"&gt;bool &lt;/span&gt;&lt;/b&gt;m_needUpdate;  &lt;br /&gt;           &lt;b&gt;&lt;span style="color: #073763;"&gt;long &lt;/span&gt;&lt;/b&gt;m_timePassed;  &lt;br /&gt;           &lt;b&gt;&lt;span style="color: #073763;"&gt;long &lt;/span&gt;&lt;/b&gt;m_lastUpdate;  &lt;br /&gt;   &lt;br /&gt;           mat4 m_modelMatrix;  &lt;br /&gt; };  &lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Transform.cpp&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: 250px; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;b style="color: #073763;"&gt; &lt;/b&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;#include&lt;/b&gt; "Transform.h"  &lt;br /&gt;   &lt;br /&gt; Transform::Transform()  &lt;br /&gt; {  &lt;br /&gt;      setScaling( vec3(1.0f) );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; Transform::Transform( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation )  &lt;br /&gt; {  &lt;br /&gt;      setScaling( vec3(1.0f) );  &lt;br /&gt;   &lt;br /&gt;      setRotation( rotation );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; Transform::Transform( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation )  &lt;br /&gt; {  &lt;br /&gt;      setScaling( vec3(1.0f) );  &lt;br /&gt;   &lt;br /&gt;      setTranslation( translation );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; Transform::Transform( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation, &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation )  &lt;br /&gt; {  &lt;br /&gt;      setScaling( vec3(1.0f) );  &lt;br /&gt;   &lt;br /&gt;      setRotation( rotation );  &lt;br /&gt;      setTranslation( translation );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;mat4 &amp;amp;Transform::getModelMatrix() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; {  &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;return &lt;/span&gt;&lt;/b&gt;m_modelMatrix;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;Transform::getScaling() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; {  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;return &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;m_scaling;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;Transform::getRotation() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; {  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;return &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;m_rotation;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;Transform::getTranslation() &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; {  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;return &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;m_translation;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::setScaling( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;scaling )  &lt;br /&gt; {  &lt;br /&gt;      m_scaling = scaling;  &lt;br /&gt;      m_needUpdate = &lt;b style="color: #073763;"&gt;true&lt;/b&gt;;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::setRotation( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation )  &lt;br /&gt; {  &lt;br /&gt;      m_rotation = rotation;  &lt;br /&gt;      m_needUpdate = &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;true&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::setTranslation( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation )  &lt;br /&gt; {  &lt;br /&gt;      m_translation = translation;  &lt;br /&gt;      m_needUpdate = &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;true&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;;  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::scale( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;scaling )  &lt;br /&gt; {  &lt;br /&gt;      setScaling( m_scaling*scaling );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::rotate( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;quat &amp;amp;rotation )  &lt;br /&gt; {  &lt;br /&gt;      setRotation( glm::cross(m_rotation, rotation) );  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::translate( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;vec3 &amp;amp;translation, bool global )  &lt;br /&gt; {  &lt;br /&gt;      &lt;b style="color: #073763;"&gt;if&lt;/b&gt;( global )  &lt;br /&gt;      {  &lt;br /&gt;           setTranslation( m_translation+translation );  &lt;br /&gt;      }  &lt;br /&gt;      &lt;b style="color: #073763;"&gt;else  &lt;/b&gt;&lt;br /&gt;      {  &lt;br /&gt;           setTranslation( m_translation+(m_rotation*translation) );  &lt;br /&gt;      }  &lt;br /&gt; }  &lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Transform::update( &lt;b&gt;&lt;span style="color: #073763;"&gt;double &lt;/span&gt;&lt;/b&gt;deltaTime, &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;const &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;mat4 &amp;amp;modelMatrix, &lt;b style="color: #073763;"&gt;bool &lt;/b&gt;force )  &lt;br /&gt; {  &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;long &lt;/span&gt;&lt;/b&gt;thisUpdate = clock();  &lt;br /&gt;      m_timePassed = thisUpdate-m_lastUpdate;  &lt;br /&gt;   &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;const bool&lt;/span&gt;&lt;/b&gt; performUpdate = force || m_needUpdate;  &lt;br /&gt;   &lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;if&lt;/span&gt;&lt;/b&gt;( performUpdate )  &lt;br /&gt;      {  &lt;br /&gt;           mat4 rotationMatrix = glm::mat4_cast( glm::normalize(m_rotation) );  &lt;br /&gt;           mat4 translationMatrix = glm::translate( mat4(), m_translation );  &lt;br /&gt;             &lt;br /&gt;           m_modelMatrix = translationMatrix*rotationMatrix;  &lt;br /&gt;           m_modelMatrix = glm::scale( m_modelMatrix, m_scaling );  &lt;br /&gt;   &lt;br /&gt;           m_modelMatrix = modelMatrix*m_modelMatrix;  &lt;br /&gt;   &lt;br /&gt;           m_needUpdate = &lt;b style="color: #073763;"&gt;false&lt;/b&gt;;  &lt;br /&gt;      }  &lt;br /&gt;        &lt;br /&gt;      m_lastUpdate = clock();  &lt;br /&gt; }  &lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-7450441031814248409?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/7450441031814248409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2011/09/transform-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/7450441031814248409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/7450441031814248409'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2011/09/transform-class.html' title='A Transform class'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-4948040049256842796</id><published>2011-08-31T14:53:00.001+02:00</published><updated>2011-09-01T23:02:01.173+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='3d graphics game engine opengl reality factory'/><title type='text'>I have to be the worst blogger ever.. (also, a video!)</title><content type='html'>Despite the usual sparsity of blog updates I've been working a lot on the engine and the editor over the course of this summer and I'm proud to say that I've made quite some progress! Considering that I haven't been writing anything in months and that noone probably remembers what this is all about anyway, I feel like I should give a quick recap.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My motivation (or justification)&lt;/b&gt;&lt;br /&gt;Some of you may remember &lt;a href="http://www.realityfactory.info/"&gt;RealityFactory&lt;/a&gt;, a gameshell based on the then popular open source game engine &lt;a href="http://www.genesis3d.com/"&gt;Genesis3D&lt;/a&gt;. The idea behind RealityFactory was (and apparently still is - there still seem to be some people around from back then!) to allow non-programmers to create computer games, merely relying on a set of level and game editors and some scripting. Frustrated by my own puny attempts at writing games using Genesis3D by essentially hacking the included (and horribly written) game shell I became a huge fan of the RealityFactory project and stayed active for several years. That was around 2003 and 2005. Time went by and eventually, people started asking for a replacement of the outdated Genesis3D engine. I raised my hand and teamed up with an American guy who at some point lost interest but the idea of creating a piece of software that would give people the chance to realize their games and learn as much I had with RealityFactory kept me going.&lt;br /&gt;&lt;br /&gt;Looking for a suitable graphics engine to base my RF2 candidate on, I stumbled upon &lt;a href="http://neoengine.sourceforge.net/index.oldsite.php"&gt;NeoEngine&lt;/a&gt;. The project was ultimately abandoned by its founder; while trying (and for the most part failing) to add new features myself I realized that graphics engine programming didn't seem to be all that hard after all, and after I had taken a look at some other open source engines and decided I didn't like any of them (basically because I hadn't written them - of course most of these were and still are great pieces of software) I decided to write my own graphics engine which would later develop into a full-blown game engine.&lt;br /&gt;&lt;br /&gt;That, of course, never happened. I got so tangled up in improving graphics that I forgot about my original intention of creating a game engine. The result was a decent but utterly slow graphics engine with support for some basic physics. And, of course, I learned a lot about how NOT to plan a project. You can still find screenshots and videos of this project in previous blog posts. So in the summer of 2009, I started from scratch. I built up a stable foundation first, utilizing all the knowledge I gained in the process of building the previous engine and considered such (basic) concepts like interfaces for sub-systems like graphics, audio, physics and scripting and the integration of more third party libraries, first and foremost &lt;a href="http://www.boost.org/"&gt;boost&lt;/a&gt;. Since then, I've been working on and off. This summer has been very productive - I've been on semester break, my part-time job is pretty relaxed, the girlfriend visting her parents, and so I've been working eight to ten hours a day for the last few weeks.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Wunderwerk Engine ("the engine")&lt;/b&gt;&lt;br /&gt;The engine's core consists of four sub-systems: graphics, sound, physics and scripting. All but one (physics) are functioning and more or less complete. The graphics engine currently uses OpenGL 3.3 in the core profile. A switch to OpenGL 4.x would exclude many and gain little, so I'll wait. Right now, only a very basic rendering pipeline is implemented, allowing for simple per-pixel shading. I'm planning to implement and extend the old engine's deferred shading pipeline and post-processing framework soon. Have a look at older posts for some screenshots and videos. The sound engine uses OpenAL and is more or less finished. It features playback and mixing of positioned 3D sound and music. Not much to say here, really. The old engine's physics engine was powered by &lt;a href="http://bulletphysics.org/"&gt;Bullet Dynamics&lt;/a&gt; and will be &lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps"&gt;incorporated &lt;/span&gt;&lt;/span&gt;as soon as the octree implementation is finished. Scripting is realized using the &lt;a href="http://www.lua.org/"&gt;Lua scripting language&lt;/a&gt;, which I've grown quite fond of. The entity system exposes most of its functionality through a simple, C-style scripting API.&lt;br /&gt;&lt;br /&gt;Here is an example of a (very, very) simple AI script; a zombie approaches and reaches for the player depending on their distance to each other (read bottom to top):&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: 250px; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;function &lt;/b&gt;idle( deltaTime )  &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- blend idle animation  &lt;/span&gt;&lt;br /&gt;      stopCycle( "Zombie", "Skeleton", "Walk", 0.5 )  &lt;br /&gt;      playCycle( "Zombie", "Skeleton", "Idle", 1.0, 0.5 )  &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;function &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;attack( deltaTime )  &lt;br /&gt;      speed = 0.6  &lt;br /&gt;      rotSpeed = 4.0  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- fade idle animation &lt;/span&gt; &lt;br /&gt;      stopCycle( "Zombie", "Skeleton", "Idle", 0.5 )  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- query zombie's health  &lt;/span&gt;&lt;br /&gt;      health = getAttribute("Zombie", "Health")  &lt;br /&gt;        &lt;br /&gt;      &lt;b style="color: #073763;"&gt;if &lt;/b&gt;health &amp;gt; 50 &lt;b style="color: #073763;"&gt;then  &lt;/b&gt;&lt;br /&gt;           &lt;span style="color: #38761d;"&gt;-- blend walk animation  &lt;/span&gt;&lt;br /&gt;           stopCycle( "Zombie", "Skeleton", "Limp", 0.5 )  &lt;br /&gt;           playCycle( "Zombie", "Skeleton", "Walk", 1.0, 0.5 )  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;else  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;           speed = 0.25  &lt;br /&gt;           rotSpeed = 1.5  &lt;br /&gt;   &lt;br /&gt;           &lt;span style="color: #38761d;"&gt;-- blend limp animation  &lt;/span&gt;&lt;br /&gt;           stopCycle( "Zombie", "Skeleton", "Walk", 0.5 )  &lt;br /&gt;           playCycle( "Zombie", "Skeleton", "Limp", 1.0, 0.5 )  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- get position vectors  &lt;/span&gt;&lt;br /&gt;      eyePos = getTranslation("Zombie")  &lt;br /&gt;      targetPos = getTranslation("Player")  &lt;br /&gt;      targetPos = vec3( targetPos.x, eyePos.y, targetPos.z )  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- compute look at matrix  &lt;/span&gt;&lt;br /&gt;      lookAtMatrix = lookAt( eyePos, targetPos, vec3(0, 1, 0) )  &lt;br /&gt;        &lt;br /&gt;      eyeRot = getRotation( "Zombie")  &lt;br /&gt;      targetRot = inverse(quat(lookAtMatrix))  &lt;br /&gt;      rotation = shortMix( eyeRot, targetRot, rotSpeed*deltaTime )  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- make zombie look at player &lt;/span&gt; &lt;br /&gt;      setRotation( "Zombie", rotation );  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- move towards player  &lt;/span&gt;&lt;br /&gt;      translate( "Zombie", vec3(0, 0, -speed*deltaTime) )  &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;function &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;slam( deltaTime )  &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- is slam animation already playing?  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;if &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;isActionPlaying("Zombie", "Skeleton", "Slam") == false &lt;b style="color: #073763;"&gt;then  &lt;/b&gt;&lt;br /&gt;           &lt;span style="color: #38761d;"&gt;-- stop animation cycles  &lt;/span&gt;&lt;br /&gt;           stopCycle( "Zombie", "Skeleton", "Walk", 0.25 )  &lt;br /&gt;           stopCycle( "Zombie", "Skeleton", "Idle", 0.25 )  &lt;br /&gt;             &lt;br /&gt;           &lt;span style="color: #38761d;"&gt;-- blend slam animation  &lt;/span&gt;&lt;br /&gt;           playAction( "Zombie", "Skeleton", "Slam", 0.15, 0.0 )  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;   &lt;br /&gt; &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;function &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;update( deltaTime )  &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- get position vectors  &lt;/span&gt;&lt;br /&gt;      pos = getTranslation( "Zombie" )  &lt;br /&gt;      target = getTranslation( "Player" )  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- calculate distance from player  &lt;/span&gt;&lt;br /&gt;      distanceFromPlayer = distance( pos, target )  &lt;br /&gt;        &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- slam if very close  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;if &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;distanceFromPlayer &amp;lt; 1 &lt;b style="color: #073763;"&gt;then  &lt;/b&gt;&lt;br /&gt;           slam( deltaTime )  &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- walk towards if close  &lt;/span&gt;&lt;br /&gt;      &lt;b style="color: #073763;"&gt;elseif &lt;/b&gt;distanceFromPlayer &amp;lt; 5 &lt;b&gt;&lt;span style="color: #073763;"&gt;then  &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;           attack( deltaTime )  &lt;br /&gt;      &lt;b style="color: #073763;"&gt;else  &lt;/b&gt;&lt;br /&gt;      &lt;span style="color: #38761d;"&gt;-- ignore if far  &lt;/span&gt;&lt;br /&gt;           idle( deltaTime )  &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt; &lt;b style="color: #073763;"&gt;end  &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Resource managment is finished and the entity system is basically complete. Static and animated models can be exported from &lt;a href="http://www.blender.org/"&gt;Blender&lt;/a&gt;, which is actively developed and most importantly, free. Textures have to be provided in .dds format; there's exporters for both Gimp and Photoshop. The sound engine expects files stored in the OggVorbis format, which provides quality similar to MP3 without the competitor's license restrictions.&lt;br /&gt;&lt;br /&gt;The entity system uses a component-based approach in place of the classical &lt;span class="st"&gt;inheritance-based one, which means that there is e.g. an entity class &lt;i&gt;Model &lt;/i&gt;which derives from a base class &lt;i&gt;RenderEntity &lt;/i&gt;which in turn derives from an abstract base class &lt;i&gt;Entity&lt;/i&gt;. Instead, an entity is merely a container for an arbitrary number of entity components such as models, sounds, cameras, decals etc. All these components have in common are a spatial or logical connection.&amp;nbsp; There's numerous threads on &lt;a href="http://www.gamedev.net/hub/community"&gt;gamedev.net&lt;/a&gt; dealing with the pros and cons to both approaches, in case you're interested. What was important to me is that the entity components themselves and the camera rendering them are ignorant of the entities these components have been attached to. Instead, whenever an entity component is added to an entity, it is added to a pool of like components and merely keeps a reference to the transform part (i.e. translation, rotation, scaling) &lt;/span&gt;&lt;span class="st"&gt;of its parent entity&lt;/span&gt;&lt;span class="st"&gt;. During rendering, a camera then fetches relevant components from these pools and renders them accordingly.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="st"&gt;Composing e.g. a player entity which contains an animated model, the corresponding skeleton and a camera could look like this:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: 250px; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &lt;span style="font-size: x-small;"&gt;shared_ptr&amp;lt;Entity&amp;gt; setupPlayer( shared_ptr&amp;lt;ResourceManager&amp;gt; resourceManager )  &lt;br /&gt; {       &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// load resources  &lt;/span&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: #073763;"&gt;auto &lt;/span&gt;&lt;/b&gt;model = resourceManager-&amp;gt;loadResourceAs&amp;lt;Model&amp;gt;( "ak-47.model" );  &lt;br /&gt;      auto skeleton = resourceManager-&amp;gt;loadResourceAs&amp;lt;Skeleton&amp;gt;( "ak-47.skeleton" );  &lt;br /&gt;&lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// setup camera  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;auto &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;camera = shared_ptr&amp;lt;Camera&amp;gt;( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Camera(60.0f, vec2(1.0f, 1000.0f)) );  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// setup mesh controller  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;auto &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;modelController = shared_ptr&amp;lt;ModelController&amp;gt;( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;ModelController(model) );  &lt;br /&gt;   &lt;br /&gt;     &lt;span style="color: #38761d;"&gt; // setup skeleton controller  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;auto &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;skeletonController = shared_ptr&amp;lt;SkeletonController&amp;gt;( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;SkeletonController(skeleton) );  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// add skeleton as modifier &lt;/span&gt; &lt;br /&gt;      modelController-&amp;gt;addModifier( L"SkeletonModifier", skeletonController );  &lt;br /&gt;   &lt;br /&gt;     &lt;span style="color: #38761d;"&gt; // setup new entity  &lt;/span&gt;&lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;auto &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;entity = shared_ptr&amp;lt;Entity&amp;gt;( &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Entity() );  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// add mesh controller to entity  &lt;/span&gt;&lt;br /&gt;      entity-&amp;gt;addComponent( L"WeaponMesh", modelController );  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// add skeleton controller to entity  &lt;/span&gt;&lt;br /&gt;      entity-&amp;gt;addComponent( L"Skeleton", skeletonController );  &lt;br /&gt;   &lt;br /&gt;      &lt;span style="color: #38761d;"&gt;// add camera to entity  &lt;/span&gt;&lt;br /&gt;      entity-&amp;gt;addComponent( L"Camera", shared_ptr&amp;lt;CameraController&amp;gt;(&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;CameraController(camera)) );  &lt;br /&gt;   &lt;br /&gt;      &lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #073763;"&gt;return &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/code&gt;&lt;code style="color: black; word-wrap: normal;"&gt;&lt;span style="font-size: x-small;"&gt;entity;  &lt;br /&gt; }  &lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span class="st"&gt;This is tedious and we don't want users to have to deal with writing code anyway&lt;/span&gt;&lt;span class="st"&gt;, so that's where the editor comes in.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Weltwunder Editor ("the editor")&lt;/b&gt;&lt;br /&gt;The editor's task will be to populate the game world with static geometry (the "level") and entities and to attach the appropiate scripts to them. The game world you create is the starting point of the simulation when the game is started. The player's interaction with the world and its entities is then controlled by scripts. Scripts can either be executed once each frame or started from other scripts, e.g. when the player enters a specific area or presses a button.&lt;br /&gt;The editor uses the &lt;a href="http://www.wxwidgets.org/"&gt;wxWidgets &lt;/a&gt;framework and would so - theoretically - run on multiple platforms. Right now, I'm developing on and for Windows only, though. It also has, just like the engine, full support for Unicode and is currently available in English, German and French.&lt;br /&gt;&lt;br /&gt;The following short video shows how to create an entity representing an animated mesh model. It could be extended by adding headlights, muzzle flashes, sound effects, etc. Using the entity's name, all components can then be controlled in scripts.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/rPATYJCVNLQ/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rPATYJCVNLQ?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="728" height="505"  src="http://www.youtube.com/v/rPATYJCVNLQ?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;Over the past week, I was racking my brains over the degree of asset customization that should be available to the user from within the editor. Usually, assets exported from Blender are perfectly fine and ready to use, but the engine supports some advanced material settings such as several texture layers each with different blend modes, texture coordinate generators, etc. which cannot be customized from within Blender. The problem is - how would I save such customizations? Should I overwrite the original files? What if the user re-imports his assets? In the end I decided to either write a small Blender plug-in or a stand-alone material editor.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The game shell &lt;/b&gt;&lt;br /&gt;The game shell loads a world created by the editor and handles script execution to simulate a game. It works.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What lies ahead?&lt;/b&gt; &lt;br /&gt;Right now, my focus is on the editor, even though I'm tempted to finally add some pretty graphics. I hope to finish entity management within the next four weeks, and then start on static, i.e. "level" geometry&lt;br /&gt;&lt;br /&gt;I'm writing all this because everybody keeps asking me what the hell I'm doing all day and whether I'm still working on "that game of yours that you never finish" and also because I'm tired of always working for myself when I should share my experiences with others. So if you've got any questions, comments or need help with your own little renderer slash game engine, leave a comment or write me a message. Also, I'll try to write some lines about my progress on the engine at least once a week. But then again, that's what I always say.&lt;br /&gt;&lt;span class="st"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="st"&gt;&lt;i&gt;&lt;/i&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-4948040049256842796?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/4948040049256842796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2011/08/i-have-to-be-worst-blogger-ever-also.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4948040049256842796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4948040049256842796'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2011/08/i-have-to-be-worst-blogger-ever-also.html' title='I have to be the worst blogger ever.. (also, a video!)'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-4382768540943398077</id><published>2011-03-26T19:45:00.006+01:00</published><updated>2011-08-18T18:57:39.508+02:00</updated><title type='text'>Update: Editor development</title><content type='html'>Wow, my last post has been over a year ago.. well, I've been working nonetheless, here's a quick update on the editor. Hope to update more regularily from now on.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fhUqDLRdsl8/TY40TySwuJI/AAAAAAAAAHw/yJ56CXgSB8o/s1600/weltwunder-02.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" border="0" height="395" id="BLOGGER_PHOTO_ID_5588461702135986322" src="http://4.bp.blogspot.com/-fhUqDLRdsl8/TY40TySwuJI/AAAAAAAAAHw/yJ56CXgSB8o/s640/weltwunder-02.jpg" style="margin: 0px auto 10px;" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-4382768540943398077?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/4382768540943398077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2011/03/update-editor-develoment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4382768540943398077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4382768540943398077'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2011/03/update-editor-develoment.html' title='Update: Editor development'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-fhUqDLRdsl8/TY40TySwuJI/AAAAAAAAAHw/yJ56CXgSB8o/s72-c/weltwunder-02.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-1174711984774010245</id><published>2010-03-10T11:52:00.020+01:00</published><updated>2011-08-20T00:09:07.662+02:00</updated><title type='text'>New demo online</title><content type='html'>I completed a small demo of my game engine for a school application. The demo shows dynamic lighting and shadows, the physics system and some post-processing effects including light bloom, depth of field and dynamic reflections. It uses my old framework from 2008, though. I did not have the time to adapt it for my new framework. Also, as there is no height imformation encoded in the normal maps, there is no parallax mapping. Don't worry about the low framerates on the screenshots, the demo actually runs pretty decent with most effects enabled. I just turned it all up to the maximum for the screenshots :) Have fun!&lt;br /&gt;&lt;br /&gt;Controls:&lt;br /&gt;- Control the camera with the cursor keys and by moving your mouse&lt;br /&gt;- Press 1 to 6 to switch light sources on and off&lt;br /&gt;- Press the left mouse button to push an object&lt;br /&gt;- Hold the right mouse button to grab an object&lt;br /&gt;- Press the space bar to pause the physics simulation&lt;br /&gt;- Press F1 to F10 to toggle effects and debug options on and off&lt;br /&gt;&lt;br /&gt;The program does not check your system for compatibility - if your graphics card does not meet the requirements, the demo will simply crash. Use at your own risk! Also, make sure you have the latest drivers for your graphics card installed. I developed and tested the demo on a GeForce GTX 260 with the 196.75 drivers.&lt;br /&gt;&lt;br /&gt;Download: &lt;strike&gt;Backyard Demo&lt;/strike&gt; &lt;b&gt;(outdated and not compatible with latest AMD and NVidia drivers - new demos using the updated framework will follow soon!)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Some screenshots:&lt;br /&gt;&lt;br /&gt;&lt;table style="margin: 0 auto;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2da6kdac4aA/Tk1FtI7DdoI/AAAAAAAAAJo/6niZfqsOkvs/s1600/1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://4.bp.blogspot.com/-2da6kdac4aA/Tk1FtI7DdoI/AAAAAAAAAJo/6niZfqsOkvs/s400/1.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;  &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-kv8LDgGJ6-U/Tk1FuhLLA5I/AAAAAAAAAJs/xh2I7QN9FI8/s1600/3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://2.bp.blogspot.com/-kv8LDgGJ6-U/Tk1FuhLLA5I/AAAAAAAAAJs/xh2I7QN9FI8/s400/3.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-8VpZ7GDBRNg/Tk1FvyvAasI/AAAAAAAAAJw/WFGqKgbyKec/s1600/Bump+mapping.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://1.bp.blogspot.com/-8VpZ7GDBRNg/Tk1FvyvAasI/AAAAAAAAAJw/WFGqKgbyKec/s400/Bump+mapping.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;  &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-g5B2okwpBGQ/Tk1Fxr3CUCI/AAAAAAAAAJ0/JR5KDtGu1kI/s1600/Soft+shadows.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://4.bp.blogspot.com/-g5B2okwpBGQ/Tk1Fxr3CUCI/AAAAAAAAAJ0/JR5KDtGu1kI/s400/Soft+shadows.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-1174711984774010245?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/1174711984774010245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2010/03/new-demo-online.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1174711984774010245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1174711984774010245'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2010/03/new-demo-online.html' title='New demo online'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-2da6kdac4aA/Tk1FtI7DdoI/AAAAAAAAAJo/6niZfqsOkvs/s72-c/1.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-519901990220396653</id><published>2009-07-12T23:11:00.008+02:00</published><updated>2011-08-18T19:08:43.579+02:00</updated><title type='text'>Hello, World!</title><content type='html'>I have returned from a one-year stay in Norway and finally find the time to program again! I got a new graphics card to be able to fully use the power of Direct3D 10 and OpenGL 3.1 and installed the latest Windows 7 RC, and I love it!&lt;br /&gt;&lt;br /&gt;But I had to admit that the engine, with its current design, is a dead end. So I started from scratch. I've been building up a stable foundation first, utilizing all the knowledge I gained in the process of building the previous one. Now I'm re-implementing all the features from the old project. The most important changes in design are:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;- game state managment&lt;br /&gt;- serialization&lt;br /&gt;- use of interfaces for sub-systems like graphics, audio and scripting&lt;br /&gt;- integration of more third party libraries, first and foremost boost&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The renderer is still using OpenGL, but I'm slowly switching over to Direct3D 10. I might keep the OpenGL renderer for compitability reasons, though. After all, it's the API I know best. Font loading and rendering is realized with the Freetype library.&lt;br /&gt;Sound output is powered by OpenAL, which is really easy to use if you're familiar with OpenGL syntax, and I've added LUA scripting. Initially, I wanted to expose most engine functionality to scripting and use it as the primary way to work with the engine, but I soon realized that it's not a good idea. I will limit its use to in-game events (HL² style) and material definitions, I guess.&lt;br /&gt;&lt;br /&gt;For the new renderer, I want to use a deferred rendering approach to keep the rendering pipeline clean and simple. For shadows I'll stick to variance shadow mapping I guess, using a geometry shader to render shadow cubes (for omni-directional lights) in one pass. But there are still a lot of questions: Should I use one shadow map per light? Or one per mesh? Or just one global shadow map that is being re-rendered before every lighting pass? How to do particle effects? On the CPU alone? With a CPU/pixel shader combination? Or purely on the GPU? We'll see.&lt;br /&gt;&lt;br /&gt;And yes, I know what they say: Make games, not engines. But I'm finishing my bachelor's degree in winter, so I have to start applying for master courses soon.. and for this, I'll need something to present my skills. So maybe, just maybe, I will be able to provide an interactive demo or at least a high quality video around October :)&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_BcbvyY3ThHs/SlpbMwufL9I/AAAAAAAAAF8/qryGTQYBq9s/s1600-h/hello_world.jpg"&gt;&lt;img alt="" border="0" height="512" id="BLOGGER_PHOTO_ID_5357694981507067858" src="http://3.bp.blogspot.com/_BcbvyY3ThHs/SlpbMwufL9I/AAAAAAAAAF8/qryGTQYBq9s/s640/hello_world.jpg" style="display: block; margin: 0px auto 10px; text-align: center;" width="640" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-519901990220396653?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/519901990220396653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2009/07/hello-world.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/519901990220396653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/519901990220396653'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2009/07/hello-world.html' title='Hello, World!'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_BcbvyY3ThHs/SlpbMwufL9I/AAAAAAAAAF8/qryGTQYBq9s/s72-c/hello_world.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-293491094741957065</id><published>2009-02-19T23:08:00.004+01:00</published><updated>2009-02-19T23:22:14.842+01:00</updated><title type='text'>Sign of life</title><content type='html'>Whoever's been wondering why there heven't been any updates in months: I have been and still are in Norway for one year as an exchange student. All I have here is a cheap notebook with integrated graphics, so I haven't been able to work on the engine (I wouldn't have much time for that anyway). But my girlfriend is on a concert tonight, so I took the chance and bagged her vista notebook to finally check out Direct3D 10. So far I'm pretty impressed and being utterly disappointed with OpenGl 3.0, I might well consider switching to D3D when I finally find some time again to work on the engine. I miss it.&lt;br /&gt;&lt;br /&gt;If you're interested what I'm doing all the time instead of programming, visit my (German) blog: &lt;a href="http://www.norwegenjuhu.wordpress.com"&gt;www.norwegenjuhu.wordpress.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-293491094741957065?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/293491094741957065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2009/02/sign-of-life.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/293491094741957065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/293491094741957065'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2009/02/sign-of-life.html' title='Sign of life'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-1951953551131340708</id><published>2008-04-03T19:04:00.006+02:00</published><updated>2011-08-18T19:13:13.650+02:00</updated><title type='text'>I'm still alive..</title><content type='html'>Damn, it's been more than three months since I've posted the last update. I've been very busy lately with university and two jobs, and I just haven't found the time to work on the engine. This week, I could finally dedicate some time to programming again.&lt;br /&gt;&lt;br /&gt;I've completed the character controller and the terrain renderer, added support for sky boxes and improved the water shader. In addition to the usual reflection/refraction stuff, it eliminates hard edges where water and terrain meet: i render the distance between the water surface and the ground into a texture and then use this to mix the distorted refraction/reflection with the undistorted refraction.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt; &lt;param name="movie" value="http://www.youtube.com/v/_YxORJYlZD0"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/_YxORJYlZD0" type="application/x-shockwave-flash" width="425" height="350"&gt; &lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-1951953551131340708?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/1951953551131340708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2008/04/im-still-alive.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1951953551131340708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/1951953551131340708'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2008/04/im-still-alive.html' title='I&apos;m still alive..'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-4066763512882826953</id><published>2007-12-18T02:21:00.000+01:00</published><updated>2007-12-18T02:36:43.756+01:00</updated><title type='text'>Reflections</title><content type='html'>The engine can now render reflections about arbitrary planes. Before, I had to setup the reflection matrix, the clip planes etc manually. Now all I have to provide is a plane equation, and everything is handled internally.&lt;br /&gt;&lt;br /&gt;One item less on my todo list :)&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/USfsrLE4CiM&amp;rel=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/USfsrLE4CiM&amp;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-4066763512882826953?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/4066763512882826953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/12/reflections.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4066763512882826953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4066763512882826953'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/12/reflections.html' title='Reflections'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-8062129631276560309</id><published>2007-12-13T21:54:00.001+01:00</published><updated>2007-12-13T23:17:51.909+01:00</updated><title type='text'>Stencil light volumes</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BcbvyY3ThHs/R2GvBuJ_WUI/AAAAAAAAADE/2PPdLtO1PY0/s1600-h/light_hulls.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_BcbvyY3ThHs/R2GvBuJ_WUI/AAAAAAAAADE/2PPdLtO1PY0/s200/light_hulls.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5143584693538478402" /&gt;&lt;/a&gt;I abandoned deferred shading after all and returned to classic multi-pass shading.. its limitations still outweigh its advantages. It's a shame, I had finally found a robust way to handle transparent geometry.&lt;br /&gt;&lt;br /&gt;But there's also positive news: I'm going work with the guys from &lt;a href="http://www.panic-dev.net"&gt;Panic&lt;/a&gt; on their project, semester break is close, and I've added stencil light volumes. The idea is the same as with stencil shadow volumes, but instead of extruded geometry, I render a cone (or a sphere respectively) to the stencil buffer. The result is a mask containing all the pixels that might be lit by the given light source. The performance boost is not as high as I expected, but it's still a somehow more elegant solution than scissor regions. I highlighted the masked areas on the screenshot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-8062129631276560309?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/8062129631276560309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/12/stencil-light-volumes.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/8062129631276560309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/8062129631276560309'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/12/stencil-light-volumes.html' title='Stencil light volumes'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_BcbvyY3ThHs/R2GvBuJ_WUI/AAAAAAAAADE/2PPdLtO1PY0/s72-c/light_hulls.jpg' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-4256658041452020528</id><published>2007-11-13T15:17:00.003+01:00</published><updated>2011-08-19T23:48:11.177+02:00</updated><title type='text'>Relief Mapping</title><content type='html'>I've just added relief mapping using code from the ShaderDesigner example. Framerate loss is ~10% compared to simple parallax mapping. SM 3.0 only, of course :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_BcbvyY3ThHs/RzmyBn9EMxI/AAAAAAAAAC0/-tFPu8aARJQ/s1600-h/relief-1.jpg"&gt;&lt;img style="float: left; cursor:pointer; margin: 0 10px 0 0; cursor:hand;" src="http://2.bp.blogspot.com/_BcbvyY3ThHs/RzmyBn9EMxI/AAAAAAAAAC0/-tFPu8aARJQ/s200/relief-1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5132328991340114706" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-4256658041452020528?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/4256658041452020528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/11/relief-mapping.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4256658041452020528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/4256658041452020528'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/11/relief-mapping.html' title='Relief Mapping'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_BcbvyY3ThHs/RzmyBn9EMxI/AAAAAAAAAC0/-tFPu8aARJQ/s72-c/relief-1.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-3039478494798443556</id><published>2007-11-12T15:00:00.014+01:00</published><updated>2011-08-20T00:02:56.997+02:00</updated><title type='text'>Variance shadow mapping &amp; Bullet physics</title><content type='html'>I've implemented variance shadow mapping, a simple modification to the standard algorithm that allows shadow maps to be filtered. I use bilinear filtering (mip maps are too slow), 8x anisotropic filtering and apply a gaussian blur and still get ~80fps with two light sources. I had to add a little hack to the lighting shader to get rid of artifacts, though.&lt;br /&gt;&lt;br /&gt;The other two screenshots show simple bilinear filtered VSM and VSM with a gaussian blur applied and parallax mapping enabled:&lt;br /&gt;&lt;br /&gt;&lt;table style="margin: 0 auto;"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-pGumGND29rE/RzhkTn9EMrI/AAAAAAAAACE/Z7s1Qo3qPB4/s1600/nov2007-2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="155" src="http://1.bp.blogspot.com/-pGumGND29rE/RzhkTn9EMrI/AAAAAAAAACE/Z7s1Qo3qPB4/s200/nov2007-2.jpg" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-uEz6BhFZvQg/RzhlUH9EMsI/AAAAAAAAACM/QKE3txilf1k/s1600/nov2007-3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="155" src="http://1.bp.blogspot.com/-uEz6BhFZvQg/RzhlUH9EMsI/AAAAAAAAACM/QKE3txilf1k/s200/nov2007-3.jpg" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-QwmMaCf-qlI/RzhlVX9EMtI/AAAAAAAAACU/fDZ4YVBpvN0/s1600/nov2007-4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="155" src="http://2.bp.blogspot.com/-QwmMaCf-qlI/RzhlVX9EMtI/AAAAAAAAACU/fDZ4YVBpvN0/s200/nov2007-4.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;I've dropped ODE and implemented &lt;a href="http://bulletphysics.org/"&gt;Bullet&lt;/a&gt; instead. It's faster, more stable and its C++ interface integrates nicely with my code. I've also added decals using code from Eric Lengyel's article in GPG2, but I still have to find a way to blend them onto world geometry. The same is true for billboards. I might abandon deferred shading and switch back to multi-pass if I can't find a decent solution.&lt;br /&gt;&lt;br /&gt;So what's left to do?&lt;br /&gt;&lt;i&gt;Omnidirectional shadow mapping&lt;/i&gt; - cube maps were to slow with the standard algorithm, they might work with VSM, but I can't use cube maps with deferred shading; I got it working with an unwrapped cube map, though. Still have to decide what's best.&lt;br /&gt;&lt;i&gt;Particle systems&lt;/i&gt; - should be possible to use Bullet for that.&lt;br /&gt;&lt;i&gt;Arbitrary reflections&lt;/i&gt; - and a way to render reflective surfaces with deferred shading.&lt;br /&gt;&lt;i&gt;Sky dome/box&lt;/i&gt; - should be easy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-3039478494798443556?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/3039478494798443556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/11/ive-implemented-variance-shadow-mapping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/3039478494798443556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/3039478494798443556'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/11/ive-implemented-variance-shadow-mapping.html' title='Variance shadow mapping &amp; Bullet physics'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-pGumGND29rE/RzhkTn9EMrI/AAAAAAAAACE/Z7s1Qo3qPB4/s72-c/nov2007-2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-241952053181918847</id><published>2007-10-19T21:30:00.000+02:00</published><updated>2007-10-19T22:33:53.792+02:00</updated><title type='text'>Deferred shading - does it pay off?</title><content type='html'>Playing Stalker I asked myself how they managed to simulate so many light sources casting soft shadows at a decent framerate. I then read their article on deferred shading in GPU Gems 2 and thought, I can do that, too. Implementation was surprisingly easy, but the results were rather disillusioning - it ran about 5% faster than the classic multi-pass algorithm i was using before.&lt;br /&gt;&lt;br /&gt;I soon realized that the problem was the g-buffer's setup. My naive approach was this:&lt;br /&gt;3 half-float RGBA textures, storing diffuse color &amp; specular intensity, normal &amp; height and worldspace position, resulting in 16bit x 4 channels x 3 = 192bpp.&lt;br /&gt;&lt;br /&gt;I could omit height as it's only needed in the initial pass (parallax mapping etc). I then read that it was possible to restore worldspace position from depth only, using the pixel's screen position and viewport information. This would not only mean that I could omit two more scalars; I could use a depth buffer to save it, so the other components of the g-buffer could be saved in fixed-point 8bit textures. Unfortunately, no paper explained this in detail :/ In the end, a professor from Erlangen University told me how to do it using a scalar saved in a floating-point texture. I modified it to work with a depth buffer, but that resulted in poor accuracy. On top of that, normals lose accuracy when saved in 8bit textures and reconstructing their z component from x/y proved to be unreliable, so I decided to stick to floating-point textures *sigh*&lt;br /&gt;&lt;br /&gt;My current setup: 2 half-float RGBA textures, storing diffuse color &amp; specular intensity, normal &amp; worldspace position z, resulting in 16bit x 4 channels x 2 = 128bpp.&lt;br /&gt;&lt;br /&gt;The performance boost is &lt;i&gt;huge&lt;/i&gt;. But what I actually wanted to achieve is this:&lt;br /&gt;2 fixed-point RGB textures, storing diffuse color, normal xy &amp; specular intensity and 1 24bit depth buffer to reconstruct worldspace position, resulting in 8bit x 3 channels x 2 + 24bit = 72bpp!&lt;br /&gt;&lt;br /&gt;While still far from perfect, the results are satisfying.&lt;br /&gt;Aside from higher framerates, hardware skinning and effects like parallax mapping only have to be computed once per frame and my rendering pipeline is much cleaner.&lt;br /&gt;&lt;br /&gt;Any suggestions how to improve my setup would be highly appreciated :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-241952053181918847?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/241952053181918847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/10/deferred-shading-does-it-pay-off.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/241952053181918847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/241952053181918847'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/10/deferred-shading-does-it-pay-off.html' title='Deferred shading - does it pay off?'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-811535198689748247</id><published>2007-09-03T14:40:00.000+02:00</published><updated>2007-09-03T17:06:50.768+02:00</updated><title type='text'>No tech demo yet - but good progress and a first video</title><content type='html'>Just when I had almost finished the level for the tech demo, I realized that some new bugs have crept in. Shadow maps were corrupted, frustum culling returned false positives etc. While fixing those bugs, I came to the brilliant conclusion that the demo would be much more impressive if it featured physics. So I implemented ODE, realized that it won't run properly before I've got some decent space partitioning working, started over, implemented octrees and then ODE again.&lt;br /&gt;&lt;br /&gt;I did not want to be left empty-handed, so I've thrown together this short, low-quality  presentation of the engine's most prominent features:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt; &lt;param name="movie" value="http://www.youtube.com/v/DL1YZQ85OeA"&gt; &lt;/param&gt; &lt;embed src="http://www.youtube.com/v/DL1YZQ85OeA" type="application/x-shockwave-flash" width="425" height="350"&gt; &lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-811535198689748247?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/811535198689748247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/09/no-tech-demo-yet-but-good-progress-and.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/811535198689748247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/811535198689748247'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/09/no-tech-demo-yet-but-good-progress-and.html' title='No tech demo yet - but good progress and a first video'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-866501689103036018</id><published>2007-07-28T01:02:00.000+02:00</published><updated>2007-07-28T18:10:12.762+02:00</updated><title type='text'>Upcoming tech demo</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_BcbvyY3ThHs/RqtqQS1JGwI/AAAAAAAAABc/uxbawAAGMPY/s1600-h/demo_scene.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_BcbvyY3ThHs/RqtqQS1JGwI/AAAAAAAAABc/uxbawAAGMPY/s200/demo_scene.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5092280631837661954" /&gt;&lt;/a&gt;I've started working on a tech demo to show off the engine's capabilities. I'm going to upload a video of it asap. I won't be able to provide a binary though, as it's using copyrighted material.&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-866501689103036018?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/866501689103036018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/07/ive-started-working-on-tech-demo-to.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/866501689103036018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/866501689103036018'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/07/ive-started-working-on-tech-demo-to.html' title='Upcoming tech demo'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_BcbvyY3ThHs/RqtqQS1JGwI/AAAAAAAAABc/uxbawAAGMPY/s72-c/demo_scene.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1245195918198356162.post-7636173203419369808</id><published>2007-07-24T13:42:00.000+02:00</published><updated>2007-07-28T18:13:29.821+02:00</updated><title type='text'>Wunderwerk Development Blog online</title><content type='html'>I've finally brought myself to setup this development blog. I've been working on this engine for almost a year now, and graphics are almost complete.&lt;br /&gt;&lt;br /&gt;For those of you who care: The engine is written in C/C++ using OpenGL for graphics. I have no plans to support DirectX, especially now that version 10 is Vista only. All shaders are written in GLSL, no fixed functionality is being used. What's still missing graphics-wise are particle systems, sky, cubic reflections and support for more image and model formats. So far the engine supports .tga and .dds image files and  Doom 3  and Milkshape3D models including animation.&lt;br /&gt;&lt;br /&gt;I've setup this blog because I'm often asked how this project is coming along and all I can do then is promise to send them some screenshots eventually. Also, i'd love to get into contact with other programmers who are interested in this project or who develop something similar. And last - but not least - there is nothing more motivating than a compliment. Still, don't hesitate to critize!&lt;br /&gt;&lt;br /&gt;Finally, here are two screenshots of the latest features I've implemented: the left one shows two post processing effects, depth of field and bloom; the right one shows reflective/refractive water.&lt;br /&gt;&lt;br /&gt;&lt;div style="width: 600px;"&gt;&lt;br /&gt;&lt;a style="float:left; margin:0 10px 10px 0; cursor:hand" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BcbvyY3ThHs/RqXxdC1JGsI/AAAAAAAAAA8/aRiRJgHyy5c/s1600-h/hdr_depth_of_field_2.jpg"&gt;&lt;img src="http://1.bp.blogspot.com/_BcbvyY3ThHs/RqXxdC1JGsI/AAAAAAAAAA8/aRiRJgHyy5c/s200/hdr_depth_of_field_2.jpg" alt="" id="BLOGGER_PHOTO_ID_5090740435090479810" border="0" /&gt;&lt;/a&gt;&lt;a style="float:left; margin:0 10px 10px 0; cursor:hand" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_BcbvyY3ThHs/RqXxoy1JGtI/AAAAAAAAABE/TBtWnzYPlHc/s1600-h/water_reflection_refraction.jpg"&gt;&lt;img src="http://4.bp.blogspot.com/_BcbvyY3ThHs/RqXxoy1JGtI/AAAAAAAAABE/TBtWnzYPlHc/s200/water_reflection_refraction.jpg" alt="" id="BLOGGER_PHOTO_ID_5090740636953942738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1245195918198356162-7636173203419369808?l=wunderwerk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wunderwerk.blogspot.com/feeds/7636173203419369808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://wunderwerk.blogspot.com/2007/07/wunderwerk-development-blog-online.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/7636173203419369808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1245195918198356162/posts/default/7636173203419369808'/><link rel='alternate' type='text/html' href='http://wunderwerk.blogspot.com/2007/07/wunderwerk-development-blog-online.html' title='Wunderwerk Development Blog online'/><author><name>Matthias</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_BcbvyY3ThHs/RqXxdC1JGsI/AAAAAAAAAA8/aRiRJgHyy5c/s72-c/hdr_depth_of_field_2.jpg' height='72' width='72'/><thr:total>4</thr:total></entry></feed>
