May 2010

Warning! Some information on this page is older than 3 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

09:54
Sun
30
May 2010

Problem with Object Names

At least I've started coding my new reflection system which I hope to use for all the stuff I do at home. I'll write about all the assumptions and decisions behind it another time, but today I'd only like to share my thoughts about a little problem I have with object names. I want my abstract base class for all objects to return its name/title to be shown as the name of a tree node in the editor. But interface should theoretically be separate from implementation, so I want an object to be able to simply store its name in some string field or alternatively to build it each time from some internal parameters. Now the question arises how should the interface for fetching this name look like? It turns out to be nontrivial problem in C++, even if I use STL strings instead of char*. Two solutions are possible:

virtual GetName1(std::string &out) = 0;
virtual const std::string & GetName2() = 0;

If some object type stores its name in a std::string Name; field, solution (2) is better because it just returns a reference to its name.

std::string Name;
virtual const std::string & GetName2() { return Name; }

Solution (1) would involve unnecessary copying of the string each time it is fetched:

std::string Name;
virtual GetName1(std::string &out) { out = Name; }

But if an object wants to build its title from some parameters, solution (1) is better:

unsigned Param1, Param2;
virtual GetName1(std::string &out) {
  out = "Params: " + UintToStr(Param1) + ", " + UintToStr(Param2);
}

Using solution (2) here is possible only if we cache built string in a field. Lazy evaluation could be done here. It's not very bad idea, but involves more coding.

unsigned Param1, Param2;
std::string CachedName;
virtual const std::string & GetName2() {
  CachedName = "Params: " + UintToStr(Param1) + ", " + UintToStr(Param2);
  return CachedName;
}

Obviously the simplest and most "universal" solution with just returning std::string by value is inefficient in each case because it involves lots of copying.

virtual std::string GetName3() = 0; // Boo!

Finally I've decided to use (1), but I don't like the thought that such problem exists. In C# we wouldn’t have to make a compromise, because there strings are immutable, passed by reference and automatically freed by the garbage collector. We can just do this and the implementation is efficient in every situation:

abstract class Base {
  public abstract string GetName();
}

class Derived1 : Base {
  private string Name;
  public override string GetName() { return Name; }
}

class Derived2 : Base {
  private uint Param1, Param2;
  public override string GetName() {
    return string.Format("Params: {0}, {1}", Param1, Param2);
  }
}

Comments (2) | Tags: c++ | Author: Adam Sawicki | Share

19:12
Fri
28
May 2010

Zjazd Twórców Gier 2010

On 15-19 July 2010 an interesting event is going to happen in Gdańsk (Poland) - Zjazd Twórców Gier 2010 (would it be "Game Developers Convention" in English?). This event, organized by some young passionates, will take place in the University of Gdansk. It is 3rd edition this year, but I didn't attend it before, so I have no idea how does it look like, especially compared to the IGK conference. But this motivates me even more to go there and find out, so I'm going to attend it this year. I hope to meet some nice people there and have much fun :) The only problem is a long travel from Warsaw to Gdansk. Who else is going to go there from Warsaw?

Comments (0) | Tags: events | Author: Adam Sawicki | Share

15:15
Sun
23
May 2010

More Defective C++ ;)

Today I'll disclose my opinions more than ever before, inspired by the C++ FQA Lite (Frequently Questioned Answers) - a great reading I recommend to any C++ programmer. If it's too long for you, just be sure to overview the introductory chapters - "Defective C++" and "Big Picture Issues". This document is written by Yossi Kreinin - a man who apparently knows and uses C++ language although doesn't like it - just like me. I like his text so much because I agree with most of his arguments. The main part of the FQA has a form of alternative answers to the questions from the C++ FAQ Lite. It's very subjective, emotional and also funny to read. I've especially laughed at point 23.2 - it's so true about all these design patterns :) Surely my opinions expressed here are not so valuable compared to opinions of all these older and more experienced programmers around, but that's what blogs are for - expressing one's opinions...

My list of objections about C++ language is long. Some specific ones are:

Read full entry > | Comments (4) | Tags: c++ | Author: Adam Sawicki | Share

19:58
Sun
16
May 2010

Some Thoughts about Library Design

Much has been said about designing good user interface, whether for desktop applications, websites or games. There are whole books available about GUI design and even this year's IGK-7'2010 conference featured two lectures about the interface in games. But what about interfaces for programmers?

I can't find much about the rules of good library API design and I believe there is much to say in this subject. I only know The Little Manual of API Design written by Jasmin Blanchette from Trolltech/Nokia, one of the creators of Qt library (thanks for the link Przemek!). There is also a blog entry about Math Library, which is quite interesting. Inspired by it, I've came up with a general thought that you cannot have all the following features when designing a library and its API, you have to choose 2 or 3 of them and make some compromise:

I think some patterns and best practices as well as some anti-patterns could be found when you look at interfaces of many libraries. Maybe I'll post some more of my thoughts on this subject in the future. In the meantime, do you know any other resources about API design?

Comments (2) | Tags: philosophy software engineering libraries | Author: Adam Sawicki | Share

13:18
Sat
15
May 2010

Effects in DirectX 11

I no longer believe Microsoft did a good job complicating new DirectX so much. Effects framework - the API that supported loading and using effect files that grouped HLSL code and render states into passes and techniques - is no longer intrinsic part of D3DX. Instead they provided source code for this library so you have to compile it by yourself!

To do this: Enter your DX SDK subdirectory "Samples\C++\Effects11", open a "Effects11_*.sln" solution file appropriate for your Visual C++ version and compile the project in both Debug and Release configuration.

Then to use effects API in your project you have to include this header: "YOUR_DX_SDK_PATH\Samples\C++\Effects11\Inc\D3dx11effect.h" and link with this lib: "YOUR_DX_SDK_PATH\Samples\C++\Effects11\Debug\D3DX11EffectsD.lib (Debug) or "YOUR_DX_SDK_PATH\Samples\C++\Effects11\Release\D3DX11Effects.lib" (Release), as well as with "d3dcompiler.lib" (in both configurations).

Here is example of how to load an effect from file. You need to first compile a source code from file or memory into a blob binary effect and then create real effect object from this blob.

// Compile effect from HLSL file into binary Blob in memory
ID3D10Blob *effectBlob = 0, *errorsBlob = 0;
HRESULT hr = D3DX11CompileFromFile(
  "Effect1.fx", 0, 0, 0, "fx_5_0", 0, 0, 0, &effectBlob, &errorsBlob, 0);
assert(SUCCEEDED(hr) && effectBlob);
if (errorsBlob) errorsBlob->Release();
// Create D3DX11 effect from compiled binary memory block
ID3DX11Effect *g_Effect;
hr = D3DX11CreateEffectFromMemory(
  effectBlob->GetBufferPointer(), effectBlob->GetBufferSize(), 0, g_Dev, &g_Effect);
assert(SUCCEEDED(hr));
effectBlob->Release();

The effect itself is not enough. You need to retrieve object that represents "pass" to use it. So you get a technique from the effect (by index or by name) and then the pass from the technique.

ID3DX11EffectTechnique *g_EffectTechnique; // No need to be Release()-d.
g_EffectTechnique = g_Effect->GetTechniqueByIndex(0);
assert(g_EffectTechnique && g_EffectTechnique->IsValid());

ID3DX11EffectPass *g_EffectPass; // No need to be Release()-d.
g_EffectPass = g_EffectTechnique->GetPassByIndex(0);
assert(g_EffectPass && g_EffectPass->IsValid());

Now when you have this object, you can apply settings from this pass to the device context during rendering:

g_EffectPass->Apply(0, g_Ctx);
g_Ctx->Draw(3, 0);

But still one problem reamins. In DirectX 11 you need to pass a pointer to the bytecode with compiled shader when creating input layout - a step that you probably cannot omit. Fortunately there is a way to access this pointer stored inside loaded effect. You just need to pass through two descriptors, just like this:

D3DX11_PASS_SHADER_DESC effectVsDesc;
g_EffectPass->GetVertexShaderDesc(&effectVsDesc);
D3DX11_EFFECT_SHADER_DESC effectVsDesc2;
effectVsDesc.pShaderVariable->GetShaderDesc(effectVsDesc.ShaderIndex, &effectVsDesc2);
const void *vsCodePtr = effectVsDesc2.pBytecode;
unsigned vsCodeLen = effectVsDesc2.BytecodeLength;

ID3D11InputLayout *g_InputLayout;
D3D11_INPUT_ELEMENT_DESC inputDesc[] = { /* ... */ };
hr = g_Dev->CreateInputLayout(
  inputDesc, _countof(inputDesc), vsCodePtr, vsCodeLen, &g_InputLayout);

Luckily it looks like the effect framework doesn't add much functionality over pure HLSL shader supported by D3D11 itself, so you don't have to use it. Defining these techniques and passess is not so important after all...

Comments (5) | Tags: directx rendering | Author: Adam Sawicki | Share

19:46
Thu
13
May 2010

Origami: Sonobe Module

It looks like Sonobe module is a "Hello World" in modular origami. This simple module prepared from square sheet of paper is very popular, so you can find lots of instructions about how to fold it on the Internet. It's also very universal - you can use it to create a cube (6 modules required), some polyhedra, as well as arbitrary unregular shapes made of cubes, like Tetris blocks :) Here are my objects made of Sonobe modules:

Comments (1) | Tags: origami | Author: Adam Sawicki | Share

20:40
Sat
08
May 2010

Modular Origami - Spike Ball

I hope you wouldn't mind if I start blogging here a bit about modular origami. I find it related to 3D graphics programming in some way ;) To introduce the topic: As you probably know, origami is a traditional Japanese art of folding paper, without use of cuts or glue. Many objects can be done this way, including characters and animals. But I'm mostly interested in modular origami - a type of origami where some number of identical pieces (called modules) have to be prepared to be then assembled together into some interesting geometrical form.

It's not very easy. I especially couldn't imagine myself developing a new kind of module. Luckily there are some books and websites about origami. There are also lots of videos on YouTube teaching how to make particular objects. I believe YouTube is kind of a revolution in teaching origami because a video shows much more and is easier to understand than traditional static diagram.

Today I've finished assembling an cuboctahedron made of 12 modules invented by Rona Gurkewitz and Bennett Arnstein.

Here is the video I've learned it from: How to make an Origami Spiky Cuboctahedron aka Spike Ball. I can see there is whole website dedicated to these spike balls: Spike Ball Heaven.

That's it for the start. Next time I'll show some more basic stuff.

See also: my Super Spike Ball.

Comments (1) | Tags: origami | Author: Adam Sawicki | Share

19:37
Sat
08
May 2010

LZMA SDK - How to Use

What do you think about when I tell a word "compression"? If you currently study computer science, you probably think about some details of algorithms like RLE, Huffman coding or Burrows-Wheeler transform. If not, then you surely associate compression with archive file formats such as ZIP and RAR. But there is something in between - a kind of libraries that let you compress some data - implement a compression algorithm but do not provide ready file format to pack multiple files and directories into one archive. Such library is useful in gamedev for creating VFS (Virtual File System). Probably the most popular one is zlib - a free C library that implements Deflate algorithm. I've recently discovered another one - LZMA. Its SDK is also free (public domain) and the basic version is a small C library (C++, C# and Java API-s are also available, as well as some additional tools). The library uses LZMA algorithm (Lempel–Ziv–Markov chain algorithm, same as in 7z archive format), which has better compression ratio than Deflate AFAIK. So I've decided to start using it. Here is what I've learned:

If you decide to use only the C API, it's enough to add some C and H files to your project - the ones from LZMASDK\C directory (without subdirectories). Alternatively you can compile them as a static library.

There is a little bit of theory behind the LZMA SDK API. First, the term props means a 5-byte header where the library stores some settings. It must be saved with compressed data to be given to the library before decompression.

