Monday, November 15, 2010

Vim Tabs

If you are not used with the buffer concept as the buffers do not necessarily visible, and you also want to focus on the current file, you have the tabs in Vim just as you have in Editplus or Notepad++ or most of modern text editors. Here is my vim with two tabs each holding its own windows. Yes, it's important that each tab can hold multiple windows, isn't it cool or what!



Here is how you can work with tabs in Vim.

Create a new tab:

  • - vim -p file1 file2... : Open multiple files each in one tab.
  • - :tabnew [filename] : Crate a new tab, empty or possibly open a file at the same time.
  • - Ctrl-w T : If you have multiple windows opened in one tab, use this command to put the current window into a new tab.


Navigate between tabs:

  • - :tabs : list all opened tabs
  • - :tabn, :tabp: go to next or previous tab. Less convenient. 
  • - gt : go to next tab. Better.

Vim Windows

Vim is able to show your files in separated windows which is very handy in many situation. For example, if you are a programmer, very often you need to look at a .cpp file and its header .h at the same time. Or if you are simply writing some text and need to refer to certain part of the same file that can not fill in one screen because your text is quite long.

Then it's the time to think about multiple windows and it will helps a lot. Here is how vim looks like with multiple windows.

Basically, here I created three windows, left top, left bottom and the right one. Several interesting thing to mention here. First, as you can see, we are able to create vertically or horizontally separated windows. Then, we are able to crate multiple windows containing the same file. Finally, we have some important information for each window, the file name, the index of the buffer (the number before the file name), etc.

Here is how I use multiple windows.
To create new window:
  • - Ctrl-w s  will split the current window into two containing the same file.
  • - :sp same as above.
  • - :sp filename will create a new window with the file filename.
  • - Ctrl-w v Split the current window vertically. 
  • - :vs same as above
  • - :vs filename Vertical split with file filename.
To move between windows: All commands here start with Ctrl-w.
  • - h,j,k,l:  Navigate: same as move the cursor. 
  • - x: Switch positions of two neighbor windows.
  • - p: Go to previous windows, particularly useful when browsing between .h and .c files.
Close windows:
  • - Ctrl-w c or :q 

Sunday, November 14, 2010

My Favorite Software on Windows

I reinstalled my PC this weekend as you all know that Windows tend to slow down after some time.

I take this opportunity to make a collection of my favorite software on a Windows PC.

7-Zip
Adobe Reader
Google Chrome
Mozilla Firefox
Skype
PPTV
SPlayer
MKPlayer
Sogou Chinese Input Method
Thunder Download

...
To continue.

Sunday, October 10, 2010

Problem with System.Windows.Forms.WebBrowser

I used a lot System.Windows.Forms.WebBrowser in my LSSaver project to process the pages. Recently I got a feed back that LSSaver stops to load the blog titles and is blocked there. The problem seems to happen on a WinXp + IE6 platform.

After investigation, the problem comes from a null pointer exception, but why there is a null pointer? A step by step debug showed me that when using WebBrowser’s DOM to retrieve certain HTML element, the HtmlElement.NextSibling returns an invalid pointer even when there is no more sibling of the calling HtmlElement object. It seems that this is a known issue in the .NET framework:
http://connect.microsoft.com/VisualStudio/feedback/details/304466/htmlelement-nextsibling-returns-incorrect-value

Anyway, I won’t rely on the NextSibling is null or not, I get the number of children from the parent, then rely on this count when traversing all the children elements. The problem is fixed.

Thursday, September 30, 2010

Overloading operator << for containers

Today, I saw a line of code in one of our cpp files, it looks like this:
marshaller << obj_list;
what interesting is that obj_list is an instance of type std::vector, and one of my colleagues asked me if he can do similar things with an instance of type std::map<>.

The answer is "I don't know", because it depends on if the operator << is overloaded for the marshaller type for std::map<>.

The secret why "marshaller << obj_list;" works is that, the marshaller type has an overloaded operator << for std::vector. Something looks like this, assuming marshaller has type T:
T  &operator << (T &t, const vector avector){...}

