15,041,264 members
Articles / Desktop Programming / MFC
Article
Posted 17 Feb 2009

50.9K views
44 bookmarked

# 3DHelper

Rate me:
Helper class to display 3D data

## Introduction

Ever had the problem to display 3D-related data? E.g. to display a 3D-curve in a Windows dialog window? Don't like to implement a whole DirectX/OpenGL class hierarchy?
There is a solution: The `3DHelper `class!

More tools can be found on my homepage.

## Background

If you are familiar with 3D programming, you already might have used free/not so free libraries to perform the task of rendering 3D objects onto your screen.
The big (in my opinion!) drawback of that approach is: your code is getting more and more complicated to maintain and even understand. Not to mention portability.

Having just some files to be included into your project, performing all the necessary math-stuff to "get  3D" sounds too nice to be true? Now its real!

## The Solution

Given a 3D point (e.g. a point being part of a nurbs-surface, a 3D function value, etc.) the API transforms this point and returns a coordinate pair representing a dot in your window.

And the best - there is no sophisticated OpenGL/DirectX stuff involved. This is a pure software solution.

## Using the Code

To allow the API to help you, it needs some basic steps to be performed:

1. Add a variable of type `CMF3DHelper `to your project.
2. At start up (and after each resize event) call the `CMF3DHelper::Initialize()` function of your variable. (see 1.)
This `Initialize()` function needs parameters:
• A pointer to the device context (DC) of your window (used to get the window size)
• The "cube" representing your data, represented by two vectors: `vmin` and `vmax`.
All of your data points should lay inside that cube. Imagine something like a bounding cube, covering all your data points.
Example in 2D: you need to display a curve of form y=sin(x) where x is between [-PI] and [+PI]. The result of that function is in range of [-1] up to [+1].
Therefore you have to define the bounding box (2D!) using two corners:
(-1, -PI) which is top left and
(+1, +PI) similar to bottom right.
• A flag (`bSupportTrackBall`) to tell the API whether to perform rotation controlled by mouse or not.
3. For each data point to be calculated, call the `RenderPoint()` function. It returns the corresponding screen(=window) coordinates of your 3D data point.

The best to do is to check `3DHelperDemoSimple `project. I reduced the code to the minimum (no checking code) to clarify the steps.
Open the `3DHelperDemoSimple `project, and select the `OnInitDialog` method.

Only the lines below are added to the code generated by the wizard:

C++
```// Initialize the 3D system
initialize();
```

The `initialize `function itself is implemented some lines below.
Steps performed:

1. Initialize the API.
2. Start the update timer, used to refresh the mouse (=rotation) information. In our case, the whole scene will be repainted each 25 milliseconds.
C++
```// Set up initial 3D system
void CMy3DHelperDemoSimpleDlg::initialize()
{
CWnd *pTarget = GetDlgItem(IDC_STATIC_PLACEHOLDER);
m_c3DHelper.Initialize(pTarget->GetDC(), NeHe::Vector(-2.0f, -2.0f, -2.0f),
NeHe::Vector(2.0f,2.0f,2.0f), TRUE);

// Timer used to refresh "trackball" information
SetTimer(1, 25, NULL);
}```

Triggered by the timer, every 25 ms the `OnTimer` function will be entered.
Inside, the trackball position will be updated (`UpdateTrackBall`, which again needs the current DC as parameter), and the scene will be redrawn (`redraw()`).

C++
```void CMy3DHelperDemoSimpleDlg::OnTimer(UINT nIDEvent)
{
// Timer is used to refresh trackball information
if(nIDEvent == 1) {
KillTimer(nIDEvent); // Prevent timer "overlapping"
m_c3DHelper.UpdateTrackBall
(GetDlgItem(IDC_STATIC_PLACEHOLDER)->GetDC());
redraw();
SetTimer(1, 25, NULL); // Start timer for next redrawing round
}
CDialog::OnTimer(nIDEvent);
}```

`Redraw `again is trivial. Just take your data point per point, call `RenderPoint()` for each of them and display the result using e.g. `SetPixel()` function.

The `3DHelperDemo `project implements a more complex example.

## Points of Interest