Next, the dictionary size. It is the size of a temporary memory block used during compression and decompression. Dictionary size can be set during compression and is then saved inside props. Library uses dictionary of same size during decompression. Default dictionary size is 16 MB so IMHO it's worth changing, especially as I haven't noticed any meaninful drop in compression rate when set it to 64 KB.

And finally, end mark can be saved at the end of compressed data. You can use it so decompression code can determine the end of data. Alternatively you can decide not to use the end mark, but you must remember the exact size of uncompressed data somewhere. I prefer the second method, because remembering data size takes only 4 bytes (for the 4 GB limit) and can be useful anyway, while compressed data finished with end mark are about 6 bytes longer than without it.

Compressing full block of data with single call is simple. You can find appropriate functions in LzmaLib.h header. Here is how you can compress a vector of bytes using LzmaCompress function:

Read full entry > | Comments (9) | Tags: commonlib libraries algorithms | Author: Adam Sawicki | Share

00:16
Thu
06
May 2010

Compiling wxWidgets 2.9.0 in Visual C++ 2010 Express

NEW! (2011-02-18) I posted this entry months ago, wxWidgets keeps evolving and so it may no longer work. For building wxWidgets 2.9.1 in Visual C++ 2010, I now recommend you follow steps described here: Visual Studio C++ 2010 - Microsoft Visual C++ Guide - wiki.wxwidgets.org and here: Fixed wxWidgets 2.9.1 project files Visual Studio 2010 - forums.wxwidgets.org.

My old blog entry:

Today I wanted to compile wxWidgets library (version 2.9.0, which contains lots of interesting new features, including wxPropertyGrid control) under Visual C++ 2010 Express. A strange error appeared that stopped the build and explained nothing specific about the cause:

Microsoft.CppCommon.targets(151,5): error MSB6001: Invalid command line switch for "cmd.exe". The path is not of a legal form.

It took me some time to find a correct solution on Google, as many of them didn't work. (Copy setup.h file to some another directory? Made no difference in my case. Use the wx.dsw - project file for oldest IDE version? Didn't work either, my Visual says it cannot import such projects.)

Finally I've found this forum topic: http://forums.wxwidgets.org/viewtopic.php?t=27630. Sami Hamlaoui on 25th April 2010 posted a ZIP archive there containing converted and fixed project for Visual C++ 2010 that you can download and use to successfully build wxWidgets 2.9.0. Thanks for that!

After you build all projects in Debug and Release configuration, you just need to setup include and library paths in the IDE:

...\wxWidgets-2.9.0\include
...\wxWidgets-2.9.0\include\msvc

...\wxWidgets-2.9.0\lib\vc_lib

And finally you can use wxWidgets in your projects. To do that, you need to #include files such as and link with these libraries:

comctl32.lib, rpcrt4.lib, winmm.lib, advapi32.lib, wsock32.lib

and desired wx libraries like wxbase29ud.lib and wxmsw29ud_core.lib ("d" is for debug, use versions without "d" in Release configuration). Also remember that the new wxWidgets has no ASCII support, so you have to use Unicode character set.

Comments (1) | Tags: wxwidgets visual studio | Author: Adam Sawicki | Share

18:47
Tue
04
May 2010

Introduction to XNA Math

I've recently shared my XNA Math Cheat Sheet Today I'd like to post some more information about XNA Math. It is a new C++ math library for gamedev distributed with DirectX SDK, intended to replace math support from D3DX. Its online documentation can be found here: XNA Math Library Reference and the offline one is in DXSDK\Documentation\DirectX9\directx_sdk.chm file. It's worth noticing that the documentation in recent DX SDK versions is split across two separate CHM files. windows_graphics.chm describes only graphics programming (Direct3D 9, 10 and 11, D3DX, DXGI, HLSL language, effects format, DDS format, X format etc.), while directx_sdk.chm is about all other stuff (DirectSetup, DXUT, XNA Math, XAudio2, XInput etc.).

