Chong Jiayi's Bolt3D engine




Questions and Answers

What is Bolt3D?
Bolt3D is a realtime 3D graphics rendering library for the win32 enviroment. It is in the form of a DLL that you can call from your C/C++, VB and Delphi apps. It requires a Pentium 90 or above and 16MB to run. Bolt3D is specifically optimized for the intel Pentium platform. Future enhancements include support for MMX instructions and the Pentium Pro.

What can Bolt3D do?
Bolt3D supports realtime gouraud, phong, texture-mapping, surface-mapping, particle systems and fog effects. In addition, Bolt3D allows for the creation of simple objects like spheres, cubes, cones, cylinders, sweeps and height fields.

How do I compile my apps with Bolt3D?
Firstly, you have to include the header file called blast3d.h into your app. Then you have to link your app to the file bolt3d.lib. Read the file Bolt3D.doc for more info. It will get you familiar with the Bolt3D API.

The docs don't tell me about texture-mapping or surface mapping. And what the hell is surface-mapping anyway?
In order to use texture-mapping, you have to call the CreateTexture() function like this:
textureindex=CreateTexture(currentdc,310,190,"c:\\windows\\viewtest.bmp",TRUE);
This creates a texture 310 by 190 using the file "c:\windows\viewtest.bmp" You can change the parameters to your own. After that, do this:
MapTexturetoObject(0,0,1,0,1.2,1.2);
where the first parameter represents the object index, the second the texture index and the third the mapping type. Changing the mapping type to 3 changes it to surface-mapping instead of texture-mapping. The last 2 parameters alter the scaling of the texture.
After you have finished your app, you must remember to clear the textures by calling:
CleanupTextures();
Surface mapping is actually a modified form of bump-mapping and it allows for the display of rusty surfaces.

How do I create height fields?
Bolt3D allows for the creation of height fields. Height fields are actually extrusions of 2D images into 3D. Height fields can be used to create fractal landscapes and flythroughs(the flight3d.exe is a height field demo). POVRay, the excellent ray-tracer also has a height field creation feature. Check out its images created from height fields! They are awesome. Anyway, to use height fields in Bolt3D, do this:
CreateUserHeight("Landscape",RGB(234,128,56),0,32,32,"c:\\Windows\\HEIGHT.bmp",currentdc);
This creates a height field of name "Landscape" from the file "c:\windows\height.bmp" 32 by 32 pixels wide of color RGB(234,128,56). There is another height field creation function called CreateHeight but it is not as efficient as CreateUserHeight as Bolt3D will optimize for the handling of huge scenery for CreateUserHeight(). After it is called, you can resize, move or rotate the height field like any other object:
::SelectObj(GetUserObject("Landscape"));
::inittransCPP();
::scaleobjCPP(1840,200,1840);
::rotateCPP(0,10,0);
::translateCPP(0,-390,150);
::ApplyTransformLocal();
::ApplyTransform();

How do I model, load and save objects?
Bolt3D contains a modeller mod3d.exe for you to model your 3D objects. You can save your 3D models as *.b3d files. Once saved, you can load your scenes into memory by calling:
ReadScenefromDisk("c:\\myfile.b3d");
where myfile.b3d contains your object(s). Once loaded, you can then manipulate your objects as normal. Let's say you have already 5 objects in memory. Let's say that myfile.b3d contains 4 more objects. Thus, the first object from myfile.b3d will have the index of 5(because objects indexes start from 0). You will have to select the object of index 5 to transform the first object from the file. Normally however, files created from mod3d contain UserObjects. Thus, you would only need to call GetUserObject() to get the index of that UserObject and select it using SelectObj(). Note however that your objects must have UNIQUE NAMES for this method to work!
For those of you wanting to clear the memory and start a new scene completely, call the function:
cleanup();
before calling ReadScenefromDisk().


How do I create fog effects?
It is VERY easy to do fog in Bolt3D! Yeah! All you need to do is to call the function:
CreateFog(128,128,128);
This creates a fog of RGB(128,128,128). That's all to it. Your will see fog rendered together with your objects. To turn off the fog, call:
RemoveFog();


