void draw_ui_snow( void ) { GLuint texture_id; char *binding; pp::Vec2d *pt, *tex_min, *tex_max; double size; double xres, yres; int i; xres = getparam_x_resolution(); yres = getparam_y_resolution(); UIMgr.setupDisplay(); binding = "ui_snow_particle"; if (!get_texture_binding( "ui_snow_particle", &texture_id ) ) { print_warning( IMPORTANT_WARNING, "Couldn't get texture for binding %s", binding ); texture_id = 0; } glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glBindTexture( GL_TEXTURE_2D, texture_id ); glColor4f( particleColor[0], particleColor[1], particleColor[2], particleColor[3] ); glPushMatrix(); { for ( i=0; i<num_particles; i++) { pt = &particles[i].pt; size = particles[i].size; tex_min = &particles[i].tex_min; tex_max = &particles[i].tex_max; glPushMatrix(); { glTranslatef( pt->x*xres, pt->y*yres, 0 ); glBegin( GL_QUADS ); { glTexCoord2f( tex_min->x, tex_min->y ); glVertex2f( 0, 0 ); glTexCoord2f( tex_max->x, tex_min->y ); glVertex2f( size, 0 ); glTexCoord2f( tex_max->x, tex_max->y ); glVertex2f( size, size ); glTexCoord2f( tex_min->x, tex_max->y ); glVertex2f( 0, size ); } glEnd(); } glPopMatrix(); } } glPopMatrix(); }
/*! callback for mouse button events \return None \author jfpatry \date Created: 2000-09-16 \date Modified: 2000-09-16 */ void ui_event_mouse_func( int button, int state, int x, int y ) { if ( is_mode_change_pending() ) { /* Don't process events until mode change occurs */ return; } /* Reverse y coordinate */ y = getparam_y_resolution() - y; if ( state == WS_MOUSE_DOWN ) { trigger_mouse_button_cbs( mouse_down_cbs, button, x, y ); } else { trigger_mouse_button_cbs( mouse_up_cbs, button, x, y ); } if ( button == WS_LEFT_BUTTON ) { left_mouse_button_down = (bool_t) ( state == WS_MOUSE_DOWN ); } if ( button == WS_MIDDLE_BUTTON ) { middle_mouse_button_down = (bool_t) ( state == WS_MOUSE_DOWN ); } if ( button == WS_RIGHT_BUTTON ) { right_mouse_button_down = (bool_t) ( state == WS_MOUSE_DOWN ); } ui_check_dirty(); }
static void preference_loop( scalar_t time_step ) { check_gl_error(); update_audio(); set_gl_options( GUI ); clear_rendering_context(); ui_setup_display(); if (getparam_ui_snow()) { update_ui_snow( time_step, False ); draw_ui_snow(); } ui_draw_menu_decorations(); draw_preference(); ui_draw(); reshape( getparam_x_resolution(), getparam_y_resolution() ); winsys_swap_buffers(); }
/*! Draws the text for the loading screen \author jfpatry */ void draw_loading_text( void ) { int w = getparam_x_resolution(); int h = getparam_y_resolution(); int x_org, y_org; const char *string; int string_w, asc, desc; font_t *font; x_org = w/2.0; y_org = h/2.0; if ( !get_font_binding( "loading", &font ) ) { print_warning( IMPORTANT_WARNING, "Couldn't get font for binding loading" ); } else { string = Localize("Loading, Please Wait...",""); get_font_metrics( font, string, &string_w, &asc, &desc ); glPushMatrix(); { glTranslatef( w/2.0 - string_w/2.0, h/2.0 - desc-30, 0 ); bind_font_texture( font ); draw_string( font, string ); } glPopMatrix(); } }
static void credits_loop( scalar_t time_step ) { int width, height; width = getparam_x_resolution(); height = getparam_y_resolution(); check_gl_error(); update_audio(); clear_rendering_context(); set_gl_options( GUI ); ui_setup_display(); draw_credits_text( time_step ); if (getparam_ui_snow()) { update_ui_snow( time_step, False ); draw_ui_snow(); } ui_draw_menu_decorations(); ui_draw(); reshape( width, height ); winsys_swap_buffers(); }
/*! Mode loop function \author jfpatry \date Created: 2000-09-24 \date Modified: 2000-09-24 */ static void race_select_loop( scalar_t time_step ) { check_gl_error(); update_audio(); set_gl_options( GUI ); clear_rendering_context(); ui_setup_display(); if (getparam_ui_snow()) { update_ui_snow( time_step, (bool_t) ( wind_ssbtn != NULL && ssbutton_get_state( wind_ssbtn ) ) ); draw_ui_snow(); } ui_draw_menu_decorations(); set_widget_positions_and_draw_decorations(); ui_draw(); reshape( getparam_x_resolution(), getparam_y_resolution() ); winsys_swap_buffers(); }
void GameOver::loop(float timeStep) { int width, height; width = getparam_x_resolution(); height = getparam_y_resolution(); /* Check joystick */ if ( is_joystick_active() ) { update_joystick(); if ( is_joystick_continue_button_down() ) { if ( gameMgr->gametype != GameMgr::PRACTICING ) { set_game_mode( EVENT_RACE_SELECT ); }else{ set_game_mode( RACE_SELECT ); } winsys_post_redisplay(); return; } } fpsCounter.update(); update_audio(); clear_rendering_context(); fogPlane.setup(); update_player_pos( players[0], 0 ); update_view( players[0], 0 ); setup_view_frustum( players[0], NEAR_CLIP_DIST, getparam_forward_clip_distance() ); draw_sky(players[0].view.pos); draw_fog_plane(); set_course_clipping( true ); set_course_eye_point( players[0].view.pos ); setup_course_lighting(); render_course(); draw_trees(); if ( getparam_draw_particles() ) { draw_particles( players[0] ); } ModelHndl->draw_tux(); draw_tux_shadow(); set_gl_options( GUI ); UIMgr.setupDisplay(); UIMgr.draw(); HUD1.draw(players[0]); reshape( width, height ); winsys_swap_buffers(); }
static void set_widget_positions() { button_t **button_list[] = { &enter_event_btn, &practice_btn, //&rankings_btn, &preference_btn, &credits_btn, &help_btn, &quit_btn }; int w = getparam_x_resolution(); int h = getparam_y_resolution(); int box_height; int box_max_y; int top_y; int bottom_y; int num_buttons = sizeof( button_list ) / sizeof( button_list[0] ); int i; int tot_button_height = 0; int button_sep =0; int cur_y_pos; box_height = 200 * mHeight / 320; box_max_y = h - 150 * mHeight / 320; bottom_y = 0.4*h - box_height/2 + 30 * mHeight / 320; if ( bottom_y + box_height > box_max_y ) { bottom_y = box_max_y - box_height + 30 * mHeight / 320; } top_y = bottom_y + box_height; for (i=0; i<num_buttons; i++) { tot_button_height += button_get_height( *button_list[i] ); } if ( num_buttons > 1 ) { button_sep = ( top_y - bottom_y - tot_button_height ) / ( num_buttons - 1 ); button_sep = max( 0, button_sep ); } cur_y_pos = top_y; for (i=0; i<num_buttons; i+=2) { cur_y_pos -= button_get_height( *button_list[i] ); button_set_position( *button_list[i], make_point2d( w/4.0 - button_get_width( *button_list[i] )/2.0, cur_y_pos ) ); button_set_position( *button_list[i+1], make_point2d( w/4.0*3.0 - button_get_width( *button_list[i+1] )/2.0, cur_y_pos ) ); cur_y_pos -= button_sep; } }
/* This is the main loop of the game. It dispatches into the loop functions of the various game modes. */ void main_loop() { if ( getparam_capture_mouse() ) { int w = getparam_x_resolution(); int h = getparam_y_resolution(); point2d_t pos; pos = ui_get_mouse_position(); /* Flip y coordinates */ pos.y = h - pos.y; if ( pos.x < 0 ) { pos.x = 0; } if ( pos.x > w-1 ) { pos.x = w-1; } if ( pos.y < 0 ) { pos.y = 0; } if ( pos.y > h-1 ) { pos.y = h-1; } winsys_warp_pointer( pos.x, pos.y ); } if ( g_game.mode != new_mode ) { if ( g_game.mode >= 0 && mode_funcs[ g_game.mode ].term_func != NULL ) { ( mode_funcs[ g_game.mode ].term_func )( ); } g_game.prev_mode = g_game.mode; g_game.mode = new_mode; if ( mode_funcs[ g_game.mode ].init_func != NULL ) { ( mode_funcs[ g_game.mode ].init_func )( ); /* Reset time step clock so that there isn't a sudden jump when we start the new mode */ reset_time_step_clock(); } } g_game.time_step = calc_time_step(); g_game.secs_since_start += g_game.time_step; if ( mode_funcs[ g_game.mode ].loop_func != NULL ) { ( mode_funcs[ g_game.mode ].loop_func )( g_game.time_step ); } }
void init_ui_snow( void ) { int i; num_particles=orig_num_particles=PARTICLE_DENSITY*getparam_x_resolution()*getparam_y_resolution(); for( i=0; i<num_particles; i++) { make_particle( i, frand(), frand() ); } push_position = make_point2d( 0.0, 0.0 ); }
void reset_ui_snow_cursor_pos( point2d_t pos ) { scalar_t xres, yres; xres = getparam_x_resolution(); yres = getparam_y_resolution(); push_position = make_point2d( pos.x/(scalar_t)xres, pos.y/(scalar_t)yres ); last_push_position = push_position; push_position_initialized = True; }
void make_ui_snow( point2d_t pos ) { scalar_t xres, yres; xres = getparam_x_resolution(); yres = getparam_y_resolution(); if ( num_particles < MAX_NUM_PARTICLES ) { make_particle( num_particles, pos.x/xres, pos.y/yres ); num_particles++; } }
void reset_ui_snow_cursor_pos( pp::Vec2d pos ) { double xres, yres; xres = getparam_x_resolution(); yres = getparam_y_resolution(); push_position = pp::Vec2d( pos.x/(double)xres, pos.y/(double)yres ); last_push_position = push_position; push_position_initialized = true; }
void make_ui_snow( pp::Vec2d pos ) { double xres, yres; xres = getparam_x_resolution(); yres = getparam_y_resolution(); if ( num_particles < MAX_NUM_PARTICLES ) { make_particle( num_particles, pos.x/xres, pos.y/yres ); num_particles++; } }
void UIManager::setupDisplay() { glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0, getparam_x_resolution(), 0, getparam_y_resolution(), -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0, 0.0, -1.0 ); glColor4f( 1.0, 1.0, 1.0, 1.0 ); }
void push_ui_snow( pp::Vec2d pos ) { double xres, yres; xres = getparam_x_resolution(); yres = getparam_y_resolution(); push_position = pp::Vec2d( pos.x/(double)xres, pos.y/(double)yres ); if ( !push_position_initialized ) { last_push_position = push_position; } push_position_initialized = true; }
/*! Sets up OpenGL rendering context for draw UI widgets \return None \author jfpatry \date Created: 2000-09-16 \date Modified: 2000-09-16 */ void ui_setup_display() { scalar_t offset = OFFSET_AMT; glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrthof( 0, getparam_x_resolution(), 0, getparam_y_resolution(), -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( offset, offset, -1.0 ); glColor4f( 1.0, 1.0, 1.0, 1.0 ); }
void draw_sponsor_loading() { GLuint texobj; int w = getparam_x_resolution(); int h = getparam_y_resolution(); glEnable( GL_TEXTURE_2D ); /* loading */ if ( get_texture_binding( sponsor_selected, &texobj ) ) { glBindTexture( GL_TEXTURE_2D, texobj ); draw_quad(0,0, w, h ); } }
void push_ui_snow( point2d_t pos ) { scalar_t xres, yres; return; xres = getparam_x_resolution(); yres = getparam_y_resolution(); push_position = make_point2d( pos.x/(scalar_t)xres, pos.y/(scalar_t)yres ); if ( !push_position_initialized ) { last_push_position = push_position; } push_position_initialized = True; }
void loading_init(void) { winsys_set_display_func( main_loop ); winsys_set_idle_func( main_loop ); winsys_set_reshape_func( reshape ); winsys_set_mouse_func( ui_event_mouse_func ); winsys_set_motion_func( ui_event_motion_func ); winsys_set_passive_motion_func( NULL ); passInLoop = 0; draw_loading_text(); choose_sponsor(); reshape( getparam_x_resolution(), getparam_y_resolution() ); stop_music(); }
/*! Scrolls the credits text up the screen. \author jfpatry \date Created: 2000-09-27 \date Modified: 2000-09-27 */ static void draw_credits_text( scalar_t time_step ) { int w = getparam_x_resolution(); int h = getparam_y_resolution(); font_t* font; coord_t text_coord; int i, string_w, asc, desc; scalar_t y; y_offset += time_step * winsys_scale(CREDITS_SPEED + time_step*joystick_y*CREDITS_JOYSTICK_SPEED); if (y_offset<0) { y_offset=0; } y = CREDITS_MIN_Y+y_offset; text_coord.x=w/2; text_coord.y=y; text_coord.x_coord_type=ABSOLUTE_COORD; text_coord.y_coord_type=ABSOLUTE_COORD; text_coord.x_just=text_coord.y_just=CENTER_JUST; for (i=0; i<sizeof( credit_lines ) / sizeof( credit_lines[0] ); i++) { credit_line_t line = credit_lines[i]; if ( !get_font_binding( line.binding, &font ) ) { print_warning( IMPORTANT_WARNING, "Couldn't get font for binding %s", line.binding ); } else { get_font_metrics( font, line.text, &string_w, &asc, &desc ); text_coord.y -= asc+desc; GameMenu_draw_text( line.text, 0, text_coord, line.binding ); } } if ( text_coord.y > h+CREDITS_MAX_Y ) { go_back(); } }
void reset_ui_snow( void ) { scalar_t xres, yres; int i; xres = getparam_x_resolution(); yres = getparam_y_resolution(); /* Kill off & regenerate particles */ for (i=0; i<num_particles; i++) { particle_t *p = &particles[i]; /* Delete the particle */ *p = particles[num_particles-1]; num_particles -= 1; } num_particles = orig_num_particles; init_ui_snow(); }
/*! Mode loop function \author jfpatry \date Created: 2000-09-24 \date Modified: 2000-09-24 */ static void race_select_loop( scalar_t time_step ) { use_hud_program(); check_gl_error(); update_audio(); set_gl_options( GUI ); clear_rendering_context(); ui_setup_display(); if (getparam_ui_snow()) { update_ui_snow( time_step, False ); draw_ui_snow(); } ui_draw_menu_decorations(False); if (price_update) { update_text(); price_update = False; } GameMenu_draw(); draw_preview(); winsys_update_joysticks(); ui_draw(); reshape( getparam_x_resolution(), getparam_y_resolution() ); winsys_swap_buffers(); }
Paused::Paused() { int centerX = getparam_x_resolution() / 2; int centerY = getparam_y_resolution() / 2; mp_backgroundFrm = new pp::Frame(pp::Vec2d(centerX-120,centerY-100), pp::Vec2d(240,200)); mp_pausedLbl = new pp::Label(pp::Vec2d(centerX,centerY+90),"paused",_("Paused")); mp_pausedLbl->alignment.center(); mp_pausedLbl->alignment.top(); mp_configBtn = new pp::Button(pp::Vec2d(centerX-150,centerY-15), pp::Vec2d(300, 40), "button_label", _("Configuration") ); mp_configBtn->setHilitFontBinding("button_label_hilit"); mp_configBtn->signalClicked.Connect(pp::CreateSlot(this,&Paused::configuration)); mp_resumeBtn = new pp::Button(pp::Vec2d(centerX-150,centerY-55), pp::Vec2d(300, 40), "button_label", _("Resume") ); mp_resumeBtn->setHilitFontBinding("button_label_hilit"); mp_resumeBtn->signalClicked.Connect(pp::CreateSlot(this,&Paused::resume)); mp_quitBtn = new pp::Button(pp::Vec2d(centerX-150,centerY-95), pp::Vec2d(300, 40), "button_label", _("Quit") ); mp_quitBtn->setHilitFontBinding("button_label_hilit"); mp_quitBtn->signalClicked.Connect(pp::CreateSlot(this,&Paused::quit)); play_music( "paused" ); }
void init_arrays_for_particle(particle_t particle, GLfloat* vertices, GLfloat* tex_coords) { point2d_t pt = particle.pt; scalar_t size = particle.size; point2d_t* tex_min = &particle.tex_min; point2d_t* tex_max = &particle.tex_max; scalar_t xres, yres; #define TO_RELATIVE(screen, val) (((val)/screen*2.0)-1.0) xres=getparam_x_resolution(); yres=getparam_y_resolution(); vertices[0]=TO_RELATIVE(xres, pt.x*xres); vertices[1]=TO_RELATIVE(yres, pt.y*yres); vertices[2]=TO_RELATIVE(xres, pt.x*xres); vertices[3]=TO_RELATIVE(yres, pt.y*yres+size); vertices[4]=TO_RELATIVE(xres, pt.x*xres+size); vertices[5]=TO_RELATIVE(yres, pt.y*yres+size); vertices[6]=TO_RELATIVE(xres, pt.x*xres+size); vertices[7]=TO_RELATIVE(yres, pt.y*yres); #undef TO_RELATIVE tex_coords[0]=tex_min->x; tex_coords[1]=tex_min->y; tex_coords[2]=tex_min->x; tex_coords[3]=tex_max->y; tex_coords[4]=tex_max->x; tex_coords[5]=tex_max->y; tex_coords[6]=tex_max->x; tex_coords[7]=tex_min->y; }
void UIManager::motionEvent( int x, int y ) { if ( is_mode_change_pending() ) { // Don't process events until mode change occurs return; } // Reverse y coordinate y = getparam_y_resolution() - y; std::list<pp::Widget*>::iterator it; for(it=widgets.begin();it!=widgets.end();it++){ (*it)->mouseMotion(x,y); } pp::Vec2d oldPos = cursorPos; cursorPos = pp::Vec2d(x,y); if ( oldPos.x != x || oldPos.y != y ) { // Update UI snow if ( getparam_ui_snow() ) { if ( rightMouseButtonDown ) { make_ui_snow( cursorPos ); reset_ui_snow_cursor_pos( cursorPos ); } else if ( middleMouseButtonDown ) { make_ui_snow( cursorPos ); push_ui_snow( cursorPos ); } else { push_ui_snow( cursorPos ); } } // Need to redraw cursor setDirty(); checkDirty(); } }
/*! callback for mouse motion events \return None \author jfpatry \date Created: 2000-09-16 \date Modified: 2000-09-16 */ void ui_event_motion_func( int x, int y ) { point2d_t old_pos; if ( is_mode_change_pending() ) { /* Don't process events until mode change occurs */ return; } /* Reverse y coordinate */ y = getparam_y_resolution() - y; trigger_mouse_motion_cbs( mouse_motion_cbs, x, y ); old_pos = cursor_pos; cursor_pos = make_point2d( x, y ); if ( old_pos.x != x || old_pos.y != y ) { /* Update UI snow */ if ( getparam_ui_snow() ) { if ( right_mouse_button_down ) { make_ui_snow( cursor_pos ); reset_ui_snow_cursor_pos( cursor_pos ); } else if ( middle_mouse_button_down ) { make_ui_snow( cursor_pos ); push_ui_snow( cursor_pos ); } else { push_ui_snow( cursor_pos ); } } /* Need to redraw cursor */ ui_set_dirty(); ui_check_dirty(); } }
/*! Sets the widget positions and draws other on-screen goo \author jfpatry \date Created: 2000-09-24 \date Modified: 2000-09-24 */ static void draw_preview() { GLuint texobj; { rect_t screen_rect; open_course_data_t *data; int w=getparam_x_resolution(); int h=getparam_y_resolution(); float colors[]={1, 1, 1, 1}; shader_set_color(colors); data = (open_course_data_t*) get_list_elem_data( cur_elem ); if ( !get_texture_binding( data->course, &texobj ) ) { if ( !get_texture_binding( "no_preview", &texobj ) ) { texobj = 0; } } glBindTexture( GL_TEXTURE_2D, texobj ); draw_textured_quad(0.105*w, 0.45*h, 0.34*w, 0.34*h); } }
void UIManager::mouseEvent( int button, int state, int x, int y ) { if ( is_mode_change_pending() ) { // Don't process events until mode change occurs return; } // Reverse y coordinate y = getparam_y_resolution() - y; std::list<pp::Widget*>::iterator it; if ( state == SDL_PRESSED ) { for(it=widgets.begin();it!=widgets.end();it++){ (*it)->mouseDown(button,x,y); } } else { for(it=widgets.begin();it!=widgets.end();it++){ (*it)->mouseUp(button,x,y); } } if ( button == SDL_BUTTON_LEFT ) { leftMouseButtonDown = (bool) ( state == SDL_PRESSED ); } if ( button == SDL_BUTTON_MIDDLE ) { middleMouseButtonDown = (bool) ( state == SDL_PRESSED ); } if ( button == SDL_BUTTON_RIGHT ) { rightMouseButtonDown = (bool) ( state == SDL_PRESSED ); } checkDirty(); }
void draw_ui_snow( void ) { GLuint texture_id; char *binding; point2d_t *pt, *tex_min, *tex_max; scalar_t size; scalar_t xres, yres; int i; xres = getparam_x_resolution(); yres = getparam_y_resolution(); ui_setup_display(); binding = "snow_particle"; if (!get_texture_binding( "snow_particle", &texture_id ) ) { print_warning( IMPORTANT_WARNING, "Couldn't get texture for binding %s", binding ); texture_id = 0; } glBindTexture( GL_TEXTURE_2D, texture_id ); shader_set_color(particle_colour); { GLfloat* vertices=(GLfloat*)malloc(8*num_particles*sizeof(GLfloat)); GLfloat* tex_coords=(GLfloat*)malloc(8*num_particles*sizeof(GLfloat)); GLushort* indices=(GLushort*)malloc(6*num_particles*sizeof(GLushort)); for ( i=0; i<num_particles; i++) { init_arrays_for_particle(particles[i], vertices+i*8, tex_coords+i*8); int firstvert=i*4; int firstindex=i*6; indices[0+firstindex]=0+firstvert; indices[1+firstindex]=1+firstvert; indices[2+firstindex]=2+firstvert; indices[3+firstindex]=2+firstvert; indices[4+firstindex]=3+firstvert; indices[5+firstindex]=0+firstvert; } //print_debug(DEBUG_OTHER, "indices %d %d %d %d %d %d %d %d %d %d %d %d", indices[0], indices[1], indices[2], indices[3], indices[4], indices[5], indices[6], indices[7], indices[8], indices[9], indices[10], indices[11]); //print_debug(DEBUG_OTHER, "vertices %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], vertices[6], vertices[7], vertices[8], vertices[9], vertices[10], vertices[11], vertices[12], vertices[13], vertices[14], vertices[15]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glVertexAttribPointer(shader_get_attrib_location(SHADER_VERTEX_NAME), 2, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(shader_get_attrib_location(SHADER_VERTEX_NAME)); glVertexAttribPointer(shader_get_attrib_location(SHADER_TEXTURE_COORD_NAME), 2, GL_FLOAT, GL_FALSE, 0, tex_coords); glEnableVertexAttribArray(shader_get_attrib_location(SHADER_TEXTURE_COORD_NAME)); glDrawElements(GL_TRIANGLES, num_particles*6, GL_UNSIGNED_SHORT, indices); glVertexAttribPointer(shader_get_attrib_location(SHADER_VERTEX_NAME), 2, GL_FLOAT, GL_FALSE, 0, 0); glDisableVertexAttribArray(shader_get_attrib_location(SHADER_VERTEX_NAME)); glVertexAttribPointer(shader_get_attrib_location(SHADER_TEXTURE_COORD_NAME), 2, GL_FLOAT, GL_FALSE, 0, 0); glDisableVertexAttribArray(shader_get_attrib_location(SHADER_TEXTURE_COORD_NAME)); free(vertices); free(tex_coords); } }