Here is an example with cout:
ostream &operator << (ostream &out, const vector avector)
{
    vector ::const_iterator itr = avector.begin();
    for (; itr != avector.end(); ++itr)
    {
        out << (*itr);
    }
}

int main(void)
{
    vector str_vector;
    for (int i = 0; i < 10; i++)
    {
        stringstream str_stream;
        str_stream << i;
        str_vector.push_back(str_stream.str());
    }
    cout << str_vector;
}
The output is:
0123456789

So for this works with std::map<>, we need to overload << for std::map<>. 

Finally, it turned out that there is no such an overload, unfortunately. So we have to do it for each pare in the map.

Sunday, September 19, 2010

Do It in a Programmer's Way

DiPw, I'd like to pronounce it like "deepyou", is my preferred way of doing things, especially things related with my job as a programmer/developer.

Recently, I was assigned a job to migrate documents from the old system to the new one, and this is to be done for each of our customers. In order to secure the migration, I need to check many configurations on both systems, they need to be similarly configured so the migration is transparent for the customers, ideally. What complicates things is also we have test systems and production systems, and the migration need to be done first on test systems then on production systems. So as a result, I have a lot of things to check and compare. Even worse, the settings are managed by several GUI applications so I have to click many times to find one setting on the old system then, do it on a different GUI on the new system. That is not only boring but also fault prone.

A colleague of mine kindly told me that the content of the GUI applications are finally stored in the database and he also gave me some SQL to retrieve the values. That is a big help, however, I still have to manage two types of databases, Oracle and SqlLite.

Why I have to do it manually? It's time consuming and error prone. Why not write a program doing all of these jobs for me? With always DiPw in head, I decided to write a Python program doing these boring jobs and finally it took me one day. Voila, now with the program, I retrieve all need information on all systems for a given customer in 20 minutes and when needed, I can retrieve most up-to-date information whenever I want in 20 minutes, this is impossible without the program. And when it comes the time to migrate another customer, I just run the program for this customer.

Well, I admit that the job is not all about getting all the settings, but it is the most boring part, so let a program do it!

Monday, August 30, 2010

A Real-life Story about Bad Type Cast

We have a problem today in our soft. That is, in short, we have 285 lines of text to display but only 231 lines are displayed. The investigation is not so easy because the text to be displayed is converted from structured message and the number of lines are calculated on the fly.

Basically, there is a segment in the message that specifies the maximum allowed number of lines, the sender of the message has set it to 999, assuming it the maximum possible lines in the message.

So if you are really a geek in programming C/C++, you may already know where is going wrong. Yes, an integer 999 when assigned to a unsigned char, the latter will have value 231. In more detail: binary presentation of decimal 999 is 1111100111, when assigned to unsigned char, we have only the lower 8 bits left: 11100111, it equals decimal value 231.

The problem is quite clear, but it has been hard to find it out because it hides itself deep in one of the libraries our soft uses.

Another interesting thing is that the library code uses atoi to convert the maximum allowed size in the message to an integer value, but with a parameter like this: "999blabla", that is the value in string followed by other alphabetic characters. atoi is designed to handle this correctly, take a look at the specification of atoi:

int atoi ( const char * str );
Convert string to integer
Parses the C string str interpreting its content as an integral number, which is returned as an int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus orminus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

Sunday, August 15, 2010

Wednesday, August 4, 2010

LSSaver 1.0 Release, Free download.

Finally, I'm able to announce the release of LSSaver 1.0, the result of my two-month project LiveSpaceSaver.

As said, it is for saving your Windows LiveSpace Blogs.

If you are interested, you can google LSSaver or simply download it here:
http://byunsoft.webfreehosting.net/index.html

Bug reports are appreciated :D

Monday, July 12, 2010

My New Project, a LiveSpaceSaver

I paused a little on the DirectX development because the first objective had been achieved and also a technical obstacle that I cannot find a way to float a D3D window on the desktop.

Main while, I turned to a new project that aims to write a program to save the Windows LiveSpace blog and album contents. Actually, I wrote one a year ago but for Linux, now I'd like the same for Windows.

