Additional information about developing models

The following comments about the modeler project are answers to questions asked during the Spring 2000 edition of CSE 457, updated to reflect changes in the configuration for Autumn 2000.


Auto Loading Models (and animations)

Ordinarily you load your model dll using the menu command load object.  However, this can get old when you are debugging.  There are two ways to eliminate this task.

1.  The executable will automatically load "mymodel.dll" and "myanim.anm" if it finds them.  (The .anm file is only relevant for the animation project, not the modeler.)  If you want to use this option, make sure that your model is being written to the file mymodel.dll by C++.  Probably the best way to do this is to link it with a name like classarm.dll, then copy the resulting file from your project Debug directory to the executable directory ..\Debug and give it the name myModel.dll during the copy.  The copy command can be put in the C++ post build step so that it happens automatically every time you rebuild the model.

2.  It's possible to load a model and an animation automatically by specifying them on the command line by name. If you want to use this option, select the debug tab in the project settings dialog, then select category General. Set the executable for debug session to point to the copy of modeler.exe you are using. Set the working directory if you like, and then set the program arguments.

The arguments are "?modeler path>\modeler.dll ?model path>\xxx.dll ?animation path>\yyy.anm". The paths are relative to the working directory, or absolute. xxx.dll and yyy.anm are the model and animation that you want loaded. You can leave off arguments starting from the right and animator will attempt the autoload that is described above.


Access to user interface and the animation timer.

There are several functions that are related to the user interface and the current animation time.  In order to access these functions from any method you have to to declare them external so that they are visible to the code that wants to call them.  The way to do this is to include LibModeler\modelerGUI.h.  This file provides the following statements:

extern lpScaleFunc scale;
extern lpCurveFunc curve;
extern lpCheckboxFunc checkbox;
extern lpMenuFunc menu;
extern lpGetTimeFunc get_time;

extern double get_control_d(int ctrl_id);
extern float get_control_f(int ctrl_id);
extern int get_control_i(int ctrl_id);
extern bool get_control_b(int ctrl_id);


Animation timer control

How do you reset the timer? and how do you allow to animate or not using code? (i.e. is there any way to call a function to animate/start the timer and stop it/reset it?)

The timer function is running through a 20 second loop. Depending on the rate selected, it increments the value every .2, .1, .05, etc and then it wraps at 20 seconds. Your redraw function is called every time the timer is updated while animating.

Although you can't easily change the values it generates, you could use it to drive a timer value of your own. You could increment your own static timer by whatever the get_time increment was and turn it off, reset it, or whatever you want depending on your own code and checkboxes or sliders in the UI.


Animation enabled?

What's the procedure to see if a particular menu item is checked? I can't  find where the constants are defined, I want to see if an animation is selected to be running or not.

You can't check directly on whether or not the user has selected animation mode. Redraw just gets called on a regular basis when you are animating.

One option is to just run continuously in animation mode, and have a checkbox or menu item in your UI to enable various sub-modes. For example, a menu could have the following choices: "use sliders for control", "enable timed animation mode 1", "enable timed animation mode 2". Your code then checks the menu and does the appropriate things.


OpenGL initialization

When you start to get fancy with OpenGL you sometimes want to do something of a "setup" nature that only happens once no matter how many times you redraw the image. (Creating textures from bitmap files is one example of this sort of thing.)

This sort of initialization does not happen in "init". Init is for setting up the User Interface widgets only. The OpenGL window and context do not exist when init is called and so you cannot do the setup there.

An easy solution is to put your initialization code into redraw in an "if" block that is controlled by a static variable. For example:

===============
void redraw(int drawmode) {
...
static bool initialized = false; // set to true the first time redraw is called
...
 if (!initialized) {
  initialized = true;
  printf("Vendor version %s %s\n",glGetString(GL_VENDOR),glGetString(GL_VERSION));
...
 }
...
}
===============

This initialization is only for things that happen once when you load the model originally. Actions that should happen every time you redraw should not be part of the if block.


OpenGL errors

It's a good idea to be checking errors as you go along. For example:

 GLenum error_flag;

 error_flag = glGetError();
 if (error_flag != GL_NO_ERROR) {
  printf("Error:  %1s (%i) in %1s.\n",gluErrorString(error_flag),error_flag,"redraw");
  }


Debugging

Under the debug tab in project settings you can set the name of the executable to run. The project skeletons came with that set to "..\Debug\modeler.exe".  You can set a breakpoint in your model code, then say go (F5 or the go button). The modeler will be started, you answer okay to continue (it's okay because you are not debugging the modeler), then you load your model as usual. When you execute the breakpoint in your code, you will bounce back to the debugger.


Clipping

Is there any easy way to make a section of a sphere?

See glClipPlane in the OGL references. Specify a clip plane, enable it, draw the sphere, disable the clip plane.