Munsell.zip
Munsell_src.zip
Introduction
Direct3D is the component of DirectX that can render immersive 3D worlds. Direct3D is ideally suited for programs that allow the operator to fly through complex models in 3D space. The specific model I tackled was a model of theMunsell color solid. The Munsell color solid is a model for the range of colors perceivable by the human eye. It was developed back in 1905 by Albert H. Munsell. It is called a color solid because the color varies continuously throughout the volume of the model. You usually see the Munsell color solid displayed in 2D space in one of the following manners:
A vertical slice through the Munsell color solid would result in a 2D image such as the following:
The darkest, least-colorful colors reside near the center of the Munsell color solid. In fact, the central axis is the range of black and white colors known as the gray scale. The outer perimeter of the model is lumpy, just because that's how Munsell decided to distribute the colors. Munsell was an artist. Most scientists would prefer a color model that displays some form of geometric symmetry, such as a sphere or pyramid. But there is no reason to believe that cleaner geometry better depicts human color perception.
Background On DirectX
DirectX is the name of the Microsoft technology that allows developers to write computer games that achieve a high frame rate. DirectX allows your program to write to the display much faster than Microsoft's original technology, the GDI ("graphics device interface"). Direct3D is that portion of DirectX which can draw three dimensional shapes with smooth Gouraud shading and scientifically correct lighting. With Direct3D, we can create a program that allows the operator to dynamically adjust his position with respect to a 3D object, to zoom in and out, and to rotate the object about its central axis. You can even fly right through the object to view its interior.
I decided to employ Direct3D 8, which is the version that ships as part of the Windows XP operating system. Microsoft has since moved on to Version 9. DirectX version 9 can be installed on Windows 98, Windows Me, Windows 2k, and Windows XP.
To develop Direct3D programs you need to obtain the DirectX SDK (software development kit) from Microsoft. This is over 200 Mbytes so it's a pain to download (Microsoft used to offer the SDK on a $10 CD-ROM but they seem to have stopped doing this).
To merely execute a program (as opposed to build a program) that employs Direct3D you only need the much smaller DirectX run-time which you can again download from Microsoft. It is this run-time that was included in Windows XP but not in earlier Microsoft operating systems. Alternatively, most computer games install some version of the DirectX run-time and hence your computer may already have the version 8 or 9 run-time if you have purchased and installed a fairly recent game. Once you have installed the DirectX 9 run-time, you should be able to execute any program that employs DirectX 9, DirectX 8, DirectX 7, etc.
Be warned that once you install any version of any of the DirectX technologies, you cannot easily get it back off your computer. Microsoft does not bother to provide an uninstall capability. Therefore Microsoft recommends that Windows Me and Windows XP users create a "System Restore" point before they install a new version of DirectX. Windows 9x and Windows 2k users will have to re-install their operating system to revert to an earlier version of DirectX.
My program has no other dependencies other than DirectX. It employs the standard WIN32 API described in Charles Petzold's famous book "Programming Windows". I make no use of MFC, ATL, STL, WTL, etc.
The Code
My goal was to use Direct3D to display 20 radial slices through the Munsell color solid and to allow the operator to select an arbitrary rotation, tilt, and zoom factor from which to view this representation of the color solid. The operator can use the r and R keys to rotate the model, the e and E keys to elevate his viewpoint above or below the centerline, and the z and Z keys to select the viewing distance. A typical view presented by the finished program is shown below:
By the time I had the program working I realized it was an excellent illustration of both transparent textures and the importance of the alpha test.
A texture is just a .BMP file used to provide the surface coloring for a 3D model. This particular program uses 20 .BMP files holding the radial slices through the Munsell color solid. A single one of these .BMP files is shown below:
You can see that this .BMP file has a medium gray background. Microsoft'sD3DXCreateTextureFromResourceEx() function provides a way to declare one particular color as the color key color which means that it won't be copied to the screen. The way you accomplish this in Direct3D8 is by enabling alpha blending via a statement such as:
Collapse | Copy Code
pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
After I made this code available from my web site www.computersciencelab.com/Direct3DTut1.htm I was informed of an even simpler solution by Henrik Rydgård of Sweden. If the particular video card in the computer supports analpha test then the visual distortion can be avoided even if the program continues to use the original algorithm where it always starts painting with slice #0.
d3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, true );
pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 );
pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
You can interrogate your video card to learn if it has this capability in the following manner:
HRESULT cMunsell::SetRenderStates()
HRESULT hr;
IDirect3DDevice8 * pd3dDevice = g_pd3dDevice;
// The D3DRENDERSTATETYPE enumerated type is used with
// IDirect3DDevice8::SetRenderState() to specify all possible
// By default, Direct3D performs lighting calculations on all
/
/ vertices. And consequently, if a vertex has no normal vector
// it will receive zero light. An application that specifies
// vertex colors probably will not specify normal vectors and
// hence must be sure to disable lighting or else everything
// If you plan to cover all surfaces with textures then you
// probably want to disable Direct3D lighting. Otherwise,
// you will use IDirect3DDevice8::SetLight() and
// IDirect3DDevice8::SetMaterial().
hr = pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
// Depth buffering is a method of removing hidden lines and surfaces.
// By default, Direct3D does not use depth buffering but it can
// be enabled using the D3DRS_ZENABLE state.
hr = pd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
// To convince Direct3D to render the inside of an object in
// addition to its outside you will need to turn off back-face
hr = pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Since we want to employ color keying when we load our textures,
// we need to enable alpha blending.
hr = pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
// Alpha blending means combining the color value of the new pixel
// with the pixel already stored at that location in the frame buffer.
// There are a number of ways of doing this, described by the eq.:
// FinalColor = TexelColor × SourceBlendFactor
// + PixelColor × DestBlendFactor
// To achieve complete transparency you would request:
// hr = pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
// hr = pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
// But we want the alpha blending formula to vary on a pixel by pixel
// basis, as described by the alpha channel of the source. This
hr = pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
Compiling
and then click in the left-hand column where it says "DirectX". This will bring up a list of hyperlinks including one for the "End-user Runtime" (about 20 MBytes) and another for the "Software Developer Kit" (or SDK, which is over 200 MBytes). These hyperlinks will all mention the current release of DirectX (as of this writing, that's DirectX 9.0b) and that version is compatible with the software described here. Microsoft does not bother to continue distributing the older versions of DirectX. Again, if you are running the Windows XP operating system then your computer came with the DirectX 8 run-time, which is sufficient to execute my demonstration program. But to compile the code yourself you will have to install the full SDK.
I have included my Visual C++ 6 project file (Munsell.dsp). The only customization that I had to perform is to add the library files d3d8.lib, d3dx8.lib, and dxerr8.lib to the list of "Object/Library modules" that you find on the "Link" tab of the "Project Settings" dialog (which appears when you select "Project/Settings" from the Visual C++ 6 menu). This change is already incorporated in the Visual C++ 6 project that I provide so you will only need to repeat it if you create a new project.
Because Visual C++ 6 is older than DirectX 8, you have to force the compiler to employ the DirectX .H and .LIB files from the DirectX SDK rather than those similarly named but older files that shipped with Visual C++ 6. This customization you each will need to perform because this setting is not stored in the .DSP or .DSW project files. Select "Tools/Options" from the Visual C++ 6 menu which causes the "Options" dialog to appear. Activate the "Directories" tab on this dialog and then select "Include files" from the combo box labeled "Show directories for". Click on the "New" icon and then type in the directory path where you chose to install the DirectX SDK. Assuming you accepted the defaults offered by the DirectX SDK installer, then this directory path would be:
- C:\mssdk\include
Then use the Up arrow icon to bring this new entry to the top of the list so it will be searched before the other members of the list.
Next select "Library files" from the combo box labeled "Show directories for". Click on the "New" icon and then type in the directory path where you chose to install the DirectX 8 SDK. Assuming you accepted the defaults offered by the DirectX SDK installer, then this directory path would be:
'개발언어 > c++' 카테고리의 다른 글
MS Winows 계열 의 버전 정보를 알아내는 함수 (0) | 2016.07.18 |
---|---|
3D text, 예쁜 글 표현 (0) | 2016.07.18 |
마우스 클릭으로 색상추출 하는 코드 (0) | 2016.07.16 |
Smooth color transition algorithm (0) | 2016.07.16 |
메모리 사용량 알기 (0) | 2016.07.16 |