void view_draw_model_transparent(int tick) { int n; obj_type *obj; proj_type *proj; // setup draw gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // render the models // draw backwards to sort back to front for (n=(view.render->draw_list.count-1);n>=0;n--) { switch (view.render->draw_list.items[n].type) { case view_render_type_object: obj=&server.objs[view.render->draw_list.items[n].idx]; if ((view.render->draw_list.items[n].flag&view_list_item_flag_model_in_view)!=0x0) render_model_transparent(&obj->draw); break; case view_render_type_projectile: proj=&server.projs[view.render->draw_list.items[n].idx]; render_model_transparent(&proj->draw); break; } } }
void render_map_liquid_transparent(int tick) { int n; map_liquid_type *liq; // setup view gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // setup drawing glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_NOTEQUAL,0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_FALSE); // draw transparent liquids for (n=0;n!=view.render->draw_list.count;n++) { if (view.render->draw_list.items[n].type==view_render_type_liquid) { liq=&map.liquid.liquids[view.render->draw_list.items[n].idx]; if (liquid_is_transparent(liq)) { liquid_render_liquid(tick,liq); } } } }
void view_draw_model_opaque(int tick) { int n; obj_type *obj; proj_type *proj; // setup draw gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // render the models for (n=0;n!=view.render->draw_list.count;n++) { switch (view.render->draw_list.items[n].type) { case view_render_type_object: obj=&server.objs[view.render->draw_list.items[n].idx]; render_model_setup(tick,&obj->draw); if ((view.render->draw_list.items[n].flag&view_list_item_flag_model_in_view)!=0x0) render_model_opaque(&obj->draw); break; case view_render_type_projectile: proj=&server.projs[view.render->draw_list.items[n].idx]; render_model_setup(tick,&proj->draw); render_model_opaque(&proj->draw); break; } } }
void view_draw_models_final(void) { int n; bool shadow_on; d3col col; obj_type *obj; proj_type *proj; // setup draw gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // shadow overrides shadow_on=(setup.shadow_on) && (!view.render->no_shadow); // render the shadows, remote names, // and any debugging information for (n=0;n!=view.render->draw_list.count;n++) { switch (view.render->draw_list.items[n].type) { case view_render_type_object: obj=&server.objs[view.render->draw_list.items[n].idx]; if ((shadow_on) && (obj->draw.shadow.on)) { if ((view.render->draw_list.items[n].flag&view_list_item_flag_shadow_in_view)!=0x0) shadow_render_model(&obj->draw); } if ((view.render->draw_list.items[n].flag&view_list_item_flag_model_in_view)!=0x0) { if (obj->remote.on) remote_draw_status(obj); if (object_is_targetted(obj,&col)) render_model_target(&obj->draw,&col); if (dim3_debug) { view_draw_debug_bounding_box(obj); view_draw_object_path(obj); } } break; case view_render_type_projectile: proj=&server.projs[view.render->draw_list.items[n].idx]; if ((shadow_on) && (proj->draw.shadow.on)) { if ((view.render->draw_list.items[n].flag&view_list_item_flag_shadow_in_view)!=0x0) shadow_render_model(&proj->draw); } break; } } }
void gl_project_fix_rotation(int *x,int *y,int *z) { double dx,dy,dz,dx2,dy2,dz2; // remember current settings glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); // translate from non-rotated 3D space // to rotated 3D space dx=(double)(*x); dy=(double)(*y); dz=(double)(*z); gl_3D_view(); gl_setup_project(); gluProject(dx,dy,dz,mod_matrix,proj_matrix,(GLint*)vport,&dx2,&dy2,&dz2); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); gluUnProject(dx2,dy2,dz2,mod_matrix,proj_matrix,(GLint*)vport,&dx,&dy,&dz); *x=((int)dx); *y=((int)dy); *z=((int)dz); // restore settings glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); gl_setup_project(); }
void view_draw_mesh_shadows(void) { int n; // shadows on? if ((!setup.shadow_on) || (view.render->no_shadow)) return; // setup draw gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // render the shadows for (n=0;n!=view.render->draw_list.count;n++) { if (view.render->draw_list.items[n].type!=view_render_type_mesh) continue; if (map.mesh.meshes[view.render->draw_list.items[n].idx].flag.shadow) shadow_render_mesh(view.render->draw_list.items[n].idx); } }
void view_draw_scene_build(int tick) { // setup projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // compile all lights in map gl_lights_compile(tick); // setup draw lists view_create_area_mask(); view_start_draw_list(); // add mesh and liquids to draw list view_add_mesh_draw_list(); view_add_liquid_draw_list(); // setup objects and projectiles // and add to draw list view_setup_objects(tick); view_setup_projectiles(tick); // add scene effects view_add_effect_draw_list(tick); // add scene halos halo_draw_clear(); view_add_halos(); }
void remote_draw_names_setup(void) { int n,x,y,z,dist; bool hit,has_tag; d3pnt spt,ept,hpt; obj_type *obj; model_type *mdl; ray_trace_contact_type contact; if (!net_setup.client.joined) return; if (!setup.network.show_names) return; // clear all name draws obj=server.objs; for (n=0;n!=server.count.obj;n++) { obj->draw.remote_name.on=FALSE; obj++; } // remove names behind z or off-screen // ignore console as it won't matter for projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); for (n=0;n!=view.render->draw_list.count;n++) { if (view.render->draw_list.items[n].type!=view_render_type_object) continue; obj=&server.objs[view.render->draw_list.items[n].idx]; if (!obj->player) continue; if (obj->hidden) continue; // get name point has_tag=FALSE; mdl=NULL; if ((obj->draw.uid!=-1) && (obj->draw.on)) mdl=model_find_uid(obj->draw.uid); if (mdl!=NULL) { x=obj->pnt.x; y=obj->pnt.y; z=obj->pnt.z; has_tag=model_get_name_position(mdl,&obj->draw.setup,&x,&y,&z); } if (!has_tag) { x=obj->pnt.x; y=(obj->pnt.y-obj->size.y)-map_enlarge; z=obj->pnt.z; } // translate and rotate point dist=distance_get(x,y,z,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); if (dist>=remote_name_max_distance) continue; obj->draw.remote_name.pnt.x=x; obj->draw.remote_name.pnt.y=y; obj->draw.remote_name.pnt.z=z; // is it behind the z? if (!gl_project_in_view_z(x,y,z)) continue; // project names gl_project_point(&x,&y,&z); obj->draw.remote_name.proj_pnt.x=x; obj->draw.remote_name.proj_pnt.y=y; obj->draw.remote_name.proj_pnt.z=z; // calculate the fade if (dist<remote_name_min_distance) { obj->draw.remote_name.fade=1.0f; } else { obj->draw.remote_name.fade=1.0f-((float)(dist-remote_name_min_distance)/(float)(remote_name_max_distance-remote_name_min_distance)); } obj->draw.remote_name.size=hud.font.text_size_medium-(int)((float)(hud.font.text_size_medium*dist)/(float)(remote_name_max_distance-remote_name_min_distance)); if (obj->draw.remote_name.size<10) obj->draw.remote_name.size=10; obj->draw.remote_name.on=TRUE; } // ray trace remote name to camera's eye level // to check for visibility ept.x=view.render->camera.pnt.x; ept.y=view.render->camera.pnt.y; ept.z=view.render->camera.pnt.z; contact.obj.on=TRUE; contact.proj.on=FALSE; contact.hit_mode=poly_ray_trace_hit_mode_all; contact.origin=poly_ray_trace_origin_object; for (n=0;n!=server.count.obj;n++) { obj=&server.objs[n]; if (!obj->draw.remote_name.on) continue; spt.x=obj->draw.remote_name.pnt.x; spt.y=obj->draw.remote_name.pnt.y; spt.z=obj->draw.remote_name.pnt.z; contact.obj.ignore_uid=obj->uid; hit=ray_trace_map_by_point(&spt,&ept,&hpt,&contact); if (camera.mode==cv_fpp) { if (hit) { if (contact.obj.uid!=server.player_obj_uid) { obj->draw.remote_name.on=FALSE; continue; } } else { obj->draw.remote_name.on=FALSE; continue; } } else { if (hit) { obj->draw.remote_name.on=FALSE; continue; } } } }
void view_draw_debug_info(d3pnt *pnt,d3pnt *size,int count,char *strs) { int n,x,y,dist; d3col col; d3pnt spt,ept,win_pnt; ray_trace_contact_type contact; // only show closer objects dist=distance_get(pnt->x,pnt->y,pnt->z,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); if (dist>25000) return; // ray trace check spt.x=pnt->x; spt.y=pnt->y-size->y; spt.z=pnt->z; ept.x=view.render->camera.pnt.x; ept.y=view.render->camera.pnt.y; ept.z=view.render->camera.pnt.z; contact.obj.on=FALSE; contact.proj.on=FALSE; contact.origin=poly_ray_trace_origin_object; if (ray_trace_map_by_point(&spt,&ept,&contact)) return; // project the mid point win_pnt.x=pnt->x; win_pnt.y=pnt->y-size->y; win_pnt.z=pnt->z; gl_project_point(&win_pnt); // draw the info gl_2D_view_interface(); glDisable(GL_DEPTH_TEST); // covert to interface resolution x=(win_pnt.x*iface.scale_x)/view.screen.x_sz; y=((view.screen.y_sz-win_pnt.y)*iface.scale_y)/view.screen.y_sz; y-=(iface.font.text_size_small*count); // draw text col.r=col.b=1.0f; col.g=0.0f; gl_text_start(font_hud_index,iface.font.text_size_small,FALSE); for (n=0;n!=count;n++) { y+=iface.font.text_size_small; gl_text_draw(x,y,(char*)&strs[n*128],tx_center,FALSE,&col,1.0f); } gl_text_end(); glEnable(GL_DEPTH_TEST); // restore original projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); }
void draw_sky_cube(int tick) { int k,txt_id,offset; float txt_fact,txt_x_shift,txt_y_shift; texture_type *texture; // texture sizes txt_fact=map.sky.txt_fact; txt_x_shift=((float)tick*0.0005f)*map.sky.txt_x_shift; k=(int)txt_x_shift; txt_x_shift=txt_x_shift-(float)k; txt_y_shift=((float)tick*0.0005f)*map.sky.txt_y_shift; k=(int)txt_y_shift; txt_y_shift=txt_y_shift-(float)k; // setup view gl_3D_view(); gl_3D_rotate(NULL,&view.render->camera.ang); gl_setup_project(); // setup texture gl_texture_simple_start(); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_TEXTURE); glTranslatef(txt_x_shift,txt_y_shift,0.0f); glScalef(txt_fact,txt_fact,1.0f); // bind VBO view_bind_sky_vertex_object(); // draw cube sides glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,0,(void*)0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,(void*)(((6*4)*3)*sizeof(float))); offset=0; if (map.sky.fill!=-1) { texture=&map.textures[map.sky.fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,0,4); offset+=4; } // bottom if (map.sky.bottom_fill!=-1) { texture=&map.textures[map.sky.bottom_fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,offset,4); offset+=4; } // north if (map.sky.north_fill!=-1) { texture=&map.textures[map.sky.north_fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,offset,4); offset+=4; } // east if (map.sky.east_fill!=-1) { texture=&map.textures[map.sky.east_fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,offset,4); offset+=4; } // south if (map.sky.south_fill!=-1) { texture=&map.textures[map.sky.south_fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,offset,4); offset+=4; } // west if (map.sky.west_fill!=-1) { texture=&map.textures[map.sky.west_fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glDrawArrays(GL_QUADS,offset,4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); // end texture glLoadIdentity(); gl_texture_simple_end(); // unbind the vbo view_unbind_sky_vertex_object(); }
void draw_sky_dome_hemisphere(int tick) { int k,txt_id,dome_cnt,trig_cnt; float txt_x_shift,txt_y_shift; texture_type *texture; // texture sizes txt_x_shift=((float)tick*0.0005f)*map.sky.txt_x_shift; k=(int)txt_x_shift; txt_x_shift=txt_x_shift-(float)k; txt_y_shift=((float)tick*0.0005f)*map.sky.txt_y_shift; k=(int)txt_y_shift; txt_y_shift=txt_y_shift-(float)k; // setup view gl_3D_view(); gl_3D_rotate(NULL,&view.render->camera.ang); gl_setup_project(); // setup texture gl_texture_simple_start(); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_TEXTURE); glTranslatef(txt_x_shift,txt_y_shift,0.0f); texture=&map.textures[map.sky.fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); // bind the vbo view_bind_sky_vertex_object(); // quad and trig counts dome_cnt=(20*4)*4; trig_cnt=20*3; // draw the dome glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,0,(void*)0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,(void*)(((200*4)*3)*sizeof(float))); glDrawArrays(GL_QUADS,0,dome_cnt); glDrawArrays(GL_TRIANGLES,dome_cnt,trig_cnt); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); // end textures glMatrixMode(GL_TEXTURE); glLoadIdentity(); gl_texture_simple_end(); // unbind the vbo view_unbind_sky_vertex_object(); }
void draw_sky_dome_panoramic(int tick) { int k,txt_id; float txt_x_shift,txt_y_shift; texture_type *texture; // texture sizes txt_x_shift=((float)tick*0.0005f)*map.sky.txt_x_shift; k=(int)txt_x_shift; txt_x_shift=txt_x_shift-(float)k; txt_y_shift=((float)tick*0.0005f)*map.sky.txt_y_shift; k=(int)txt_y_shift; txt_y_shift=txt_y_shift-(float)k; // setup view gl_3D_view(); gl_3D_rotate(NULL,&view.render->camera.ang); gl_setup_project(); // construct VBO view_bind_sky_vertex_object(); // both outside and cap need vertex list glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,0,(void*)0); // draw textured dome gl_texture_simple_start(); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_TEXTURE); glTranslatef(txt_x_shift,txt_y_shift,0.0f); texture=&map.textures[map.sky.fill]; txt_id=texture->frames[texture->animate.current_frame].bitmap.gl_id; gl_texture_simple_set(txt_id,FALSE,1,1,1,1); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,(void*)(((120*4)*3)*sizeof(float))); glDrawArrays(GL_QUADS,0,(100*4)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glMatrixMode(GL_TEXTURE); glLoadIdentity(); gl_texture_simple_end(); // draw colored cap glColor4f(texture->col.r,texture->col.g,texture->col.b,1.0f); glDrawArrays(GL_TRIANGLES,(100*4),(20*3)); // disable vertex array glDisableClientState(GL_VERTEX_ARRAY); // unbind the vbo view_unbind_sky_vertex_object(); }
void view_draw_scene_render(int tick,obj_type *obj,weapon_type *weap) { // setup projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); // draw background and sky // unless obscured by fog if (!fog_solid_on()) { draw_background(); draw_sky(tick); } else { fog_solid_start(); } // setup per-scene shader variables gl_shader_draw_scene_initialize(); // compile meshes for drawing if (!view_compile_mesh_gl_lists(tick)) return; // setup some map polygon drawing flags render_map_setup(); // draw opaque scene items render_map_mesh_opaque(); render_map_liquid_opaque(tick); view_draw_model_opaque(tick); // additional mesh and model drawing // shadows, remote names, etc view_draw_mesh_shadows(); view_draw_models_final(); // draw transparent scene items render_map_mesh_transparent(); view_draw_model_transparent(tick); render_map_liquid_transparent(tick); // draw decals decal_render(); // effects effect_draw(tick); // draw rain rain_draw(tick); // draw fog fog_draw_textured(tick); if (fog_solid_on()) fog_solid_end(); // setup halos, crosshairs, zoom masks remote_draw_names_setup(); halo_draw_setup(); if ((obj!=NULL) && (weap!=NULL)) { crosshair_setup(tick,obj,weap); zoom_setup(tick,obj,weap); // draw the weapons in hand if (camera.mode==cv_fpp) draw_weapon_hand(tick,obj,weap); } // draw the remote names, halos, crosshairs, and zoom masks remote_draw_names_render(); halo_draw_render(); if ((obj!=NULL) && (weap!=NULL)) { crosshair_draw(obj,weap); zoom_draw(obj,weap); } }
void rain_draw(int tick) { int n,xadd,yadd,zadd,density, slant_add,slant_mult,slant_div; float slant_ang_y; float *vertex_ptr,*col_ptr; rain_draw_type *rain_draw; // is rain on and not under liquid? if (!map.rain.on) return; if (view.render->camera.under_liquid_idx!=-1) return; // reset on? if (map.rain.reset) { map.rain.reset=FALSE; rain_setup(tick,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); } // rain slant slant_add=rain_slant_add; slant_ang_y=rain_slant_ang_y; if (map.rain.slant_time_msec!=0) { // time to change slant? if (tick>rain_slant_next_end_tick) { rain_slant_add=slant_add=rain_slant_next_add; rain_slant_ang_y=slant_ang_y=rain_slant_next_ang_y; rain_setup_next_slant(tick); } else { // slant in the middle of changing if (tick>rain_slant_next_start_tick) { slant_mult=tick-rain_slant_next_start_tick; slant_div=(rain_slant_next_end_tick-rain_slant_next_start_tick); slant_add=rain_slant_add+(((rain_slant_next_add-rain_slant_add)*slant_mult)/slant_div); slant_ang_y=rain_slant_ang_y+((rain_slant_next_ang_y-rain_slant_ang_y)*((float)slant_mult/(float)slant_div)); } } } angle_get_movement(slant_ang_y,slant_add,&xadd,&zadd); // rain change xadd=(tick-rain_last_tick)*xadd; yadd=(tick-rain_last_tick)*map.rain.speed; zadd=(tick-rain_last_tick)*zadd; rain_last_tick=tick; // rain density density=map.rain.density; if (density>max_rain_density) density=max_rain_density; // construct VBO vertex_ptr=view_bind_map_next_vertex_object(((density*2)*(3+4))); if (vertex_ptr==NULL) return; col_ptr=vertex_ptr+((density*2)*3); // create vertexes rain_draw=view.rain_draws; for (n=0;n!=density;n++) { // move rain rain_draw->x+=xadd; rain_draw->y+=yadd; rain_draw->z+=zadd; if (rain_draw->y>rain_draw->by) rain_setup_single_reset(rain_draw,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); // draw rain *vertex_ptr++=(float)rain_draw->x; *vertex_ptr++=(float)rain_draw->y; *vertex_ptr++=(float)rain_draw->z; *col_ptr++=map.rain.start_color.r; *col_ptr++=map.rain.start_color.g; *col_ptr++=map.rain.start_color.b; *col_ptr++=map.rain.alpha; *vertex_ptr++=(float)(rain_draw->x+xadd); *vertex_ptr++=(float)(rain_draw->y+map.rain.line_length); *vertex_ptr++=(float)(rain_draw->z+zadd); *col_ptr++=map.rain.end_color.r; *col_ptr++=map.rain.end_color.g; *col_ptr++=map.rain.end_color.b; *col_ptr++=map.rain.alpha; rain_draw++; } view_unmap_current_vertex_object(); // setup view gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_FALSE); // draw the rain glLineWidth((float)map.rain.line_width); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,0,(void*)0); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT,0,(void*)(((density*2)*3)*sizeof(float))); glDrawArrays(GL_LINES,0,(density*2)); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glLineWidth(1); // unbind the vbo view_unbind_current_vertex_object(); }