XNA Math is different from old D3DX and I'm afraid also harder to use. But I believe it's better. It's your decision whether you start to use it or not, because it's completely separate library that can be used with DirectX 11, 10, 9 or without anyone of them. On the other hand, you can still link with old D3DX while coding in new DirectX 11, so it's all your choice.

By the way, I don't know why is this library called "XNA Math". It looks like it has nothing to do with the XNA technology. XNA is a .NET library with its own vector and matrix classes while XNA Math is pure native C++ library distributed with DirectX SDK. It looks like a misnomer.

Beginning with XNA Math is simple. You just #include <xnamath.h> and that's all. There is even no need to link with any LIB file - all code is inline in this header or INL files included by it (which sum up to 26530 lines :) It provides support for vectors (up to 4D), matrices (up to 4x4), colors, planes and quaternions - all made of 32-bit floats, just as we all use in gamedev.

But design ideas of this API are totally different from D3DX. There is now one main data type called XMVECTOR - a vector of 4 floats. When the library uses SSE (which is the default on PC), this type is simply a typedef to __m128 (if you know what I mean). So it must be always aligned to 16-byte boundary. As a consequence, it's safe to cast this type to any other one interpreted as a vector of floats (like float[4] or D3DVECTOR), but not the other way around (because the pointer you cast might not be property aligned). This single type is used in all computations and interpreted as a 2D, 3D or 4D vector, plane, quaternion, part of 4x4 matrix or even a vector of unsigned integers, depending on the context. It may also feel strange at the beginning that this not-so-small object is usually passed and returned by value, not by reference.

Old DirectX versions used a D3DVECTOR and D3DMATRIX structures, which were extended by inheritance in D3DX library as D3DXVECTOR and D3DXMATRIX - structures with lots of overloaded operators and methods to operate on. The idea behind new DirectX 11 is that the graphics API is not dependent on any particular math library - it only uses float* or even void* and it's you job to use some library that would help you with math computations (like D3DX or XNA Math).

If you ever coded in SSE or other vector instruction set, you might know the concept of loading and storing. Here is an example that sets and gets vector as well as its components in many different ways.

XMVECTOR v = XMVectorZero();
// v is now (0, 0, 0, 0)
v = XMVectorSplatOne();
// v is now (1, 1, 1, 1)
v = XMVectorReplicate(5.f);
// v is now (5, 5, 5, 5)
v = XMVectorSet(1.f, 2.f, 3.f, 4.f);
// v is now (1, 2, 3, 4)
v = XMVectorSetX(v, 10.f);
// v is now (10, 2, 3, 4)
std::cout << XMVectorGetW(v);
// Prints 4

There are lots of structures defined in XNA Math that represent different ways vectors can be stored and packet in the memory. Many of them are very weird, but there is good reason for their existence - they are CPU equivalents for some of DXGI_FORMAT-s available in DirectX 10/11. For example, the XMUDECN4 type, representing DXGI_FORMAT_R10G10B10A2_UNORM, is defined as follows:

union {
  struct { UINT x : 10; UINT y : 10; UINT z : 10; UINT w : 2; };
  UINT v;
};

It is a 32-bit value that stores 4D vector in 10+10+10+2 bit format, where float values 0.0 .. 1.0 are mapped to integers 0..1023 for x, y, z components and 0..3 for w component (just a bit smaller precision, nothing more ;) XNA Math provides us with functions to load and store XMVECTOR from/to all these strange types, so you can just do something like this:

XMVECTOR v = XMVectorSet(0.f, 1.f, 0.5f, 0.5f);
XMUDECN4 packedV;
XMStoreUDecN4(&packedV, v);
// packedV is 0x5ffffc00
XMVECTOR v2 = XMLoadUDecN4(&packedV);
// v2 is (0, 1, 0.499511, 0.333333)

XNA Math contains lots of functions that we all know from old good D3DX. (The only missing thing are SH* functions for spherical harmonics, but well - I have never used them anyway :) For example, a function for normalizing 3D vector now has a signature:

XMVECTOR XMVector3Normalize(XMVECTOR V)