The function of the program is simple, it saves the LiveSpace blog and photos in the albums to local disk. The program works like a crawler, it obtains the html contents from the server and extract interested part from them, after all, I don't want to save the complex page with lots of useless links, banners...

This project will be a RAD. With .NET, I prefer managed C++.

Basically, I'd like it to be a GUI program, on the left, I'd like to have a TreeView that shows the blog titles grouped by months, photos grouped by albums, same as shown on the webpage. TreeView does not support multiple selection by itself, but one can write customized code to support that. For the first prototype, maybe using CheckBox is OK. On the right, I'll show the contents for selected blogs or photos. Then on the top of the main window, I'd like to have a strip that holds the input for LiveSpace username and the buttons for "Obtain" and "Save". So it is a very simple GUI doing simple things.

Obviously, I need to obtain the webpage from LiveSpace, I selected the WebBrowser control which is based on IE and is quite easy to use.
WebBrowser can parse the HTML into DOM, then we can use HtmlDocument obtained by WebBrowser::Document. In this way, it is easier to regenerate the HTML from the modified DOM to customize output.

As for the final step that is the actual save operation, I need to download the pic files appeared in the blogs as well as the photo files. I selected WebClient for the job.

Development is on going, first version coming soon. :D









Monday, May 17, 2010

Processing User Input

By now, I'm able to render a floating 3D object with transparent background, my first objective is almost achieved.

Now I need to be able to process the user's mouse input, and especially, to let the user to pick something on the 3D object. The following references are useful for this:
http://msdn.microsoft.com/en-us/library/ee418864(v=VS.85).aspx
http://www.microsoft.com/whdc/archive/pointer-bal.mspx
http://www.microsoft.com/whdc/archive/pointer-bal.mspx
http://creators.xna.com/en-US/sample/picking

Friday, May 14, 2010

D3D Rendering with Transparent Background

After several months, I'm finally able to do this. The basic idea has been posted previously, that is use layered window and create a render target which I'm able to get the DC from. Then render everything on this target, then use UpdateLayeredWindow instead of Present to draw the backbuffer.

I have performance penalty but for a small window, it is acceptable.

The last thing I have to deal with is to slow down the FPS. This may relate to the unique way the layered window processes the messages.

Wednesday, April 21, 2010

Using DXUT

DXUT is a part of DirectX SDK examples. With may help wrapper functions and a simple DirectX based dialog/control framework, it is a good starting point of a DirectX project.
DXUT programming guide can be found here: http://msdn.microsoft.com/en-us/library/ee417532(v=VS.85).aspx

Towards my goal to a floating D3D window, I modified the CustomUI example and the DXUT framework, now the CustomUI is floating on top of desktop. What remains is to move the GUI.

Wednesday, April 7, 2010

Some Useful Utilities on Linux

find, xargs and rename are three useful utilities I discovered recently that make a programmer's life much easier.

Sometimes, I need to make a symbolic link to each of quite many files, I can write a perl or python script for that. I'm learning the shell script but I cannot write something effectively with it till the moment. However, I found out that I can do the job by two lines of commands.
For example, I have many files ending with .so.1.0.0
First I make a link to each file by giving the name of the link an additional .link based on the original filename:
find . -type f -exec ln -s '{}' '{}'.link \;
or with xargs if there are too many files to handle:
find . -type f | xargs -t -l1 -i ln -s '{}' '{}'.link
So I have many links ending with .so.1.0.0.link
A small problem here with xargs, I can add prefix or postfix but not modify the actual name, what I needed is a shorter name, in order to do that, I use rename to change the name as I wanted, a name shorter than the original file name.
rename 's/\.1.0.0.link//' *
this will rename all the links I have created with name .so.1.0.0.link to .so, the 1.0.0.link is removed.

I'll give discuss each of them in more details later.

Thursday, April 1, 2010

Interesting Points about STL

In this post, I'll collect some interesting points about STL, knowing them may save me some time when the a strange problem appears.

1. The remove() algorithm is convenient sometimes. But be careful to know it does not change the number of elements in the container after some elements is "removed", it returns an iterator marking the new end.

