Files
fs2open.github.com/code/model/modelrender.h
T
asarium 3fcb731621 Refactor shader handling
This fixes a few of the bad design descisions of previous shader
iterations. This uses a dedicated class for managing the resources and
uniform locations of a shader program.

Uniforms are also stored in this object which makes a lot more sense
than storing them in the OpenGL state where they had to be reset every
time a new shader was used.

There are still a lot of possible enhancments to make, e.g. by using
uniform blocks and buffers instead of standard uniforms which would make
uniform location handling easier.

Another optimization that I will investigate is reducing the amount or
different compiled shaders by turning some of the current compile-time
defines into bool uniforms.
2016-08-29 12:38:38 +02:00

328 lines
8.5 KiB
C++

/*
* 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/opengl/gropengltnl.h"
#include "graphics/material.h"
#include "lighting/lighting.h"
#include "math/vecmat.h"
#include "model/model.h"
extern light Lights[MAX_LIGHTS];
extern int Num_lights;
extern bool Rendering_to_shadow_map;
extern matrix Object_matrix;
extern vec3d Object_position;
inline int in_box(vec3d *min, vec3d *max, vec3d *pos, 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(vec3d *pos, float radius, vec3d *view_position)
{
if ( vm_vec_dist(view_position, pos) <= radius )
return 1;
else
return -1;
}
extern int model_interp_get_texture(texture_info *tinfo, fix base_frametime);
struct transform_old
{
matrix basis;
vec3d origin;
transform_old(): basis(vmd_identity_matrix), origin(vmd_zero_vector) {}
transform_old(matrix *m, vec3d *v): basis(*m), origin(*v) {}
matrix4 get_matrix4()
{
matrix4 new_mat;
new_mat.a1d[0] = basis.vec.rvec.xyz.x; new_mat.a1d[4] = basis.vec.uvec.xyz.x; new_mat.a1d[8] = basis.vec.fvec.xyz.x;
new_mat.a1d[1] = basis.vec.rvec.xyz.y; new_mat.a1d[5] = basis.vec.uvec.xyz.y; new_mat.a1d[9] = basis.vec.fvec.xyz.y;
new_mat.a1d[2] = basis.vec.rvec.xyz.z; new_mat.a1d[6] = basis.vec.uvec.xyz.z; new_mat.a1d[10] = basis.vec.fvec.xyz.z;
new_mat.a1d[12] = origin.xyz.x;
new_mat.a1d[13] = origin.xyz.y;
new_mat.a1d[14] = origin.xyz.z;
new_mat.a1d[15] = 1.0f;
return new_mat;
}
};
class model_render_params
{
uint Model_flags;
uint Debug_flags;
int Objnum;
int Detail_level_locked;
float Depth_scale;
int Warp_bitmap;
float Warp_alpha;
vec3d Warp_scale;
color Color;
float Xparent_alpha;
int Forced_bitmap;
int Insignia_bitmap;
int *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;
bool Normal_alpha;
float Normal_alpha_min;
float Normal_alpha_max;
bool Normal_extrude;
float Normal_extrude_width;
public:
model_render_params();
void set_flags(uint 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_warp_params(int bitmap, float alpha, vec3d &scale);
void set_color(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(int *textures);
void set_team_color(team_color &clr);
void set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
void set_clip_plane(vec3d &pos, vec3d &normal);
void set_animated_effect(int effect_num, float timer);
void set_thruster_info(mst_info &info);
void set_normal_alpha(float min, float max);
void set_normal_extrude_width(float width);
bool is_clip_plane_set();
bool is_team_color_set();
bool is_normal_alpha_set();
bool is_normal_extrude_set();
uint get_model_flags();
uint get_debug_flags();
int get_object_number();
int get_detail_level_lock();
float get_depth_scale();
int get_warp_bitmap();
float get_warp_alpha();
const vec3d& get_warp_scale();
const color& get_color();
float get_alpha();
int get_forced_bitmap();
int get_insignia_bitmap();
const int* get_replacement_textures();
const team_color& get_team_color();
const vec3d& get_clip_plane_pos();
const vec3d& get_clip_plane_normal();
int get_animated_effect_num();
float get_animated_effect_timer();
const mst_info& get_thruster_info();
float get_normal_alpha_min();
float get_normal_alpha_max();
float get_normal_extrude_width();
};
struct arc_effect
{
transform transformation;
vec3d v1;
vec3d v2;
color primary;
color secondary;
float width;
};
struct insignia_draw_data
{
transform transformation;
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;
model_material render_material;
transform transformation;
vec3d scale;
indexed_vertex_source *vert_src;
vertex_buffer *buffer;
size_t texi;
int flags;
int sdr_flags;
light_indexing_info lights;
queued_buffer_draw()
{
}
};
struct outline_draw
{
vertex* vert_array;
int n_verts;
transform transformation;
color clr;
};
class model_batch_buffer
{
SCP_vector<matrix4> Submodel_matrices;
void* Mem_alloc;
size_t Mem_alloc_size;
size_t Current_offset;
void allocate_memory();
public:
model_batch_buffer() : Mem_alloc(NULL), Mem_alloc_size(0), Current_offset(0) {};
void reset();
size_t get_buffer_offset();
void set_num_models(int n_models);
void set_model_transform(matrix4 &transform, int model_id);
void submit_buffer_data();
void add_matrix(matrix4 &mat);
};
class draw_list
{
transform Current_transform;
vec3d Current_scale;
SCP_vector<transform> Transform_stack;
scene_lights Scene_light_handler;
light_indexing_info Current_lights_set;
void render_arc(arc_effect &arc);
void render_insignia(insignia_draw_data &insignia_info);
void render_outline(outline_draw &outline_info);
void render_buffer(queued_buffer_draw &render_elements);
SCP_vector<queued_buffer_draw> Render_elements;
SCP_vector<int> Render_keys;
SCP_vector<arc_effect> Arcs;
SCP_vector<insignia_draw_data> Insignias;
SCP_vector<outline_draw> Outlines;
static draw_list *Target;
static bool sort_draw_pair(const int a, const int b);
void sort_draws();
public:
draw_list();
void init();
void add_submodel_to_batch(int model_num);
void start_model_batch(int n_models);
void add_buffer_draw(model_material *render_material, indexed_vertex_source *vert_src, vertex_buffer *buffer, size_t texi, uint tmap_flags);
vec3d get_view_position();
void clear_transforms();
void push_transform(vec3d* pos, matrix* orient);
void pop_transform();
void set_scale(vec3d *scale = NULL);
void add_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
void render_arcs();
void add_insignia(model_render_params *params, polymodel *pm, int detail_level, int bitmap_num);
void render_insignias();
void add_outline(vertex* vert_array, int n_verts, color *clr);
void render_outlines();
void set_light_filter(int objnum, vec3d *pos, float rad);
void init_render(bool sort = true);
void render_all(gr_zbuffer_type depth_mode = ZBUFFER_TYPE_DEFAULT);
void reset();
};
class DrawListSorter
{
static draw_list *Target;
public:
static void sort(draw_list *target);
static int sortDrawPair(const void* a, const void* b);
};
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d * pos, int render = MODEL_RENDER_ALL, bool sort = true);
void model_render_queue(model_render_params *render_info, draw_list* scene, int model_num, matrix *orient, vec3d *pos);
void submodel_render_immediate(model_render_params *render_info, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void submodel_render_queue(model_render_params *render_info, draw_list *scene, int model_num, int submodel_num, matrix *orient, vec3d * pos);
void model_render_buffers(draw_list* scene, model_material *rendering_material, model_render_params* interp, vertex_buffer *buffer, polymodel *pm, int mn, int detail_level, uint tmap_flags);
void model_render_set_thrust(model_render_params *interp, int model_num, mst_info *mst);
void model_render_set_clip_plane(model_render_params *interp, vec3d *pos = NULL, vec3d *normal = NULL);
fix model_render_determine_base_frametime(int objnum, uint flags);
bool model_render_check_detail_box(vec3d *view_pos, polymodel *pm, int submodel_num, uint flags);
void model_render_arc(vec3d *v1, vec3d *v2, color *primary, color *secondary, float arc_width);
void model_render_insignias(insignia_draw_data *insignia);
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