XNA Math also supports matrices. XMMATRIX type is a 4x4 matrix. It contains 4 XMVECTOR-s inside. Functions for manipulating matrices include XMMatrixTranslation, XMMatrixRotationRollPitchYaw, XMMatrixPerspectiveFovLH and so on. You can also do computations on 3D planes if only you agree to treat (x, y, z, w) vectors as (A, B, C, D) factors of plane equation. Same applies to colors - functions like XMColorAdjustSaturation also operate on XMVECTOR, but treat its components as (R, G, B, A) values.

XNA Math wouldn't be complete without some basic functions, constants and macros for scalars, such as XM_PI, XMMax, XMScalarSin. Functions with -Est suffix (from "estimated") are faster but less precise versions, e.g. XMScalarSinEst.

If you want to make full use of the performance of vector arithmetic, you should also use swizzling, permutation and comparison functionality. Swizzling is about permutation of components of a vector. It's elegant and intuitive in languages designed with gamedev in mind (like HLSL), where you just write:

float4 v2 = v1.xyxy;

In C++ with XNA Math, same operation can be written as:

XMVECTOR v2 = XMVectorSwizzle(v1, 0, 1, 0, 1);

When it comes to comparisons, functions with -R suffix return additional UINT value, which is a bitfield designed to be tested with special functions. For example:

XMVECTOR v1 = XMVectorSet(0.0f, 1.0f, 0.5f, 0.5f);
XMVECTOR v2 = XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f);
UINT cr; XMVECTORU32 res;
res.v = XMVectorGreaterR(&cr, v1, v2);
// res contains (0, 0xffffffff, 0, 0)
std::cout << XMComparisonAnyTrue(cr);
// Prints 1.

Comments (3) | Tags: math directx | Author: Adam Sawicki | Share

19:14
Sat
01
May 2010

HLSL syntax highlighting for jEdit

Some time ago I've created a syntax highlighting mode of HLSL language (the shader language of DirectX) for jEdit - my favourite text editor. It is now included in the official jEdit distribution. But it wasn't updated for a long time, since Shader Model 2. Now I've created a new version that supports all the features of new DirectX shaders and effects up to these from DirectX 11 (Shader Model 5), including ones from the upcoming June 2010 version.

So if you don't use jEdit, just keep in mind that there is probably no other text editor (which I would know about) with a coloring scheme for shader language. (I know AMD RenderMonkey and NVIDIA Fx Composer do that, but these are big shader IDE-s, not just text editors.) And if you do, here is how to install it. Download the file:

hlsl.xml

Place it in your jEdit's "modes" subdirectory, e.g.: "C:\Program Files (x86)\jEdit 4.3.1\modes" and replace the existing one. That's all. You can double-click on the right part of the status bar in jEdit to open the Buffer Options window and select Edit mode = "hlsl".

But it's better to associate this coloring scheme with some file extensions. To do that, open file: "C:\Program Files (x86)\jEdit 4.3.1\modes\catalog", comment out the "javafx" mode as it owns the "fx" file extension by defalt:

<!--<MODE NAME="javafx"    FILE="javafx.xml"
        FILE_NAME_GLOB="*.fx" />-->

Then find and alter the entry about "hlsl" mode to associate it with whatever file extension you use for your shaders, like the example:

<MODE NAME="hlsl"    FILE="hlsl.xml"
        FILE_NAME_GLOB="*.{fx,hlsl}" />

If you edit this file inside jEdit, you don't even have to restart it - new rules are applied automatically.

You may ask why not just use the C++ coloring scheme for shader code? Of course you can do it, the syntax is similar because all the tokens, like strings, numbers and identifiers look the same way. But my coloring schemes give separate colors for language elements such as: semantics (like c:COLOR0), component indexing (like v.xyzz), atomic types (like float), object types (like Texture2D or RWStructuredBuffer) and intrinsic functions (like sin, cos, InterlockedCompareExchange).

Kolorowanie składni HLSL

Comments (1) | Tags: tools rendering directx | Author: Adam Sawicki | Share

STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2017 Adam Sawicki
Copyright © 2004-2017 Adam Sawicki