2. Sometimes I may want to write a line of code like this: ++aCol.begin(), in this case I'm operating on a temporary variable, this is not alway allowed depending on the type of aCol and its implementation. First, modifying a temporary value of a fundamental type such as pointer is not allowed. The vector and string usually implement their iterator as a pointer, so if this is the case, ++aCol.begin() will not compile.

Tuesday, March 30, 2010

Towards a D3D Windows Framework - 1

I haven't any progress on the D3D programming for two weeks. During this time, I'm thinking about building a windows framework based on D3D which will enable me to build real 3D applications more easily.

I'm following the book DirectX9 User Interfaces Design and Implementation, it is a  very good reference.

But before building the windowing system, I spent several days writing a very simple debug library that enables me to trace the debug information in a file, with a formate that I like.

Also, the book used very primitive techniques, I need to think about the feasibility using advanced libraries such as STL, boost to build the windowing system.

Tuesday, March 16, 2010

A Reallife Story about Memory Leak

My colleague alerted me today a potential memory leak in a component that I have written. It looks like the following piece of code:
try
{
    // new an object.
    // Call the Init() of the object, that may throw in case of error.
    // Put the object pointer into the pool.
}
CATCH...

I use capital CATCH here because actually, I used a macro that wraps the standard catch into one line. While it simplifies the code, it also made me to forget to do necessary cleanups in the catch clause. Finnaly, I gave up using the beautiful macro and went back to the standard catch and put a delete there.

More words on the pointer in the pool. It seems that to put the object itself in the pool is better but this is possible only when the class provides a default constructor and a copy constructor, if one uses a STL container as the pool. It is not my case, the class I'm using does not have a default constructor nor a copy constructor... Bad design or are there some special reasons to not provide a default or copy constructor?

Monday, March 15, 2010

A Generic Way to Render on GDI

In this post I'll introduce a generic way to do a DirectX rendering on Windows GDI.


In the previous post, I did an experiment with the texture created by calling the D3DXCreateTextureFromFile function from a file then obtain the level 0 surface of the texture and then get the DC of the surface, and finally, render this content in the DC to a screen DC. This is working because D3DXCreateTextureFromFile uses D3DPOOL_MANAGED by default, so it is possible to get the DC from its surface.


The key idea is then to create then render on a surface from which we can get its DC.


Notice it is not alway possible to get a DC from a surface, as specified by the DirectX document, the following restrictions apply when calling the GetDC method of a surface:


# IDirect3DSurface9::GetDC is valid on the following formats only: D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_R8G8B8, and D3DFMT_X8R8G8B8. Formats that contain Alpha are not supported because the GDI implementations don't have a well-defined behavior on the alpha channel. For more information about formats, see D3DFORMAT.

# Only one device context per surface can be returned at a time.

# IDirect3DSurface9::GetDC will fail if the surface is already locked. If the surface is a member of a mipmap or cubemap, IDirect3DSurface9::GetDC fails if any other mipmap or cubemap member is locked.

# IDirect3DSurface9::GetDC fails on render targets unless they were created lockable (or, in the case of back buffers, with the D3DPRESENTFLAG_LOCKABLE_BACKBUFFER flag).

# For surfaces not created with IDirect3DDevice9::CreateOffscreenPlainSurface, IDirect3DSurface9::GetDC will fail on default pool (D3DPOOL_DEFAULT) surfaces unless they are dynamic (D3DUSAGE_DYNAMIC) or are lockable render targets.

# IDirect3DSurface9::GetDC will fail on D3DPOOL_SCRATCH surfaces.

# IDirect3DSurface9::GetDC causes an implicit lock; do not retain the device context for later use. Call IDirect3DSurface9::ReleaseDC to release it.
It is valid to call IDirect3DSurface9::GetDC/IDirect3DSurface9::ReleaseDC on levels of a mipmap or cubemap, however, these calls will be slow to all miplevels except the topmost level, and GDI operations to these miplevels will not be accelerated.


As a result, GetDC of a default BackBuffer will usually fail as the default BackBuffer uses D3DPOOL_DEFAULT. So I need to create a lockable surface with CreateRenderTarget method:


HRESULT CreateRenderTarget(
  UINT Width,
  UINT Height,
  D3DFORMAT Format,
  D3DMULTISAMPLE_TYPE MultiSample,
  DWORD MultisampleQuality,
  BOOL Lockable,
  IDirect3DSurface9** ppSurface,
  HANDLE* pSharedHandle
);

and specify Locable as true. In order to fill the first five parameters, I can get the default BackBuffer's description and use the same information for the new surface.


The following steps are straightforward, when doing the render, first set the render target as the new surface, then render. Finally, instead of calling Present, get the DC of the surface then use GDI to put the contents on the screen.


Till now, I used a surface without an alpha channel, if you want to use an alpha channel in the surface and you are on a Windows XP as me, be sure to get the SP3 which contains an important fix KB 937106 that allows GetDC from a surface with an alpha channel.

Sunday, March 7, 2010

A Simple Example for Rending Texture with GDI

In this example, I'll demonstrate how to render a texture with GDI. You may wonder why I need to do that anyway as texture is generally used to render shapes in DirectX. The idea here is if I use the layered window with a transparent key color, the color in the texture, when finally rendered using GDI, will be transparent so I see everything behind my program window. Using only DirectX will not produce the same effect.

Let's start with a quick introduction to the layered window. Layed window is created by calling CreateWindowEx with label WS_EX_LAYERED. After the window is created, I can use either SetLayeredWindowAttributes or UpdateLayeredWindow to actually show the window. By calling SetLayeredWindowAttributes, I need to process the rending in the WM_PAINT message. As I'm going to use GDI mixed with DirectX, I want to have total control on the rending process, I'll use the UpdateLayeredWindow instead. This function saves me from the WM_PAINT message. I can call it whenever I finished the drawing.


Next I'll do the DirectX initialization, where I'll initialize the divece and especially, I'll create the texture. For simplicity, I create the texture from a bmp file using D3DXCreateTextureFromFile. The bmp file I'm using contains in the part where I want it transparent a special color, e.g. RGB(255, 128, 64). I'll specify the same color as the color key when calling the UpdateLayeredWindow.

After the texture is created, I'll retrieve the level 0 surface associated to it. This is done by simply calling the texture's GetSurfaceLevel method.

As I'm going to render the texture with GDI, I need two DC handles to call the UpdateLayeredWindow, one is the source and the other is the destination. I already have a surface ready to be presented on the screen, I need to get the DC associated with it. This is done by calling the surface's GetDC method. If the call succeeds, the source is ready. Then I still need to prepare the destination. That is simply a call to global GetDC.

There are still some parameters to prepare in order to call UpdateLayeredWindow. The BLENDFUNCTION sturcture contains information about the blend I want to do with the contents to be rendered. I give the following values:
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.AlphaFormat = 0;
blend.SourceConstantAlpha = 255;

I need to specify also the new position, size of the new window. Be careful here, I need to retrieve the size of the bmp file I have loaded as it will be my entire window. What's more, give a size larger than the actual size will not work. Currently, I load the bitmap and get the size information from it, I'm not aware the way to get this information from the texture which is created from the bmp also. So I actually load twice the bmp file.

Next, the location of the layer in the source DC, which is usually (0,0).

Finally, I set the transparent color as the color key and the ULW_COLORKEY as the flag and call the UpdateLayeredWindow.

The whole process is:
  • Create a layered window.
  • Load bmp into texture.
  • Get surface 0 of the texture.
  • Get DC of the surface.
  • Get DC of the destination (Desktop)
  • UpdateLayeredWindow with source DC as the DC of the surface, destination DC as the Desktop.