I decided not to implement the whole math stuff by myself (think that is not a unique task...). So I have taken some matrix/vector code from NeHe (a GREAT site related to OpenGL, got my 5!).

To get a better idea on how OpenGL is implemented, I took a closer look at the free mesa implementation. This is a must for everyone interested in 3D implementation!

## Notes

Any feedback would be appreciated!

See more tools and updates on SoftwareHive.

## History

• 2009/02/14 - Initial release

## Share

 Business Analyst UPC AT B2B customers Austria
No Biography provided

 First Prev Next
 Memory deallocation problem. mrsilver9-Apr-19 1:57 mrsilver 9-Apr-19 1:57
 Reading mateusz.matyaszek8-Jun-10 22:24 mateusz.matyaszek 8-Jun-10 22:24
 Re: Reading MikeTheDwarf9-Jun-10 1:14 MikeTheDwarf 9-Jun-10 1:14
 Hi, thanks for using this application! The code itself "emulates" a very small subset of OpenGL, but without using OpenGL libraries itself. The reason why I wrote this piece of software was to ease the usage of 3D without the requirement to understand all the 3D relevant stuff (working in 3D can be for sure frustrating sometimes). So the classes where written not to explain the 3D topic itself but to allow their easy usage - that's the reason why the code (especially the 3D related stuff) itself isn't annotated in an acceptable manner. References: Well, from my point of view the most valuable sources of information is: http://nehe.gamedev.net/[^] which provides tons of information related to the 3D technologies. Another underestimated source of information is: http://www.opengl.org/[^] and SGIs OpenGL page: http://www.sgi.com/products/software/opengl/[^] as well as http://www.opengl.org/wiki/Getting_started[^] The 3D topic and mechanics are covered in the "OpenGL programming guide" - the so called red book: http://www.opengl.org/documentation/red_book/[^] 3D requires a little bit of base knowledge, which can be obtained by visiting the links above. After mastering this first hurdle it became pure fun! Related to your problem: Maybe link below helps you a little bit: http://www.songho.ca/opengl/gl_projectionmatrix.html[^] and http://www.songho.ca/opengl/gl_transform.html[^] Good luck!
 Re: Reading mateusz.matyaszek22-Jun-10 21:34 mateusz.matyaszek 22-Jun-10 21:34
 Re: Reading MikeTheDwarf23-Jun-10 0:59 MikeTheDwarf 23-Jun-10 0:59
 use in VB.net GeneralBiSoN27-Feb-09 23:21 GeneralBiSoN 27-Feb-09 23:21
 Re: use in VB.net MikeTheDwarf1-Mar-09 21:12 MikeTheDwarf 1-Mar-09 21:12
 Re: use in VB.net [modified] GeneralBiSoN4-Mar-09 8:14 GeneralBiSoN 4-Mar-09 8:14
 Re: use in VB.net MikeTheDwarf4-Mar-09 8:34 MikeTheDwarf 4-Mar-09 8:34
 Re: use in VB.net GeneralBiSoN5-Mar-09 5:16 GeneralBiSoN 5-Mar-09 5:16
 Re: use in VB.net MikeTheDwarf5-Mar-09 8:27 MikeTheDwarf 5-Mar-09 8:27
 Sounds nice john wallis17-Feb-09 11:20 john wallis 17-Feb-09 11:20
 Re: Sounds nice MikeTheDwarf17-Feb-09 23:47 MikeTheDwarf 17-Feb-09 23:47
 Re: Sounds nice john wallis18-Feb-09 12:22 john wallis 18-Feb-09 12:22
 Re: Sounds nice john wallis18-Feb-09 12:36 john wallis 18-Feb-09 12:36
 Re: Sounds nice MikeTheDwarf19-Feb-09 6:54 MikeTheDwarf 19-Feb-09 6:54
 Re: Sounds nice john wallis20-Feb-09 0:34 john wallis 20-Feb-09 0:34
 Re: Sounds nice MikeTheDwarf20-Feb-09 5:46 MikeTheDwarf 20-Feb-09 5:46
 Last Visit: 31-Dec-99 18:00     Last Update: 27-Sep-21 9:35 Refresh 1