/* * Copyright (C) Freespace Open 2013. All rights reserved. * * All source code herein is the property of Freespace Open. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #ifndef _MODELRENDER_H #define _MODELRENDER_H #include "graphics/material.h" #include "graphics/render_queue.h" #include "lighting/lighting.h" #include "math/vecmat.h" #include "model/model.h" #include "mission/missionparse.h" #include "graphics/util/UniformBuffer.h" #include "utils/boost/hash_combine.h" extern SCP_vector Lights; extern int Num_lights; extern matrix Object_matrix; extern vec3d Object_position; extern color Wireframe_color; extern int Lab_object_detail_level; extern bool Model_load_clear_CPU_buffers; typedef enum { TECH_SHIP, TECH_WEAPON, TECH_POF, TECH_JUMP_NODE, TECH_PROP, } tech_render_type; inline int in_box(const vec3d *min, const vec3d *max, const vec3d *pos, const vec3d *view_position) { vec3d point; vm_vec_sub(&point, view_position, pos); if ( (point.xyz.x >= min->xyz.x) && (point.xyz.x <= max->xyz.x) && (point.xyz.y >= min->xyz.y) && (point.xyz.y <= max->xyz.y) && (point.xyz.z >= min->xyz.z) && (point.xyz.z <= max->xyz.z) ) { return 1; } return -1; } inline int in_sphere(const vec3d *pos, float radius, const vec3d *view_position) { if ( vm_vec_dist(view_position, pos) <= radius ) return 1; else return -1; } extern int model_interp_get_texture(const texture_info *tinfo, int elapsed_time); class model_render_params { uint64_t Model_flags; uint Debug_flags; int Objnum; int Detail_level_locked; float Depth_scale; float Attached_model_draw_distance; int Warp_bitmap; float Warp_alpha; vec3d Warp_scale; color Color; float Xparent_alpha; int Forced_bitmap; int Insignia_bitmap; std::shared_ptr Replacement_textures; bool Team_color_set; team_color Current_team_color; bool Clip_plane_set; vec3d Clip_normal; vec3d Clip_pos; int Animated_effect; float Animated_timer; mst_info Thruster_info; float Outline_thickness = -1.0f; bool Use_alpha_mult; float Alpha_mult; model_render_params(const model_render_params&) = delete; model_render_params& operator=(const model_render_params&) = delete; public: model_render_params(); void set_flags(uint64_t flags); void set_debug_flags(uint flags); void set_object_number(int num); void set_detail_level_lock(int detail_level_lock); void set_depth_scale(float scale); void set_attached_model_draw_distance(float distance); void set_warp_params(int bitmap, float alpha, const vec3d &scale); void set_color(const color &clr); void set_color(int r, int g, int b); void set_alpha(float alpha); void set_forced_bitmap(int bitmap); void set_insignia_bitmap(int bitmap); void set_replacement_textures(std::shared_ptr textures); void set_replacement_textures(int modelnum, const SCP_vector& replacement_textures); void set_team_color(const team_color &clr); void set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime); void set_clip_plane(const vec3d &pos, const vec3d &normal); void set_animated_effect(int effect_num, float timer); void set_thruster_info(const mst_info &info); void set_outline_thickness(float thick); void set_alpha_mult(float alpha); bool is_clip_plane_set() const; bool is_team_color_set() const; bool is_alpha_mult_set() const; bool uses_thick_outlines() const; uint64_t get_model_flags() const; uint get_debug_flags() const; int get_object_number() const; int get_detail_level_lock() const; float get_depth_scale() const; float get_attached_model_draw_distance() const; int get_warp_bitmap() const; float get_warp_alpha() const; const vec3d& get_warp_scale() const; const color& get_color() const; float get_alpha() const; int get_forced_bitmap() const; int get_insignia_bitmap() const; std::shared_ptr get_replacement_textures() const; const team_color& get_team_color() const; const vec3d& get_clip_plane_pos() const; const vec3d& get_clip_plane_normal() const; int get_animated_effect_num() const; float get_animated_effect_timer() const; const mst_info& get_thruster_info() const; float get_outline_thickness() const; float get_alpha_mult() const; }; struct cached_ui_render_instance_key { int model_num; int state_instance_id; size_t instance_data_hash; bool operator==(const cached_ui_render_instance_key& other) const { return model_num == other.model_num && state_instance_id == other.state_instance_id && instance_data_hash == other.instance_data_hash; } }; struct cached_ui_render_instance_key_hash { size_t operator()(const cached_ui_render_instance_key& key) const { size_t seed = 0; boost::hash_combine(seed, key.model_num); boost::hash_combine(seed, key.state_instance_id); boost::hash_combine(seed, key.instance_data_hash); return seed; } }; struct cached_ui_render_instance_entry { int model_instance = -1; int last_used_framecount = -1; }; struct arc_effect { matrix4 transform; vec3d v1; vec3d v2; color primary; color secondary; float width; ubyte segment_depth; const SCP_vector *persistent_arc_points; }; struct insignia_draw_data { matrix4 transform; const polymodel *pm; int detail_level; int bitmap_num; // if there's a clip plane bool clip; vec3d clip_normal; vec3d clip_position; }; struct queued_buffer_draw { size_t transform_buffer_offset = 0; size_t uniform_buffer_offset = 0; model_material render_material; matrix4 transform; vec3d scale; const indexed_vertex_source *vert_src; const vertex_buffer *buffer; size_t texi; int flags; int sdr_flags; light_indexing_info lights; queued_buffer_draw() { } }; struct outline_draw { const vertex* vert_array; int n_verts; matrix4 transform; color clr; }; class model_draw_list : public render_queue { friend class render_queue; light_indexing_info Current_lights_set; void render_arc(const arc_effect &arc); static void render_insignia(const insignia_draw_data &insignia_info); void render_outline(const outline_draw &outline_info); SCP_vector Arcs; SCP_vector Insignias; SCP_vector Outlines; void build_uniform_buffer(); void render_buffer(const queued_buffer_draw &render_elements); bool sort_draw_pair(int a, int b) const; public: model_draw_list(); ~model_draw_list(); model_draw_list(const model_draw_list&) = delete; model_draw_list& operator=(const model_draw_list&) = delete; void init(); void add_buffer_draw(const model_material *render_material, const indexed_vertex_source *vert_src, const vertex_buffer *buffer, size_t texi, uint tmap_flags); vec3d get_view_position() const; void add_arc(const vec3d *v1, const vec3d *v2, const SCP_vector *persistent_arc_points, const color *primary, const color *secondary, float arc_width, ubyte segment_depth); void render_arcs(); void add_insignia(const model_render_params *params, const polymodel *pm, int detail_level, int bitmap_num); void render_insignias() const; void add_outline(const vertex* vert_array, int n_verts, const color *clr); void render_outlines(); void set_light_filter(const vec3d *pos, float rad); void render_all(gr_zbuffer_type depth_mode = ZBUFFER_TYPE_DEFAULT); }; void model_render_only_glowpoint_lights(const model_render_params* interp, int model_num, int model_instance_num, const matrix* orient, const vec3d* pos); float model_render_get_point_activation(const glow_point_bank* bank, const glow_point_bank_override* gpo); void model_render_glowpoint_add_light(int point_num, const vec3d* pos, const matrix* orient, const glow_point_bank* bank, const glow_point_bank_override* gpo, const polymodel* pm, const polymodel_instance* pmi, const ship* shipp); void model_render_immediate(const model_render_params* render_info, int model_num, const matrix* orient, const vec3d* pos, int render = MODEL_RENDER_ALL, bool sort = true); void model_render_immediate(const model_render_params* render_info, int model_num, int model_instance_num, const matrix* orient, const vec3d* pos, int render = MODEL_RENDER_ALL, bool sort = true); void model_render_queue(const model_render_params* render_info, model_draw_list* scene, int model_num, const matrix* orient, const vec3d* pos); void model_render_queue(const model_render_params* render_info, model_draw_list* scene, int model_num, int model_instance_num, const matrix* orient, const vec3d* pos); void submodel_render_immediate(const model_render_params* render_info, const polymodel* pm, const polymodel_instance* pmi, int submodel_num, const matrix* orient, const vec3d* pos); void submodel_render_queue(const model_render_params* render_info, model_draw_list* scene, const polymodel* pm, const polymodel_instance* pmi, int submodel_num, const matrix* orient, const vec3d* pos); void model_render_buffers(model_draw_list* scene, model_material* rendering_material, const model_render_params* interp, const vertex_buffer* buffer, const polymodel* pm, int mn, int detail_level, uint tmap_flags); bool model_render_check_detail_box(const vec3d* view_pos, const polymodel* pm, int submodel_num, uint64_t flags); void model_render_arc(const vec3d* v1, const vec3d* v2, const SCP_vector *persistent_arc_points, const color* primary, const color* secondary, float arc_width, ubyte depth_limit); void model_render_insignias(const insignia_draw_data* insignia); void model_render_set_wireframe_color(const color* clr); float model_render_determine_depth(int obj_num, int model_num, const matrix* orient, const vec3d* pos, int detail_level_locked, const vec3d* eye_pos = nullptr); int model_render_determine_detail(float depth, int model_num, int detail_level_locked); bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int y2, float zoom, bool lighting, int class_idx, const matrix* orient, const SCP_string& pof_filename = "", float closeup_zoom = 0, const vec3d* closeup_pos = &vmd_zero_vector, const SCP_string& tcolor = "", const SCP_vector& destroyed_subsystems = SCP_vector()); size_t model_hash_subsystem_name_list_for_cache(const SCP_vector& subsystem_names); TriStateBool model_get_cached_ui_render_instance(int model_num, int* model_instance_out, size_t instance_data_hash = 0); void model_clear_cached_ui_render_instances(); void model_process_cached_ui_render_instances(); float convert_distance_and_diameter_to_pixel_size(float distance, float diameter, float field_of_view, int screen_width); float model_render_get_diameter_clamped_to_min_pixel_size(const vec3d* pos, float diameter, float min_pixel_size); void model_render_determine_color(color* clr, float alpha, gr_alpha_blend blend_mode, bool no_texturing, bool desaturate); gr_alpha_blend model_render_determine_blend_mode(int base_bitmap, bool blending); #endif