Something I need to note, with D3DXCreateTextureFromFile, I can always get the DC of the surface 0 associated. But with a texture created by CreateTexture, I can fail sometimes when get the DC. This is due to the usage and memory pool used by the methods. D3DXCreateTextureFromFile always uses D3DPOOL_MANAGED. (Cited from DirectX Doc for this method: "Note that a resource created with this function will be placed in the memory class denoted by D3DPOOL_MANAGED.) And the GetDC method of the surface has several limitations and especially, it will fail on D3DPOOL_DEFAULT unless the usage is dynamic (D3DUSAGE_DYNAMIC). 

I'll investigate more on this issue. But the idea is clear, once I have surface from which I can get its device context, I'll be able to render it to a layered window. On the other side, I need also be able to render on the surface, obviously. So I'll need a surface that I can render on it and can get DC from it. I need to see if this is actually possible, otherwise, maybe I can render on on surface and put the result to another one from which I can get the DC.

Friday, March 5, 2010

Mixing D3D Rendering and GDI

I tried my first solution to render a 3d scene to transparent window,
that is, get the desktop bitmap with GDI then render 3d on it. The
performance is bad.

So I tried the second solution, which is more or less a common
practice, to render on a texture then get it's surface then get the
device context of the surface. This DC can then be used for GDI
rending. To make transparent effect, just use a layered window with a
transparent color key and use the same color for the transparent part
in the texture. Also I need to use UpdateLayeredWindow onstead of
standard GDI rendering in WM_PAINT.

There are some tech details I need to solve in order to use it freely
with different types of textures.

Thursday, March 4, 2010

Email to blogger, give it a try!

Maybe i can write on the bus. :)
Just a small problem, no way to give the post a label?

Wednesday, March 3, 2010

Vim tips

Vim is fantastic. It may improve your editing efficiency a lot. After using it for four years, I discovered recently something really useful.

You can do an "instant search" with * (for forward) or # (for backward) command when your cursor is on a word. These commands saves me two seconds for a search with my word under the eyes. Before I switch search mode and type the word. These commands match whole word only, but you can use g* or g# to do a partial match.

Also I started to try to locate my cursor precisely faster with commands each time I want to move it. Before I use l,i,j,k,home,end... I need to repeat many times before the cursor arrives at the good position, now I'm using commands like e,E,b,B,A,0,$,w,W... I need some time to get used with them.

When using visual mode to select lines, I can use the v$ command that will select to the end of the line regardless where my cursor currently is, I use j,k to move upwards or downwards.

Now I also learned to use the J or gJ command to join multiple lines into one. This is extremely useful because I need to do this occasionally and it is really boring to do it manually.

Thursday, February 18, 2010

D3D Texture, Light, Blending

I made some progress on these points. Now I'm able to draw something with a texture and light it up. Also, I can alpha blend the texture so that it appears translucent or with an irregular shape as defined by the mask. That is quite cool.

However, what I really want to achieve is something more sophisticated. Say, ultimately, I want to have a 3D figure floating on top of the desktop, with no window boarder, nothing. It seems that I have to use a irregular shaped window so the 3D figure itself defines the window boarder.

The first idea is to get the screen covered by the my program and then render my 3D figure on top of it so that I can create an effect that the 3D figure is floating on top of the desktop. But it does not work quite well because it performs very badly, the window flickers.

Another idea is to use a transparent window and render the 3D figure on top of a certain rarely used color and make this color as the mask color so it is transparent on the client window.

Finally, maybe I can try to use the irregular window based on the SetWindowRgn technique. But a similar performance problem is how to setup the window's region efficiently. If I setup the window region pixel by pixel from the rendered 3D figure, it should be very slow, one can afford doing this normally only once when the program loads.

I'll try the second and the third.

Tuesday, February 9, 2010

D3D Render and Color Basics

After several demo programmes in the tutorial, I get familar with the basic D3D render procedure now.

In order to draw something on the screen, you need to do some preparation, e.g. create an IDirect3D9 instance and setup the device.
Next, you need to create the buffer to hold your content: basically they are vertices organized in a certain way. You put all your vertices and then optionally, tell D3D how they are organized with another buffer with indices. The indices indicate the order of the vertices in which they are constructed to form triangles.
Now that you have triangles representing your object, you can tell D3D how these triangles should be drawn: only a point at each vertex, a line on each side of the triagle or the triangle surface. This is done by setting the render state option D3DRS_FILLMODE with different values: D3DFILL_POINT, D3DFILL_WIREFRAME or D3DFILL_SOLID.
After setting up necessary transforms, camera, etc. you will be able to render the vertices in the buffer. At this stage, you still have an opertunity to tell D3D what the vertices in the buffer mean exactly: just some isolated point, lines with certain relationship between each other, triangles... by specifing the first parameter of the method DrawIndexedPrimitive or DrawPrimitive which is a D3DPRIMITIVETYPE.


