Back to index

extremetuxracer  0.5beta
lights.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * Copyright (C) 1999-2001 Jasmin F. Patry
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 #include "lights.h"
00023 #include "gl_util.h"
00024 #include "tcl_util.h"
00025 
00026 static light_t course_lights[NUM_COURSE_LIGHTS];
00027 
00028 light_t* get_course_lights() { 
00029     return course_lights; 
00030 }
00031 
00032 
00033 void reset_lights()
00034 {
00035     int i;
00036     GLfloat black[] = { 0., 0., 0., 1. };
00037     for (i=0; i<NUM_COURSE_LIGHTS; i++) {
00038        /* Note: we initialize the lights to default OpenGL values
00039            EXCEPT that light 0 isn't treated differently than the
00040            others */
00041        course_lights[i].is_on = false;
00042        init_glfloat_array( 4, course_lights[i].ambient, 0., 0., 0., 1. );
00043        init_glfloat_array( 4, course_lights[i].diffuse, 0., 0., 0., 1. );
00044        init_glfloat_array( 4, course_lights[i].specular, 0., 0., 0., 1. );
00045        init_glfloat_array( 4, course_lights[i].position, 0., 0., 1., 0. );
00046        init_glfloat_array( 3, course_lights[i].spot_direction, 0., 0., -1. );
00047        course_lights[i].spot_exponent = 0.0;
00048        course_lights[i].spot_cutoff = 180.0;
00049        course_lights[i].constant_attenuation = 1.0;
00050        course_lights[i].linear_attenuation = 0.0;
00051        course_lights[i].quadratic_attenuation = 0.0;
00052     }
00053 
00054     /* Turn off global ambient light */
00055     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
00056 }
00057 
00058 void setup_course_lighting()
00059 {
00060     int i;
00061     light_t *course_lights;
00062 
00063     course_lights = get_course_lights();
00064 
00065     for (i=0; i<NUM_COURSE_LIGHTS; i++) {
00066        if ( ! course_lights[i].is_on ) {
00067            glDisable( GL_LIGHT0 + i );
00068            continue;
00069        }
00070        glEnable( GL_LIGHT0 + i );
00071 
00072        glLightfv( GL_LIGHT0 + i, GL_AMBIENT, course_lights[i].ambient );
00073        glLightfv( GL_LIGHT0 + i, GL_DIFFUSE, course_lights[i].diffuse );
00074        glLightfv( GL_LIGHT0 + i, GL_SPECULAR, course_lights[i].specular );
00075        glLightfv( GL_LIGHT0 + i, GL_POSITION, course_lights[i].position );
00076        glLightfv( GL_LIGHT0 + i, GL_SPOT_DIRECTION, 
00077                  course_lights[i].spot_direction );
00078        glLightf( GL_LIGHT0 + i, GL_SPOT_EXPONENT, 
00079                 course_lights[i].spot_exponent );
00080        glLightf( GL_LIGHT0 + i, GL_SPOT_CUTOFF, 
00081                 course_lights[i].spot_cutoff );
00082        glLightf( GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, 
00083                 course_lights[i].constant_attenuation );
00084        glLightf( GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, 
00085                 course_lights[i].linear_attenuation );
00086        glLightf( GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, 
00087                 course_lights[i].quadratic_attenuation );
00088     }
00089 }
00090 
00091 static int course_light_cb (ClientData cd, Tcl_Interp *ip, 
00092                          int argc, CONST84 char **argv) 
00093 {
00094     int light_num;
00095     double tmp_arr[4];
00096     double tmp_dbl;
00097     bool error = false;
00098     
00099     if (argc < 3) {
00100        error = true;
00101     }
00102 
00103     NEXT_ARG;
00104 
00105     if ( Tcl_GetInt( ip, *argv, &light_num ) == TCL_ERROR ) {
00106        error = true;
00107     }
00108 
00109     if ( light_num < 0 || light_num >= NUM_COURSE_LIGHTS ) {
00110        error = true;
00111     }
00112 
00113     NEXT_ARG;
00114 
00115     while ( !error && argc > 0 ) {
00116        if ( strcmp( "-on", *argv ) == 0 ) {
00117            course_lights[light_num].is_on = true;
00118        } else if ( strcmp( "-off", *argv ) == 0 ) {
00119            course_lights[light_num].is_on = false;
00120        } else if ( strcmp( "-ambient", *argv ) == 0 ) {
00121            NEXT_ARG;
00122            if ( argc == 0 ) {
00123               error = true;
00124               break;
00125            }
00126            if ( get_tcl_tuple ( ip, *argv, tmp_arr, 4 ) == TCL_ERROR ) {
00127               error = true;
00128               break;
00129            }
00130            copy_to_glfloat_array( course_lights[light_num].ambient, 
00131                                tmp_arr, 4 );
00132        } else if ( strcmp( "-diffuse", *argv ) == 0 ) {
00133            NEXT_ARG;
00134            if ( argc == 0 ) {
00135               error = true;
00136               break;
00137            }
00138            if ( get_tcl_tuple ( ip, *argv, tmp_arr, 4 ) == TCL_ERROR ) {
00139               error = true;
00140               break;
00141            }
00142            copy_to_glfloat_array( course_lights[light_num].diffuse, 
00143                                tmp_arr, 4 );
00144        } else if ( strcmp( "-specular", *argv ) == 0 ) {
00145            NEXT_ARG;
00146            if ( argc == 0 ) {
00147               error = true;
00148               break;
00149            }
00150            if ( get_tcl_tuple ( ip, *argv, tmp_arr, 4 ) == TCL_ERROR ) {
00151               error = true;
00152               break;
00153            }
00154            copy_to_glfloat_array( course_lights[light_num].specular, 
00155                                tmp_arr, 4 );
00156        } else if ( strcmp( "-position", *argv ) == 0 ) {
00157            NEXT_ARG;
00158            if ( argc == 0 ) {
00159               error = true;
00160               break;
00161            }
00162            if ( get_tcl_tuple ( ip, *argv, tmp_arr, 4 ) == TCL_ERROR ) {
00163               error = true;
00164               break;
00165            }
00166            copy_to_glfloat_array( course_lights[light_num].position, 
00167                                tmp_arr, 4 );
00168        } else if ( strcmp( "-spot_direction", *argv ) == 0 ) {
00169            NEXT_ARG;
00170            if ( argc == 0 ) {
00171               error = true;
00172               break;
00173            }
00174            if ( get_tcl_tuple ( ip, *argv, tmp_arr, 3 ) == TCL_ERROR ) {
00175               error = true;
00176               break;
00177            }
00178            copy_to_glfloat_array( course_lights[light_num].spot_direction, 
00179                                tmp_arr, 3 );
00180        } else if ( strcmp( "-spot_exponent", *argv ) == 0 ) {
00181            NEXT_ARG;
00182            if ( argc == 0 ) {
00183               error = true;
00184               break;
00185            }
00186            if ( Tcl_GetDouble ( ip, *argv, &tmp_dbl ) == TCL_ERROR ) {
00187               error = true;
00188               break;
00189            }
00190            course_lights[light_num].spot_exponent = tmp_dbl;
00191        } else if ( strcmp( "-spot_cutoff", *argv ) == 0 ) {
00192            NEXT_ARG;
00193            if ( argc == 0 ) {
00194               error = true;
00195               break;
00196            }
00197            if ( Tcl_GetDouble ( ip, *argv, &tmp_dbl ) == TCL_ERROR ) {
00198               error = true;
00199               break;
00200            }
00201            course_lights[light_num].spot_cutoff = tmp_dbl;
00202        } else if ( strcmp( "-constant_attenuation", *argv ) == 0 ) {
00203            NEXT_ARG;
00204            if ( argc == 0 ) {
00205               error = true;
00206               break;
00207            }
00208            if ( Tcl_GetDouble ( ip, *argv, &tmp_dbl ) == TCL_ERROR ) {
00209               error = true;
00210               break;
00211            }
00212            course_lights[light_num].constant_attenuation = tmp_dbl;
00213        } else if ( strcmp( "-linear_attenuation", *argv ) == 0 ) {
00214            NEXT_ARG;
00215            if ( argc == 0 ) {
00216               error = true;
00217               break;
00218            }
00219            if ( Tcl_GetDouble ( ip, *argv, &tmp_dbl ) == TCL_ERROR ) {
00220               error = true;
00221               break;
00222            }
00223            course_lights[light_num].linear_attenuation = tmp_dbl;
00224        } else if ( strcmp( "-quadratic_attenuation", *argv ) == 0 ) {
00225            NEXT_ARG;
00226            if ( argc == 0 ) {
00227               error = true;
00228               break;
00229            }
00230            if ( Tcl_GetDouble ( ip, *argv, &tmp_dbl ) == TCL_ERROR ) {
00231               error = true;
00232               break;
00233            }
00234            course_lights[light_num].quadratic_attenuation = tmp_dbl;
00235        } else {
00236            print_warning( TCL_WARNING, "tux_course_light: unrecognized "
00237                         "parameter `%s'", *argv );
00238        }
00239 
00240        NEXT_ARG;
00241     }
00242 
00243     if ( error ) {
00244        print_warning( TCL_WARNING, "error in call to tux_course_light" );
00245        Tcl_AppendResult(
00246            ip, 
00247            "\nUsage: tux_course_light <light_number> [-on|-off] "
00248            "[-ambient { r g b a }] "
00249            "[-diffuse { r g b a }] "
00250            "[-specular { r g b a }] "
00251            "[-position { x y z w }] "
00252            "[-spot_direction { x y z }] "
00253            "[-spot_exponent <value>] "
00254            "[-spot_cutoff <value>] "
00255            "[-constant_attenuation <value>] "
00256            "[-linear_attenuation <value>] "
00257            "[-quadratic_attenuation <value>] ",
00258            (char *) 0 );
00259        return TCL_ERROR;
00260     }
00261     
00262     return TCL_OK;
00263 }
00264 
00265 void register_course_light_callbacks( Tcl_Interp *ip )
00266 {
00267     Tcl_CreateCommand (ip, "tux_course_light", course_light_cb, 0,0);
00268 }