Tutorial Four - Model Viewer

 Download the WocModelViewer EXE (127KB) in compressed ZIP format.

 Download the WocModelViewer project files (7KB) in compressed ZIP format.

For this and all the tutorials you will need to download the WOC header and implementation files. I recommend that you unzip them into a folder named woc and locate it at the same level as (i.e. a sibling of) the project folders which use it. This is because the projects look for the WOC files at the path: ..\woc\ as we'll see later.

 Download the Nessie OJB Model (367KB) in compressed ZIP format.
   
About the tutorial
The goal of this sample is to build a handy 3-D model viewing application. It so happens that all the required functionality is already in WOC, therefore all that remains for us to do is to incorporate WOC into another project and put a menu interface onto that existing functionality.

Up to date, all of the samples have derived their own frame window class from CWocFrameWnd. This one will be no exception but we will be creating a new menu and handling its commands in our frame window class.

WinZip® brings the convenience of Windows to the use of Zip files and other compression formats. If you don't have "the most celebrated shareware app in the history of computing" already, use the above link to download it.
   
The steps
1. You first need to set up a new project which should start life in the same state as the WocSkeleton project. Please perform the usual copying and renaming process except that this time we are replacing WocSkeleton with WocModelViewer.

2. You now have a renamed copy of the original skeleton project, so open it in Visual Studio and build and run it to check it's okay. Remember to consult the WOC Class Reference at any point if you need to.

We'll be adding two new menus to your resources next. They should both go between the existing File and Help menus. First, create a new menu called Model. Add menu commands to it by copying from the following table which shows the text to use (the ampersand indicates the accelerator key) and the name to give to the command's resource Id:
        IDM_OPEN_OBJ                   &Open OBJ file
        IDM_SHOW_NORMALS               &Show normals
        IDM_HIDE_NORMALS               &Hide normals
        IDM_FACE_NORMALS               &Face normals
        IDM_VERTEX_NORMALS             &Vertex normals
        IDM_CLEAR                      &Clear model
        IDM_AUTOROT_ON                 &AutoRotate on
        IDM_AUTOROT_OFF                A&utoRotate off
Next, create a new menu called Primitive Mode. Add the following menu commands to it:
        IDM_MODE_TRIANGLES             &Triangles
        IDM_MODE_LINES                 &Lines
        IDM_MODE_POINTS                &Points
That done, compile and run and check everything looks okay. Now to add handlers for the new menu commands. Find the frame window class in your project which is called CWocModelViewerFrameWnd and can be found in the file WocModelViewer.cpp. Locate the OnMenuOrAcceleratorCommand method and you will notice that its body has nothing in it but a switch statement containing a couple of case clauses and a default. Immediately before that switch statement, but inside the function, paste the following two lines so that they become the first lines of the function:
        static CWocOGLWnd* pOGLWnd = theApp.GetMainView();
        static CWocModel& s_Model = pOGLWnd->GetDefaultModel();
All we need to do now is add a few more case clauses to that switch statement, so paste the following code immediately before the IDM_EXIT case:
            case IDM_OPEN_OBJ :
                {
                    CWocModelLoaderObjFile loader(_T(""));;
                    loader.Load(&s_Model, -1, FALSE, _DEFAULT_NAME, TRUE);
                    s_Model.UnitizeAndCenter();
                    s_Model.GenerateFaceNormals();
                    s_Model.AdjustOGLState(pOGLWnd);
                    break;
                }
            case IDM_SHOW_NORMALS :
                s_Model.SetShowNormals(TRUE);
                break;
            case IDM_HIDE_NORMALS :
                s_Model.SetShowNormals(FALSE);
                break;
            case IDM_AUTOROT_ON :
                pOGLWnd->SetAutoRotate(TRUE);
                break;
            case IDM_AUTOROT_OFF :
                pOGLWnd->SetAutoRotate(FALSE);
                break;
            case IDM_FACE_NORMALS :
                s_Model.GenerateFaceNormals();
                break;
            case IDM_VERTEX_NORMALS :
                s_Model.GenerateVertexNormals();
                break;
            case IDM_MODE_TRIANGLES :
                s_Model.SetPrimitiveMode(GL_TRIANGLES);
                break;
            case IDM_MODE_LINES :
                s_Model.SetPrimitiveMode(GL_LINE_LOOP);
                break;
            case IDM_MODE_POINTS :
                s_Model.SetPrimitiveMode(GL_POINTS);
                break;
            case IDM_CLEAR :
                s_Model.Initialise();
                break;
Now compile and run. You'll see the default model rotating as usual. Start by dropping down the Model menu and choosing Hide normals. The normals should now be invisible as normals normally are. You can show them again whenever you like. There are menu commands to toggle auto-rotation; the same service offered by the OpenGL Window's properties dialog. This shows how two different UI objects offer a facade to the same object method. You can clear the model at any time. If you do so, then you might get bored looking at a blank screen so choose the Open OBJ file command. Here's the Common File dialog allowing you to navigate to and open a .OBJ file (try the Nessie OJB Model). It will open with face normals but you can smooth it by choosing Vertex normals. The Primitive Mode menu can be used to show a model as lines or points as well as the usual triangles.

This simple utility almost wrote itself, but that was because it happened to require only services that WOC has built-in. Other applications will certainly require more effort and more knowledge of WOC internals. However, given that WOC's model classes expose a general-purpose public interface, another application whose development might be significantly eased by WOC is a 3-D model creator and editor. The functionality to write .OBJ files is still under development, though, and would need to be present first.
 
last updated: 4-oct-01