Each vertex can be augmented with a color component. In order to use this feature, you need to define a customized vertex formate and then tell D3D the formate you are using by the method SetFVF with a good parameter.
In case you define a vertex like this:
struct Vertex
{
float x, y, z;
D3DCOLOR color;
};
you will need to use D3DFVF_XYZ | D3DFVF_DIFFUSE as the parameter when calling the SetFVF method.

Monday, January 25, 2010

Continue on DirectX

Now I'm following the tutorials in the DirectX SDK. Since I have a WinXP on my PC, I started with DirectX9. The tutorials are generally well designed, I would like to say, for beginners. But there are some small problems in the document such as typos, etc. Reading the code may resolve these kind of problems.

However, if you want to really understand how the programme works, you'd better to type the write the programme by your self instead of just open the tutorial project and compile and run it or to copy the code into your project. That is because there are quite a few details when you miss it the programme will simple not work, and the worst thing is it is hard for the beginners to know where is going wrong as you generally can not run the programme step by step as usual to find it out: you simply see the final, bad, result on the screen. For example, when I modified you code to use a zbuffer, I fogot to give an additional flag to the Clear method, as a result, I got a quite strange result on the screen, I checked my code again and again and found the problem finally. I'm not aware of any way to debug this kind of problem, please tell me if you know.

I have just completed the first four tutorials which cover the basic topics such as initialize the D3D device, render the vertices, use matrices and lights. There is one thing that I do not understand, the programme runs fine when it is visible, but it consumes 100% of CPU time whenever the client rectangle is invisble: when it is covered by another window or when the window is minimized. I'm not happy with this but I can not explain why, I'm still investigating.

Basically, D3D9 programming is quite demanding.

Friday, January 22, 2010

Starting DirectX Programming

Purely as a hobby because DirectX makes you really fatastic visual effects. There is only one thing makes me unhappy: I have to work on a Windows and Visual C++.

I installed a vi, although it looks terreble under Window as compared with a native Linux vi, the editing is all the same efficient. This makes my life a little better.

The first objective is to master basic DirectX programming skills. It may take weeks to build my first "Hello World" DirectX application.

Tuesday, January 19, 2010

A reallife story about return value

Today we detected a random failure in some of our regression scenarios. After an investigation in the traces, we found the problem actually came from a component we are using, which parses a string into tokens. The parser fails randomly when processing certain tokens.

As usual, the first suspect is a memory issue, but after a detailed inspection with gdb, we found nothing really harmful. Fortunately, the parser leaves a detailed error message when it stops and it seems that the function used to retrieve the token from the buffer encounters some problems.

Finally, after reading the user guide of the parser, we noticed that the function has to return a bool value indicating the parser if there is an error or not and it turned out this particular function does not have a return actually even it is defined to return a bool value.

In this case, the return value is a random value in the register. Actually, this is warned by the gcc.

Lesson learned here, always remember to return something for every branch in a function that is supposed to return something. Pay attention to compiler warnings.

-----------------------------------------------------------------------
Yet another story.
This time our soft encountered a failure. After investigation, the problem is caused by a misuse of the string::find(), similar to the following:
aPos = aStr.find(' ', 0);

if(aPos == string::npos)...

the aPos is declared as 32 bits unsigned integer, as the string::npos has value -1 but a special type string::size_type which is usually size_t, so the exact type depends on how size_t is defined by the compiler, the comparison will never succeed even if no space is found in the string on 64-bit systems, for example.

So the lesson is always use string::size_type for string positions.

Wednesday, January 13, 2010

A Programmer's Nice Day

For many years, I consider myself a programmer. But until recently, I found a job as a programmer. Things are going to be interesting, because as a programmer, you never stop learning.

This blog will be dedicated to the subjects related to my life as a programmer from now on.