void HudGaugeRadarOrb::drawOutlines() { int i; vertex center; // vertex extents[6]; vertex proj_orb_lines_xy[NUM_ORB_RING_SLICES]; vertex proj_orb_lines_xz[NUM_ORB_RING_SLICES]; vertex proj_orb_lines_yz[NUM_ORB_RING_SLICES]; g3_start_instance_matrix(&vmd_zero_vector, &view_perturb, false); g3_start_instance_matrix(&vmd_zero_vector, &Player_obj->orient, false); g3_rotate_vertex(¢er, &vmd_zero_vector); g3_rotate_vertex(&proj_orb_lines_xy[0], &orb_ring_xy[0]); g3_rotate_vertex(&proj_orb_lines_yz[0], &orb_ring_yz[0]); g3_rotate_vertex(&proj_orb_lines_xz[0], &orb_ring_xz[0]); g3_project_vertex(¢er); gr_set_color(255,255,255); g3_draw_sphere(¢er, .05f); g3_project_vertex(&proj_orb_lines_xy[0]); g3_project_vertex(&proj_orb_lines_yz[0]); g3_project_vertex(&proj_orb_lines_xz[0]); for (i=1; i < NUM_ORB_RING_SLICES; i++) { g3_rotate_vertex(&proj_orb_lines_xy[i], &orb_ring_xy[i]); g3_rotate_vertex(&proj_orb_lines_yz[i], &orb_ring_yz[i]); g3_rotate_vertex(&proj_orb_lines_xz[i], &orb_ring_xz[i]); g3_project_vertex(&proj_orb_lines_xy[i]); g3_project_vertex(&proj_orb_lines_yz[i]); g3_project_vertex(&proj_orb_lines_xz[i]); gr_set_color(192,96,32); g3_draw_sphere(&proj_orb_lines_xy[i-1], .01f); g3_draw_sphere(&proj_orb_lines_xz[i-1], .01f); g3_draw_line(&proj_orb_lines_xy[i-1],&proj_orb_lines_xy[i]); g3_draw_line(&proj_orb_lines_xz[i-1],&proj_orb_lines_xz[i]); gr_set_color(112,16,192); g3_draw_sphere(&proj_orb_lines_yz[i-1], .01f); g3_draw_line(&proj_orb_lines_yz[i-1],&proj_orb_lines_yz[i]); } g3_done_instance(false); }
/** * Render jump node * * @param pos World position * @param view_pos Viewer's world position, can be NULL */ void CJumpNode::RenderDEPRECATED(vec3d *pos, vec3d *view_pos) { Assert(pos != NULL); // Assert(view_pos != NULL); - view_pos can be NULL if(m_flags & JN_HIDE) return; if(m_modelnum < 0) return; matrix node_orient = IDENTITY_MATRIX; int mr_flags = MR_NO_LIGHTING; if(!(m_flags & JN_SHOW_POLYS)) { mr_flags |= MR_NO_CULL | MR_NO_POLYS | MR_SHOW_OUTLINE_PRESET; } if ( Fred_running ) { gr_set_color_fast(&m_display_color); model_render_DEPRECATED(m_modelnum, &node_orient, pos, mr_flags ); } else { if (m_flags & JN_USE_DISPLAY_COLOR) { gr_set_color_fast(&m_display_color); } else if ( view_pos != NULL) { int alpha_index = HUD_color_alpha; // generate alpha index based on distance to jump this float dist; dist = vm_vec_dist_quick(view_pos, pos); // linearly interpolate alpha. At 1000m or less, full intensity. At 10000m or more 1/2 intensity. if ( dist < 1000 ) { alpha_index = HUD_COLOR_ALPHA_USER_MAX - 2; } else if ( dist > 10000 ) { alpha_index = HUD_COLOR_ALPHA_USER_MIN; } else { alpha_index = fl2i( HUD_COLOR_ALPHA_USER_MAX - 2 + (dist-1000) * (HUD_COLOR_ALPHA_USER_MIN-HUD_COLOR_ALPHA_USER_MAX-2) / (9000) + 0.5f); if ( alpha_index < HUD_COLOR_ALPHA_USER_MIN ) { alpha_index = HUD_COLOR_ALPHA_USER_MIN; } } gr_set_color_fast(&HUD_color_defaults[alpha_index]); } else { gr_set_color(HUD_color_red, HUD_color_green, HUD_color_blue); } model_render_DEPRECATED(m_modelnum, &node_orient, pos, mr_flags ); } }
void grid_render_elevation_line(vector *pos, grid* gridp) { vector gpos; // Location of point on grid. vector tpos; float dxz; plane tplane; vector *gv; tplane.A = gridp->gmatrix.v.uvec.xyz.x; tplane.B = gridp->gmatrix.v.uvec.xyz.y; tplane.C = gridp->gmatrix.v.uvec.xyz.z; tplane.D = gridp->planeD; compute_point_on_plane(&gpos, &tplane, pos); dxz = vm_vec_dist(pos, &gpos)/8.0f; gv = &gridp->gmatrix.v.uvec; if (gv->xyz.x * pos->xyz.x + gv->xyz.y * pos->xyz.y + gv->xyz.z * pos->xyz.z < -gridp->planeD) gr_set_color(127, 127, 127); else gr_set_color(255, 255, 255); // white rpd_line(&gpos, pos); // Line from grid to object center. tpos = gpos; vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.rvec, -dxz/2); vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.fvec, -dxz/2); vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.rvec, dxz/2); vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.fvec, dxz/2); rpd_line(&gpos, &tpos); vm_vec_scale_add2(&gpos, &gridp->gmatrix.v.rvec, dxz); vm_vec_scale_add2(&tpos, &gridp->gmatrix.v.rvec, -dxz); rpd_line(&gpos, &tpos); }
void training_menu_do_frame(float frametime) { int training_menu_choice; if (!training_menu_inited) { training_menu_init(); training_menu_inited = 1; } gr_reset_clip(); gr_set_color(0, 0, 0); GR_MAYBE_CLEAR_RES(trainingMenuBitmap); // set the background if (trainingMenuBitmap != -1) { gr_set_bitmap(trainingMenuBitmap); gr_bitmap(0, 0); } int snazzy_action = -1; training_menu_choice = snazzy_menu_do(mask_data, Training_mask_w, Training_mask_h, num_training, region, &snazzy_action); if (snazzy_action != SNAZZY_CLICKED) { training_menu_choice = -1; } switch (training_menu_choice) { case TRAINING_MENU_TRAINING_MISSIONS_MASK: break; case TRAINING_MENU_REPLAY_MISSIONS_MASK: // TODO: load the mission and start the briefing break; case TRAINING_MENU_RETURN_MASK: case ESC_PRESSED: gameseq_post_event(GS_EVENT_MAIN_MENU); break; case -1: // nothing selected break; default: Error(LOCATION, "Unknown option %d in training menu screen", training_menu_choice); break; } // end switch gr_flip(); }
// draw overlay on the screen void help_overlay_blit(int overlay_id) { int idx, width, height; int plinecount = help_overlaylist[overlay_id].plinecount; int textcount = help_overlaylist[overlay_id].textcount; int rbracketcount = help_overlaylist[overlay_id].rbracketcount; int lbracketcount = help_overlaylist[overlay_id].lbracketcount; Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS); // this draws each line of help text with white on black text (use the GR_640 index for the string) for (idx = 0; idx < textcount; idx++) { gr_set_color_fast(&Color_black); gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist[GR_640][idx].string, strlen(help_overlaylist[overlay_id].textlist[GR_640][idx].string)); gr_rect(help_overlaylist[overlay_id].textlist[gr_screen.res][idx].x_coord - 2 * HELP_PADDING, help_overlaylist[overlay_id].textlist[gr_screen.res][idx].y_coord - 3 * HELP_PADDING, width + 4 * HELP_PADDING, height + 4 * HELP_PADDING); gr_set_color_fast(&Color_bright_white); gr_printf(help_overlaylist[overlay_id].textlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].textlist[gr_screen.res][idx].y_coord, help_overlaylist[overlay_id].textlist[GR_640][idx].string); } // this draws each right bracket for (idx = 0; idx < rbracketcount; idx++) { gr_set_bitmap(help_right_bracket_bitmap); gr_bitmap(help_overlaylist[overlay_id].rbracketlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].rbracketlist[gr_screen.res][idx].y_coord); } // this draws each left bracket for (idx = 0; idx < lbracketcount; idx++) { gr_set_bitmap(help_left_bracket_bitmap); gr_bitmap(help_overlaylist[overlay_id].lbracketlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].lbracketlist[gr_screen.res][idx].y_coord); } // this draws each 2d line for the help screen //gr_set_color_fast(&Color_yellow); gr_set_color(255, 255, 0); for (idx = 0; idx < plinecount; idx++) { gr_pline_special(help_overlaylist[overlay_id].plinelist[gr_screen.res][idx].pvtx, help_overlaylist[overlay_id].plinelist[GR_640][idx].vtxcount, HELP_PLINE_THICKNESS); } }
// draw overlay on the screen void help_overlay_blit(int overlay_id, int resolution_index) { int idx, width, height; int plinecount = help_overlaylist[overlay_id].plinecount; int textcount = help_overlaylist[overlay_id].textcount; int rbracketcount = help_overlaylist[overlay_id].rbracketcount; int lbracketcount = help_overlaylist[overlay_id].lbracketcount; Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS); // this draws each line of help text with white on black text (use the first resolution index for the string) gr_set_font(help_overlaylist[overlay_id].fontlist.at(resolution_index)); for (idx = 0; idx < textcount; idx++) { gr_set_color_fast(&Color_black); gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist.at(0).at(idx).string, strlen(help_overlaylist[overlay_id].textlist.at(0).at(idx).string)); gr_rect(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord-2*HELP_PADDING, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord-3*HELP_PADDING, width+4*HELP_PADDING, height+4*HELP_PADDING, GR_RESIZE_MENU); gr_set_color_fast(&Color_bright_white); gr_printf_menu(help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).x_coord, help_overlaylist[overlay_id].textlist.at(resolution_index).at(idx).y_coord, help_overlaylist[overlay_id].textlist.at(0).at(idx).string); } gr_set_font(FONT1); // this draws each right bracket for (idx = 0; idx < rbracketcount; idx++) { gr_set_bitmap(help_right_bracket_bitmap); gr_bitmap(help_overlaylist[overlay_id].rbracketlist.at(resolution_index).at(idx).x_coord, help_overlaylist[overlay_id].rbracketlist.at(resolution_index).at(idx).y_coord, GR_RESIZE_MENU); } // this draws each left bracket for (idx = 0; idx < lbracketcount; idx++) { gr_set_bitmap(help_left_bracket_bitmap); gr_bitmap(help_overlaylist[overlay_id].lbracketlist.at(resolution_index).at(idx).x_coord, help_overlaylist[overlay_id].lbracketlist.at(resolution_index).at(idx).y_coord, GR_RESIZE_MENU); } // this draws each 2d line for the help screen //gr_set_color_fast(&Color_yellow); gr_set_color(255, 255, 0); for (idx = 0; idx<plinecount; idx++) { gr_pline_special(&help_overlaylist[overlay_id].plinelist.at(resolution_index).at(idx).vtx, HELP_PLINE_THICKNESS, GR_RESIZE_MENU); } }
void HudGaugeRadarOrb::drawOutlinesHtl() { int i, last = NUM_ORB_RING_SLICES - 1; g3_start_instance_matrix(&vmd_zero_vector, &view_perturb, true); g3_start_instance_matrix(&vmd_zero_vector, &Player_obj->orient, true); gr_set_color(255, 255, 255); g3_render_sphere(&vmd_zero_vector, .05f); gr_set_line_width(2.0f); for (i = 0; i < NUM_ORB_RING_SLICES; i++) { gr_init_alphacolor(&Orb_color_orange, 192, 96, 32, calcAlpha(&orb_ring_xy[last])); gr_set_color_fast(&Orb_color_orange); //g3_draw_htl_line(&orb_ring_xy[last],&orb_ring_xy[i]); g3_render_line_3d(false, &orb_ring_xy[last],&orb_ring_xy[i]); gr_init_alphacolor(&Orb_color_teal, 48, 160, 96, calcAlpha(&orb_ring_xz[last])); gr_set_color_fast(&Orb_color_teal); //g3_draw_htl_line(&orb_ring_xz[last],&orb_ring_xz[i]); g3_render_line_3d(false, &orb_ring_xz[last],&orb_ring_xz[i]); gr_init_alphacolor(&Orb_color_purple, 112, 16, 192, calcAlpha(&orb_ring_yz[last])); gr_set_color_fast(&Orb_color_purple); //g3_draw_htl_line(&orb_ring_yz[last],&orb_ring_yz[i]); g3_render_line_3d(false, &orb_ring_yz[last],&orb_ring_yz[i]); last = i; } gr_set_line_width(1.0f); g3_done_instance(true); g3_done_instance(true); }
// Play one movie bool movie_play(char *name) { // mark the movie as viewable to the player when in a campaign // do this before anything else so that we're sure the movie is available // to the player even if it's not going to play right now if (Game_mode & GM_CAMPAIGN_MODE) { cutscene_mark_viewable(name); } extern int Mouse_hidden; extern int Is_standalone; if (Cmdline_nomovies || Is_standalone) return false; char full_name[MAX_PATH]; int rc = 0; memset(full_name, 0, sizeof(full_name)); rc = movie_find(name, full_name); if (rc == MOVIE_NONE) { strcpy_s(full_name, name); char *p = strrchr(full_name, '.'); if ( p ) *p = 0; mprintf(("Movie Error: Unable to open '%s' movie in any supported format.\n", full_name)); return false; } // clear the screen and hide the mouse cursor Mouse_hidden++; gr_reset_clip(); gr_set_color(255, 255, 255); gr_set_clear_color(0, 0, 0); gr_zbuffer_clear(0); // clear first buffer gr_clear(); gr_flip(); // clear second buffer (may not be one, but that's ok) gr_clear(); gr_flip(); // clear third buffer (may not be one, but that's ok) gr_clear(); if (rc == MOVIE_OGG) { THEORAFILE *movie_ogg = theora_open(name); if (movie_ogg) { // start playing ... theora_play(movie_ogg); // ... done playing, close the movie theora_close(movie_ogg); } else { // uh-oh, movie is invalid... Abory, Retry, Fail? mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name)); Mouse_hidden--; // show the mouse cursor! return false; } } else if (rc == MOVIE_MVE) { MVESTREAM *movie_mve = mve_open(name); if (movie_mve) { // start playing ... mve_init(movie_mve); mve_play(movie_mve); // ... done playing, close the movie mve_shutdown(); mve_close(movie_mve); } else { // uh-oh, movie is invalid... Abory, Retry, Fail? mprintf(("MOVIE ERROR: Found invalid movie! (%s)\n", name)); Mouse_hidden--; // show the mouse cursor! return false; } } // show the mouse cursor again Mouse_hidden--; return true; }
void shadows_debug_show_frustum(matrix* orient, vec3d *pos, float fov, float aspect, float z_near, float z_far) { // find the widths and heights of the near plane and far plane to determine the points of this frustum float near_height = (float)tan((double)fov * 0.5) * z_near; float near_width = near_height * aspect; float far_height = (float)tan((double)fov * 0.5) * z_far; float far_width = far_height * aspect; vec3d up_scale = ZERO_VECTOR; vec3d right_scale = ZERO_VECTOR; vec3d forward_scale_near = orient->vec.fvec; vec3d forward_scale_far = orient->vec.fvec; vm_vec_scale(&forward_scale_near, z_near); vm_vec_scale(&forward_scale_far, z_far); // find the eight points using eye orientation and position vec3d near_top_left = ZERO_VECTOR; vec3d near_top_right = ZERO_VECTOR; vec3d near_bottom_left = ZERO_VECTOR; vec3d near_bottom_right = ZERO_VECTOR; // near top left up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, -near_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, -near_width); vm_vec_add(&near_top_left, &up_scale, &right_scale); vm_vec_add2(&near_top_left, &forward_scale_near); // near top right up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, -near_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, near_width); vm_vec_add(&near_top_right, &up_scale, &right_scale); vm_vec_add2(&near_top_right, &forward_scale_near); // near bottom left up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, near_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, -near_width); vm_vec_add(&near_bottom_left, &up_scale, &right_scale); vm_vec_add2(&near_bottom_left, &forward_scale_near); // near bottom right up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, near_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, near_width); vm_vec_add(&near_bottom_right, &up_scale, &right_scale); vm_vec_add2(&near_bottom_right, &forward_scale_near); vec3d far_top_left = ZERO_VECTOR; vec3d far_top_right = ZERO_VECTOR; vec3d far_bottom_left = ZERO_VECTOR; vec3d far_bottom_right = ZERO_VECTOR; // far top left up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, -far_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, -far_width); vm_vec_add(&far_top_left, &up_scale, &right_scale); vm_vec_add2(&far_top_left, &forward_scale_far); // far top right up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, -far_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, far_width); vm_vec_add(&far_top_right, &up_scale, &right_scale); vm_vec_add2(&far_top_right, &forward_scale_far); // far bottom left up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, far_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, -far_width); vm_vec_add(&far_bottom_left, &up_scale, &right_scale); vm_vec_add2(&far_bottom_left, &forward_scale_far); // far bottom right up_scale = orient->vec.uvec; vm_vec_scale(&up_scale, far_height); right_scale = orient->vec.rvec; vm_vec_scale(&right_scale, far_width); vm_vec_add(&far_bottom_right, &up_scale, &right_scale); vm_vec_add2(&far_bottom_right, &forward_scale_far); // translate frustum vm_vec_add2(&near_bottom_left, pos); vm_vec_add2(&near_bottom_right, pos); vm_vec_add2(&near_top_right, pos); vm_vec_add2(&near_top_left, pos); vm_vec_add2(&far_top_left, pos); vm_vec_add2(&far_top_right, pos); vm_vec_add2(&far_bottom_right, pos); vm_vec_add2(&far_bottom_left, pos); gr_set_color(0, 255, 255); g3_draw_htl_line(&near_bottom_left, &near_bottom_right); g3_draw_htl_line(&near_bottom_right, &near_top_right); g3_draw_htl_line(&near_bottom_right, &near_top_left); g3_draw_htl_line(&near_top_right, &near_top_left); g3_draw_htl_line(&far_top_left, &far_top_right); g3_draw_htl_line(&far_top_right, &far_bottom_right); g3_draw_htl_line(&far_bottom_right, &far_bottom_left); g3_draw_htl_line(&far_bottom_left, &far_top_left); }
void ship_draw_shield( object *objp) { int model_num; int i; vec3d pnt; polymodel * pm; if (objp->flags & OF_NO_SHIELDS) return; Assert(objp->instance >= 0); model_num = Ship_info[Ships[objp->instance].ship_info_index].model_num; if ( Fred_running ) return; pm = model_get(model_num); if (pm->shield.ntris<1) return; // Scan all the triangles in the mesh. for (i=0; i<pm->shield.ntris; i++ ) { int j; vec3d gnorm, v2f, tri_point; vertex prev_pnt, pnt0; shield_tri *tri; tri = &pm->shield.tris[i]; if (i == Break_value) Int3(); // Hack! Only works for object in identity orientation. // Need to rotate eye position into object's reference frame. // Only draw facing triangles. vm_vec_rotate(&tri_point, &pm->shield.verts[tri->verts[0]].pos, &Eye_matrix); vm_vec_add2(&tri_point, &objp->pos); vm_vec_sub(&v2f, &tri_point, &Eye_position); vm_vec_unrotate(&gnorm, &tri->norm, &objp->orient); if (vm_vec_dot(&gnorm, &v2f) < 0.0f) { int intensity; intensity = (int) (Ships[objp->instance].shield_integrity[i] * 255); if (intensity < 0) intensity = 0; else if (intensity > 255) intensity = 255; gr_set_color(0, 0, intensity); // Process the vertices. // Note this rotates each vertex each time it's needed, very dumb. for (j=0; j<3; j++ ) { vertex tmp; // Rotate point into world coordinates vm_vec_unrotate(&pnt, &pm->shield.verts[tri->verts[j]].pos, &objp->orient); vm_vec_add2(&pnt, &objp->pos); // Pnt is now the x,y,z world coordinates of this vert. // For this example, I am just drawing a sphere at that // point. g3_rotate_vertex(&tmp, &pnt); if (j) g3_draw_line(&prev_pnt, &tmp); else pnt0 = tmp; prev_pnt = tmp; } g3_draw_line(&pnt0, &prev_pnt); } } }
void particle_render_all() { ubyte flags; float pct_complete; float alpha; vertex pos; vec3d ts, te, temp; int rotate = 1; int framenum, cur_frame; bool render_batch = false; int tmap_flags = TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT | TMAP_FLAG_SOFT_QUAD; if ( !Particles_enabled ) return; MONITOR_INC( NumParticlesRend, Num_particles ); if ( Particles.empty() ) return; for (SCP_vector<particle*>::iterator p = Particles.begin(); p != Particles.end(); ++p) { particle* part = *p; // skip back-facing particles (ripped from fullneb code) // Wanderer - add support for attached particles vec3d p_pos; if (part->attached_objnum >= 0) { vm_vec_unrotate(&p_pos, &part->pos, &Objects[part->attached_objnum].orient); vm_vec_add2(&p_pos, &Objects[part->attached_objnum].pos); } else { p_pos = part->pos; } if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p_pos) <= 0.0f ) { continue; } // calculate the alpha to draw at alpha = get_current_alpha(&p_pos); // if it's transparent then just skip it if (alpha <= 0.0f) { continue; } // make sure "rotate" is enabled for this particle rotate = 1; // if this is a tracer style particle, calculate tracer vectors if (part->tracer_length > 0.0f) { ts = p_pos; temp = part->velocity; vm_vec_normalize_quick(&temp); vm_vec_scale_add(&te, &ts, &temp, part->tracer_length); // don't bother rotating rotate = 0; } // rotate the vertex if (rotate) { flags = g3_rotate_vertex( &pos, &p_pos ); if ( flags ) { continue; } if (!Cmdline_nohtl) g3_transfer_vertex(&pos, &p_pos); } // pct complete for the particle pct_complete = part->age / part->max_life; // figure out which frame we should be using if (part->nframes > 1) { framenum = fl2i(pct_complete * part->nframes + 0.5); CLAMP(framenum, 0, part->nframes-1); cur_frame = part->reverse ? (part->nframes - framenum - 1) : framenum; } else { cur_frame = 0; } if (part->type == PARTICLE_DEBUG) { gr_set_color( 255, 0, 0 ); g3_draw_sphere_ez( &p_pos, part->radius ); } else { framenum = part->optional_data; Assert( cur_frame < part->nframes ); // if this is a tracer style particle if (part->tracer_length > 0.0f) { batch_add_laser( framenum + cur_frame, &ts, part->radius, &te, part->radius ); } // draw as a regular bitmap else { batch_add_bitmap( framenum + cur_frame, tmap_flags, &pos, part->particle_index % 8, part->radius, alpha ); } render_batch = true; } } profile_begin("Batch Render"); if (render_batch) { batch_render_all(Particle_buffer_object); } profile_end("Batch Render"); }