How do render particle systems?
Bolt3D allows the rendering of smoke and bubbles in the form of particle systems. In order to use this feature, write the following code to initialize the particle systems:
btfparticle * myparticle;
myparticle=::CreateParticleSystem2("c:\\windows\\partest.bmp",currentdc);
::UpdateParticle2(myparticle);
::SetParticleColor(255,255,255,10,10,10);
This will initialize a particle system of type 2(which is used for smoke) using the image map file c:\windows\partest.bmp. You should use images like plasma fractals to create convincing smoke. Altering the images alter the looks of the particles as a whole. If what you want is not smoke but bubbles, initialize the lorenz particle system(based on the lorenz chaos attractor) by the following code:
myparticle=::CreateParticleSystem();
::UpdateParticle(myparticle);
::SetParticleColor(0,255,255,0,0,255);
After setting the particle color, you can then begin to render the particles. If you created particle type 2, you can apply a force to it:
::ApplyForce2(myparticle,0,.5,0);
::UpdateParticle2(myparticle);
If it's type 1, do this:
::ApplyForce(myparticle,0,.5,0);
::UpdateParticle(myparticle);
This code applies a force in the direction(x,y,z) where x now =0,y=0.5 and z=0. You can change the parameters to suit your app.
Ok, to transform your particles, you can use almost the same code you use to transform objects:
For Particle type 2:
::UpdateParticle2(myparticle);
::inittransCPP();
::scaleobjCPP(190,190,90);
::rotateCPP(angx, angy, angz);
::translateCPP(0, 40, 150);
For type 1:
::UpdateParticle(myparticle);
::inittransCPP();
::scaleobjCPP(190,190,90);
::rotateCPP(angx, angy, angz);
::translateCPP(0, 40, 150);
After all that, call:
::TransformParticle(myparticle);
::SetParticleView(myparticle);
where SetParticleView will set the orientation of the particles to that set by the function setTHEviewer. If you want to include particle systems in your program, you have to call different functions to render all the objects:
::RenderObjects(); //instead of RenderAll()
then call:
::RenderParticle2(myparticle);
or
::RenderParticle(myparticle);
depending on your particle type. After that, call this:
::CopytoScreen(currentdc);
to copy the image buffer to screen where currentdc is your current windows hdc. Note that you have to cast your hdc into an int type before passing it to CopytoScreen. When it's time to close your app, you have to delete the particles by doing this:
::DeleteParticleSystem(myparticle);
that's all to particle systems.


Why are you doing this?
Coz it's cool. Anyway, I hope to be able to make this engine a freeware in the future(that depends on the restrictions of my paper which I am still unsure of).


Any other enhancements you want to add?
Yeah. Like collision detection or maybe 3DFx support. Actually I'm hoping that some of you guys will be willing to write some sort of C++ wrapper class for this API(like MFC). The C++ wrapper class will be able to include features like collision detection(there is no need to modify the actual library to add such a feature). As for 3DFx support, I'll look into it. Meanwhile, I should be able to get a Pentium Pro enhanced version and maybe an MMX enhanced one up here soon. I'm actually also hoping if somebody or myself will have the time to change mod3d into a REAL 3D Developer Studio... where you can create and delete objects... and then add object events like movements and explosions... then all the programmer needs to do after the object has been developed is to click a button "export to C/C++" and the program will generate a wrapper class for the object. Just like AppWizard! Tell me if you're interested. I'll probably put the source code for mod3d and other examples on the web page soon(or if any of you requests for it).


How do I do collision detection and Draw to the buffer?
You can now do collision detection and draw to the screen buffer! I added a couple of new functions to do that. The function:
int WINAPI GetObjectCoords(btfvertex * boxbound1,btfvertex * boxbound2,btfvertex * boxbound3,btfvertex * boxbound4,btfvertex * boxbound5,btfvertex * boxbound6,btfvertex * boxbound7,btfvertex * boxbound8);
retrieves the 8 world coordinates of the bounding box for a single object. Similarly, the function:
int WINAPI GetObjectViewCoords(btfvertex * boxbound1,btfvertex * boxbound2,btfvertex * boxbound3,btfvertex * boxbound4,btfvertex * boxbound5,btfvertex * boxbound6,btfvertex * boxbound7,btfvertex * boxbound8);
retrieves the coordinates of the object relative to the viewer. You can then do your own intersection and comparison tests for collision detection.
You can also draw to the buffer now. Call:
int WINAPI GetBufferDC(int * bufferbitmap);
which returns the hdc of the buffer and the hbitmap of the buffer to draw your own sprites and stuff. If you want to project your 2D sprites and stuff into 3D, call:
int WINAPI GetFrom3D(float x, float y,float z,int * returnx,int * returny);


Can I do hardware acceleration with Bolt3D?
You can now do hardware acceleration using Bolt3D. It achieves this via Microsoft's D3D API. You'll need DirectX 5.0 and above to have hardware support. The following chipsets are supported: NVidia, Verite Rentition, Permedia, S3(some problems) 3DFX might not work as it does not do acceleration in windowed mode.
To use acceleration, you'll have to initialize the hardware card BEFORE YOU DO ANYTHING ELSE.
Call:

iniHardware(mywindow,mywidth,myheight);

where mywindow is the HANDLE(hwnd property) of the window, mywidth is its width, my height is its height.
After that, call:

inibufferCPP(myHDC, 5, MyWidth, MyHeight);

where myHDC is the hdc property of the destination, MyWidth is its width and MyHeight is its height.
You will then have to set the render mode:

setrendermode(0);

IT IS IMPORTANT THAT the rendermode is 0!



Continue to visit this page for I'll answer more of your questions on the engine soon
Back to Main Page...