PDA

View Full Version : 3D engine example by Howie



howie
07-26-2004, 09:36 PM
I see a lot of the same questions asked in these forums. I also know online examples don't always give a clear picture of how to do something. Nothing like clean, well commented code to help you see how it is done. This engine only uses OpenGL as a rasterizer, everything else is in software. You did want to learn the hard way, didn't you? Not to worry, it's not all that hard. :p

http://www.howiesfunware.com/3DEngineByHowie.zip

Loading models, lighting, textures and collision/reaction are just a few things it does. You can use BMP, tga, gif & jpg for your textures. The example has you running through a simple map FPS style. I wrote a program that parsers Wavefront OBJ files and makes native files the engine loads so your free to design complicated models for easy loading.

Going through the door ways is a little sticky. Need to design the door ways a little differently. For this simple example, it will do for now.

There's a file by the name of "File description.txt" that describes each file in the zip. Have fun. :D

ypsd
07-26-2004, 10:44 PM
Originally posted by howie:
I see a lot of the same questions asked in these forums. I also know online examples don't always give a clear picture of how to do something. Nothing like clean, well commented code to help you see how it is done. This engine only uses OpenGL as a rasterizer, everything else is in software. You did want to learn the hard way, didn't you? Not to worry, it's not all that hard. :p

http://www.howiesfunware.com/3DEngineByHowie.zip

Loading models, lighting, textures and collision/reaction are just a few things it does. You can use BMP, tga, gif & jpg for your textures. The example has you running through a simple map FPS style. I wrote a program that parsers Wavefront OBJ files and makes native files the engine loads so your free to design complicated models for easy loading.

Going through the door ways is a little sticky. Need to design the door ways a little differently. For this simple example, it will do for now.

There's a file by the name of "File description.txt" that describes each file in the zip. Have fun. :D Unfortunately, I use OpenGL with Cygwin. Is there any easy way to modifiy your codes such that I can use them with cygwin?

howie
07-27-2004, 04:11 AM
I don't know what Cygwin is but yes, this would be very easy. The 3D library files are kept general and are not tied to anything. The file "Example.cpp" is for working with Windows and the 3d Library files. Ignore the Window handling parts and look at how the 3D library files are used (CMeshTri, CTextureLib, CLightList, CMatrix).

Specificly look at functions...
InitGLwindow()
LoadGameObjects()
GameLoop()
RenderBuffer()
ReactToCollision()
GetUserImput()
in Example.cpp

This engine is all code. No LIB's and DLL's are used. Spend some time going over Example.cpp, going through the code, reading the comments. Then work you way through the 3D library files the same way to get a feel for how all this is done.

Surgeon
07-27-2004, 04:20 AM
Thanks a lot for the code! I wish I had it a week ago :)

You said you'd made many members public to increase the speed but isn't it true that a compiler converts functions like:

float getUpVector () { return m_upvector; }

into the same code as if m_upvector was a public variable? Or it depends upon the compiler?

I will steal your light class, that's for sure :)

howie
07-27-2004, 04:37 AM
Could be. I'm not sure. Good C++ design suggests all data needs to be protected and only set via class functions. Speed is everything in our field so making some variables public helps in the speed department.

ypsd
07-27-2004, 12:31 PM
Originally posted by howie:
I don't know what Cygwin is but yes, this would be very easy. The 3D library files are kept general and are not tied to anything. The file "Example.cpp" is for working with Windows and the 3d Library files. Ignore the Window handling parts and look at how the 3D library files are used (CMeshTri, CTextureLib, CLightList, CMatrix).
cygwin (http://www.cygwin.com) is a *NIX like implement on MS Windows.
Usually, a project under Linux has a Makefile for compiling. You sources don't have a Makefile. I don't know to compile it. What compile options do you use?

howie
07-27-2004, 02:49 PM
I don't do much with make files.

07-27-2004, 04:46 PM
thanks for all the hard work, howie!

ypsd, maybe you can write a conversion as an exersize!

Kilam Malik
07-27-2004, 10:37 PM
Originally posted by howie:
Could be. I'm not sure. Good C++ design suggests all data needs to be protected and only set via class functions. Speed is everything in our field so making some variables public helps in the speed department.You could use inline functions to set and get protected variables. Then you have clean C++ code and speed.

Kilam.

howie
07-28-2004, 06:29 AM
thanks for all the hard work, howie!

ypsd, maybe you can write a conversion as an exersize! Thanks! The conversion code is there. The file is "CObjParser.cpp". Parsing a text based file format is not that hard, it just gets messy fast.


You could use inline functions to set and get protected variables. There is overhead in calling a function, even if it is inline. The way an inline is compiled down to assembly differs from compiler to compiler and sometimes it's handled like a regular function. The variables that I made public are usually arrays and we are only talking about a few of them.

:) I uploaded a new zip file with some changes. All the code for the converter is there. :)

Kilam Malik
07-29-2004, 04:33 AM
Originally posted by howie:
There is overhead in calling a function, even if it is inline. The way an inline is compiled down to assembly differs from compiler to compiler and sometimes it's handled like a regular function. The variables that I made public are usually arrays and we are only talking about a few of them.It depends on your compiler settings. Only using the inline-keyword in the code won't help.
I just made a little sample with VC++ with a class variable d which is set/get via functions and as comparison directly (variable is public). The assembler code is the same:


1: class InlineTestC
2: {
3: public:
4: InlineTestC() { d = 0.0; }
5: ~InlineTestC() {}
6:
7: inline double GetDiameter() { return d; }
8: inline void SetDiameter(double _d) { d = _d; }
9:
10: double d;
11: };
12:
13: void main(void)
14: {
00401000 push ebp
00401001 mov ebp,esp
00401003 sub esp,10h
15: InlineTestC cl;
00401006 mov dword ptr [cl],0
0040100D mov dword ptr [ebp-0Ch],0
16: double myD;
17:
18: // Inline:
19: cl.SetDiameter(5.432);
00401014 mov dword ptr [cl],353F7CEEh
0040101B mov dword ptr [ebp-0Ch],4015BA5Eh
20: myD = cl.GetDiameter();
00401022 mov eax,dword ptr [cl]
00401025 mov dword ptr [myD],eax
00401028 mov ecx,dword ptr [ebp-0Ch]
0040102B mov dword ptr [ebp-4],ecx
21:
22: // Direct:
23: cl.d = 5.432;
0040102E mov dword ptr [cl],353F7CEEh
00401035 mov dword ptr [ebp-0Ch],4015BA5Eh
24: myD = cl.d;
0040103C mov edx,dword ptr [cl]
0040103F mov dword ptr [myD],edx
00401042 mov eax,dword ptr [ebp-0Ch]
00401045 mov dword ptr [ebp-4],eax
25: }
00401048 mov esp,ebp
0040104A pop ebp
0040104B retIt's even done with VC++ 6 which has a rather bad optimizer ;-)

Kilam.

howie
07-29-2004, 06:03 AM
I agree. :)

For this engine, since the main goal is to show how things are done, I don't want to hide the data too much. It's easer to see how it works when the implemintation is not hidden.